TODO hongjun: find table from parent select statement, should find table in subquery level only
779140
public static Optional<String> findTableName(final PredicateSegment predicateSegment, final SQLStatement sqlStatement, final ShardingTableMetaData shardingTableMetaData) {
        if (!(sqlStatement instanceof SelectStatement)) {
            return Optional.of(sqlStatement.getTables().getSingleTableName());
        }
        SelectStatement currentSelectStatement = (SelectStatement) sqlStatement;
        while (null != currentSelectStatement.getParentStatement()) {
            currentSelectStatement = currentSelectStatement.getParentStatement();
            Optional<String> tableName = findTableName(predicateSegment, currentSelectStatement.getTables(), shardingTableMetaData);
            if (tableName.isPresent()) {
                return tableName;
            }
        }
        return findTableName(predicateSegment, currentSelectStatement.getTables(), shardingTableMetaData);
    }
1314355
def split_subquery(sql):
    """"""
    sql, params = mark_quoted_strings(sql)
    sql = simplify_expression(sql)
    _ = params  # NOQA
    start = 0
    out = []
    subqueries = []
    pattern = re.compile(r'\(SELECT\b', re.I)
    match = pattern.search(sql, start)
    while match:
        out.append(sql[start:match.start() + 1] + '&')
        start, pos = find_closing_parenthesis(sql, match.start())
        start, pos = start + 1, pos - 1
        subqueries.append(split_subquery(sql[start:pos]))
        start = pos
        match = pattern.search(sql, start)
    out.append(sql[start:len(sql)])
    return ''.join(out), subqueries
321642
private String chooseFirstOccurence(String[] among_owners, String[] within_listgroup,
			String prior_tableName) {
		int index = CStringUtils.indexOf(within_listgroup, prior_tableName);
		for(int i = index-1; i >= 0; i-- ){
			String closest = within_listgroup[i];
			if(CStringUtils.indexOf(among_owners, closest) >= 0){
				return closest;
			}
		}
		return null;
	}
400275
@Override
    public <E> List<E> getColumnsById(String schemaName, String tableName, String pKeyColumnName, String columnName,
        Object pKeyColumnValue, Class columnJavaType) {
        // select columnName from tableName where pKeyColumnName =
        // pKeyColumnValue
        List results = new ArrayList();
        CQLTranslator translator = new CQLTranslator();
        String selectQuery = translator.SELECT_QUERY;
        selectQuery = StringUtils.replace(selectQuery, CQLTranslator.COLUMN_FAMILY,
            translator.ensureCase(new StringBuilder(), tableName, false).toString());
        selectQuery = StringUtils.replace(selectQuery, CQLTranslator.COLUMNS,
            translator.ensureCase(new StringBuilder(), columnName, false).toString());

        StringBuilder selectQueryBuilder = new StringBuilder(selectQuery);

        selectQueryBuilder.append(CQLTranslator.ADD_WHERE_CLAUSE);

        translator.buildWhereClause(selectQueryBuilder, columnJavaType, pKeyColumnName, pKeyColumnValue,
            CQLTranslator.EQ_CLAUSE, false);
        selectQueryBuilder.delete(selectQueryBuilder.lastIndexOf(CQLTranslator.AND_CLAUSE),
            selectQueryBuilder.length());

        ResultSet rSet = execute(selectQueryBuilder.toString(), null);

        Iterator<Row> rowIter = rSet.iterator();
        while (rowIter.hasNext()) {
            Row row = rowIter.next();
            DataType dataType = row.getColumnDefinitions().getType(columnName);
            Object columnValue =
                DSClientUtilities.assign(row, null, null, dataType.getName(), null, columnName, null, null);
            results.add(columnValue);
        }
        return results;
    }
