Add RawSqlBuilder.withPlaceholders() for CTEs and other complex SQL (#3649)#3827
Merged
Conversation
…3649) RawSqlBuilder.parse() uses keyword-based scanning to locate SELECT columns and the WHERE/HAVING injection points. This fails for CTEs, window functions and other complex SQL where "select"/"from" keywords appear in places the scanner doesn't expect. withPlaceholders(sql) skips SELECT/FROM column parsing entirely and only locates the ${where}, ${andWhere}, ${having} and ${andHaving} placeholder positions, requiring explicit columnMapping() calls (as with unparsed()). This lets dynamic where()/having() expressions be injected into otherwise unparseable SQL. Also fixes two bugs in the underlying placeholder-position splitting: - static SQL following a ${having}/${andHaving} placeholder (e.g. a trailing ORDER BY) was silently dropped when both a where and a having placeholder were present - using only ${having}/${andHaving} (no where placeholder) caused a dynamically added HAVING clause to be appended after trailing static SQL, producing invalid SQL Changes: - RawSqlBuilder.withPlaceholders(sql) + SpiRawSqlService.withPlaceholders() - DRawSqlParser.parseAsTemplate() / parseTemplate() - placeholder-position only parsing, correctly splitting preWhere/preHaving/trailing SQL - CQueryBuilderRawSql - skip column-list and "select" prefix handling in template mode (signalled by an empty preFrom) - Unit tests in DRawSqlServiceTest covering where/andWhere/having/andHaving placeholder combinations, including the two fixed edge cases - Integration tests in TestRawSqlWithPlaceholders (ebean-test) covering CTE queries with dynamic where/having and verifying generated SQL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RawSqlBuilder.parse() uses keyword-based scanning to locate SELECT columns and the WHERE/HAVING injection points. This fails for CTEs, window functions and other complex SQL where "select"/"from" keywords appear in places the scanner doesn't expect.
withPlaceholders(sql) skips SELECT/FROM column parsing entirely and only locates the ${where}, ${andWhere}, ${having} and ${andHaving} placeholder positions, requiring explicit columnMapping() calls (as with unparsed()). This lets dynamic where()/having() expressions be injected into otherwise unparseable SQL.
Also fixes two bugs in the underlying placeholder-position splitting:
Changes: