Skip to content

Commit

Permalink
for #701, only cache preparedStatement, do not cache statement
Browse files Browse the repository at this point in the history
  • Loading branch information
terrymanu committed Apr 9, 2018
1 parent d6bb344 commit 98e400f
Show file tree
Hide file tree
Showing 13 changed files with 41 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private Iterator<MemoryQueryResultRow> init(final List<QueryResult> queryResults
memoryResultSetRow.setCell(1, logicTableName);
String createTableDDL = memoryResultSetRow.getCell(2).toString();
SQLParsingEngine sqlParsingEngine = new SQLParsingEngine(DatabaseType.MySQL, createTableDDL, shardingRule);
String actualTableName = sqlParsingEngine.parse().getTables().getSingleTableName();
String actualTableName = sqlParsingEngine.parse(true).getTables().getSingleTableName();
if (actualTableName.startsWith("`")) {
logicTableName = "`" + logicTableName + "`";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.shardingjdbc.core.parsing;

import com.google.common.base.Optional;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.cache.ParsingResultCache;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
Expand Down Expand Up @@ -45,23 +46,28 @@ public final class SQLParsingEngine {
/**
* Parse SQL.
*
* @param useCache use cache or not
* @return parsed SQL statement
*/
public SQLStatement parse() {
SQLStatement cachedSQLStatement = ParsingResultCache.getInstance().getSQLStatement(sql);
if (null != cachedSQLStatement) {
return cachedSQLStatement;
public SQLStatement parse(final boolean useCache) {
Optional<SQLStatement> cachedSQLStatement = getSQLStatementFromCache(useCache);
if (cachedSQLStatement.isPresent()) {
return cachedSQLStatement.get();
}
LexerEngine lexerEngine = LexerEngineFactory.newInstance(dbType, sql);
lexerEngine.nextToken();
SQLStatement result = SQLParserFactory.newInstance(dbType, lexerEngine.getCurrentToken().getType(), shardingRule, lexerEngine).parse();
// TODO cannot cache InsertStatement here by generate key, should not modify original InsertStatement on router.
if (!findGeneratedKeyToken(result)) {
if (useCache && !findGeneratedKeyToken(result)) {
ParsingResultCache.getInstance().put(sql, result);
}
return result;
}

private Optional<SQLStatement> getSQLStatementFromCache(final boolean useCache) {
return useCache ? Optional.fromNullable(ParsingResultCache.getInstance().getSQLStatement(sql)) : Optional.<SQLStatement>absent();
}

private boolean findGeneratedKeyToken(final SQLStatement sqlStatement) {
for (SQLToken each : sqlStatement.getSqlTokens()) {
if (each instanceof GeneratedKeyToken) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public PreparedStatementRoutingEngine(final String logicSQL, final ShardingRule
*/
public SQLRouteResult route(final List<Object> parameters) {
if (null == sqlStatement) {
sqlStatement = sqlRouter.parse(logicSQL);
sqlStatement = sqlRouter.parse(logicSQL, true);
}
return sqlRouter.route(logicSQL, parameters, sqlStatement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public StatementRoutingEngine(final ShardingRule shardingRule, final DatabaseTyp
* @return route result
*/
public SQLRouteResult route(final String logicSQL) {
SQLStatement sqlStatement = sqlRouter.parse(logicSQL);
SQLStatement sqlStatement = sqlRouter.parse(logicSQL, false);
return sqlRouter.route(logicSQL, Collections.emptyList(), sqlStatement);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public final class DatabaseHintSQLRouter implements SQLRouter {
private final boolean showSQL;

@Override
public SQLStatement parse(final String logicSQL) {
public SQLStatement parse(final String logicSQL, final boolean useCache) {
return new SQLJudgeEngine(logicSQL).judge();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public final class ParsingSQLRouter implements SQLRouter {
private final List<Number> generatedKeys = new LinkedList<>();

@Override
public SQLStatement parse(final String logicSQL) {
public SQLStatement parse(final String logicSQL, final boolean useCache) {
SQLParsingEngine parsingEngine = new SQLParsingEngine(databaseType, logicSQL, shardingRule);
SQLStatement result = parsingEngine.parse();
SQLStatement result = parsingEngine.parse(useCache);
if (result instanceof InsertStatement) {
((InsertStatement) result).appendGenerateKeyToken(shardingRule);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ public interface SQLRouter {
* Parse SQL.
*
* @param logicSQL logic SQL
* @param useCache use cache to save SQL parse result or not
* @return parse result
*/
SQLStatement parse(String logicSQL);
SQLStatement parse(String logicSQL, boolean useCache);

/**
* Route SQL.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ public static Collection<Object[]> getTestParameters() {
@Test
public void assertSupportedSQL() {
String sql = sqlCasesLoader.getSupportedSQL(sqlCaseId, sqlCaseType, parserResultSetLoader.getParserResult(sqlCaseId).getParameters());
new SQLStatementAssert(new SQLParsingEngine(databaseType, sql, getShardingRule()).parse(), sqlCaseId, sqlCaseType).assertSQLStatement();
new SQLStatementAssert(new SQLParsingEngine(databaseType, sql, getShardingRule()).parse(false), sqlCaseId, sqlCaseType).assertSQLStatement();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ public static Collection<Object[]> getTestParameters() {

@Test(expected = SQLParsingUnsupportedException.class)
public void assertUnsupportedSQL() {
new SQLParsingEngine(databaseType, sqlCasesLoader.getUnsupportedSQL(sqlCaseId, sqlCaseType, Collections.emptyList()), getShardingRule()).parse();
new SQLParsingEngine(databaseType, sqlCasesLoader.getUnsupportedSQL(sqlCaseId, sqlCaseType, Collections.emptyList()), getShardingRule()).parse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public final class DeleteStatementParserTest extends AbstractStatementParserTest
public void parseWithoutCondition() {
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, "DELETE FROM TABLE_XXX", shardingRule);
DMLStatement deleteStatement = (DMLStatement) statementParser.parse();
DMLStatement deleteStatement = (DMLStatement) statementParser.parse(false);
assertThat(deleteStatement.getTables().find("TABLE_XXX").get().getName(), is("TABLE_XXX"));
}

Expand All @@ -53,7 +53,7 @@ public void parseWithoutParameter() {
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL,
"DELETE FROM TABLE_XXX xxx WHERE field4<10 AND TABLE_XXX.field1=1 AND field5>10 AND xxx.field2 IN (1,3) AND field6<=10 AND field3 BETWEEN 5 AND 20 AND field7>=10", shardingRule);
DMLStatement deleteStatement = (DMLStatement) statementParser.parse();
DMLStatement deleteStatement = (DMLStatement) statementParser.parse(false);
assertDeleteStatementWithoutParameter(deleteStatement);
}

Expand Down Expand Up @@ -81,7 +81,7 @@ public void parseWithParameter() {
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL,
"DELETE FROM TABLE_XXX xxx WHERE field4<? AND field1=? AND field5>? AND field2 IN (?,?) AND field6<=? AND field3 BETWEEN ? AND ? AND field7>=?", shardingRule);
DMLStatement deleteStatement = (DMLStatement) statementParser.parse();
DMLStatement deleteStatement = (DMLStatement) statementParser.parse(false);
assertDeleteStatementWithParameter(deleteStatement);
}

Expand All @@ -107,13 +107,13 @@ private void assertDeleteStatementWithParameter(final DMLStatement deleteStateme
@Test(expected = UnsupportedOperationException.class)
public void parseStatementWithDeleteMultipleTable() {
ShardingRule shardingRule = createShardingRule();
new SQLParsingEngine(DatabaseType.MySQL, "DELETE TABLE_XXX1, TABLE_xxx2 FROM TABLE_XXX1 JOIN TABLE_XXX2", shardingRule).parse();
new SQLParsingEngine(DatabaseType.MySQL, "DELETE TABLE_XXX1, TABLE_xxx2 FROM TABLE_XXX1 JOIN TABLE_XXX2", shardingRule).parse(false);
}

@Test(expected = UnsupportedOperationException.class)
public void parseStatementWithDeleteMultipleTableWithUsing() {
ShardingRule shardingRule = createShardingRule();
new SQLParsingEngine(DatabaseType.MySQL, "DELETE FROM TABLE_XXX1, TABLE_xxx2 USING TABLE_XXX1 JOIN TABLE_XXX2", shardingRule).parse();
new SQLParsingEngine(DatabaseType.MySQL, "DELETE FROM TABLE_XXX1, TABLE_xxx2 USING TABLE_XXX1 JOIN TABLE_XXX2", shardingRule).parse(false);
}

@Test
Expand All @@ -125,7 +125,7 @@ public void parseWithSpecialSyntax() {

private void parseWithSpecialSyntax(final DatabaseType dbType, final String actualSQL) {
ShardingRule shardingRule = createShardingRule();
DMLStatement deleteStatement = (DMLStatement) new SQLParsingEngine(dbType, actualSQL, shardingRule).parse();
DMLStatement deleteStatement = (DMLStatement) new SQLParsingEngine(dbType, actualSQL, shardingRule).parse(false);
assertThat(deleteStatement.getTables().find("TABLE_XXX").get().getName(), is("TABLE_XXX"));
assertFalse(deleteStatement.getTables().find("TABLE_XXX").get().getAlias().isPresent());
Condition condition = deleteStatement.getConditions().find(new Column("field1", "TABLE_XXX")).get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,23 @@ public final class InsertStatementParserTest extends AbstractStatementParserTest
public void assertParseWithoutParameter() {
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, "INSERT INTO `TABLE_XXX` (`field1`, `field2`) VALUES (10, 1)", shardingRule);
InsertStatement insertStatement = (InsertStatement) statementParser.parse();
InsertStatement insertStatement = (InsertStatement) statementParser.parse(false);
assertInsertStatementWithoutParameter(insertStatement);
}

@Test
public void assertParseWithParameter() {
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, "INSERT INTO TABLE_XXX (field1, field2) VALUES (?, ?)", shardingRule);
InsertStatement insertStatement = (InsertStatement) statementParser.parse();
InsertStatement insertStatement = (InsertStatement) statementParser.parse(false);
assertInsertStatementWithParameter(insertStatement);
}

@Test
public void assertParseWithGenerateKeyColumnsWithoutParameter() {
ShardingRule shardingRule = createShardingRuleWithGenerateKeyColumns();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, "INSERT INTO `TABLE_XXX` (`field1`) VALUES (10)", shardingRule);
InsertStatement insertStatement = (InsertStatement) statementParser.parse();
InsertStatement insertStatement = (InsertStatement) statementParser.parse(false);
assertInsertStatementWithoutParameter(insertStatement);
}

Expand All @@ -84,7 +84,7 @@ private void assertInsertStatementWithoutParameter(final InsertStatement insertS
public void assertParseWithGenerateKeyColumnsWithParameter() {
ShardingRule shardingRule = createShardingRuleWithGenerateKeyColumns();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, "INSERT INTO `TABLE_XXX` (`field1`) VALUES (?)", shardingRule);
InsertStatement insertStatement = (InsertStatement) statementParser.parse();
InsertStatement insertStatement = (InsertStatement) statementParser.parse(false);
assertInsertStatementWithParameter(insertStatement);
}

Expand Down Expand Up @@ -129,7 +129,7 @@ public void parseWithSpecialSyntax() {
@SuppressWarnings("unchecked")
private void parseWithSpecialSyntax(final DatabaseType dbType, final String actualSQL) {
ShardingRule shardingRule = createShardingRule();
InsertStatement insertStatement = (InsertStatement) new SQLParsingEngine(dbType, actualSQL, shardingRule).parse();
InsertStatement insertStatement = (InsertStatement) new SQLParsingEngine(dbType, actualSQL, shardingRule).parse(false);
assertThat(insertStatement.getTables().find("TABLE_XXX").get().getName(), is("TABLE_XXX"));
assertFalse(insertStatement.getTables().find("TABLE_XXX").get().getAlias().isPresent());
Condition condition = insertStatement.getConditions().find(new Column("field1", "TABLE_XXX")).get();
Expand All @@ -141,18 +141,18 @@ private void parseWithSpecialSyntax(final DatabaseType dbType, final String actu
// TODO assert
public void parseMultipleInsertForMySQL() {
ShardingRule shardingRule = createShardingRule();
new SQLParsingEngine(DatabaseType.MySQL, "INSERT INTO TABLE_XXX (`field1`, `field2`) VALUES (1, 'value_char'), (2, 'value_char')", shardingRule).parse();
new SQLParsingEngine(DatabaseType.MySQL, "INSERT INTO TABLE_XXX (`field1`, `field2`) VALUES (1, 'value_char'), (2, 'value_char')", shardingRule).parse(false);
}

@Test(expected = SQLParsingUnsupportedException.class)
public void parseInsertAllForOracle() {
ShardingRule shardingRule = createShardingRule();
new SQLParsingEngine(DatabaseType.Oracle, "INSERT ALL INTO TABLE_XXX (field1) VALUES (field1) SELECT field1 FROM TABLE_XXX2", shardingRule).parse();
new SQLParsingEngine(DatabaseType.Oracle, "INSERT ALL INTO TABLE_XXX (field1) VALUES (field1) SELECT field1 FROM TABLE_XXX2", shardingRule).parse(false);
}

@Test(expected = SQLParsingUnsupportedException.class)
public void parseInsertFirstForOracle() {
ShardingRule shardingRule = createShardingRule();
new SQLParsingEngine(DatabaseType.Oracle, "INSERT FIRST INTO TABLE_XXX (field1) VALUES (field1) SELECT field1 FROM TABLE_XXX2", shardingRule).parse();
new SQLParsingEngine(DatabaseType.Oracle, "INSERT FIRST INTO TABLE_XXX (field1) VALUES (field1) SELECT field1 FROM TABLE_XXX2", shardingRule).parse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public final class UpdateStatementParserTest extends AbstractStatementParserTest
public void parseWithoutCondition() {
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, "UPDATE TABLE_XXX SET field1=field1+1", shardingRule);
DMLStatement updateStatement = (DMLStatement) statementParser.parse();
DMLStatement updateStatement = (DMLStatement) statementParser.parse(false);
assertThat(updateStatement.getTables().find("TABLE_XXX").get().getName(), is("TABLE_XXX"));
}

Expand All @@ -54,7 +54,7 @@ public void parseWithoutParameter() {
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, "UPDATE TABLE_XXX xxx SET TABLE_XXX.field1=field1+1,xxx.field2=2 WHERE TABLE_XXX.field4<10 AND"
+ " TABLE_XXX.field1=1 AND xxx.field5>10 AND TABLE_XXX.field2 IN (1,3) AND xxx.field6<=10 AND TABLE_XXX.field3 BETWEEN 5 AND 20 AND xxx.field7>=10", shardingRule);
DMLStatement updateStatement = (DMLStatement) statementParser.parse();
DMLStatement updateStatement = (DMLStatement) statementParser.parse(false);
assertUpdateStatementWithoutParameter(updateStatement);
}

Expand Down Expand Up @@ -82,7 +82,7 @@ public void parseWithParameter() {
String sql = "UPDATE TABLE_XXX AS xxx SET field1=field1+? WHERE field4<? AND xxx.field1=? AND field5>? AND xxx.field2 IN (?, ?) AND field6<=? AND xxx.field3 BETWEEN ? AND ? AND field7>=?";
ShardingRule shardingRule = createShardingRule();
SQLParsingEngine statementParser = new SQLParsingEngine(DatabaseType.MySQL, sql, shardingRule);
DMLStatement updateStatement = (DMLStatement) statementParser.parse();
DMLStatement updateStatement = (DMLStatement) statementParser.parse(false);
assertUpdateStatementWitParameter(updateStatement);
}

Expand All @@ -109,7 +109,7 @@ private void assertUpdateStatementWitParameter(final DMLStatement updateStatemen
@Test(expected = SQLParsingUnsupportedException.class)
public void parseWithOr() {
ShardingRule shardingRule = createShardingRule();
new SQLParsingEngine(DatabaseType.Oracle, "UPDATE TABLE_XXX SET field1=1 WHERE field1<1 AND (field1 >2 OR field2 =1)", shardingRule).parse();
new SQLParsingEngine(DatabaseType.Oracle, "UPDATE TABLE_XXX SET field1=1 WHERE field1<1 AND (field1 >2 OR field2 =1)", shardingRule).parse(false);
}

@Test
Expand All @@ -123,7 +123,7 @@ public void parseWithSpecialSyntax() {

private void parseWithSpecialSyntax(final DatabaseType dbType, final String actualSQL) {
ShardingRule shardingRule = createShardingRule();
DMLStatement updateStatement = (DMLStatement) new SQLParsingEngine(dbType, actualSQL, shardingRule).parse();
DMLStatement updateStatement = (DMLStatement) new SQLParsingEngine(dbType, actualSQL, shardingRule).parse(false);
assertThat(updateStatement.getTables().find("TABLE_XXX").get().getName(), is("TABLE_XXX"));
assertFalse(updateStatement.getTables().find("TABLE_XXX").get().getAlias().isPresent());
Condition condition = updateStatement.getConditions().find(new Column("field1", "TABLE_XXX")).get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public List<DatabaseProtocolPacket> execute() {
log.debug("COM_STMT_PREPARE received for Sharding-Proxy: {}", sql);
List<DatabaseProtocolPacket> result = new LinkedList<>();
int currentSequenceId = 0;
SQLStatement sqlStatement = new SQLParsingEngine(DatabaseType.MySQL, sql, ShardingRuleRegistry.getInstance().getShardingRule()).parse();
SQLStatement sqlStatement = new SQLParsingEngine(DatabaseType.MySQL, sql, ShardingRuleRegistry.getInstance().getShardingRule()).parse(true);
result.add(new ComStmtPrepareOKPacket(++currentSequenceId, PreparedStatementRegistry.getInstance().register(sql), getNumColumns(sqlStatement), sqlStatement.getParametersIndex(), 0));
for (int i = 0; i < sqlStatement.getParametersIndex(); i++) {
// TODO add column name
Expand Down

0 comments on commit 98e400f

Please sign in to comment.