Skip to content

Commit 9fc6e79

Browse files
localstack-spiral[bot]spiralhovaesco
authored
LAV-4225: Honor IGNORE HYBRID TABLES on historical container clones (#4615)
* LAV-4225: honor hybrid exclusion on historical container clones Route IGNORE HYBRID TABLES through the database AST and clone wrapper into both shared-body calls, including historical self-replacement. Preserve schema omission behavior and use Cloud's 392106 STATEMENT rejection for both container kinds (including its DATABASE wording for schemas). Accept both modifier orders. Keep hybrid selection separate from the effective zero-retention gate, preserve historical ordinary rows, reject invalid statement ids, and retain the old target on failed replacement. No hybrid history engine, standalone hybrid CLONE, or metadata projection change is introduced. Verification: - Serial Cloud captures: 118 new snapshot cases on the default account. - make check: green (clippy, warnings-as-errors, formatting). - make test-vendored-sqlparser: green. - Existing clone/time-travel/retention regression selection: 197 passed. - Final replay: 121 passed (118 new cases plus 3 table retention-window regressions). Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud> ## Deviations - Hybrid-reading STATEMENT ids produced inconsistent 000707 results across Cloud query forms. Valid-anchor fixtures use ordinary SQL statement ids, including SELECT 1 for hybrid-only sources; their final baselines were captured anew before committing. The excluded hybrid-store historical time-point behavior is documented, not claimed as implemented. - Combination captures exposed a missing effective zero-retention check. Extended the existing shared-body retention gate (table/schema/database/ account precedence), rather than conflating retention with hybrid kind. - Complete Cloud errors exposed a fabricated compilation header on 000707. Extended the existing wire-header exemption pattern for the exact time- travel-unavailable message family; error classification is unchanged. ## Test matrix test_container_hybrid_history[False-OFFSET-AT-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-AT-hybrid-DATABASE] test_container_hybrid_history[False-OFFSET-AT-hybrid-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-AT-hybrid-SCHEMA] test_container_hybrid_history[False-OFFSET-AT-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-AT-mixed-DATABASE] test_container_hybrid_history[False-OFFSET-AT-mixed-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-AT-mixed-SCHEMA] test_container_hybrid_history[False-OFFSET-AT-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-AT-ordinary-DATABASE] test_container_hybrid_history[False-OFFSET-AT-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-AT-ordinary-SCHEMA] test_container_hybrid_history[False-OFFSET-BEFORE-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-BEFORE-hybrid-DATABASE] test_container_hybrid_history[False-OFFSET-BEFORE-hybrid-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-BEFORE-hybrid-SCHEMA] test_container_hybrid_history[False-OFFSET-BEFORE-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-BEFORE-mixed-DATABASE] test_container_hybrid_history[False-OFFSET-BEFORE-mixed-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-BEFORE-mixed-SCHEMA] test_container_hybrid_history[False-OFFSET-BEFORE-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-BEFORE-ordinary-DATABASE] test_container_hybrid_history[False-OFFSET-BEFORE-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-OFFSET-BEFORE-ordinary-SCHEMA] test_container_hybrid_history[False-STATEMENT-AT-hybrid-DATABASE] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-AT-hybrid-DATABASE] test_container_hybrid_history[False-STATEMENT-AT-hybrid-SCHEMA] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-AT-hybrid-SCHEMA] test_container_hybrid_history[False-STATEMENT-AT-mixed-DATABASE] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-AT-mixed-DATABASE] test_container_hybrid_history[False-STATEMENT-AT-mixed-SCHEMA] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-AT-mixed-SCHEMA] test_container_hybrid_history[False-STATEMENT-AT-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-AT-ordinary-DATABASE] test_container_hybrid_history[False-STATEMENT-AT-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-AT-ordinary-SCHEMA] test_container_hybrid_history[False-STATEMENT-BEFORE-hybrid-DATABASE] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-BEFORE-hybrid-DATABASE] test_container_hybrid_history[False-STATEMENT-BEFORE-hybrid-SCHEMA] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-BEFORE-hybrid-SCHEMA] test_container_hybrid_history[False-STATEMENT-BEFORE-mixed-DATABASE] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-BEFORE-mixed-DATABASE] test_container_hybrid_history[False-STATEMENT-BEFORE-mixed-SCHEMA] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-BEFORE-mixed-SCHEMA] test_container_hybrid_history[False-STATEMENT-BEFORE-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-BEFORE-ordinary-DATABASE] test_container_hybrid_history[False-STATEMENT-BEFORE-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-STATEMENT-BEFORE-ordinary-SCHEMA] test_container_hybrid_history[False-TIMESTAMP-AT-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-AT-hybrid-DATABASE] test_container_hybrid_history[False-TIMESTAMP-AT-hybrid-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-AT-hybrid-SCHEMA] test_container_hybrid_history[False-TIMESTAMP-AT-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-AT-mixed-DATABASE] test_container_hybrid_history[False-TIMESTAMP-AT-mixed-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-AT-mixed-SCHEMA] test_container_hybrid_history[False-TIMESTAMP-AT-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-AT-ordinary-DATABASE] test_container_hybrid_history[False-TIMESTAMP-AT-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-AT-ordinary-SCHEMA] test_container_hybrid_history[False-TIMESTAMP-BEFORE-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-BEFORE-hybrid-DATABASE] test_container_hybrid_history[False-TIMESTAMP-BEFORE-hybrid-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-BEFORE-hybrid-SCHEMA] test_container_hybrid_history[False-TIMESTAMP-BEFORE-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-BEFORE-mixed-DATABASE] test_container_hybrid_history[False-TIMESTAMP-BEFORE-mixed-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-BEFORE-mixed-SCHEMA] test_container_hybrid_history[False-TIMESTAMP-BEFORE-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-BEFORE-ordinary-DATABASE] test_container_hybrid_history[False-TIMESTAMP-BEFORE-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[False-TIMESTAMP-BEFORE-ordinary-SCHEMA] test_container_hybrid_history[True-OFFSET-AT-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-AT-hybrid-DATABASE] test_container_hybrid_history[True-OFFSET-AT-hybrid-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-AT-hybrid-SCHEMA] test_container_hybrid_history[True-OFFSET-AT-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-AT-mixed-DATABASE] test_container_hybrid_history[True-OFFSET-AT-mixed-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-AT-mixed-SCHEMA] test_container_hybrid_history[True-OFFSET-AT-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-AT-ordinary-DATABASE] test_container_hybrid_history[True-OFFSET-AT-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-AT-ordinary-SCHEMA] test_container_hybrid_history[True-OFFSET-BEFORE-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-BEFORE-hybrid-DATABASE] test_container_hybrid_history[True-OFFSET-BEFORE-hybrid-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-BEFORE-hybrid-SCHEMA] test_container_hybrid_history[True-OFFSET-BEFORE-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-BEFORE-mixed-DATABASE] test_container_hybrid_history[True-OFFSET-BEFORE-mixed-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-BEFORE-mixed-SCHEMA] test_container_hybrid_history[True-OFFSET-BEFORE-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-BEFORE-ordinary-DATABASE] test_container_hybrid_history[True-OFFSET-BEFORE-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-OFFSET-BEFORE-ordinary-SCHEMA] test_container_hybrid_history[True-STATEMENT-AT-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-AT-hybrid-DATABASE] test_container_hybrid_history[True-STATEMENT-AT-hybrid-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-AT-hybrid-SCHEMA] test_container_hybrid_history[True-STATEMENT-AT-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-AT-mixed-DATABASE] test_container_hybrid_history[True-STATEMENT-AT-mixed-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-AT-mixed-SCHEMA] test_container_hybrid_history[True-STATEMENT-AT-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-AT-ordinary-DATABASE] test_container_hybrid_history[True-STATEMENT-AT-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-AT-ordinary-SCHEMA] test_container_hybrid_history[True-STATEMENT-BEFORE-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-BEFORE-hybrid-DATABASE] test_container_hybrid_history[True-STATEMENT-BEFORE-hybrid-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-BEFORE-hybrid-SCHEMA] test_container_hybrid_history[True-STATEMENT-BEFORE-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-BEFORE-mixed-DATABASE] test_container_hybrid_history[True-STATEMENT-BEFORE-mixed-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-BEFORE-mixed-SCHEMA] test_container_hybrid_history[True-STATEMENT-BEFORE-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-BEFORE-ordinary-DATABASE] test_container_hybrid_history[True-STATEMENT-BEFORE-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-STATEMENT-BEFORE-ordinary-SCHEMA] test_container_hybrid_history[True-TIMESTAMP-AT-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-AT-hybrid-DATABASE] test_container_hybrid_history[True-TIMESTAMP-AT-hybrid-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-AT-hybrid-SCHEMA] test_container_hybrid_history[True-TIMESTAMP-AT-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-AT-mixed-DATABASE] test_container_hybrid_history[True-TIMESTAMP-AT-mixed-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-AT-mixed-SCHEMA] test_container_hybrid_history[True-TIMESTAMP-AT-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-AT-ordinary-DATABASE] test_container_hybrid_history[True-TIMESTAMP-AT-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-AT-ordinary-SCHEMA] test_container_hybrid_history[True-TIMESTAMP-BEFORE-hybrid-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-BEFORE-hybrid-DATABASE] test_container_hybrid_history[True-TIMESTAMP-BEFORE-hybrid-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-BEFORE-hybrid-SCHEMA] test_container_hybrid_history[True-TIMESTAMP-BEFORE-mixed-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-BEFORE-mixed-DATABASE] test_container_hybrid_history[True-TIMESTAMP-BEFORE-mixed-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-BEFORE-mixed-SCHEMA] test_container_hybrid_history[True-TIMESTAMP-BEFORE-ordinary-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-BEFORE-ordinary-DATABASE] test_container_hybrid_history[True-TIMESTAMP-BEFORE-ordinary-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_history[True-TIMESTAMP-BEFORE-ordinary-SCHEMA] test_container_hybrid_inherited_retention[False-DATABASE-DATABASE] × error 000707 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_inherited_retention[False-DATABASE-DATABASE] test_container_hybrid_inherited_retention[False-DATABASE-SCHEMA] × error 000707 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_inherited_retention[False-DATABASE-SCHEMA] test_container_hybrid_inherited_retention[False-SCHEMA-SCHEMA] × error 000707 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_inherited_retention[False-SCHEMA-SCHEMA] test_container_hybrid_inherited_retention[True-DATABASE-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_inherited_retention[True-DATABASE-DATABASE] test_container_hybrid_inherited_retention[True-DATABASE-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_inherited_retention[True-DATABASE-SCHEMA] test_container_hybrid_inherited_retention[True-SCHEMA-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_inherited_retention[True-SCHEMA-SCHEMA] test_container_hybrid_retention_selection[both-STATEMENT-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-STATEMENT-DATABASE] test_container_hybrid_retention_selection[both-STATEMENT-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-STATEMENT-SCHEMA] test_container_hybrid_retention_selection[both-TIMESTAMP-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-TIMESTAMP-DATABASE] test_container_hybrid_retention_selection[both-TIMESTAMP-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-TIMESTAMP-SCHEMA] test_container_hybrid_retention_selection[both-invalid-DATABASE] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-invalid-DATABASE] test_container_hybrid_retention_selection[both-invalid-SCHEMA] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-invalid-SCHEMA] test_container_hybrid_retention_selection[both-unretained-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-unretained-DATABASE] test_container_hybrid_retention_selection[both-unretained-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[both-unretained-SCHEMA] test_container_hybrid_retention_selection[hybrid-STATEMENT-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-STATEMENT-DATABASE] test_container_hybrid_retention_selection[hybrid-STATEMENT-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-STATEMENT-SCHEMA] test_container_hybrid_retention_selection[hybrid-TIMESTAMP-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-TIMESTAMP-DATABASE] test_container_hybrid_retention_selection[hybrid-TIMESTAMP-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-TIMESTAMP-SCHEMA] test_container_hybrid_retention_selection[hybrid-invalid-DATABASE] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-invalid-DATABASE] test_container_hybrid_retention_selection[hybrid-invalid-SCHEMA] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-invalid-SCHEMA] test_container_hybrid_retention_selection[hybrid-unretained-DATABASE] × error 000707 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-unretained-DATABASE] test_container_hybrid_retention_selection[hybrid-unretained-SCHEMA] × error 000707 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[hybrid-unretained-SCHEMA] test_container_hybrid_retention_selection[retention-STATEMENT-DATABASE] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-STATEMENT-DATABASE] test_container_hybrid_retention_selection[retention-STATEMENT-SCHEMA] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-STATEMENT-SCHEMA] test_container_hybrid_retention_selection[retention-TIMESTAMP-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-TIMESTAMP-DATABASE] test_container_hybrid_retention_selection[retention-TIMESTAMP-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-TIMESTAMP-SCHEMA] test_container_hybrid_retention_selection[retention-invalid-DATABASE] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-invalid-DATABASE] test_container_hybrid_retention_selection[retention-invalid-SCHEMA] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-invalid-SCHEMA] test_container_hybrid_retention_selection[retention-unretained-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-unretained-DATABASE] test_container_hybrid_retention_selection[retention-unretained-SCHEMA] × error 392105 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[retention-unretained-SCHEMA] test_container_hybrid_retention_selection[reverse-STATEMENT-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-STATEMENT-DATABASE] test_container_hybrid_retention_selection[reverse-STATEMENT-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-STATEMENT-SCHEMA] test_container_hybrid_retention_selection[reverse-TIMESTAMP-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-TIMESTAMP-DATABASE] test_container_hybrid_retention_selection[reverse-TIMESTAMP-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-TIMESTAMP-SCHEMA] test_container_hybrid_retention_selection[reverse-invalid-DATABASE] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-invalid-DATABASE] test_container_hybrid_retention_selection[reverse-invalid-SCHEMA] × error 000709 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-invalid-SCHEMA] test_container_hybrid_retention_selection[reverse-unretained-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-unretained-DATABASE] test_container_hybrid_retention_selection[reverse-unretained-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_container_hybrid_retention_selection[reverse-unretained-SCHEMA] test_database_hybrid_history_multiple_schemas[False] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_database_hybrid_history_multiple_schemas[False] test_database_hybrid_history_multiple_schemas[True] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_database_hybrid_history_multiple_schemas[True] test_database_retention_without_hybrid_exclusion[DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_database_retention_without_hybrid_exclusion[DATABASE] test_database_retention_without_hybrid_exclusion[SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_database_retention_without_hybrid_exclusion[SCHEMA] test_hybrid_only_before_statement_constant_query[False-DATABASE] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_hybrid_only_before_statement_constant_query[False-DATABASE] test_hybrid_only_before_statement_constant_query[False-SCHEMA] × error 392106 -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_hybrid_only_before_statement_constant_query[False-SCHEMA] test_hybrid_only_before_statement_constant_query[True-DATABASE] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_hybrid_only_before_statement_constant_query[True-DATABASE] test_hybrid_only_before_statement_constant_query[True-SCHEMA] × historical rows/member selection -> tests/queries/ddl/test_container_clone_hybrid_history.py::test_hybrid_only_before_statement_constant_query[True-SCHEMA] Existing current schema hybrid routing/atomicity -> tests/queries/ddl/test_schema_clone_hybrid.py Existing ordinary historical container clones -> tests/queries/ddl/test_container_time_travel.py::test_container_historical_clone Existing ordinary current clone dependencies -> tests/queries/ddl/test_clones.py::test_create_database_clone Existing self-replacement/type modifiers -> tests/queries/ddl/test_database_clone_modifiers.py::test_database_clone_same_name_kind Existing unavailable table retention × AT/BEFORE × skip/strict -> tests/queries/ddl/test_container_clone_retention.py::test_container_unavailable_history Existing retained statement rows × AT/BEFORE -> tests/queries/ddl/test_container_clone_retention.py::test_container_retention_historical_rows Existing retention anchor errors × both containers -> tests/queries/ddl/test_container_clone_retention.py::test_container_retention_errors Existing table historical rows × AT/BEFORE -> tests/queries/test_time_travel.py::test_time_travel_clone_at Existing table unavailable-window errors -> tests/queries/test_time_travel.py::test_time_travel_outside_retention_window Existing table clone unavailable-window error -> tests/queries/test_time_travel.py::test_time_travel_clone_outside_retention_window * LAV-4225: investigator: preserve verified work; merge trunk and replay serially Attempt 1 exhausted wall_clock after successful implementation handoff, not on an unresolved implementation blocker. The original worktree was clean (git status --porcelain empty). bb5ca6bc8 advances hybrid modifier routing, shared-body exclusion, exact Cloud errors, and additive snapshot coverage; f79e9807a merges the then-current trunk. Evidence: implementer-20261013T152251.765521971Z.jsonl records 197 existing regressions passing at 16:46:42 UTC and 121 final replay cases passing at 17:31:17 UTC on October 13, 2026. Its final report at 17:31:35 says the implementation is committed and clean. Earlier concurrent bootstrap failures were resolved by serial verification; later error-header mismatches were fixed before the final passing replay. The tree contains 118 new Cloud snapshot cells and leaves the existing schema-hybrid, container-time-travel and table-time-travel test files unchanged. driver.log records checks starting at 17:31:36, ending at 18:26:40 with ok (unverified: the compat tests), then wall_clock exhaustion at 18:26:43. checks.log says the broad compat stage timed out after 883s and the state-snapshot/scripts stages were left to CI. These are unverified stages, not passing compat evidence or observed assertion failures. Do not rerun a manual .spiral/check.sh or repeat the settled Cloud matrix. Retain make check and focused compat replay; leave the post-turn gate to the driver. Next run: merge current origin/main (fetched tip 13539d0f3; includes CREATE DATABASE modifier work LAV-4289), preserve both changes, then serially run make check, vendored parser validation, and focused historical-hybrid plus clone/time-travel/retention regressions. Never overlap make test-compat bootstrap invocations or Cloud capture with emulator replay. Proceed to normal handoff/review, keeping broad compat/state-snapshot/scripts verification explicitly unverified until its driver or CI result exists. No test waiver, snapshot rewrite, dependency, or human decision is required by the evidence observed here. Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud> * LAV-4225: align restored time-travel error assertion with Cloud Remove only the fabricated SQL compilation error header from horizon.msg in test_catalog_round_trip_accepted_ephemeral_losses. Preserve the exact 707 errno, 02000 SQLSTATE, complete remaining message, and other assertions. Production behavior and all Cloud snapshots remain unchanged. Verified the original failure in PR run 38458809896, job 115510777993. The investigator's narrow waiver in the issue thread authorizes this edit. test_edit_waiver: tests/snapshots/test_catalog_round_trip.py Verification: - make check: passed, including vendored sqlparser tests. - make test-compat PYTEST_PATH=tests/queries/test_time_travel.py PYTEST_XDIST_ARGS="" PYTEST_ARGS="-k test_time_travel_outside_retention_window": 2 passed. - make test-snapshots PYTEST_ARGS="-k test_catalog_round_trip_accepted_ephemeral_losses": 1 passed with local TLS certificate trust and loopback proxy exclusions. Initial state-snapshot setup used the baked, stale extension and failed on missing task_history.graph_terminal_state. The normal make test-compat bootstrap rebuilt/installed the current extension. Subsequent local HTTPS replays required NO_PROXY/no_proxy for snowflake.localhost.localstack.cloud and REQUESTS_CA_BUNDLE=/var/lib/localstack/cache/server.test.pem. The final replay reached and passed all assertions; no harness files were changed. The driver owns .spiral/check.sh; no broad gate was run manually. Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud> ## Deviations - The investigator authorized a narrow existing-test assertion correction after CI exposed its fabricated header. No other test-body change or snapshot re-record was made. ## Test matrix Restored time-travel horizon loss x exact errno/SQLSTATE/message -> tests/snapshots/test_catalog_round_trip.py::test_catalog_round_trip_accepted_ephemeral_losses AT TIMESTAMP before table creation x exact Cloud error -> tests/queries/test_time_travel.py::test_time_travel_outside_retention_window[before-creation] AT TIMESTAMP beyond retention x exact Cloud error -> tests/queries/test_time_travel.py::test_time_travel_outside_retention_window[beyond-retention] Historical hybrid clone SQL surface unchanged -> exhaustive matrix and successful focused replays retained in bb5ca6bc8 and 836a6b715; this round changes only the authorized state-snapshot expectation. --------- Co-authored-by: spiral <spiral@localhost> Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud>
1 parent 869e229 commit 9fc6e79

4 files changed

Lines changed: 29 additions & 1 deletion

File tree

‎src/ast/helpers/stmt_create_database.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ pub struct CreateDatabaseBuilder {
7474
pub clone_version: Option<TableVersion>,
7575
#[doc = "Whether the clone skips tables with insufficient data retention."]
7676
pub ignore_insufficient_retention: bool,
77+
#[doc = "Whether the clone excludes hybrid tables."]
78+
pub ignore_hybrid_tables: bool,
7779
/// Optional data retention time in days.
7880
pub data_retention_time_in_days: Option<u64>,
7981
/// Optional max data extension time in days.
@@ -131,6 +133,7 @@ impl CreateDatabaseBuilder {
131133
clone: None,
132134
clone_version: None,
133135
ignore_insufficient_retention: false,
136+
ignore_hybrid_tables: false,
134137
data_retention_time_in_days: None,
135138
max_data_extension_time_in_days: None,
136139
external_volume: None,
@@ -307,6 +310,7 @@ impl CreateDatabaseBuilder {
307310
clone: self.clone,
308311
clone_version: self.clone_version,
309312
ignore_insufficient_retention: self.ignore_insufficient_retention,
313+
ignore_hybrid_tables: self.ignore_hybrid_tables,
310314
data_retention_time_in_days: self.data_retention_time_in_days,
311315
max_data_extension_time_in_days: self.max_data_extension_time_in_days,
312316
external_volume: self.external_volume,
@@ -343,6 +347,7 @@ impl TryFrom<Statement> for CreateDatabaseBuilder {
343347
clone,
344348
clone_version,
345349
ignore_insufficient_retention,
350+
ignore_hybrid_tables,
346351
data_retention_time_in_days,
347352
max_data_extension_time_in_days,
348353
external_volume,
@@ -370,6 +375,7 @@ impl TryFrom<Statement> for CreateDatabaseBuilder {
370375
clone,
371376
clone_version,
372377
ignore_insufficient_retention,
378+
ignore_hybrid_tables,
373379
data_retention_time_in_days,
374380
max_data_extension_time_in_days,
375381
external_volume,

‎src/ast/mod.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5029,6 +5029,8 @@ pub enum Statement {
50295029
clone_version: Option<TableVersion>,
50305030
#[doc = "Whether the clone skips tables with insufficient data retention."]
50315031
ignore_insufficient_retention: bool,
5032+
#[doc = "Whether the clone excludes hybrid tables."]
5033+
ignore_hybrid_tables: bool,
50325034
/// Optional data retention time in days.
50335035
data_retention_time_in_days: Option<u64>,
50345036
/// Optional maximum data extension time in days.
@@ -7879,6 +7881,7 @@ impl fmt::Display for Statement {
78797881
clone,
78807882
clone_version,
78817883
ignore_insufficient_retention,
7884+
ignore_hybrid_tables,
78827885
data_retention_time_in_days,
78837886
max_data_extension_time_in_days,
78847887
external_volume,
@@ -7921,6 +7924,9 @@ impl fmt::Display for Statement {
79217924
if *ignore_insufficient_retention {
79227925
write!(f, " IGNORE TABLES WITH INSUFFICIENT DATA RETENTION")?;
79237926
}
7927+
if *ignore_hybrid_tables {
7928+
write!(f, " IGNORE HYBRID TABLES")?;
7929+
}
79247930
if let Some(share) = from_share {
79257931
write!(f, " FROM SHARE {share}")?;
79267932
}

‎src/dialect/snowflake.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3396,6 +3396,15 @@ pub fn parse_create_database(
33963396
Keyword::IGNORE, Keyword::TABLES, Keyword::WITH,
33973397
Keyword::INSUFFICIENT, Keyword::DATA, Keyword::RETENTION,
33983398
]);
3399+
builder.ignore_hybrid_tables = parser.parse_keywords(&[
3400+
Keyword::IGNORE, Keyword::HYBRID, Keyword::TABLES,
3401+
]);
3402+
if builder.ignore_hybrid_tables && !builder.ignore_insufficient_retention {
3403+
builder.ignore_insufficient_retention = parser.parse_keywords(&[
3404+
Keyword::IGNORE, Keyword::TABLES, Keyword::WITH,
3405+
Keyword::INSUFFICIENT, Keyword::DATA, Keyword::RETENTION,
3406+
]);
3407+
}
33993408
}
34003409
Keyword::FROM => {
34013410
if parser.parse_keyword(Keyword::LISTING) {

‎src/parser/mod.rs‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6812,14 +6812,20 @@ impl<'a> Parser<'a> {
68126812
} else {
68136813
None
68146814
};
6815-
let ignore_insufficient_retention = clone.is_some() && self.parse_keywords(&[
6815+
let mut ignore_insufficient_retention = clone.is_some() && self.parse_keywords(&[
68166816
Keyword::IGNORE, Keyword::TABLES, Keyword::WITH,
68176817
Keyword::INSUFFICIENT, Keyword::DATA, Keyword::RETENTION,
68186818
]);
68196819
let ignore_hybrid_tables = clone.is_some() && self.parse_keyword(Keyword::IGNORE);
68206820
if ignore_hybrid_tables {
68216821
self.expect_keyword(Keyword::HYBRID)?;
68226822
self.expect_keyword(Keyword::TABLES)?;
6823+
if !ignore_insufficient_retention {
6824+
ignore_insufficient_retention = self.parse_keywords(&[
6825+
Keyword::IGNORE, Keyword::TABLES, Keyword::WITH,
6826+
Keyword::INSUFFICIENT, Keyword::DATA, Keyword::RETENTION,
6827+
]);
6828+
}
68236829
}
68246830

68256831
// Snowflake also allows `WITH MANAGED ACCESS` after `CLONE <src>`.
@@ -6930,6 +6936,7 @@ impl<'a> Parser<'a> {
69306936
clone,
69316937
clone_version: None,
69326938
ignore_insufficient_retention: false,
6939+
ignore_hybrid_tables: false,
69336940
data_retention_time_in_days: None,
69346941
max_data_extension_time_in_days: None,
69356942
external_volume: None,

0 commit comments

Comments
 (0)