Parse SQL.

@param useCache use cache or not
@return parsed SQL statement
16780
public SQLStatement parse(final boolean useCache) {
        Optional<SQLStatement> cachedSQLStatement = getSQLStatementFromCache(useCache);
        if (cachedSQLStatement.isPresent()) {
            return cachedSQLStatement.get();
        }
        LexerEngine lexerEngine = LexerEngineFactory.newInstance(dbType, sql);
        SQLStatement result = SQLParserFactory.newInstance(dbType, shardingRule, lexerEngine, shardingTableMetaData, sql).parse();
        if (useCache) {
            parsingResultCache.put(sql, result);
        }
        return result;
    }
1065272
public function buildCache($table = null, $key = null, $cache = null)
    {
        if ($this->sql &&
            ($table === null || $this->setTableName($table)) &&
            ($key === null || $this->setKeyName($key)) &&
            ($cache === null || $this->setCacheName($cache))) {
            if ($this->sql->query("
                CREATE TABLE IF NOT EXISTS `{$this->table}` (
                    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
                    `{$this->key}` text NOT NULL,
                    `{$this->cache}` longtext NOT NULL,
                    `expire` timestamp NULL DEFAULT NULL,
                    `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                    PRIMARY KEY (`id`)
                );
            ")) {
                $this->initialized = true;

                /* Upgrade older cache tables for longer cache data */
                $this->sql->query("
                    ALTER TABLE `{$this->table}` CHANGE `{$this->cache}` `{$this->cache}` longtext NOT NULL;
                ");

                /* Upgrade older cached tables to include an expire column for each row */
                $this->sql->query("
                    ALTER TABLE `{$this->table}` ADD `expire` timestamp NULL DEFAULT NULL AFTER `{$this->cache};
                ");
            }
        }
        return $this->initialized;
    }
1148423
public void parse(final InsertStatement insertStatement) {
        if (!lexerEngine.skipIfEqual(getCustomizedInsertKeywords())) {
            return;
        }
        lexerEngine.accept(DefaultKeyword.DUPLICATE);
        lexerEngine.accept(DefaultKeyword.KEY);
        lexerEngine.accept(DefaultKeyword.UPDATE);
        do {
            Column column = new Column(SQLUtil.getExactlyValue(lexerEngine.getCurrentToken().getLiterals()), insertStatement.getTables().getSingleTableName());
            if (shardingRule.isShardingColumn(column.getName(), column.getTableName())) {
                throw new SQLParsingException("INSERT INTO .... ON DUPLICATE KEY UPDATE can not support on sharding column, token is '%s', literals is '%s'.",
                        lexerEngine.getCurrentToken().getType(), lexerEngine.getCurrentToken().getLiterals());
            }
            basicExpressionParser.parse(insertStatement);
            lexerEngine.accept(Symbol.EQ);
            if (lexerEngine.skipIfEqual(DefaultKeyword.VALUES)) {
                lexerEngine.accept(Symbol.LEFT_PAREN);
                basicExpressionParser.parse(insertStatement);
                lexerEngine.accept(Symbol.RIGHT_PAREN);
            } else {
                lexerEngine.nextToken();
            }
        } while (lexerEngine.skipIfEqual(Symbol.COMMA));
    }
1158101
public static String getIfCacheNotNull(EntityColumn column, String contents) {
        StringBuilder sql = new StringBuilder();
        sql.append("<if test=\"").append(column.getProperty()).append("_cache != null\">");
        sql.append(contents);
        sql.append("</if>");
        return sql.toString();
    }
715603
private QueryBuilderKraken parseUpdate()
  {
    Token token;
    
    UpdateQueryBuilder query = new UpdateQueryBuilder(_tableManager, _sql);
    
    String tableName = parseTableName();

    query.setTableName(tableName);

    _query = query;

    if ((token = scanToken()) != Token.SET) {
      throw error(L.l("expected SET at {0}", token));
    }

    do {
      parseSetItem(query);
    } while ((token = scanToken()) == Token.COMMA);
    
    _token = token;

    //query.setUpdateBuilder(new SetUpdateBuilder(setItems));
    
    ExprKraken whereExpr = null;

    token = scanToken();
    
    if (token == Token.WHERE) {
      whereExpr = parseExpr();
    }
    else if (token != null && token != Token.EOF) {
      throw error("expected WHERE at '{0}'", token);
    }

    ParamExpr []params = _params.toArray(new ParamExpr[_params.size()]);

    query.setParams(params);
    query.setWhereExpr(whereExpr);

    return query;
  }
754880
public void parse(final InsertStatement insertStatement) {
        lexerEngine.unsupportedIfEqual(getUnsupportedKeywordsBeforeInto());
        lexerEngine.skipUntil(DefaultKeyword.INTO);
        lexerEngine.nextToken();
        tableReferencesClauseParser.parse(insertStatement, true);
        skipBetweenTableAndValues(insertStatement);
    }
241270
public function useCache($caching = null)
    {
        if (is_null($caching)) {
            return ($this->useCache && $this->getCache());
        }

        $this->useCache = (bool) $caching;

        return $this;
    }
1355484
public static <K, V> Cache<K, V> createCache(String sqlCacheClass, String prefix, Properties properties) {
        if (StringUtil.isEmpty(sqlCacheClass)) {
            try {
                Class.forName("com.google.common.cache.Cache");
                return new GuavaCache<K, V>(properties, prefix);
            } catch (Throwable t) {
                return new SimpleCache<K, V>(properties, prefix);
            }
        } else {
            try {
                Class<? extends Cache> clazz = (Class<? extends Cache>) Class.forName(sqlCacheClass);
                try {
                    Constructor<? extends Cache> constructor = clazz.getConstructor(Properties.class, String.class);
                    return constructor.newInstance(properties, prefix);
                } catch (Exception e) {
                    return clazz.newInstance();
                }
            } catch (Throwable t) {
                throw new PageException("Created Sql Cache [" + sqlCacheClass + "] Error", t);
            }
        }
    }
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;
    }
62291
private QueryParameters readCachedValue(int index) {
        QueryParameters result = null;

        if (generatedCacheMap.containsKey(index) == true) {
            result = generatedCacheMap.get(index);
        } else if (resultSetCacheMap.containsKey(index) == true) {
            result = resultSetCacheMap.get(index);
        }

        return result;
    }
554260
private void parseInputQuery(String query) {
    List<String> projectedColumns = new ArrayList<>();
    if (StringUtils.isNotBlank(query)) {
      String queryLowerCase = query.toLowerCase();
      int startIndex = queryLowerCase.indexOf("select ") + 7;
      int endIndex = queryLowerCase.indexOf(" from ");
      if (startIndex >= 0 && endIndex >= 0) {
        String columnProjection = query.substring(startIndex, endIndex);
        this.setInputColumnProjection(columnProjection);
        // parse the select list
        StringBuffer sb = new StringBuffer();
        int bracketCount = 0;
        for (int i = 0; i < columnProjection.length(); i++) {
          char c = columnProjection.charAt(i);
          if (c == '(') {
            bracketCount++;
          }

          if (c == ')') {
            bracketCount--;
          }

          if (bracketCount != 0) {
            sb.append(c);
          } else {
            if (c != ',') {
              sb.append(c);
            } else {
              projectedColumns.add(sb.toString());
              sb = new StringBuffer();
            }
          }
        }
        projectedColumns.add(sb.toString());
      }
    }

    if (this.isSelectAllColumns()) {
      List<String> columnList = this.getMetadataColumnList();
      for (String columnName : columnList) {
        ColumnAttributes col = new ColumnAttributes();
        col.setColumnName(columnName);
        col.setAliasName(columnName);
        col.setSourceColumnName(columnName);
        this.addToColumnAliasMap(col);
      }
    } else {
      for (String projectedColumn : projectedColumns) {
        String column = projectedColumn.trim();
        String alias = null;
        String sourceColumn = column;
        int spaceOccurences = StringUtils.countMatches(column.trim(), " ");
        if (spaceOccurences > 0) {
          // separate column and alias if they are separated by "as"
          // or space
          int lastSpaceIndex = column.toLowerCase().lastIndexOf(" as ");
          sourceColumn = column.substring(0, lastSpaceIndex);
          alias = column.substring(lastSpaceIndex + 4);
        }

        // extract column name if projection has table name in it
        String columnName = sourceColumn;
        if (sourceColumn.contains(".")) {
          columnName = sourceColumn.substring(sourceColumn.indexOf(".") + 1);
        }

        ColumnAttributes col = new ColumnAttributes();
        col.setColumnName(columnName);
        col.setAliasName(alias);
        col.setSourceColumnName(sourceColumn);
        this.addToColumnAliasMap(col);
      }
    }
  }
601368
public GetCacheQuotaResponse getCacheQuota(GetCacheQuotaRequest request) {
        InternalRequest internalRequest = this.createRequest(request, HttpMethodName.GET, CACHE, "quota");
        return this.invokeHttpClient(internalRequest, GetCacheQuotaResponse.class);
    }
462976
public InternalQueryCache<K, V> tryCreateQueryCache(String mapName, String cacheName,
                                                        ConstructorFunction<String, InternalQueryCache<K, V>> constructor) {

        ContextMutexFactory.Mutex mutex = lifecycleMutexFactory.mutexFor(mapName);
        try {
            synchronized (mutex) {
                ConcurrentMap<String, InternalQueryCache<K, V>> queryCacheRegistry
                        = getOrPutIfAbsent(queryCacheRegistryPerMap, mapName, queryCacheRegistryConstructor);

                InternalQueryCache<K, V> queryCache = queryCacheRegistry.get(cacheName);
                // if this is a recreation we expect to have a Uuid otherwise we
                // need to generate one for the first creation of query cache.
                String cacheId = queryCache == null
                        ? UuidUtil.newUnsecureUuidString() : queryCache.getCacheId();

                queryCache = constructor.createNew(cacheId);

                if (queryCache != NULL_QUERY_CACHE) {
                    queryCacheRegistry.put(cacheName, queryCache);
                    return queryCache;
                }

                return null;
            }
        } finally {
            closeResource(mutex);
        }
    }
1126115
protected void applyCacheHints(TypedQuery<?> typedQuery, SearchParameters sp) {
        if (sp.isCacheable()) {
            typedQuery.setHint("org.hibernate.cacheable", true);

            if (sp.hasCacheRegion()) {
                typedQuery.setHint("org.hibernate.cacheRegion", sp.getCacheRegion());
            } else {
                typedQuery.setHint("org.hibernate.cacheRegion", cacheRegion);
            }
        }
    }
854585
private static void cacheOnStart()
    {
        try {
            boolean closeContext = false;
            if (!Context.isThreadActive()) {
                Context.begin();
                closeContext = true;
            }
            Context.getThreadContext();
            final Connection con = Context.getConnection();
            final PreparedStatement stmtLang = con.prepareStatement(DBProperties.SQLLANG);
            final ResultSet rsLang = stmtLang.executeQuery();
            final Set<String> languages = new HashSet<>();
            while (rsLang.next()) {
                languages.add(rsLang.getString(1).trim());
            }
            rsLang.close();
            stmtLang.close();
            final Cache<String, String> cache = InfinispanCache.get().<String, String>getCache(
                            DBProperties.CACHENAME);
            final PreparedStatement stmt = con.prepareStatement(DBProperties.SQLSELECTONSTART);
            final ResultSet resultset = stmt.executeQuery();
            while (resultset.next()) {
                final String propKey = resultset.getString(1).trim();
                final String defaultValue = resultset.getString(2);
                if (defaultValue != null) {
                    final String value = defaultValue.trim();
                    for (final String lang : languages) {
                        final String cachKey = lang + ":" + propKey;
                        if (!cache.containsKey(cachKey)) {
                            cache.put(cachKey, value);
                        }
                    }
                }
                final String value = resultset.getString(3);
                final String lang = resultset.getString(4);
                if (value != null) {
                    final String cachKey = lang.trim() + ":" + propKey;
                    cache.put(cachKey, value.trim());
                }
            }
            resultset.close();
            stmt.close();
            con.commit();
            con.close();
            if (closeContext) {
                Context.rollback();
            }
        } catch (final EFapsException e) {
            DBProperties.LOG.error("initialiseCache()", e);
        } catch (final SQLException e) {
            DBProperties.LOG.error("initialiseCache()", e);
        }
    }
436069
private static synchronized Object getFromCache(Cache cache,
            byte[] encoding) {
        Object key = new Cache.EqualByteArray(encoding);
        Object value = cache.get(key);
        return value;
    }
41938
public void parse(final InsertStatement insertStatement) {
        if (!lexerEngine.skipIfEqual(getCustomizedInsertKeywords())) {
            return;
        }
        removeUnnecessaryToken(insertStatement);
        Optional<InsertValuesToken> insertValuesToken = insertStatement.findSQLToken(InsertValuesToken.class);
        Preconditions.checkState(insertValuesToken.isPresent());
        insertStatement.getSQLTokens().remove(insertValuesToken.get());
        insertStatement.addSQLToken(new InsertSetToken(insertValuesToken.get().getStartIndex()));
        do {
            SQLExpression left = basicExpressionParser.parse(insertStatement);
            Column column = null;
            if (left instanceof SQLPropertyExpression) {
                column = new Column(SQLUtil.getExactlyValue(((SQLPropertyExpression) left).getName()), insertStatement.getTables().getSingleTableName());
            }
            if (left instanceof SQLIdentifierExpression) {
                column = new Column(SQLUtil.getExactlyValue(((SQLIdentifierExpression) left).getName()), insertStatement.getTables().getSingleTableName());
            }
            if (left instanceof SQLIgnoreExpression) {
                column = new Column(SQLUtil.getExactlyValue(((SQLIgnoreExpression) left).getExpression()), insertStatement.getTables().getSingleTableName());
            }
            Preconditions.checkNotNull(column);
            lexerEngine.accept(Symbol.EQ);
            SQLExpression right = basicExpressionParser.parse(insertStatement);
            if (shardingRule.isShardingColumn(column.getName(), column.getTableName()) 
                    && (right instanceof SQLNumberExpression || right instanceof SQLTextExpression || right instanceof SQLParameterMarkerExpression)) {
                insertStatement.getRouteConditions().add(new Condition(column, right));
            }
        } while (lexerEngine.skipIfEqual(Symbol.COMMA));
        InsertValue insertValue = new InsertValue(new LinkedList<SQLExpression>());
        insertStatement.getValues().add(insertValue);
    }