fix: REPL JOIN hardening — qualifier round-trip, loud no-extension failure, bare-alias sort rejection (#157, #158, #159) - #160
Merged
Conversation
…158) FieldSort.sql rendered via identifierName, which drops the tableAlias re-attached by Identifier.sql — so a parsed JOIN query re-rendered via SingleSearch.sql lost the ORDER BY qualifier (e.salary -> salary) and the join planner's re-parse failed with 400 'Ambiguous column'. Render via field.sql instead; FieldSort.name / identifierName / aliasOrName are untouched (they key the ES-side sort maps). Story: _bmad-output/implementation-artifacts/bug-158-repl-join-order-by-qualifier.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- re-parse assertions on all 4 qualifier round-trip tests (pin the join-planner re-parse failure mode at unit level) - qualified sort + NULLS LAST composition round-trip test - pin unaliased ranking-window derived column name with qualified OVER-sort (row_number_over_order_by_e_salary_desc) per review decision Story: bug-158-repl-join-order-by-qualifier (code review) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ension (#157) CoreDqlExtension (inherited by EnforcedDqlExtension) translates only the first FROM table — a cross-index JOIN reaching it silently executed as a single-index search (joined columns NULL, orphans kept), or worse wrote that wrong data via INSERT ... SELECT / CREATE TABLE ... AS SELECT. - guard in execute: any statement whose (embedded) SELECT has from.enrichmentRequired now fails with a clear 400 pointing at the softclient4es-arrow-extensions jar (Java 11+) - canHandle additionally claims write-with-JOIN statements (mirroring the arrow JoinExtension) so they cannot fall through to the core DML/DDL executors; join-less writes keep their existing routing - UNNEST joins excluded by construction (joinedTables = StandardJoin only) - 6 new CoreDqlExtensionSpec tests (SELECT, UNION leg, UNNEST carve-out, INSERT...SELECT, CTAS, canHandle claims) With the arrow JoinExtension registered at priority 40 join statements never reach this guard; without it users get a clear error instead of wrong results. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… qualifier (#159) A sort identifier colliding with a FROM alias (ORDER BY e where e aliases a table, or ORDER BY oi on an UNNEST alias) left GenericIdentifier.update's alias-split with an empty column name, silently rendering malformed SQL (ORDER BY e. after #158; ORDER BY ASC before it). FieldSort.validate now rejects the empty/dangling column name with "Column name expected after table alias '<alias>'" — surfaced through OrderBy.validate at Parser.apply, chaining to the FunctionChain aggregation-chain validation otherwise. 2 new ParserSpec tests (table alias, UNNEST alias). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Fixes #157, fixes #158, fixes #159 — the three REPL/JOIN bugs found during the R1 installer E2E verification and the #158 code review, targeted at the 0.20.1 patch line.
#158 — preserve table-alias qualifier in FieldSort SQL rendering
FieldSort.sqlwas the only clause renderer going throughIdentifier.identifierName(qualifier-dropping); the REPL JOIN path re-renders the parsed statement via.sqland re-parses it in the arrowJoinPlanner, which rejected the manufactured unqualified column as ambiguous. Now renders viafield.sql.FieldSort.name/identifierName/aliasOrNameare byte-for-byte untouched (they key the ES-side sort maps).JoinExtensionIntegrationSpectemplate gains aJOIN + ORDER BY <alias>.<field> DESCordered-rows test; Es6/Es7/Es8/Es9 runners 13/13 green against live ES (arrow-side change ships separately)row_number_over_order_by_e_salary_desc), consistent with PARTITION BY#157 — fail loudly on cross-index JOIN without a join-capable extension
CoreDqlExtension(inherited byEnforcedDqlExtension) translates only the first FROM table: withoutsoftclient4es-arrow-extensionson the classpath aSELECT … JOINsilently executed as a single-index search (joined columns NULL, orphans kept) — andINSERT … SELECT/CREATE TABLE … AS SELECTwrote that wrong data. Any statement whose (embedded) SELECT hasfrom.enrichmentRequirednow fails with a clear 400 pointing at the extensions jar;canHandleadditionally claims write-with-JOIN statements (mirroring the arrowJoinExtension) so they cannot fall through to the core DML/DDL executors. UNNEST joins are excluded by construction. With the arrow JoinExtension registered at priority 40 (arrow#125), join statements never reach the guard.CoreDqlExtensionSpectests: SELECT JOIN, UNION leg, UNNEST carve-out, INSERT…SELECT, CTAS, canHandle claims#159 — reject ORDER BY on a bare table alias
ORDER BY ewhereealiases a FROM table (orORDER BY oion an UNNEST alias) left the alias-split with an empty column name, silently rendering malformed SQL (ORDER BY e.after #158;ORDER BY ASCbefore it).FieldSort.validatenow rejects it withColumn name expected after table alias '<alias>', surfaced atParser.apply.Verification
+ sql/test376/376,+ softclient4es-sql-bridge/test118/118,+ core/test605/605 — Scala 2.12.20 and 2.13.16+ compile,scalafmtAll,headerCheckgreenJavaClient8ReplGatewayIntegrationSpec55/55,JavaClientGatewayApiSpec43/43,JavaClientSortNullsSpec3/3🤖 Generated with Claude Code