@@ -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