266927
def select(self, fields=['rowid', '*'], offset=None, limit=None):
        ''' 
        '''
        # base SQL
        SQL = 'SELECT %s FROM %s' % (','.join(fields), self._table)
        
        # selectors
        if self._selectors:
            SQL = ' '.join([SQL, 'WHERE', self._selectors]).strip()
        
        # modifiers
        if self._modifiers:
            SQL = ' '.join([SQL, self._modifiers])

        # limit
        if limit is not None and isinstance(limit, int):
            SQL = ' '.join((SQL, 'LIMIT %s' % limit))

        # offset
        if (limit is not None) and (offset is not None) and isinstance(offset, int):
            SQL = ' '.join((SQL, 'OFFSET %s' % offset))

        return ''.join((SQL, ';'))
1258733
public <T extends Object, O extends Object> List<T> findBySQL(String sql, List<O> params, RowMapper<T> mapper) {

        if (sql == null) {
            recordLog(" param sql is null!");
        }

        // 构造参数
        Object[] args = null;
        if (params == null) {
            args = new Object[0];
        } else {
            args = params.toArray(new Object[params.size()]);
        }

        // 查询
        if (params != null) {
            recordLog(sql + "\t" + params.toString());
        } else {
            recordLog(sql);
        }
        return (List<T>) jdbcTemplate.query(sql, args, mapper);
    }
434597
function traverseToParentIf(node) {
  let parent = node.parent;
  while (parent) {
    if (parent.type === 'IfStatement') {
      return parent;
    }
    parent = parent.parent;
  }
}
1158913
@Override
    public <E> List<E> getColumnsById(String schemaName, String joinTableName, String joinColumnName,
            String inverseJoinColumnName, Object parentId, Class columnJavaType)
    {
        StringBuffer sqlQuery = new StringBuffer();
        sqlQuery.append("SELECT ").append(inverseJoinColumnName).append(" FROM ")
                .append(getFromClause(schemaName, joinTableName)).append(" WHERE ").append(joinColumnName).append("='")
                .append(parentId).append("'");

        Session s = getSession();

        SQLQuery query = s.createSQLQuery(sqlQuery.toString());

        List<E> foreignKeys = new ArrayList<E>();

        foreignKeys = query.list();

        return foreignKeys;
    }
1131070
def select_join(self, table, field, join_table, join_field):
        
        sql = "select {table}.{field} from {table} left join {join_table} "\
              "on {table}.{field}={join_table}.{join_field} "\
              "where {join_table}.{join_field} is null;".format(table=table,
                                                                field=field,
                                                                join_table=join_table,
                                                                join_field=join_field)
        return super(PGWrapper, self).execute(sql, result=True).results
1263838
private String getSubQuerySQL(Query subQuery)
    {
        ClassDescriptor cld = getRoot().cld.getRepository().getDescriptorFor(subQuery.getSearchClass());
        String sql;

        if (subQuery instanceof QueryBySQL)
        {
            sql = ((QueryBySQL) subQuery).getSql();
        }
        else
        {
            sql = new SqlSelectStatement(this, m_platform, cld, subQuery, m_logger).getStatement();
        }

        return sql;
    }
