Details
-
Improvement
-
Resolution: Unresolved
-
Major
-
None
-
None
-
Unknown
-
Description
Every time JSqlParser parses a query through its default entry points, it creates a new single-thread ExecutorService (so a new thread), runs the parse in it to enforce its timeout (8s by default), and then shuts the executor down. This applies to:
- CCJSqlParserUtil.parse(String), used by EscapeLikeParametersQuery (the escapeLikeParameters filter), which is applied to every HQL query executed through the Query Manager, and re-parses the statement each time getStatement() is called
- Validation#validate() (through ParseCapability), used by StandardHQLCompleteStatementValidator each time an HQL query reaches that validator
This has been the case at least since JSqlParser 4.6 (there, it happens inside parseStatement(CCJSqlParser) / parseStatements(CCJSqlParser)), but JSqlParser 4.6 did not offer any way to avoid it. Since JSqlParser 5.x, it is possible to provide the ExecutorService to use: CCJSqlParserUtil.parse(String, ExecutorService, Consumer), CCJSqlParserUtil.parseStatements(CCJSqlParser, ExecutorService), etc.
Possible improvements:
- parse the statement with a shared (reused) ExecutorService in both places
- for StandardHQLCompleteStatementValidator, parse the statement itself (with CCJSqlParserUtil.newParser(statement).withConfiguration(...) and the shared executor) and then call the static Validation.validate(Statement, ValidationContext), which only checks the features without parsing again
- use the same parser configuration in both places
- avoid parsing the same statement several times in EscapeLikeParametersQuery (e.g. by caching the modified statement)
The actual cost has not been measured yet.