@@ -212,9 +212,9 @@ ClientSideStatement getClientSideStatement() {
212
212
}
213
213
}
214
214
215
- private final Set <String > ddlStatements = ImmutableSet .of ("CREATE" , "DROP" , "ALTER" );
216
- private final Set <String > selectStatements = ImmutableSet .of ("SELECT" , "WITH" );
217
- private final Set <String > dmlStatements = ImmutableSet .of ("INSERT" , "UPDATE" , "DELETE" );
215
+ private static final Set <String > ddlStatements = ImmutableSet .of ("CREATE" , "DROP" , "ALTER" );
216
+ private static final Set <String > selectStatements = ImmutableSet .of ("SELECT" , "WITH" );
217
+ private static final Set <String > dmlStatements = ImmutableSet .of ("INSERT" , "UPDATE" , "DELETE" );
218
218
private final Set <ClientSideStatementImpl > statements ;
219
219
220
220
/** Private constructor for singleton instance. */
@@ -445,19 +445,31 @@ public static String removeCommentsAndTrim(String sql) {
445
445
446
446
/** Removes any statement hints at the beginning of the statement. */
447
447
static String removeStatementHint (String sql ) {
448
- // Valid statement hints at the beginning of a SQL statement can only contain a fixed set of
448
+ // Valid statement hints at the beginning of a query statement can only contain a fixed set of
449
449
// possible values. Although it is possible to add a @{FORCE_INDEX=...} as a statement hint, the
450
450
// only allowed value is _BASE_TABLE. This means that we can safely assume that the statement
451
- // hint will not contain any special characters, for example a closing curly brace, and
452
- // that we can keep the check simple by just searching for the first occurrence of a closing
453
- // curly brace at the end of the statement hint.
451
+ // hint will not contain any special characters, for example a closing curly brace or one of the
452
+ // keywords SELECT, UPDATE, DELETE, WITH, and that we can keep the check simple by just
453
+ // searching for the first occurrence of a keyword that should be preceded by a closing curly
454
+ // brace at the end of the statement hint.
454
455
int startStatementHintIndex = sql .indexOf ('{' );
455
- int endStatementHintIndex = sql .indexOf ('}' );
456
- if (startStatementHintIndex == -1 || startStatementHintIndex > endStatementHintIndex ) {
457
- // Looks like an invalid statement hint. Just ignore at this point and let the caller handle
458
- // the invalid query.
459
- return sql ;
456
+ // Statement hints are only allowed for queries.
457
+ int startQueryIndex = -1 ;
458
+ String upperCaseSql = sql .toUpperCase ();
459
+ for (String keyword : selectStatements ) {
460
+ startQueryIndex = upperCaseSql .indexOf (keyword );
461
+ if (startQueryIndex > -1 ) break ;
460
462
}
461
- return removeCommentsAndTrim (sql .substring (endStatementHintIndex + 1 ));
463
+ if (startQueryIndex > -1 ) {
464
+ int endStatementHintIndex = sql .substring (0 , startQueryIndex ).lastIndexOf ('}' );
465
+ if (startStatementHintIndex == -1 || startStatementHintIndex > endStatementHintIndex ) {
466
+ // Looks like an invalid statement hint. Just ignore at this point and let the caller handle
467
+ // the invalid query.
468
+ return sql ;
469
+ }
470
+ return removeCommentsAndTrim (sql .substring (endStatementHintIndex + 1 ));
471
+ }
472
+ // Seems invalid, just return the original statement.
473
+ return sql ;
462
474
}
463
475
}
0 commit comments