1286643
private int getTotalCount(String sql, Connection conn, MappedStatement ms, BoundSql boundSql) throws SQLException {
    int start = sql.indexOf("from");
    if (start == -1) {
      throw new RuntimeException("statement has no 'from' keyword");
    }
    int stop = sql.indexOf("order by");
    if (stop == -1) {
      stop = sql.length();
    }

    String countSql = "select count(0) " + sql.substring(start, stop);
    BoundSql countBoundSql = new BoundSql(ms.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
    ParameterHandler parameterHandler = new DefaultParameterHandler(ms, boundSql.getParameterObject(), countBoundSql);
    PreparedStatement stmt = null;
    ResultSet rs = null;
    int count = 0;
    try {
      stmt = conn.prepareStatement(countSql);
      // 通过parameterHandler给PreparedStatement对象设置参数
      parameterHandler.setParameters(stmt);
      rs = stmt.executeQuery();
      if (rs.next()) {
        count = rs.getInt(1);
      }
    } finally {
      CloseableUtil.closeQuietly(rs);
      CloseableUtil.closeQuietly(stmt);
    }
    return count;
  }
659842
public Select parseSelect(MySqlSelectQueryBlock query) throws SqlParseException {

        Select select = new Select();
        /*zhongshu-comment SqlParser类没有成员变量，里面全是方法，所以将this传到WhereParser对象时是无状态的，
                          即SqlParser对象并没有给WhereParser传递任何属性，也不存在WhereParser修改SqlParser的成员变量值这一说
                         WhereParser只是单纯想调用SqlParser的方法而已
        */
        WhereParser whereParser = new WhereParser(this, query);

        /*
        zhongshu-comment 例如sql：select   a,sum(b),case when c='a' then 1 else 2 end as my_c from tbl，
        那findSelect()就是解析这一部分了：a,sum(b),case when c='a' then 1 else 2 end as my_c
         */
        findSelect(query, select, query.getFrom().getAlias()); //zhongshu-comment 看过

        select.getFrom().addAll(findFrom(query.getFrom())); //zhongshu-comment 看过

        select.setWhere(whereParser.findWhere()); //zhongshu-comment 看过

        //zhongshu-comment 这个应该是针对where子查询的，而不是from子查询，貌似又不是解析from子查询的，报错了
        //zhongshu-comment 也许es本身就不支持子查询，所以es-sql就没实现，那这个fillSubQueries是什么啊？？
        //todo 看不懂，测试了好几个常见的sql，都没有进去该方法，那就先不理了，看别的
        select.fillSubQueries();

        //zhongshu-comment 解析sql语句中的注释：select /*! USE_SCROLL(10,120000) */ * FROM spark_es_table
        //hint单词的意思是提示，即sql中的注释内容
        // /* 和 */之间是sql的注释内容，这是sql本身的语法，然后sql解析器会将注释块之间的内容“! USE_SCROLL(10,120000) ”抽取出来
        // ! USE_SCROLL是es-sql自己定义的一套规则，
        // 在不增加mysql原有语法的情况下，利用注释来灵活地扩展es-sql的功能，这样就能使用druid的mysql语法解析器了，无需自己实现
        // 注意：!叹号和USE_SCROLL之间要空且只能空一格
        select.getHints().addAll(parseHints(query.getHints()));

        findLimit(query.getLimit(), select);

        //zhongshu-comment 和那个_score有关
        findOrderBy(query, select); //zhongshu-comment 还没看

        findGroupBy(query, select); //zhongshu-comment aggregations
        return select;
    }
475139
@Override
  public void findAll(Result<Iterable<byte[]>> result,
                      byte []tableKey,
                      String sql, 
                      Object[] args)
  {
    try {
      TableKraken table = _tableManager.getTable(tableKey);
      
      if (table == null) {
        throw new QueryException(L.l("'{0}' is an unknown table.",
                                     Hex.toShortHex(tableKey)));
      }
      
      QueryBuilderKraken builder = QueryParserKraken.parse(_tableManager, sql);
      
      QueryKraken query = builder.build();
      
      query.findAllLocalKeys(result, args);
    } catch (Throwable e) {
      result.fail(e);
    }
  }
174675
def select_all(self, table, limit=MAX_ROWS_PER_QUERY, execute=True):
        """"""
        # Determine if a row per query limit should be set
        num_rows = self.count_rows(table)
        if num_rows > limit:
            return self._select_batched(table, '*', num_rows, limit, execute=execute)
        else:
            return self.select(table, '*', execute=execute)
1129510
@Override
    protected AstNode parseCustomStatement( DdlTokenStream tokens,
                                            AstNode parentNode ) throws ParsingException {
        assert tokens != null;
        assert parentNode != null;

        if (tokens.matches(STMT_RENAME_DATABASE)) {
            markStartOfStatement(tokens);

            // RENAME DATABASE db_name TO new_db_name;
            tokens.consume(STMT_RENAME_DATABASE);
            String oldName = parseName(tokens);
            tokens.consume("TO");
            AstNode node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_DATABASE_STATEMENT);
            String newName = parseName(tokens);
            node.setProperty(NEW_NAME, newName);

            markEndOfStatement(tokens, node);
            return node;
        } else if (tokens.matches(STMT_RENAME_SCHEMA)) {
            markStartOfStatement(tokens);

            // RENAME SCHEMA schema_name TO new_schema_name;
            tokens.consume(STMT_RENAME_SCHEMA);
            String oldName = parseName(tokens);
            tokens.consume("TO");
            AstNode node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_SCHEMA_STATEMENT);
            String newName = parseName(tokens);
            node.setProperty(NEW_NAME, newName);

            markEndOfStatement(tokens, node);
            return node;
        } else if (tokens.matches(STMT_RENAME_TABLE)) {
            markStartOfStatement(tokens);

            // RENAME TABLE old_table TO tmp_table,
            // new_table TO old_table,
            // tmp_table TO new_table;
            tokens.consume(STMT_RENAME_TABLE);

            String oldName = parseName(tokens);
            tokens.consume("TO");
            String newName = parseName(tokens);

            AstNode node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_TABLE_STATEMENT);
            node.setProperty(NEW_NAME, newName);

            // IF NOT MULTIPLE RENAMES, FINISH AND RETURN
            if (!tokens.matches(COMMA)) {
                markEndOfStatement(tokens, node);
                return node;
            }

            // Assume multiple renames

            // Create list of nodes so we can re-set the expression of each to reflect ONE rename.
            List<AstNode> nodes = new ArrayList<AstNode>();
            nodes.add(node);

            while (tokens.matches(COMMA)) {
                tokens.consume(COMMA);
                oldName = parseName(tokens);
                tokens.consume("TO");
                newName = parseName(tokens);
                node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_TABLE_STATEMENT);
                node.setProperty(NEW_NAME, newName);
                nodes.add(node);
            }

            markEndOfStatement(tokens, nodes.get(0));

            String originalExpression = (String)nodes.get(0).getProperty(DDL_EXPRESSION);
            Object startLineNumber = nodes.get(0).getProperty(DDL_START_LINE_NUMBER);
            Object startColumnNumber = nodes.get(0).getProperty(DDL_START_COLUMN_NUMBER);
            Object startCharIndex = nodes.get(0).getProperty(DDL_START_CHAR_INDEX);

            for (AstNode nextNode : nodes) {
                oldName = nextNode.getName();
                newName = (String)nextNode.getProperty(NEW_NAME);
                String express = "RENAME TABLE" + SPACE + oldName + SPACE + "TO" + SPACE + newName + SEMICOLON;
                nextNode.setProperty(DDL_EXPRESSION, express);
                nextNode.setProperty(DDL_ORIGINAL_EXPRESSION, originalExpression);
                nextNode.setProperty(DDL_START_LINE_NUMBER, startLineNumber);
                nextNode.setProperty(DDL_START_COLUMN_NUMBER, startColumnNumber);
                nextNode.setProperty(DDL_START_CHAR_INDEX, startCharIndex);
            }

            return nodes.get(0);
        }

        return super.parseCustomStatement(tokens, parentNode);
    }
224805
def query(self, parents=None):
        
        # TODO: benchmark single-query strategy
        q = Select([])
        q = self.project(q, parent=True)
        q = self.filter(q, parents=parents)

        if self.parent is None:
            subq = Select([self.var])
            subq = self.filter(subq, parents=parents)
            subq = subq.offset(self.node.offset)
            subq = subq.limit(self.node.limit)
            subq = subq.distinct()
            # TODO: sorting.
            subq = subq.order_by(desc(self.var))
            q = q.where(subq)

        # if hasattr(self.context, 'identifier'):
        #     q._where = graph(self.context.identifier, q._where)
        log.debug("Compiled query: %r", q.compile())
        return q
56115
def subquery(self, name=None):
        
        query = self.query()
        return query.subquery(name=name)