├── .gitignore ├── LICENSE ├── README.md ├── dbms_test.go ├── go.mod ├── go.sum ├── normalizer.go ├── normalizer_bench_test.go ├── normalizer_test.go ├── obfuscate_and_normalize.go ├── obfuscate_and_normalize_bench_test.go ├── obfuscate_and_normalize_test.go ├── obfuscator.go ├── obfuscator_bench_test.go ├── obfuscator_test.go ├── sqllexer.go ├── sqllexer_bench_test.go ├── sqllexer_fuzz_test.go ├── sqllexer_test.go ├── sqllexer_utils.go └── testdata ├── README.md ├── mssql ├── complex │ ├── extremely-complex-poorly-written-sql.json │ ├── indexed-views.json │ ├── partitioned-tables-indexes.json │ └── super-complex-poorly-written-sql.json ├── delete │ ├── conditional-delete-case.json │ ├── delete-basic.json │ ├── delete-cascade.json │ ├── delete-rowlock-hint.json │ ├── delete-using-subquery.json │ ├── delete-using-table-variable.json │ ├── delete-with-cte.json │ ├── delete-with-join.json │ ├── delete-with-output.json │ └── delete-with-top.json ├── insert │ ├── insert-basic.json │ ├── insert-default-values.json │ ├── insert-identity-insert.json │ ├── insert-merge.json │ ├── insert-output.json │ ├── insert-select-into.json │ ├── insert-subquery-values.json │ ├── insert-top-orderby.json │ ├── insert-values-multiple-rows.json │ ├── insert-with-select.json │ └── using-throw-error-handling.json ├── procedure │ ├── complex-stored-procedure-multiple-operations.json │ ├── complex-stored-procedure-multiple-statements.json │ ├── stored-procedure-comprehensive-logic-explanation.json │ ├── stored-procedure-conditional-logic.json │ ├── stored-procedure-cursor-temp-table.json │ ├── stored-procedure-detailed-documentation.json │ ├── stored-procedure-dynamic-sql-error-handling.json │ ├── stored-procedure-dynamic-sql-execution.json │ ├── stored-procedure-executing-another.json │ ├── stored-procedure-temp-tables-transaction.json │ ├── stored-procedure-try-catch-error.json │ ├── stored-procedure-version-control.json │ └── stored-procedure-with-params-and-execution.json.json ├── select │ ├── basic-select.json │ ├── data-compression-features.json │ ├── filetable-storage.json │ ├── pivot-unpivot-operations.json │ ├── select-choose.json │ ├── select-format.json │ ├── select-full-outer-join.json │ ├── select-identity.json │ ├── select-iif.json │ ├── select-join-aggregation.json │ ├── select-system-user.json │ ├── select-using-pivot.json │ ├── select-using-try-convert.json │ ├── select-with-bind-parameter.json │ ├── select-with-cte.json │ ├── select-with-offset-fetch.json │ ├── select-with-string-agg.json │ ├── select-with-table-sample.json │ ├── select-with-window-function.json │ ├── service-broker.json │ ├── spatial-data-types-functions.json │ └── xml-data-types-queries.json └── update │ ├── conditional-update-case.json │ ├── update-basic.json │ ├── update-complex-where.json │ ├── update-from-aliases.json │ ├── update-join-top.json │ ├── update-rowlock-hint.json │ ├── update-using-quoted-identifiers.json │ ├── update-using-top.json │ ├── update-using-variable-store-value.json │ ├── update-with-boolean-logic.json │ ├── update-with-case.json │ ├── update-with-cte.json │ ├── update-with-date-manipulation.json │ ├── update-with-join.json │ ├── update-with-named-variables.json │ ├── update-with-null-handling.json │ ├── update-with-numeric-calculation.json │ ├── update-with-output.json │ ├── update-with-string-concatenation.json │ └── update-with-subquery.json ├── mysql ├── complex │ ├── super-complex-poorly-written-sql.json │ ├── super-complex-sql-multiple-joins.json │ └── super-complex-sql-nested-subqueries.json ├── delete │ ├── delete-basic.json │ ├── delete-cascade.json │ ├── delete-cascading-triggers.json │ ├── delete-conditional-logic.json │ ├── delete-foreign-key-constraints.json │ ├── delete-free-disk-space.json │ ├── delete-join-multiple-conditions.json │ ├── delete-lock-tables.json │ ├── delete-multiple-tables.json │ ├── delete-optimized-conditions.json │ ├── delete-order-by-limit.json │ ├── delete-range-conditions.json │ ├── delete-regular-expressions.json │ ├── delete-safe-update-mode.json │ ├── delete-subquery-optimization.json │ ├── delete-truncate.json │ ├── delete-using-subquery.json │ ├── delete-with-join.json │ ├── delete-with-limit.json │ └── delete-with-user-variables.json ├── insert │ ├── batch-insert-multiple-rows.json │ ├── insert-auto-increment.json │ ├── insert-basic.json │ ├── insert-blob-data.json │ ├── insert-enum-data.json │ ├── insert-ignore.json │ ├── insert-json-data.json │ ├── insert-on-duplicate-key.json │ ├── insert-select-union.json │ ├── insert-spatial-data.json │ ├── insert-using-last-insert-id.json │ ├── insert-using-subquery.json │ ├── insert-with-conditional-logic.json │ ├── insert-with-curdate-curtime.json │ ├── insert-with-encryption-functions.json │ ├── insert-with-generated-columns.json │ ├── insert-with-replace.json │ ├── insert-with-set-syntax.json │ ├── insert-with-spatial-data.json │ └── insert-with-timestamp.json ├── procedure │ ├── complex-procedure-error-handling.json │ ├── stored-procedure-basic.json │ ├── stored-procedure-conditional-logic-loop.json │ ├── stored-procedure-cursor.json │ ├── stored-procedure-dynamic-sql.json │ ├── stored-procedure-error-handling.json │ ├── stored-procedure-input-output-parameters.json │ ├── stored-procedure-loop-control.json │ ├── stored-procedure-parameters.json │ └── stored-procedure-transaction-management.json ├── select │ ├── bit-data-type.json │ ├── blob-text-data-types.json │ ├── decimal-data-type.json │ ├── enum-set-data-types.json │ ├── full-text-search-innodb.json │ ├── select-aggregate-functions.json │ ├── select-basic.json │ ├── select-case-statement.json │ ├── select-coalesce-function.json │ ├── select-conditional-case.json │ ├── select-date-functions.json │ ├── select-distinct.json │ ├── select-full-text-search.json │ ├── select-geospatial-data.json │ ├── select-group-concat.json │ ├── select-join-aliases.json │ ├── select-join.json │ ├── select-json-functions.json │ ├── select-limit-offset.json │ ├── select-lock-in-share-mode.json │ ├── select-natural-join.json │ ├── select-parameter-binding.json │ ├── select-regex.json │ ├── select-straight-join.json │ ├── select-string-functions.json │ ├── select-subquery.json │ ├── select-user-defined-variables.json │ ├── select-variable-assignment.json │ ├── select-window-functions.json │ ├── spatial-data-types-functions.json │ ├── spatial-geometry-data-types.json │ ├── system-versioned-tables.json │ ├── using-temporary-tables.json │ └── virtual-generated-columns.json └── update │ ├── bulk-update-multiple-conditions.json │ ├── conditional-update-case.json │ ├── update-basic.json │ ├── update-case-aggregate-functions.json │ ├── update-date-time-functions.json │ ├── update-encryption-functions.json │ ├── update-enum-data.json │ ├── update-json-functions.json │ ├── update-json-modify.json │ ├── update-lock-tables.json │ ├── update-math-functions.json │ ├── update-optimizing-conditions.json │ ├── update-order-by-limit.json │ ├── update-regular-expressions.json │ ├── update-spatial-data.json │ ├── update-string-functions.json │ ├── update-user-defined-variables.json │ ├── update-using-variables.json │ ├── update-with-join.json │ └── update-with-subquery.json ├── oracle ├── complex │ ├── bulk-operations.json │ ├── complex-multi-table-delete.json │ ├── complex-nested-subqueries.json │ ├── complex-select-aggregates-joins.json │ ├── extremely-complex-oracle-query.json │ ├── extremely-complex-stored-procedure.json │ ├── plsql-blocks.json │ └── super-complex-oracle-query.json ├── delete │ ├── conditional-delete-with-case.json │ ├── delete-basic.json │ ├── delete-cascade.json │ ├── delete-using-rowid.json │ ├── delete-where-current-of.json │ ├── delete-with-complex-subqueries.json │ ├── delete-with-flashback-query.json │ ├── delete-with-join-syntax.json │ ├── delete-with-pseudocolumns.json │ ├── delete-with-returning-clause.json │ └── delete-with-subquery.json ├── insert │ ├── insert-all-into-multiple-tables.json │ ├── insert-all-multiple-conditions.json │ ├── insert-basic.json │ ├── insert-using-decode.json │ ├── insert-with-column-ordering.json │ ├── insert-with-returning-clause.json │ ├── insert-with-select-union.json │ ├── insert-with-sequence.json │ ├── insert-with-subquery.json │ └── multitable-insert-conditional.json ├── procedure │ ├── create-procedure-in-out-params.json │ ├── create-procedure-with-cursors.json │ ├── create-procedure-with-exception-handling.json │ ├── create-simple-stored-procedure.json │ ├── error-handling-exception.json │ ├── invoke-stored-procedure-with-exec.json │ ├── invoke-stored-procedure.json │ ├── packages.json │ ├── pipelined-functions.json │ ├── stored-procedures-functions.json │ └── triggers.json ├── select │ ├── complex-join-operations.json │ ├── full-hint.json │ ├── hierarchical-queries.json │ ├── index-hint.json │ ├── large-objects-lobs.json │ ├── multiple-hints.json │ ├── optimizer-mode-hint.json │ ├── oracle-text.json │ ├── quoted-identifiers-case-sensitive.json │ ├── quoted-identifiers-special-characters.json │ ├── recursive-cte.json │ ├── select-basic-conditions.json │ ├── select-hierarchical-query.json │ ├── select-using-oracle-text.json │ ├── select-using-with-clause.json │ ├── select-with-flashback-query.json │ ├── select-with-model-clause.json │ ├── select-with-multi-line-comments.json │ ├── select-with-oracle-specific-joins.json │ ├── select-with-partition-by.json │ ├── select-with-pseudocolumns.json │ ├── select-with-rollup-function.json │ ├── select-with-sample-clause.json │ ├── select-with-single-line-comments.json │ ├── select-with-skip-locked.json │ ├── use-nl-hint.json │ └── window-functions-analytics.json └── update │ ├── conditional-update-with-case.json │ ├── conditional-update-with-decode.json │ ├── dynamic-plsql.json │ ├── update-basic.json │ ├── update-oracle-specific-syntax.json │ ├── update-using-correlated-subquery.json │ ├── update-using-join-syntax.json │ ├── update-with-correlated-subquery.json │ ├── update-with-join.json │ ├── update-with-returning-clause.json │ ├── update-with-subquery-in-set.json │ └── update-with-subquery.json ├── postgresql ├── complex │ ├── delete-complex-subqueries-joins.json │ ├── insert-complex-select-joins.json │ ├── select-complex-aggregates-subqueries.json │ ├── select-complex-joins-window-functions.json │ ├── select-nested-subqueries-aggregates-limits.json │ └── update-complex-subquery-conditional.json ├── delete │ ├── delete-all-rows.json │ ├── delete-returning.json │ ├── delete-simple.json │ ├── delete-using-join.json │ ├── delete-with-cte.json │ └── delete-with-subquery.json ├── function │ ├── create-function-that-raises-notice.json │ ├── create-function-with-dynamic-query.json │ ├── create-function-with-parameters.json │ ├── create-function-with-table-return.json │ ├── create-simple-plpgsql-function.json │ ├── invoke-function-positional-parameters.json │ ├── invoke-function-returning-table.json │ ├── invoke-function-that-raises-notice.json │ ├── invoke-function-with-dynamic-query.json │ ├── invoke-function-with-parameter.json │ └── invoke-simple-function.json ├── insert │ ├── insert-array-data.json │ ├── insert-json-data.json │ ├── insert-multiple-rows.json │ ├── insert-positional-parameters.json │ ├── insert-returning-positional-parameter.json │ ├── insert-simple-row.json │ ├── insert-with-conflict-do-nothing.json │ ├── insert-with-conflict-update.json │ ├── insert-with-default.json │ ├── insert-with-enum-type.json │ ├── insert-with-geometric-data.json │ ├── insert-with-hstore-data.json │ ├── insert-with-range-data.json │ ├── insert-with-returning.json │ ├── insert-with-select.json │ └── insert-with-subquery-and-alias.json ├── select │ ├── aggregate-functions-count.json │ ├── basic_select_with_alias.json │ ├── case-statements.json │ ├── common-table-expressions-cte.json │ ├── cross-joins.json │ ├── distinct-on-expressions.json │ ├── fetch-first-clause.json │ ├── for-update-of.json │ ├── full-outer-joins.json │ ├── group-by-having.json │ ├── json-field-access.json │ ├── jsonb-array-elements-text.json │ ├── jsonb-array-length.json │ ├── jsonb-contained-in-path.json │ ├── jsonb-contains-key.json │ ├── jsonb-contains-object-at-top-level.json │ ├── jsonb-delete-array-element.json │ ├── jsonb-delete-key.json │ ├── jsonb-delete-path.json │ ├── jsonb-extract-path-text.json │ ├── jsonb-extract-path.json │ ├── jsonb-pretty-print.json │ ├── jsonb-set-new-value.json │ ├── lateral-joins.json │ ├── limit-and-offset.json │ ├── natural-joins.json │ ├── quoted-identifiers-case-sensitive.json │ ├── quoted-identifiers-special-characters.json │ ├── select-in-clause-positional-parameters.json │ ├── select-multiple-conditions-positional-parameters.json │ ├── select-only.json │ ├── select-with-positional-parameter.json │ ├── self-joins.json │ ├── subquery-in-from.json │ ├── subquery-in-select.json │ ├── subquery-in-where.json │ └── tablesample-bernoulli.json └── update │ ├── update-array-append.json │ ├── update-increment-numeric.json │ ├── update-json-data.json │ ├── update-multiple-fields-positional-parameters.json │ ├── update-positional-parameters.json │ ├── update-returning.json │ ├── update-set-multiple-columns.json │ ├── update-set-single-column.json │ ├── update-using-join.json │ ├── update-with-case.json │ ├── update-with-cte.json │ └── update-with-subquery.json └── snowflake └── test-cases ├── data-clone.json ├── external-data.json ├── listagg.json ├── materialized-view.json ├── semi-structured-data-types.json ├── stream.json ├── task.json ├── time-travel.json └── warehouse-controls.json /.gitignore: -------------------------------------------------------------------------------- 1 | # If you prefer the allow list template instead of the deny list, see community template: 2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 3 | # 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.exe~ 7 | *.dll 8 | *.so 9 | *.dylib 10 | 11 | # Test binary, built with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Dependency directories (remove the comment below to include it) 18 | # vendor/ 19 | 20 | # Go workspace file 21 | go.work 22 | 23 | # Go fuzz test files 24 | testdata/fuzz/ 25 | 26 | # Benchmark files 27 | bench -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/happysatire/go-sqllexer 2 | 3 | retract v0.1.0 // This version had memory leaks and should not be used 4 | 5 | go 1.21 6 | 7 | require github.com/stretchr/testify v1.8.4 8 | 9 | require ( 10 | github.com/davecgh/go-spew v1.1.1 // indirect 11 | github.com/pmezard/go-difflib v1.0.0 // indirect 12 | gopkg.in/yaml.v3 v3.0.1 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 6 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 7 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 8 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | -------------------------------------------------------------------------------- /testdata/mssql/complex/indexed-views.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE VIEW dbo.OrderSummary WITH SCHEMABINDING AS SELECT customer_id, COUNT_BIG(*) AS TotalOrders, SUM(amount) AS TotalAmount FROM dbo.orders GROUP BY customer_id; CREATE UNIQUE CLUSTERED INDEX IDX_V1 ON dbo.OrderSummary(customer_id);", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE VIEW dbo.OrderSummary WITH SCHEMABINDING AS SELECT customer_id, COUNT_BIG ( * ), SUM ( amount ) FROM dbo.orders GROUP BY customer_id; CREATE UNIQUE CLUSTERED INDEX IDX_V? ON dbo.OrderSummary ( customer_id )", 6 | "statement_metadata": { 7 | "size": 22, 8 | "tables": ["dbo.orders"], 9 | "commands": ["CREATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [], 12 | "views": ["dbo.OrderSummary"] 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /testdata/mssql/complex/partitioned-tables-indexes.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE PARTITION FUNCTION myRangePF1 (INT) AS RANGE LEFT FOR VALUES (1, 100, 1000); CREATE PARTITION SCHEME myScheme AS PARTITION myRangePF1 TO ([PRIMARY], [SECONDARY], [TERTIARY]); CREATE TABLE partitionedTable (id INT) ON myScheme(id);", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE PARTITION FUNCTION myRangePF? ( INT ) LEFT FOR VALUES ( ? ); CREATE PARTITION SCHEME myScheme myRangePF? TO ( PRIMARY, SECONDARY, TERTIARY ); CREATE TABLE partitionedTable ( id INT ) ON myScheme ( id )", 6 | "statement_metadata": { 7 | "size": 22, 8 | "tables": ["partitionedTable"], 9 | "commands": ["CREATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/conditional-delete-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status = CASE WHEN order_date < GETDATE() - 90 THEN 'Expired' ELSE 'Active' END;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status = CASE WHEN order_date < GETDATE ( ) - ? THEN ? ELSE ? END", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status = 'Cancelled';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-cascade.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM customers WHERE region = 'North'; -- Assuming CASCADE DELETE is set up on the foreign key in the orders table", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM customers WHERE region = ?", 6 | "statement_metadata": { 7 | "size": 90, 8 | "tables": ["customers"], 9 | "commands": ["DELETE"], 10 | "comments": ["-- Assuming CASCADE DELETE is set up on the foreign key in the orders table"], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-rowlock-hint.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WITH (ROWLOCK) WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WITH ( ROWLOCK ) WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-using-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE region = 'West');", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE customer_id IN ( SELECT id FROM customers WHERE region = ? )", 6 | "statement_metadata": { 7 | "size": 27, 8 | "tables": ["orders", "customers"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-using-table-variable.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DECLARE @ExpiredOrders TABLE (id INT); INSERT INTO @ExpiredOrders (id) SELECT id FROM orders WHERE order_date < GETDATE() - 365; DELETE FROM orders WHERE id IN (SELECT id FROM @ExpiredOrders);", 3 | "outputs": [ 4 | { 5 | "expected": "DECLARE @ExpiredOrders TABLE ( id INT ); INSERT INTO @ExpiredOrders ( id ) SELECT id FROM orders WHERE order_date < GETDATE ( ) - ?; DELETE FROM orders WHERE id IN ( SELECT id FROM @ExpiredOrders )", 6 | "statement_metadata": { 7 | "size": 24, 8 | "tables": ["orders"], 9 | "commands": ["INSERT", "SELECT", "DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-with-cte.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "WITH OldOrders AS (SELECT id FROM orders WHERE order_date < '2022-01-01') DELETE FROM orders WHERE id IN (SELECT id FROM OldOrders);", 3 | "outputs": [ 4 | { 5 | "expected": "WITH OldOrders AS ( SELECT id FROM orders WHERE order_date < ? ) DELETE FROM orders WHERE id IN ( SELECT id FROM OldOrders )", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["SELECT", "DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-with-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE o FROM orders o INNER JOIN customers c ON o.customer_id = c.id WHERE c.region = 'East' AND o.status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE o FROM orders o INNER JOIN customers c ON o.customer_id = c.id WHERE c.region = ? AND o.status = ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["DELETE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-with-output.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders OUTPUT DELETED.* WHERE status = 'Shipped';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders OUTPUT DELETED. * WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/delete/delete-with-top.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE TOP (10) FROM orders WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE TOP ( ? ) FROM orders WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, order_date, status) VALUES (1, GETDATE(), 'Pending');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, order_date, status ) VALUES ( ?, GETDATE ( ), ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-default-values.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders DEFAULT VALUES;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders DEFAULT VALUES", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-identity-insert.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SET IDENTITY_INSERT orders ON; INSERT INTO orders (id, customer_id, order_date, status) VALUES (100, 3, GETDATE(), 'Pending'); SET IDENTITY_INSERT orders OFF;", 3 | "outputs": [ 4 | { 5 | "expected": "SET IDENTITY_INSERT orders ON; INSERT INTO orders ( id, customer_id, order_date, status ) VALUES ( ?, GETDATE ( ), ? ); SET IDENTITY_INSERT orders OFF", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-merge.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "MERGE INTO orders AS target USING (SELECT customer_id, order_date, status FROM incoming_orders) AS source ON target.id = source.id WHEN NOT MATCHED THEN INSERT (customer_id, order_date, status) VALUES (source.customer_id, source.order_date, source.status);", 3 | "outputs": [ 4 | { 5 | "expected": "MERGE INTO orders USING ( SELECT customer_id, order_date, status FROM incoming_orders ) ON target.id = source.id WHEN NOT MATCHED THEN INSERT ( customer_id, order_date, status ) VALUES ( source.customer_id, source.order_date, source.status )", 6 | "statement_metadata": { 7 | "size": 38, 8 | "tables": ["orders", "incoming_orders"], 9 | "commands": ["MERGE", "SELECT", "INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-output.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, order_date, status) OUTPUT INSERTED.id VALUES (3, GETDATE(), 'Processing');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, order_date, status ) OUTPUT INSERTED.id VALUES ( ?, GETDATE ( ), ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-select-into.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * INTO new_orders FROM orders WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * INTO new_orders FROM orders WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 22, 8 | "tables": ["new_orders", "orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-subquery-values.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO order_totals (order_id, total_amount) VALUES ((SELECT MAX(id) FROM orders), 500);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO order_totals ( order_id, total_amount ) VALUES ( ( SELECT MAX ( id ) FROM orders ), ? )", 6 | "statement_metadata": { 7 | "size": 30, 8 | "tables": ["order_totals", "orders"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-top-orderby.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO top_orders (id, amount) SELECT TOP 5 id, amount FROM orders ORDER BY amount DESC;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO top_orders ( id, amount ) SELECT TOP ? id, amount FROM orders ORDER BY amount DESC", 6 | "statement_metadata": { 7 | "size": 28, 8 | "tables": ["top_orders", "orders"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-values-multiple-rows.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO customers (name, region) VALUES ('John Doe', 'North'), ('Jane Smith', 'South');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO customers ( name, region ) VALUES ( ? ), ( ? )", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["customers"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/insert-with-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders_archive (id, customer_id, order_date, status) SELECT id, customer_id, order_date, status FROM orders WHERE status = 'Completed';", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders_archive ( id, customer_id, order_date, status ) SELECT id, customer_id, order_date, status FROM orders WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 32, 8 | "tables": ["orders_archive", "orders"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/insert/using-throw-error-handling.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "BEGIN TRY INSERT INTO orders (customer_id, amount) VALUES (1, -100); END TRY BEGIN CATCH THROW; END CATCH;", 3 | "outputs": [ 4 | { 5 | "expected": "BEGIN TRY INSERT INTO orders ( customer_id, amount ) VALUES ( ? ); END TRY BEGIN CATCH THROW; END CATCH", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": ["orders"], 9 | "commands": ["BEGIN", "INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/basic-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, name, email FROM customers WHERE active = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, name, email FROM customers WHERE active = ?", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["customers"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/data-compression-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE TABLE orders_compressed WITH (DATA_COMPRESSION = PAGE) AS SELECT * FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE TABLE orders_compressed WITH ( DATA_COMPRESSION = PAGE ) AS SELECT * FROM orders", 6 | "statement_metadata": { 7 | "size": 35, 8 | "tables": ["orders_compressed", "orders"], 9 | "commands": ["CREATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/filetable-storage.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE TABLE DocumentStore AS FileTable;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE TABLE DocumentStore", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": ["DocumentStore"], 9 | "commands": ["CREATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/pivot-unpivot-operations.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM (SELECT customer_id, product_id, amount FROM order_details) AS SourceTable PIVOT (SUM(amount) FOR product_id IN ([1], [2], [3])) AS PivotTable;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM ( SELECT customer_id, product_id, amount FROM order_details ) PIVOT ( SUM ( amount ) FOR product_id IN ( ? ) )", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": ["order_details"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-choose.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, name, CHOOSE(department_id, 'Sales', 'Engineering', 'HR') AS DepartmentName FROM employees;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, name, CHOOSE ( department_id, ?, ?, ? ) FROM employees", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-format.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT name, FORMAT(joining_date, 'dd-MM-yyyy') AS FormattedJoiningDate FROM employees;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT name, FORMAT ( joining_date, ? ) FROM employees", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-full-outer-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT c.name, o.order_date FROM customers c FULL OUTER JOIN orders o ON c.id = o.customer_id WHERE c.region = 'West' OR o.amount > 500;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT c.name, o.order_date FROM customers c FULL OUTER JOIN orders o ON c.id = o.customer_id WHERE c.region = ? OR o.amount > ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["customers", "orders"], 9 | "commands": ["SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-identity.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO employees (name, department) VALUES ('John Doe', 'Sales'); SELECT @@IDENTITY AS LastInsertedIdentity;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO employees ( name, department ) VALUES ( ? ); SELECT @@IDENTITY", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": ["employees"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-iif.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT name, IIF(gender = 'M', 'Male', 'Female') AS GenderDescription FROM employees;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT name, IIF ( gender = ?, ?, ? ) FROM employees", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-join-aggregation.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT c.name, SUM(o.amount) AS total_sales FROM customers c INNER JOIN orders o ON c.id = o.customer_id GROUP BY c.name;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT c.name, SUM ( o.amount ) FROM customers c INNER JOIN orders o ON c.id = o.customer_id GROUP BY c.name", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["customers", "orders"], 9 | "commands": ["SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-system-user.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT SYSTEM_USER AS CurrentSystemUser, USER_NAME() AS CurrentDatabaseUser, NEWID() AS UniqueIdentifier;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT SYSTEM_USER, USER_NAME ( ), NEWID ( )", 6 | "statement_metadata": { 7 | "size": 6, 8 | "tables": [], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-using-pivot.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM (SELECT customer_id, product_id, amount FROM orders) AS SourceTable PIVOT (SUM(amount) FOR product_id IN ([1], [2], [3])) AS PivotTable;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM ( SELECT customer_id, product_id, amount FROM orders ) PIVOT ( SUM ( amount ) FOR product_id IN ( ? ) )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-using-try-convert.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, TRY_CONVERT(float, total_amount) AS TotalFloat FROM orders WHERE TRY_CONVERT(float, total_amount) IS NOT NULL;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, TRY_CONVERT ( float, total_amount ) FROM orders WHERE TRY_CONVERT ( float, total_amount ) IS NOT ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-with-offset-fetch.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, name FROM customers ORDER BY name OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, name FROM customers ORDER BY name OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["customers"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-with-string-agg.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT STRING_AGG(name, ', ') AS names FROM customers WHERE region = 'East';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT STRING_AGG ( name, ? ) FROM customers WHERE region = ?", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["customers"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-with-table-sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM customers TABLESAMPLE (10 PERCENT);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM customers TABLESAMPLE ( ? PERCENT )", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["customers"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/select-with-window-function.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, amount, ROW_NUMBER() OVER (ORDER BY amount DESC) AS rownum FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, amount, ROW_NUMBER ( ) OVER ( ORDER BY amount DESC ) AS rownum FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT id, amount, ROW_NUMBER() OVER (ORDER BY amount DESC) AS rownum FROM orders;", 16 | "normalizer_config": { 17 | "keep_sql_alias": true, 18 | "keep_trailing_semicolon": true, 19 | "remove_space_between_parentheses": true 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /testdata/mssql/select/service-broker.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE MESSAGE TYPE RequestMessage VALIDATION = WELL_FORMED_XML; CREATE CONTRACT RequestContract (RequestMessage SENT BY INITIATOR);", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE MESSAGE TYPE RequestMessage VALIDATION = WELL_FORMED_XML; CREATE CONTRACT RequestContract ( RequestMessage SENT BY INITIATOR )", 6 | "statement_metadata": { 7 | "size": 6, 8 | "tables": [], 9 | "commands": ["CREATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/spatial-data-types-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT geography::Point(latitude, longitude, 4326).ToString() FROM locations;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT geography :: Point ( latitude, longitude, ? ) . ToString ( ) FROM locations", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["locations"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/select/xml-data-types-queries.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT xmlData.value('(/Customer/Name)[1]', 'nvarchar(100)') AS CustomerName FROM customerRecords;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT xmlData.value ( ? ) FROM customerRecords", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": ["customerRecords"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/conditional-update-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = CASE WHEN amount >= 1000 THEN 'High Value' ELSE 'Regular' END;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = CASE WHEN amount >= ? THEN ? ELSE ? END", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Processed' WHERE order_date < GETDATE() - 30;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE order_date < GETDATE ( ) - ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-complex-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Review Needed' WHERE customer_id IN (SELECT id FROM customers WHERE last_order_date < GETDATE() - 365) AND status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE customer_id IN ( SELECT id FROM customers WHERE last_order_date < GETDATE ( ) - ? ) AND status = ?", 6 | "statement_metadata": { 7 | "size": 27, 8 | "tables": ["orders", "customers"], 9 | "commands": ["UPDATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-from-aliases.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE o SET o.status = 'Completed' FROM orders o WHERE o.order_date > '2023-01-01' AND o.amount > 500;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE o SET o.status = ? FROM orders o WHERE o.order_date > ? AND o.amount > ?", 6 | "statement_metadata": { 7 | "size": 13, 8 | "tables": ["o", "orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-join-top.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE TOP (5) o SET o.status = 'Pending Review' FROM orders o INNER JOIN customers c ON o.customer_id = c.id WHERE c.region = 'North';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE TOP ( ? ) o SET o.status = ? FROM orders o INNER JOIN customers c ON o.customer_id = c.id WHERE c.region = ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["UPDATE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-rowlock-hint.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders WITH (ROWLOCK) SET status = 'Processing' WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders WITH ( ROWLOCK ) SET status = ? WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-using-quoted-identifiers.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE [orders] SET [status] = 'Confirmed' WHERE [order_date] >= '2023-01-01';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE order_date >= ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-using-top.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE TOP (10) orders SET status = 'Reviewed' WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE TOP ( ? ) orders SET status = ? WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 6, 8 | "tables": [], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-using-variable-store-value.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DECLARE @maxDate DATETIME; SET @maxDate = (SELECT MAX(order_date) FROM orders); UPDATE orders SET status = 'Old Order' WHERE order_date < @maxDate;", 3 | "outputs": [ 4 | { 5 | "expected": "DECLARE @maxDate DATETIME; SET @maxDate = ( SELECT MAX ( order_date ) FROM orders ); UPDATE orders SET status = ? WHERE order_date < @maxDate", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["SELECT", "UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-boolean-logic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET is_priority = CASE WHEN total_amount > 1000 THEN 1 ELSE 0 END WHERE order_date > '2023-01-01';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET is_priority = CASE WHEN total_amount > ? THEN ? ELSE ? END WHERE order_date > ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = CASE WHEN amount > 1000 THEN 'High Value' ELSE 'Standard' END WHERE order_date >= '2023-01-01';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = CASE WHEN amount > ? THEN ? ELSE ? END WHERE order_date >= ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-cte.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "WITH UpdatedOrders AS (SELECT id FROM orders WHERE order_date < GETDATE() - 30) UPDATE o SET o.status = 'Archived' FROM orders o JOIN UpdatedOrders uo ON o.id = uo.id;", 3 | "outputs": [ 4 | { 5 | "expected": "WITH UpdatedOrders AS ( SELECT id FROM orders WHERE order_date < GETDATE ( ) - ? ) UPDATE o SET o.status = ? FROM orders o JOIN UpdatedOrders uo ON o.id = uo.id", 6 | "statement_metadata": { 7 | "size": 23, 8 | "tables": ["orders", "o"], 9 | "commands": ["SELECT", "UPDATE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-date-manipulation.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET due_date = DATEADD(day, 10, order_date) WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET due_date = DATEADD ( day, ?, order_date ) WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE o SET o.status = 'Dispatched' FROM orders o INNER JOIN customers c ON o.customer_id = c.id WHERE c.region = 'West' AND o.status = 'Processed';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE o SET o.status = ? FROM orders o INNER JOIN customers c ON o.customer_id = c.id WHERE c.region = ? AND o.status = ?", 6 | "statement_metadata": { 7 | "size": 26, 8 | "tables": ["o", "orders", "customers"], 9 | "commands": ["UPDATE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-named-variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DECLARE @status NVARCHAR(50); SET @status = 'Delayed'; UPDATE orders SET status = @status WHERE order_date < GETDATE() - 60;", 3 | "outputs": [ 4 | { 5 | "expected": "DECLARE @status NVARCHAR ( ? ); SET @status = ?; UPDATE orders SET status = @status WHERE order_date < GETDATE ( ) - ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-null-handling.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET delivery_date = NULLIF(order_date, due_date) WHERE status = 'Cancelled';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET delivery_date = NULLIF ( order_date, due_date ) WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-numeric-calculation.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET total_amount = quantity * unit_price WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET total_amount = quantity * unit_price WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-output.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Cancelled' OUTPUT deleted.id, deleted.status WHERE status = 'Pending' AND order_date < GETDATE() - 90;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? OUTPUT deleted.id, deleted.status WHERE status = ? AND order_date < GETDATE ( ) - ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-string-concatenation.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET notes = CONCAT(notes, ' Updated on ', CONVERT(VARCHAR, GETDATE(), 101)) WHERE status = 'Shipped';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET notes = CONCAT ( notes, ?, CONVERT ( VARCHAR, GETDATE ( ), ? ) ) WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mssql/update/update-with-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'High Priority' WHERE id IN (SELECT order_id FROM order_details WHERE quantity > 10);", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE id IN ( SELECT order_id FROM order_details WHERE quantity > ? )", 6 | "statement_metadata": { 7 | "size": 31, 8 | "tables": ["orders", "order_details"], 9 | "commands": ["UPDATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status = 'Cancelled';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-cascade.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM customers WHERE region = 'North'; -- Assuming CASCADE DELETE is set up on the foreign key in the orders table", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM customers WHERE region = ?", 6 | "statement_metadata": { 7 | "size": 90, 8 | "tables": ["customers"], 9 | "commands": ["DELETE"], 10 | "comments": ["-- Assuming CASCADE DELETE is set up on the foreign key in the orders table"], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-cascading-triggers.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM customers WHERE id = 1; -- Assumes a trigger exists for cascading delete to orders", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM customers WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 73, 8 | "tables": ["customers"], 9 | "commands": ["DELETE"], 10 | "comments": ["-- Assumes a trigger exists for cascading delete to orders"], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-conditional-logic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status = IF(DAYOFWEEK(CURDATE()) = 1, 'Pending', 'Completed');", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status = IF ( DAYOFWEEK ( CURDATE ( ) ) = ?, ?, ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-foreign-key-constraints.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE id IN (SELECT order_id FROM order_details WHERE quantity = 0);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE id IN ( SELECT order_id FROM order_details WHERE quantity = ? )", 6 | "statement_metadata": { 7 | "size": 31, 8 | "tables": ["orders", "order_details"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-free-disk-space.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE order_date < '2020-01-01'; OPTIMIZE TABLE orders;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE order_date < ?; OPTIMIZE TABLE orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-join-multiple-conditions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'Completed' AND c.region = 'South';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = ? AND c.region = ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["DELETE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-lock-tables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "LOCK TABLES orders WRITE; DELETE FROM orders WHERE status = 'Failed'; UNLOCK TABLES;", 3 | "outputs": [ 4 | { 5 | "expected": "LOCK TABLES orders WRITE; DELETE FROM orders WHERE status = ?; UNLOCK TABLES", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-multiple-tables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE orders, order_details FROM orders INNER JOIN order_details ON orders.id = order_details.order_id WHERE orders.status = 'Obsolete';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE orders, order_details FROM orders INNER JOIN order_details ON orders.id = order_details.order_id WHERE orders.status = ?", 6 | "statement_metadata": { 7 | "size": 29, 8 | "tables": ["orders", "order_details"], 9 | "commands": ["DELETE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-optimized-conditions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status = 'Completed' AND order_date < DATE_SUB(NOW(), INTERVAL 1 YEAR);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status = ? AND order_date < DATE_SUB ( NOW ( ), INTERVAL ? YEAR )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-order-by-limit.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status = 'Completed' ORDER BY order_date DESC LIMIT 5;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status = ? ORDER BY order_date DESC LIMIT ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-range-conditions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE amount BETWEEN 100 AND 500;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE amount BETWEEN ? AND ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-regular-expressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status REGEXP '^C.*';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status REGEXP ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-safe-update-mode.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SET SQL_SAFE_UPDATES = 0; DELETE FROM orders WHERE customer_id = 1; SET SQL_SAFE_UPDATES = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "SET SQL_SAFE_UPDATES = ?; DELETE FROM orders WHERE customer_id = ?; SET SQL_SAFE_UPDATES = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-subquery-optimization.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE id IN (SELECT id FROM orders WHERE status = 'Failed' LIMIT 10);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE id IN ( SELECT id FROM orders WHERE status = ? LIMIT ? )", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-truncate.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "TRUNCATE TABLE order_details;", 3 | "outputs": [ 4 | { 5 | "expected": "TRUNCATE TABLE order_details", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": ["order_details"], 9 | "commands": ["TRUNCATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-using-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE region = 'West');", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE customer_id IN ( SELECT id FROM customers WHERE region = ? )", 6 | "statement_metadata": { 7 | "size": 27, 8 | "tables": ["orders", "customers"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-with-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.region = 'East' AND o.status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.region = ? AND o.status = ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["DELETE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-with-limit.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE status = 'Pending' LIMIT 10;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE status = ? LIMIT ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/delete/delete-with-user-variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SET @max_id = (SELECT MAX(id) FROM orders); DELETE FROM orders WHERE id = @max_id;", 3 | "outputs": [ 4 | { 5 | "expected": "SET @max_id = ( SELECT MAX ( id ) FROM orders ); DELETE FROM orders WHERE id = @max_id", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["SELECT", "DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/batch-insert-multiple-rows.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status) VALUES (1, 'Pending'), (2, 'Completed'), (3, 'Processing');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status ) VALUES ( ? ), ( ? ), ( ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-auto-increment.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status) VALUES (3, 'Processing');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, order_date, status) VALUES (1, NOW(), 'Pending');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, order_date, status ) VALUES ( ?, NOW ( ), ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-blob-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, document) VALUES (5, 'Pending', LOAD_FILE('/path/to/file'));", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, document ) VALUES ( ?, LOAD_FILE ( ? ) )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-enum-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, order_type) VALUES (7, 'Pending', 'Express');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, order_type ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-ignore.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT IGNORE INTO orders (id, customer_id, status) VALUES (1, 10, 'Cancelled');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT IGNORE INTO orders ( id, customer_id, status ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-json-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, details) VALUES (1, 'Pending', '{\"items\": [\"item1\", \"item2\"]}');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, details ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-on-duplicate-key.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (id, customer_id, status) VALUES (100, 2, 'Pending') ON DUPLICATE KEY UPDATE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( id, customer_id, status ) VALUES ( ? ) ON DUPLICATE KEY UPDATE status = ?", 6 | "statement_metadata": { 7 | "size": 24, 8 | "tables": ["orders", "status"], 9 | "commands": ["INSERT", "UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-select-union.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status) SELECT customer_id, status FROM archived_orders UNION ALL SELECT customer_id, status FROM special_orders;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status ) SELECT customer_id, status FROM archived_orders UNION ALL SELECT customer_id, status FROM special_orders", 6 | "statement_metadata": { 7 | "size": 47, 8 | "tables": ["orders", "archived_orders", "special_orders"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-spatial-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, location) VALUES (6, 'Delivered', ST_GeomFromText('POINT(1 1)'));", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, location ) VALUES ( ?, ST_GeomFromText ( ? ) )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-using-last-insert-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO customers (name) VALUES ('John Doe'); INSERT INTO orders (customer_id, status) VALUES (LAST_INSERT_ID(), 'Pending');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO customers ( name ) VALUES ( ? ); INSERT INTO orders ( customer_id, status ) VALUES ( LAST_INSERT_ID ( ), ? )", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": ["customers", "orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-using-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO order_audit (order_id, status) SELECT id, status FROM orders WHERE customer_id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO order_audit ( order_id, status ) SELECT id, status FROM orders WHERE customer_id = ?", 6 | "statement_metadata": { 7 | "size": 29, 8 | "tables": ["order_audit", "orders"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-conditional-logic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, amount) SELECT id, 'New', IF(region = 'West', 100, 50) FROM customers;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, amount ) SELECT id, ?, IF ( region = ?, ?, ? ) FROM customers", 6 | "statement_metadata": { 7 | "size": 27, 8 | "tables": ["orders", "customers"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-curdate-curtime.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, order_date, order_time) VALUES (15, 'Pending', CURDATE(), CURTIME());", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, order_date, order_time ) VALUES ( ?, CURDATE ( ), CURTIME ( ) )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-encryption-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, encrypted_note) VALUES (13, 'Pending', AES_ENCRYPT('Confidential note', 'encryption_key'));", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, encrypted_note ) VALUES ( ?, AES_ENCRYPT ( ? ) )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-generated-columns.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, total_incl_tax) VALUES (12, 'Pending', 150); -- total_incl_tax is a generated column", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, total_incl_tax ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 51, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": ["-- total_incl_tax is a generated column"], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-replace.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "REPLACE INTO orders (id, customer_id, status) VALUES (1, 9, 'Completed');", 3 | "outputs": [ 4 | { 5 | "expected": "REPLACE INTO orders ( id, customer_id, status ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 6, 8 | "tables": ["orders"], 9 | "commands": [], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-set-syntax.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders SET customer_id = 8, status = 'Processing', order_date = CURDATE();", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders SET customer_id = ?, status = ?, order_date = CURDATE ( )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-spatial-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, location) VALUES (14, 'Pending', ST_GeomFromText('POINT(1 1)'));", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, location ) VALUES ( ?, ST_GeomFromText ( ? ) )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/insert/insert-with-timestamp.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (customer_id, status, created_at) VALUES (4, 'Shipped', CURRENT_TIMESTAMP);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( customer_id, status, created_at ) VALUES ( ?, CURRENT_TIMESTAMP )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/procedure/stored-procedure-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE PROCEDURE GetAllOrders() BEGIN SELECT * FROM orders; END;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE PROCEDURE GetAllOrders ( ) BEGIN SELECT * FROM orders; END", 6 | "statement_metadata": { 7 | "size": 35, 8 | "tables": ["orders"], 9 | "commands": ["CREATE", "BEGIN", "SELECT"], 10 | "comments": [], 11 | "procedures": ["GetAllOrders"] 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /testdata/mysql/procedure/stored-procedure-dynamic-sql.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE PROCEDURE DynamicQuery(IN tbl_name VARCHAR(50)) BEGIN SET @s = CONCAT('SELECT * FROM ', tbl_name); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE PROCEDURE DynamicQuery ( IN tbl_name VARCHAR ( ? ) ) BEGIN SET @s = CONCAT ( ?, tbl_name ); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; END", 6 | "statement_metadata": { 7 | "size": 30, 8 | "tables": [], 9 | "commands": ["CREATE", "BEGIN", "EXECUTE"], 10 | "comments": [], 11 | "procedures": ["DynamicQuery"] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/procedure/stored-procedure-error-handling.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE PROCEDURE SafeUpdate(IN order_id INT, IN new_status VARCHAR(50)) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- handle error\n SET @error = 'An error occurred'; END; UPDATE orders SET status = new_status WHERE id = order_id; END;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE PROCEDURE SafeUpdate ( IN order_id INT, IN new_status VARCHAR ( ? ) ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SET @error = ?; END; UPDATE orders SET status = new_status WHERE id = order_id; END", 6 | "statement_metadata": { 7 | "size": 48, 8 | "tables": ["orders"], 9 | "commands": ["CREATE", "BEGIN", "UPDATE"], 10 | "comments": ["-- handle error"], 11 | "procedures": ["SafeUpdate"] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/procedure/stored-procedure-input-output-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE PROCEDURE GetTotalOrders(OUT total INT) BEGIN SELECT COUNT(*) INTO total FROM orders; END;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE PROCEDURE GetTotalOrders ( OUT total INT ) BEGIN SELECT COUNT ( * ) INTO total FROM orders; END", 6 | "statement_metadata": { 7 | "size": 42, 8 | "tables": ["total", "orders"], 9 | "commands": ["CREATE", "BEGIN", "SELECT"], 10 | "comments": [], 11 | "procedures": ["GetTotalOrders"] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/procedure/stored-procedure-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE PROCEDURE GetOrdersByStatus(IN status VARCHAR(20)) BEGIN SELECT * FROM orders WHERE orders.status = status; END;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE PROCEDURE GetOrdersByStatus ( IN status VARCHAR ( ? ) ) BEGIN SELECT * FROM orders WHERE orders.status = status; END", 6 | "statement_metadata": { 7 | "size": 40, 8 | "tables": ["orders"], 9 | "commands": ["CREATE", "BEGIN", "SELECT"], 10 | "comments": [], 11 | "procedures": ["GetOrdersByStatus"] 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /testdata/mysql/procedure/stored-procedure-transaction-management.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE PROCEDURE UpdateOrderTransaction(IN order_id INT, IN new_status VARCHAR(50)) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; END; START TRANSACTION; UPDATE orders SET status = new_status WHERE id = order_id; COMMIT; END;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE PROCEDURE UpdateOrderTransaction ( IN order_id INT, IN new_status VARCHAR ( ? ) ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; END; START TRANSACTION; UPDATE orders SET status = new_status WHERE id = order_id; COMMIT; END", 6 | "statement_metadata": { 7 | "size": 51, 8 | "tables": ["orders"], 9 | "commands": ["CREATE", "BEGIN", "UPDATE", "COMMIT"], 10 | "comments": [], 11 | "procedures": ["UpdateOrderTransaction"] 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /testdata/mysql/select/bit-data-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, status, (is_paid & 1) AS isPaidFlag FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, status, ( is_paid & ? ) FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/blob-text-data-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, SUBSTRING(order_notes, 1, 100) AS short_notes FROM orders WHERE LENGTH(document_blob) > 1024;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, SUBSTRING ( order_notes, ?, ? ) FROM orders WHERE LENGTH ( document_blob ) > ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/decimal-data-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, ROUND(total_amount, 2) AS rounded_total FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, ROUND ( total_amount, ? ) FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/enum-set-data-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, order_type, status_flags FROM order_details WHERE order_type = 'Standard' AND FIND_IN_SET('urgent', status_flags);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, order_type, status_flags FROM order_details WHERE order_type = ? AND FIND_IN_SET ( ?, status_flags )", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": ["order_details"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/full-text-search-innodb.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE FULLTEXT INDEX ft_index ON orders (description); SELECT * FROM orders WHERE MATCH(description) AGAINST ('+delivery -return' IN BOOLEAN MODE);", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE FULLTEXT INDEX ft_index ON orders ( description ); SELECT * FROM orders WHERE MATCH ( description ) AGAINST ( ? IN BOOLEAN MODE )", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["CREATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-aggregate-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT customer_id, COUNT(*) AS total_orders FROM orders GROUP BY customer_id HAVING COUNT(*) > 5;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT customer_id, COUNT ( * ) FROM orders GROUP BY customer_id HAVING COUNT ( * ) > ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, customer_id, order_date, status FROM orders WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, customer_id, order_date, status FROM orders WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-case-statement.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, CASE WHEN status = 'Pending' THEN 'P' WHEN status = 'Completed' THEN 'C' ELSE 'Other' END AS status_code FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, CASE WHEN status = ? THEN ? WHEN status = ? THEN ? ELSE ? END FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-coalesce-function.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, COALESCE(comments, 'No comments') AS order_comments FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, COALESCE ( comments, ? ) FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-conditional-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, CASE WHEN status = 'Pending' THEN 'P' WHEN status = 'Completed' THEN 'C' ELSE 'Other' END AS status_code FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, CASE WHEN status = ? THEN ? WHEN status = ? THEN ? ELSE ? END FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-date-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, YEAR(order_date) AS order_year FROM orders WHERE MONTH(order_date) = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, YEAR ( order_date ) FROM orders WHERE MONTH ( order_date ) = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-distinct.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT DISTINCT status FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT DISTINCT status FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-full-text-search.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, MATCH (description) AGAINST ('+shipping -delayed' IN BOOLEAN MODE) AS score FROM orders WHERE MATCH (description) AGAINST ('+shipping -delayed' IN BOOLEAN MODE) > 0;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, MATCH ( description ) AGAINST ( ? IN BOOLEAN MODE ) FROM orders WHERE MATCH ( description ) AGAINST ( ? IN BOOLEAN MODE ) > ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-geospatial-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, ST_AsText(location) AS location FROM orders WHERE ST_Distance_Sphere(location, ST_GeomFromText('POINT(10 20)')) < 10000;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, ST_AsText ( location ) FROM orders WHERE ST_Distance_Sphere ( location, ST_GeomFromText ( ? ) ) < ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-group-concat.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT customer_id, GROUP_CONCAT(status ORDER BY order_date DESC SEPARATOR ', ') AS order_statuses FROM orders GROUP BY customer_id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT customer_id, GROUP_CONCAT ( status ORDER BY order_date DESC SEPARATOR ? ) FROM orders GROUP BY customer_id", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-join-aliases.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT o.id, c.name AS customer_name, o.status FROM orders o LEFT JOIN customers c ON o.customer_id = c.id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT o.id, c.name, o.status FROM orders o LEFT JOIN customers c ON o.customer_id = c.id", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT o.id, c.name, o.status FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'Completed';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT o.id, c.name, o.status FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-json-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, JSON_EXTRACT(order_details, '$.items[0].name') AS first_item_name FROM orders WHERE JSON_CONTAINS(order_details, '\"Active\"', '$.status');", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, JSON_EXTRACT ( order_details, ? ) FROM orders WHERE JSON_CONTAINS ( order_details, ?, ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-limit-offset.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM orders ORDER BY order_date DESC LIMIT 10 OFFSET 5;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM orders ORDER BY order_date DESC LIMIT ? OFFSET ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-lock-in-share-mode.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM orders WHERE status = 'Pending' LOCK IN SHARE MODE;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM orders WHERE status = ? LOCK IN SHARE MODE", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-natural-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM orders NATURAL JOIN customers;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM orders NATURAL JOIN customers", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-parameter-binding.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, status FROM orders WHERE customer_id = ?;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, status FROM orders WHERE customer_id = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-regex.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, customer_id FROM orders WHERE status REGEXP '^Comp.*';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, customer_id FROM orders WHERE status REGEXP ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-straight-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM orders STRAIGHT_JOIN customers ON orders.customer_id = customers.id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM orders STRAIGHT_JOIN customers ON orders.customer_id = customers.id", 6 | "statement_metadata": { 7 | "size": 34, 8 | "tables": ["orders", "customers"], 9 | "commands": ["SELECT", "STRAIGHT_JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-string-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, UPPER(status) AS status_upper FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, UPPER ( status ) FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, (SELECT name FROM customers WHERE id = orders.customer_id) AS customer_name FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, ( SELECT name FROM customers WHERE id = orders.customer_id ) FROM orders", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": ["customers", "orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-user-defined-variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SET @orderRank := 0; SELECT @orderRank := @orderRank + 1 AS rank, id, status FROM orders ORDER BY id;", 3 | "outputs": [ 4 | { 5 | "expected": "SET @orderRank := ?; SELECT @orderRank := @orderRank + ?, id, status FROM orders ORDER BY id", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-variable-assignment.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT @orderCount := COUNT(*) FROM orders WHERE status = 'Completed';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT @orderCount := COUNT ( * ) FROM orders WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/select-window-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, status, RANK() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rank FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, status, RANK ( ) OVER ( PARTITION BY customer_id ORDER BY order_date DESC ) FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/spatial-data-types-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, ST_AsText(location) AS location FROM orders WHERE ST_Distance_Sphere(location, ST_GeomFromText('POINT(10 20)')) < 10000;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, ST_AsText ( location ) FROM orders WHERE ST_Distance_Sphere ( location, ST_GeomFromText ( ? ) ) < ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/spatial-geometry-data-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, ST_AsText(location) FROM orders WHERE ST_Distance(location, ST_GeomFromText('POINT(1 1)')) < 100;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, ST_AsText ( location ) FROM orders WHERE ST_Distance ( location, ST_GeomFromText ( ? ) ) < ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/system-versioned-tables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE TABLE orders_with_history (id INT, status VARCHAR(20)) WITH SYSTEM VERSIONING;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE TABLE orders_with_history ( id INT, status VARCHAR ( ? ) ) WITH SYSTEM VERSIONING", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders_with_history"], 9 | "commands": ["CREATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/using-temporary-tables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE TEMPORARY TABLE temp_orders SELECT * FROM orders; SELECT * FROM temp_orders WHERE status = 'Pending'; DROP TEMPORARY TABLE temp_orders;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE TEMPORARY TABLE temp_orders SELECT * FROM orders; SELECT * FROM temp_orders WHERE status = ?; DROP TEMPORARY TABLE temp_orders", 6 | "statement_metadata": { 7 | "size": 33, 8 | "tables": ["temp_orders", "orders"], 9 | "commands": ["CREATE", "SELECT", "DROP"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/select/virtual-generated-columns.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE TABLE orders_with_virtual (id INT, amount DECIMAL(10, 2), total_incl_tax DECIMAL(10, 2) GENERATED ALWAYS AS (amount * 1.1) STORED);", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE TABLE orders_with_virtual ( id INT, amount DECIMAL ( ? ), total_incl_tax DECIMAL ( ? ) GENERATED ALWAYS AS ( amount * ? ) STORED )", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders_with_virtual"], 9 | "commands": ["CREATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/bulk-update-multiple-conditions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = IF(amount > 1000, 'High Value', 'Regular'), order_date = IF(status = 'Pending', CURDATE(), order_date);", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = IF ( amount > ?, ?, ? ), order_date = IF ( status = ?, CURDATE ( ), order_date )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/conditional-update-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = CASE WHEN amount > 100 THEN 'High Value' ELSE 'Regular' END;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = CASE WHEN amount > ? THEN ? ELSE ? END", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Completed' WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /testdata/mysql/update/update-case-aggregate-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders o SET o.status = CASE WHEN avg_amount > 500 THEN 'High' ELSE 'Low' END FROM (SELECT customer_id, AVG(amount) as avg_amount FROM orders GROUP BY customer_id) a WHERE o.customer_id = a.customer_id;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders o SET o.status = CASE WHEN avg_amount > ? THEN ? ELSE ? END FROM ( SELECT customer_id, AVG ( amount ) FROM orders GROUP BY customer_id ) a WHERE o.customer_id = a.customer_id", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-date-time-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET order_date = CURDATE(), order_time = CURTIME() WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET order_date = CURDATE ( ), order_time = CURTIME ( ) WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-encryption-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET encrypted_note = AES_ENCRYPT('Confidential', 'key') WHERE id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET encrypted_note = AES_ENCRYPT ( ? ) WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-enum-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET order_type = 'Standard' WHERE order_type = 'Express';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET order_type = ? WHERE order_type = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-json-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET details = JSON_SET(details, '$.shippingMethod', 'Express') WHERE id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET details = JSON_SET ( details, ?, ? ) WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-json-modify.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET details = JSON_SET(details, '$.status', 'Updated') WHERE JSON_EXTRACT(details, '$.priority') = 'High';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET details = JSON_SET ( details, ?, ? ) WHERE JSON_EXTRACT ( details, ? ) = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-lock-tables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "LOCK TABLES orders WRITE; UPDATE orders SET status = 'Cancelled' WHERE status = 'Pending'; UNLOCK TABLES;", 3 | "outputs": [ 4 | { 5 | "expected": "LOCK TABLES orders WRITE; UPDATE orders SET status = ? WHERE status = ?; UNLOCK TABLES", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-math-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET amount = amount * 1.1 WHERE status = 'Completed';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET amount = amount * ? WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-optimizing-conditions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Archived' WHERE status = 'Completed' AND order_date < DATE_SUB(NOW(), INTERVAL 1 YEAR);", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE status = ? AND order_date < DATE_SUB ( NOW ( ), INTERVAL ? YEAR )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-order-by-limit.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Cancelled' WHERE status = 'Pending' ORDER BY order_date ASC LIMIT 10;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE status = ? ORDER BY order_date ASC LIMIT ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-regular-expressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Query' WHERE status REGEXP '^Q.*';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE status REGEXP ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-spatial-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET location = ST_GeomFromText('POINT(1 1)') WHERE id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET location = ST_GeomFromText ( ? ) WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-string-functions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = CONCAT(status, ' - Updated') WHERE id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = CONCAT ( status, ? ) WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-user-defined-variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SET @new_status = 'Delayed'; UPDATE orders SET status = @new_status WHERE status = 'Pending';", 3 | "outputs": [ 4 | { 5 | "expected": "SET @new_status = ?; UPDATE orders SET status = @new_status WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-using-variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SET @new_status = 'Shipped'; UPDATE orders SET status = @new_status WHERE status = 'Processing';", 3 | "outputs": [ 4 | { 5 | "expected": "SET @new_status = ?; UPDATE orders SET status = @new_status WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-with-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders o JOIN customers c ON o.customer_id = c.id SET o.status = 'Processing' WHERE c.region = 'East';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders o JOIN customers c ON o.customer_id = c.id SET o.status = ? WHERE c.region = ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["orders", "customers"], 9 | "commands": ["UPDATE", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/mysql/update/update-with-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET status = 'Archived' WHERE id IN (SELECT id FROM orders WHERE order_date < '2020-01-01');", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET status = ? WHERE id IN ( SELECT id FROM orders WHERE order_date < ? )", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/complex/plsql-blocks.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DECLARE x NUMBER; BEGIN SELECT COUNT(*) INTO x FROM employees; DBMS_OUTPUT.PUT_LINE('Count: ' || x); END;", 3 | "outputs": [ 4 | { 5 | "expected": "DECLARE x NUMBER; BEGIN SELECT COUNT ( * ) INTO x FROM employees; DBMS_OUTPUT.PUT_LINE ( ? || x ); END", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": ["x", "employees"], 9 | "commands": ["BEGIN", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/conditional-delete-with-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM user_notifications WHERE id IN (SELECT id FROM notifications WHERE recipient_id = 123 AND status = CASE WHEN urgency = 'High' THEN 'Unread' ELSE 'Read' END);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM user_notifications WHERE id IN ( SELECT id FROM notifications WHERE recipient_id = ? AND status = CASE WHEN urgency = ? THEN ? ELSE ? END )", 6 | "statement_metadata": { 7 | "size": 43, 8 | "tables": ["user_notifications", "notifications"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM customers WHERE last_purchase_date < ADD_MONTHS(SYSDATE, -12);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM customers WHERE last_purchase_date < ADD_MONTHS ( SYSDATE, ? )", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["customers"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-cascade.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE customer_id = 456 CASCADE;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE customer_id = ? CASCADE", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-using-rowid.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM employees WHERE rowid = (SELECT max(rowid) FROM employees WHERE department_id = 20);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM employees WHERE rowid = ( SELECT max ( rowid ) FROM employees WHERE department_id = ? )", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": ["employees"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-where-current-of.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM employees WHERE CURRENT OF emp_cursor;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM employees WHERE CURRENT OF emp_cursor", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-with-complex-subqueries.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM products WHERE id IN (SELECT p.id FROM products p JOIN inventory i ON p.id = i.product_id WHERE i.quantity = 0);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM products WHERE id IN ( SELECT p.id FROM products p JOIN inventory i ON p.id = i.product_id WHERE i.quantity = ? )", 6 | "statement_metadata": { 7 | "size": 33, 8 | "tables": ["products", "inventory"], 9 | "commands": ["DELETE", "SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-with-flashback-query.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders AS OF TIMESTAMP TO_TIMESTAMP('2023-03-15 08:30:00', 'YYYY-MM-DD HH24:MI:SS') WHERE order_date < '2023-01-01';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders AS OF TIMESTAMP TO_TIMESTAMP ( ? ) WHERE order_date < ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-with-join-syntax.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders o WHERE EXISTS (SELECT 1 FROM customers c WHERE o.customer_id = c.id AND c.status = 'Inactive');", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders o WHERE EXISTS ( SELECT ? FROM customers c WHERE o.customer_id = c.id AND c.status = ? )", 6 | "statement_metadata": { 7 | "size": 27, 8 | "tables": ["orders", "customers"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-with-pseudocolumns.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM session_logs WHERE ROWNUM <= 10;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM session_logs WHERE ROWNUM <= ?", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["session_logs"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-with-returning-clause.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM logs WHERE entry_date < SYSDATE RETURNING id INTO :deleted_ids;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM logs WHERE entry_date < SYSDATE RETURNING id INTO :deleted_ids", 6 | "statement_metadata": { 7 | "size": 10, 8 | "tables": ["logs"], 9 | "commands": ["DELETE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/delete/delete-with-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM logs WHERE entry_date < (SELECT MIN(order_date) FROM orders);", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM logs WHERE entry_date < ( SELECT MIN ( order_date ) FROM orders )", 6 | "statement_metadata": { 7 | "size": 22, 8 | "tables": ["logs", "orders"], 9 | "commands": ["DELETE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "DELETE FROM logs WHERE entry_date < (SELECT MIN(order_date) FROM orders);", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-all-into-multiple-tables.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT ALL INTO sales (product_id, amount) VALUES (product_id, amount) INTO audit_log (action_type, message) VALUES ('INSERT', 'Inserted into sales') SELECT product_id, amount FROM temp_sales WHERE amount > 1000;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT ALL INTO sales ( product_id, amount ) VALUES ( product_id, amount ) INTO audit_log ( action_type, message ) VALUES ( ? ) SELECT product_id, amount FROM temp_sales WHERE amount > ?", 6 | "statement_metadata": { 7 | "size": 36, 8 | "tables": ["sales", "audit_log", "temp_sales"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO customers (id, name, address) VALUES (101, 'John Doe', '123 Oracle Ln');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO customers ( id, name, address ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["customers"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-using-decode.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO user_log (user_id, action, log_date) SELECT user_id, DECODE(activity_type, 'LOGIN', 'Logged In', 'LOGOUT', 'Logged Out', 'Unknown'), SYSDATE FROM user_activity;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO user_log ( user_id, action, log_date ) SELECT user_id, DECODE ( activity_type, ?, ?, ?, ?, ? ), SYSDATE FROM user_activity", 6 | "statement_metadata": { 7 | "size": 33, 8 | "tables": ["user_log", "user_activity"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-with-column-ordering.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO customer_addresses (address, city, customer_id) VALUES ('123 Main St', 'Anytown', 456);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO customer_addresses ( address, city, customer_id ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 24, 8 | "tables": ["customer_addresses"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-with-returning-clause.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO transactions (account_id, amount) VALUES (123, 500) RETURNING transaction_id INTO :new_id;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO transactions ( account_id, amount ) VALUES ( ? ) RETURNING transaction_id INTO :new_id", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["transactions"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-with-select-union.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO log (message) SELECT 'User logged in' FROM dual UNION ALL SELECT 'User performed an action' FROM dual;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO log ( message ) SELECT ? FROM dual UNION ALL SELECT ? FROM dual", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": ["log", "dual"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-with-sequence.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO products (id, name, price) VALUES (product_seq.NEXTVAL, 'New Product', 99.99);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO products ( id, name, price ) VALUES ( product_seq.NEXTVAL, ?, ? )", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": ["products"], 9 | "commands": ["INSERT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/insert/insert-with-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (id, user_id, amount) SELECT order_seq.NEXTVAL, user_id, 100 FROM users WHERE status = 'active';", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( id, user_id, amount ) SELECT order_seq.NEXTVAL, user_id, ? FROM users WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 23, 8 | "tables": ["orders", "users"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "INSERT INTO orders (id, user_id, amount) SELECT order_seq.NEXTVAL, user_id, ? FROM users WHERE status = ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/insert/multitable-insert-conditional.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT FIRST INTO sales_audit (action) VALUES ('Sale occurred') WHEN amount > 1000 THEN INTO high_value_sales (sale_id, amount) VALUES (sale_id, amount) SELECT sale_id, amount FROM sales;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT FIRST INTO sales_audit ( action ) VALUES ( ? ) WHEN amount > ? THEN INTO high_value_sales ( sale_id, amount ) VALUES ( sale_id, amount ) SELECT sale_id, amount FROM sales", 6 | "statement_metadata": { 7 | "size": 44, 8 | "tables": ["sales_audit", "high_value_sales", "sales"], 9 | "commands": ["INSERT", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/procedure/invoke-stored-procedure-with-exec.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "EXEC UpdateOrderStatus(123, 'Shipped');", 3 | "outputs": [ 4 | { 5 | "expected": "EXEC UpdateOrderStatus(?);", 6 | "statement_metadata": { 7 | "size": 4, 8 | "tables": [], 9 | "commands": ["EXEC"], 10 | "comments": [], 11 | "procedures": [] 12 | }, 13 | "obfuscator_config": { 14 | "replace_digits": true 15 | }, 16 | "normalizer_config": { 17 | "collect_tables": true, 18 | "collect_commands": true, 19 | "collect_comments": true, 20 | "collect_procedure": true, 21 | "keep_trailing_semicolon": true, 22 | "remove_space_between_parentheses": true 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /testdata/oracle/procedure/invoke-stored-procedure.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "BEGIN UpdateOrderStatus(123, 'Shipped'); END;", 3 | "outputs": [ 4 | { 5 | "expected": "BEGIN UpdateOrderStatus(?); END;", 6 | "statement_metadata": { 7 | "size": 5, 8 | "tables": [], 9 | "commands": ["BEGIN"], 10 | "comments": [], 11 | "procedures": [] 12 | }, 13 | "obfuscator_config": { 14 | "replace_digits": true 15 | }, 16 | "normalizer_config": { 17 | "collect_tables": true, 18 | "collect_commands": true, 19 | "collect_comments": true, 20 | "collect_procedure": true, 21 | "keep_trailing_semicolon": true, 22 | "remove_space_between_parentheses": true 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /testdata/oracle/select/complex-join-operations.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT e.employee_id, e.last_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE e.test_amt > (SELECT AVG(test_amt) FROM employees WHERE department_id = e.department_id);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT e.employee_id, e.last_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE e.test_amt > ( SELECT AVG ( test_amt ) FROM employees WHERE department_id = e.department_id )", 6 | "statement_metadata": { 7 | "size": 30, 8 | "tables": ["employees", "departments"], 9 | "commands": ["SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/select/full-hint.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT /*+ FULL(e) */ employee_id, first_name, last_name FROM employees e WHERE department_id = 10;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT employee_id, first_name, last_name FROM employees e WHERE department_id = ?;", 6 | "statement_metadata": { 7 | "size": 29, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": ["/*+ FULL(e) */"], 11 | "procedures": [] 12 | }, 13 | "normalizer_config": { 14 | "collect_tables": true, 15 | "collect_commands": true, 16 | "collect_comments": true, 17 | "collect_procedure": true, 18 | "keep_trailing_semicolon": true, 19 | "remove_space_between_parentheses": true 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /testdata/oracle/select/hierarchical-queries.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT employee_id, last_name, manager_id FROM employees START WITH manager_id IS NULL CONNECT BY PRIOR employee_id = manager_id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT employee_id, last_name, manager_id FROM employees START WITH manager_id IS ? CONNECT BY PRIOR employee_id = manager_id", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/select/index-hint.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT /*+ INDEX(e employee_index) */ employee_id, first_name, last_name FROM employees e WHERE department_id = 10;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT employee_id, first_name, last_name FROM employees e WHERE department_id = ?;", 6 | "statement_metadata": { 7 | "size": 45, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": ["/*+ INDEX(e employee_index) */"], 11 | "procedures": [] 12 | }, 13 | "normalizer_config": { 14 | "collect_tables": true, 15 | "collect_commands": true, 16 | "collect_comments": true, 17 | "collect_procedure": true, 18 | "keep_trailing_semicolon": true, 19 | "remove_space_between_parentheses": true 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /testdata/oracle/select/large-objects-lobs.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, DBMS_LOB.SUBSTR(blob_data, 2000, 1) as blob_content, DBMS_LOB.SUBSTR(clob_data, 2000, 1) as clob_content FROM lob_test WHERE id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, DBMS_LOB.SUBSTR ( blob_data, ?, ? ), DBMS_LOB.SUBSTR ( clob_data, ?, ? ) FROM lob_test WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": ["lob_test"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/select/optimizer-mode-hint.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT /*+ ALL_ROWS */ order_id, description FROM orders WHERE price > 100;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT order_id, description FROM orders WHERE price > ?;", 6 | "statement_metadata": { 7 | "size": 27, 8 | "tables": ["orders"], 9 | "commands": ["SELECT"], 10 | "comments": ["/*+ ALL_ROWS */"], 11 | "procedures": [] 12 | }, 13 | "normalizer_config": { 14 | "collect_tables": true, 15 | "collect_commands": true, 16 | "collect_comments": true, 17 | "collect_procedure": true, 18 | "keep_trailing_semicolon": true, 19 | "remove_space_between_parentheses": true 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /testdata/oracle/select/oracle-text.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, title FROM articles WHERE CONTAINS(text, 'Oracle', 1) > 0;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, title FROM articles WHERE CONTAINS ( text, ?, ? ) > ?", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": ["articles"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/select/quoted-identifiers-case-sensitive.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT \"OrderId\", \"OrderDate\", \"CustomerName\" FROM \"Sales\".\"Orders\" WHERE \"OrderStatus\" = 'Shipped';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT OrderId, OrderDate, CustomerName FROM Sales.Orders WHERE OrderStatus = ?", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["Sales.Orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "normalizer_config": { 16 | "keep_identifier_quotation": true, 17 | "Keep_trailing_semicolon": true 18 | }, 19 | "expected": "SELECT \"OrderId\", \"OrderDate\", \"CustomerName\" FROM \"Sales\".\"Orders\" WHERE \"OrderStatus\" = ?;" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /testdata/oracle/select/quoted-identifiers-special-characters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM \"Sales\".\"Order-Details\" WHERE \"Product#Name\" LIKE '%Gadget%';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM Sales.Order-Details WHERE Product#Name LIKE ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["Sales.Order-Details"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "normalizer_config": { 16 | "keep_identifier_quotation": true, 17 | "Keep_trailing_semicolon": true 18 | }, 19 | "expected": "SELECT * FROM \"Sales\".\"Order-Details\" WHERE \"Product#Name\" LIKE ?;" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /testdata/oracle/select/recursive-cte.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "WITH RECURSIVE subordinates AS (SELECT employee_id, manager_id FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.employee_id, e.manager_id FROM employees e JOIN subordinates s ON e.manager_id = s.employee_id) SELECT * FROM subordinates;", 3 | "outputs": [ 4 | { 5 | "expected": "WITH RECURSIVE subordinates AS ( SELECT employee_id, manager_id FROM employees WHERE manager_id IS ? UNION ALL SELECT e.employee_id, e.manager_id FROM employees e JOIN subordinates s ON e.manager_id = s.employee_id ) SELECT * FROM subordinates", 6 | "statement_metadata": { 7 | "size": 31, 8 | "tables": ["employees", "subordinates"], 9 | "commands": [ "SELECT", "JOIN"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-basic-conditions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, name FROM users WHERE age > 30 AND status = 'active';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, name FROM users WHERE age > ? AND status = ?", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": ["users"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT id, name FROM users WHERE age > ? AND status = ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-using-oracle-text.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, title FROM articles WHERE CONTAINS(text, 'Oracle', 1) > 0;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, title FROM articles WHERE CONTAINS ( text, ?, ? ) > ?", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": ["articles"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT id, title FROM articles WHERE CONTAINS(text, ?, ?) > ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-flashback-query.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM employees AS OF TIMESTAMP TO_TIMESTAMP('2023-03-15 08:30:00', 'YYYY-MM-DD HH24:MI:SS') WHERE department_id = 10;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM employees AS OF TIMESTAMP TO_TIMESTAMP ( ? ) WHERE department_id = ?", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT * FROM employees AS OF TIMESTAMP TO_TIMESTAMP(?) WHERE department_id = ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-multi-line-comments.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT /* Multi-line\n comment */ id, name FROM users WHERE status = 'active';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, name FROM users WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 36, 8 | "tables": ["users"], 9 | "commands": ["SELECT"], 10 | "comments": ["/* Multi-line\n comment */"], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT id, name FROM users WHERE status = ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-partition-by.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT department_id, last_name, test_amt, AVG(test_amt) OVER (PARTITION BY department_id) AS avg_dept_test_amt FROM employees;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT department_id, last_name, test_amt, AVG ( test_amt ) OVER ( PARTITION BY department_id ) FROM employees", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT department_id, last_name, test_amt, AVG(test_amt) OVER (PARTITION BY department_id) FROM employees;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-pseudocolumns.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT LEVEL, ROWNUM, employee_id, last_name FROM employees WHERE ROWNUM <= 10 CONNECT BY PRIOR employee_id = manager_id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT LEVEL, ROWNUM, employee_id, last_name FROM employees WHERE ROWNUM <= ? CONNECT BY PRIOR employee_id = manager_id", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT LEVEL, ROWNUM, employee_id, last_name FROM employees WHERE ROWNUM <= ? CONNECT BY PRIOR employee_id = manager_id;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-rollup-function.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT department_id, job_id, SUM(test_amt) total_test_amt FROM employees GROUP BY ROLLUP (department_id, job_id);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT department_id, job_id, SUM ( test_amt ) total_test_amt FROM employees GROUP BY ROLLUP ( department_id, job_id )", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT department_id, job_id, SUM(test_amt) total_test_amt FROM employees GROUP BY ROLLUP (department_id, job_id);", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-sample-clause.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM employees SAMPLE (10);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM employees SAMPLE ( ? )", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT * FROM employees SAMPLE (?);", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-single-line-comments.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT id, name FROM users WHERE status = 'active'; -- Single-line comment explaining the query", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT id, name FROM users WHERE status = ?", 6 | "statement_metadata": { 7 | "size": 54, 8 | "tables": ["users"], 9 | "commands": ["SELECT"], 10 | "comments": ["-- Single-line comment explaining the query"], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT id, name FROM users WHERE status = ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/select/select-with-skip-locked.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM orders WHERE order_status = 'PENDING' FOR UPDATE SKIP LOCKED;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM orders WHERE order_status = ? FOR UPDATE SKIP LOCKED", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["orders"], 9 | "commands": ["SELECT", "UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "SELECT * FROM orders WHERE order_status = ? FOR UPDATE SKIP LOCKED;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/select/window-functions-analytics.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT employee_id, test_amt, AVG(yoe) OVER (PARTITION BY department_id) AS avg_department_yoe FROM employees;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT employee_id, test_amt, AVG ( yoe ) OVER ( PARTITION BY department_id ) FROM employees", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/update/conditional-update-with-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE employees SET test_amt = CASE WHEN job_id = 'XX' THEN test_amt * 1.10 WHEN job_id = 'YY' THEN test_amt * 1.20 ELSE test_amt END;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE employees SET test_amt = CASE WHEN job_id = ? THEN test_amt * ? WHEN job_id = ? THEN test_amt * ? ELSE test_amt END", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "UPDATE employees SET test_amt = CASE WHEN job_id = ? THEN test_amt * ? WHEN job_id = ? THEN test_amt * ? ELSE test_amt END;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/update/conditional-update-with-decode.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE order_items SET discount = DECODE(quantity, 10, 5, 20, 10, 0) WHERE order_id = 456;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE order_items SET discount = DECODE ( quantity, ?, ?, ?, ?, ? ) WHERE order_id = ?", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": ["order_items"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "UPDATE order_items SET discount = DECODE(quantity, ?, ?, ?, ?, ?) WHERE order_id = ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/oracle/update/dynamic-plsql.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "BEGIN EXECUTE IMMEDIATE 'UPDATE logs SET retention = retention * 1.1'; END;", 3 | "outputs": [ 4 | { 5 | "expected": "BEGIN EXECUTE IMMEDIATE ?; END", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [], 9 | "commands": ["BEGIN", "EXECUTE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /testdata/oracle/update/update-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE employees SET test_amt = test_amt * 1.05 WHERE department_id = 3;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE employees SET test_amt = test_amt * ? WHERE department_id = ?", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": ["employees"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "UPDATE employees SET test_amt = test_amt * ? WHERE department_id = ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/update/update-with-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE products p SET p.price = p.price * 1.1 FROM suppliers s WHERE p.supplier_id = s.id AND s.rating > 4;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE products p SET p.price = p.price * ? FROM suppliers s WHERE p.supplier_id = s.id AND s.rating > ?", 6 | "statement_metadata": { 7 | "size": 23, 8 | "tables": ["products", "suppliers"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "UPDATE products p SET p.price = p.price * ? FROM suppliers s WHERE p.supplier_id = s.id AND s.rating > ?;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/update/update-with-returning-clause.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET order_status = 'Completed' WHERE order_id = 123 RETURNING customer_id, order_total INTO :cust_id, :total;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET order_status = ? WHERE order_id = ? RETURNING customer_id, order_total INTO :cust_id, :total", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": ["orders"], 9 | "commands": ["UPDATE"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "UPDATE orders SET order_status = ? WHERE order_id = ? RETURNING customer_id, order_total INTO :cust_id, :total;", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /testdata/oracle/update/update-with-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE products SET price = price * 0.9 WHERE id IN (SELECT product_id FROM inventory WHERE quantity > 100);", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE products SET price = price * ? WHERE id IN ( SELECT product_id FROM inventory WHERE quantity > ? )", 6 | "statement_metadata": { 7 | "size": 29, 8 | "tables": ["products", "inventory"], 9 | "commands": ["UPDATE", "SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "expected": "UPDATE products SET price = price * ? WHERE id IN (SELECT product_id FROM inventory WHERE quantity > ?);", 16 | "normalizer_config": { 17 | "keep_trailing_semicolon": true, 18 | "remove_space_between_parentheses": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /testdata/postgresql/complex/delete-complex-subqueries-joins.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM \n users u\nUSING \n orders o,\n order_items oi,\n products p\nWHERE \n u.id = o.user_id\nAND o.id = oi.order_id\nAND oi.product_id = p.id\nAND p.category = 'obsolete'\nAND o.order_date < NOW() - INTERVAL '5 years';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM users u USING orders o, order_items oi, products p WHERE u.id = o.user_id AND o.id = oi.order_id AND oi.product_id = p.id AND p.category = ? AND o.order_date < NOW ( ) - INTERVAL ?", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "DELETE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/delete/delete-all-rows.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM temp_table;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM temp_table", 6 | "statement_metadata": { 7 | "size": 16, 8 | "tables": [ 9 | "temp_table" 10 | ], 11 | "commands": [ 12 | "DELETE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/delete/delete-returning.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM orders WHERE id = 8 RETURNING *;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM orders WHERE id = ? RETURNING *", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "orders" 10 | ], 11 | "commands": [ 12 | "DELETE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/delete/delete-simple.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM users WHERE id = 7;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM users WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "DELETE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/delete/delete-using-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM user_logins USING users WHERE user_logins.user_id = users.id AND users.status = 'inactive';", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM user_logins USING users WHERE user_logins.user_id = users.id AND users.status = ?", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "user_logins" 10 | ], 11 | "commands": [ 12 | "DELETE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/delete/delete-with-cte.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "WITH deleted AS (\n DELETE FROM users WHERE last_login < NOW() - INTERVAL '2 years' RETURNING *\n)\nSELECT * FROM deleted;", 3 | "outputs": [ 4 | { 5 | "expected": "WITH deleted AS ( DELETE FROM users WHERE last_login < NOW ( ) - INTERVAL ? RETURNING * ) SELECT * FROM deleted", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "DELETE", 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/delete/delete-with-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM comments WHERE user_id IN (SELECT id FROM users WHERE status = 'banned');", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM comments WHERE user_id IN ( SELECT id FROM users WHERE status = ? )", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": [ 9 | "comments", 10 | "users" 11 | ], 12 | "commands": [ 13 | "DELETE", 14 | "SELECT" 15 | ], 16 | "comments": [], 17 | "procedures": [] 18 | } 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/create-function-that-raises-notice.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE OR REPLACE FUNCTION log_activity(activity text) RETURNS void AS $func$\nBEGIN\n RAISE NOTICE 'Activity: %', activity;\nEND;\n$func$ LANGUAGE plpgsql;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE OR REPLACE FUNCTION log_activity ( activity text ) RETURNS void AS $func$BEGIN RAISE NOTICE ?, activity; END$func$ LANGUAGE plpgsql" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "dollar_quoted_func": false 10 | }, 11 | "expected": "CREATE OR REPLACE FUNCTION log_activity ( activity text ) RETURNS void AS ? LANGUAGE plpgsql" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/create-function-with-dynamic-query.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE OR REPLACE FUNCTION dynamic_query(sql_query text) RETURNS SETOF RECORD AS $func$\nBEGIN\n RETURN QUERY EXECUTE sql_query;\nEND;\n$func$ LANGUAGE plpgsql;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE OR REPLACE FUNCTION dynamic_query ( sql_query text ) RETURNS SETOF RECORD AS $func$BEGIN RETURN QUERY EXECUTE sql_query; END$func$ LANGUAGE plpgsql" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "dollar_quoted_func": false 10 | }, 11 | "expected": "CREATE OR REPLACE FUNCTION dynamic_query ( sql_query text ) RETURNS SETOF RECORD AS ? LANGUAGE plpgsql" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/create-function-with-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE OR REPLACE FUNCTION get_user_email(user_id integer) RETURNS text AS $func$\nBEGIN\n RETURN (SELECT email FROM users WHERE id = user_id);\nEND;\n$func$ LANGUAGE plpgsql;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE OR REPLACE FUNCTION get_user_email ( user_id integer ) RETURNS text AS $func$BEGIN RETURN ( SELECT email FROM users WHERE id = user_id ); END$func$ LANGUAGE plpgsql" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "dollar_quoted_func": false 10 | }, 11 | "expected": "CREATE OR REPLACE FUNCTION get_user_email ( user_id integer ) RETURNS text AS ? LANGUAGE plpgsql" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/create-function-with-table-return.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE OR REPLACE FUNCTION get_users() RETURNS TABLE(user_id integer, user_name text) AS $func$\nBEGIN\n RETURN QUERY SELECT id, name FROM users;\nEND;\n$func$ LANGUAGE plpgsql;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE OR REPLACE FUNCTION get_users ( ) RETURNS TABLE ( user_id integer, user_name text ) AS $func$BEGIN RETURN QUERY SELECT id, name FROM users; END$func$ LANGUAGE plpgsql" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "dollar_quoted_func": false 10 | }, 11 | "expected": "CREATE OR REPLACE FUNCTION get_users ( ) RETURNS TABLE ( user_id integer, user_name text ) AS ? LANGUAGE plpgsql" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/create-simple-plpgsql-function.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE OR REPLACE FUNCTION get_user_count() RETURNS integer AS $func$\nBEGIN\n RETURN (SELECT COUNT(*) FROM users);\nEND;\n$func$ LANGUAGE plpgsql;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE OR REPLACE FUNCTION get_user_count ( ) RETURNS integer AS $func$BEGIN RETURN ( SELECT COUNT ( * ) FROM users ); END$func$ LANGUAGE plpgsql" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "dollar_quoted_func": false 10 | }, 11 | "expected": "CREATE OR REPLACE FUNCTION get_user_count ( ) RETURNS integer AS ? LANGUAGE plpgsql" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/invoke-function-positional-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT calculate_discount($1, $2);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT calculate_discount ( ? )" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false 10 | }, 11 | "normalizer_config": { 12 | "remove_space_between_parentheses": true 13 | }, 14 | "expected": "SELECT calculate_discount($1, $2)" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/invoke-function-returning-table.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM get_users();", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM get_users ( )" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/invoke-function-that-raises-notice.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT log_activity('User logged in');", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT log_activity ( ? )" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/invoke-function-with-dynamic-query.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM dynamic_query('SELECT * FROM users WHERE id = 1') AS t(id integer, name text, email text);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM dynamic_query ( ? ) AS t ( id integer, name text, email text )" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/invoke-function-with-parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT get_user_email(1);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT get_user_email ( ? )" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /testdata/postgresql/function/invoke-simple-function.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT get_user_count();", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT get_user_count ( )" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-array-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO users (name, favorite_numbers) VALUES ('Array User', ARRAY[3, 6, 9]);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO users ( name, favorite_numbers ) VALUES ( ?, ARRAY [ ? ] )", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "INSERT INTO users (name, favorite_numbers) VALUES (?, ARRAY [?])", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-json-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO events (data) VALUES ('{\"type\": \"user_signup\", \"user_id\": 1}');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO events ( data ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "events" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-multiple-rows.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO users (name, email) VALUES ('Jane Doe', 'jane@example.com'), ('Bob Smith', 'bob@example.com');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO users ( name, email ) VALUES ( ? ), ( ? )", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-positional-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO users (name, email, age) VALUES ($1, $2, $3);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO users ( name, email, age ) VALUES ( ? )" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false 10 | }, 11 | "expected": "INSERT INTO users ( name, email, age ) VALUES ( $1, $2, $3 )" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-returning-positional-parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO orders (product_id, quantity, total) VALUES ($1, $2, $3) RETURNING id;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO orders ( product_id, quantity, total ) VALUES ( ? ) RETURNING id" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false 10 | }, 11 | "expected": "INSERT INTO orders ( product_id, quantity, total ) VALUES ( $1, $2, $3 ) RETURNING id" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-simple-row.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO users ( name, email ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-conflict-do-nothing.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO users (id, name, email) VALUES (1, 'Duplicate', 'duplicate@example.com') ON CONFLICT (id) DO NOTHING;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO users ( id, name, email ) VALUES ( ? ) ON CONFLICT ( id ) DO NOTHING", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-conflict-update.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO users (id, name, email) VALUES (1, 'Duplicate', 'duplicate@example.com') ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO users ( id, name, email ) VALUES ( ? ) ON CONFLICT ( id ) DO UPDATE SET email = EXCLUDED.email", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "INSERT", 13 | "UPDATE" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-default.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO products (name, price, description) VALUES ('New Product', 123, DEFAULT);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO products ( name, price, description ) VALUES ( ?, DEFAULT )", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "products" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-enum-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO shipments (status) VALUES ('delivered'::shipment_status);", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO shipments ( status ) VALUES ( ? :: shipment_status )", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": [ 9 | "shipments" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-geometric-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO places (name, location) VALUES ('Point Place', point '(10, 20)');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO places ( name, location ) VALUES ( ?, point ? )", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "places" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-hstore-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO user_profiles (profile) VALUES ('\"height\"=>\"2m\", \"weight\"=>\"70kg\"');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO user_profiles ( profile ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": [ 9 | "user_profiles" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-range-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO reservations (during) VALUES ('[2023-01-01 14:00, 2023-01-01 15:00)');", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO reservations ( during ) VALUES ( ? )", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": [ 9 | "reservations" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-returning.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO users (name, email) VALUES ('Alice Jones', 'alice@example.com') RETURNING id;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO users ( name, email ) VALUES ( ? ) RETURNING id", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "INSERT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO user_logins (user_id, login_time) SELECT id, NOW() FROM users WHERE active;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO user_logins ( user_id, login_time ) SELECT id, NOW ( ) FROM users WHERE active", 6 | "statement_metadata": { 7 | "size": 28, 8 | "tables": [ 9 | "user_logins", 10 | "users" 11 | ], 12 | "commands": [ 13 | "INSERT", 14 | "SELECT" 15 | ], 16 | "comments": [], 17 | "procedures": [] 18 | } 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/insert/insert-with-subquery-and-alias.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "INSERT INTO user_logins (user_id, login_time) SELECT u.id, NOW() FROM users u WHERE u.active;", 3 | "outputs": [ 4 | { 5 | "expected": "INSERT INTO user_logins ( user_id, login_time ) SELECT u.id, NOW ( ) FROM users u WHERE u.active", 6 | "statement_metadata": { 7 | "size": 28, 8 | "tables": [ 9 | "user_logins", 10 | "users" 11 | ], 12 | "commands": [ 13 | "INSERT", 14 | "SELECT" 15 | ], 16 | "comments": [], 17 | "procedures": [] 18 | } 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/aggregate-functions-count.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT COUNT(*) AS total_users FROM users;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT COUNT ( * ) FROM users", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT COUNT(*) FROM users", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/basic_select_with_alias.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT u.id AS user_id, u.name AS username FROM users u;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT u.id, u.name FROM users u", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "normalizer_config": { 20 | "keep_sql_alias": true 21 | }, 22 | "expected": "SELECT u.id AS user_id, u.name AS username FROM users u" 23 | }, 24 | { 25 | "normalizer_config": { 26 | "keep_trailing_semicolon": true 27 | }, 28 | "expected": "SELECT u.id, u.name FROM users u;" 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/case-statements.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT name, CASE WHEN age < 18 THEN 'minor' ELSE 'adult' END FROM users;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT name, CASE WHEN age < ? THEN ? ELSE ? END FROM users", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/common-table-expressions-cte.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "WITH recursive_subordinates AS (\n SELECT id, manager_id FROM employees WHERE id = 1\n UNION ALL\n SELECT e.id, e.manager_id FROM employees e INNER JOIN recursive_subordinates rs ON rs.id = e.manager_id\n)\nSELECT * FROM recursive_subordinates;", 3 | "outputs": [ 4 | { 5 | "expected": "WITH recursive_subordinates AS ( SELECT id, manager_id FROM employees WHERE id = ? UNION ALL SELECT e.id, e.manager_id FROM employees e INNER JOIN recursive_subordinates rs ON rs.id = e.manager_id ) SELECT * FROM recursive_subordinates", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": [ 9 | "employees" 10 | ], 11 | "commands": [ 12 | "SELECT", 13 | "JOIN" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/cross-joins.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM users CROSS JOIN cities;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM users CROSS JOIN cities", 6 | "statement_metadata": { 7 | "size": 21, 8 | "tables": [ 9 | "users", 10 | "cities" 11 | ], 12 | "commands": [ 13 | "SELECT", 14 | "JOIN" 15 | ], 16 | "comments": [], 17 | "procedures": [] 18 | } 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/distinct-on-expressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT DISTINCT ON (location) location, time FROM events ORDER BY location, time DESC;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT DISTINCT ON ( location ) location, time FROM events ORDER BY location, time DESC", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "events" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/fetch-first-clause.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM users ORDER BY created_at DESC FETCH FIRST 10 ROWS ONLY;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM users ORDER BY created_at DESC FETCH FIRST ? ROWS ONLY", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/for-update-of.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM users WHERE last_login < NOW() - INTERVAL '1 year' FOR UPDATE OF users;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM users WHERE last_login < NOW ( ) - INTERVAL ? FOR UPDATE OF users", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT", 13 | "UPDATE" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/full-outer-joins.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM customers FULL OUTER JOIN orders ON customers.id = orders.customer_id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM customers FULL OUTER JOIN orders ON customers.id = orders.customer_id", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": [ 9 | "customers", 10 | "orders" 11 | ], 12 | "commands": [ 13 | "SELECT", 14 | "JOIN" 15 | ], 16 | "comments": [], 17 | "procedures": [] 18 | } 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/group-by-having.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT status, COUNT(*) FROM orders GROUP BY status HAVING COUNT(*) > 1;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT status, COUNT ( * ) FROM orders GROUP BY status HAVING COUNT ( * ) > ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "orders" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT status, COUNT(*) FROM orders GROUP BY status HAVING COUNT(*) > ?", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/json-field-access.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT data->'customer'->>'name' AS customer_name FROM orders;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT data -> ? ->> ? FROM orders", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "orders" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-array-elements-text.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT jsonb_array_elements_text(data->'tags') AS tag FROM products;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT jsonb_array_elements_text ( data -> ? ) FROM products", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "products" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT jsonb_array_elements_text(data -> 'tags') FROM products", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | }, 23 | "obfuscator_config": { 24 | "keep_json_path": true 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-array-length.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT jsonb_array_length(data->'tags') AS num_tags FROM products;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT jsonb_array_length ( data -> ? ) FROM products", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "products" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT jsonb_array_length(data -> 'tags') FROM products", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | }, 23 | "obfuscator_config": { 24 | "keep_json_path": true 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-contained-in-path.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM events WHERE payload <@ '{\"events\": {\"type\": \"user_event\"}}';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM events WHERE payload <@ ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "events" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected":"SELECT * FROM events WHERE payload <@ '{\"events\": {\"type\": \"user_event\"}}'", 20 | "obfuscator_config": { 21 | "keep_json_path": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-contains-key.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM events WHERE payload ? 'user_id';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM events WHERE payload ? ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "events" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-contains-object-at-top-level.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM events WHERE payload @> '{\"type\": \"user_event\"}';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM events WHERE payload @> ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "events" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected":"SELECT * FROM events WHERE payload @> '{\"type\": \"user_event\"}'", 20 | "obfuscator_config": { 21 | "keep_json_path": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-delete-array-element.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT data #- '{tags,0}' AS tags_without_first FROM products;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT data #- ? FROM products", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "products" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT data #- '{tags,0}' FROM products", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | }, 23 | "obfuscator_config": { 24 | "keep_json_path": true 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-delete-key.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT data - 'temporary_field' AS cleaned_data FROM user_profiles;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT data - ? FROM user_profiles", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": [ 9 | "user_profiles" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-delete-path.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT jsonb_set(data, '{info,address}', NULL) AS removed_address FROM users;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT jsonb_set ( data, ?, ? ) FROM users", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT jsonb_set(data, ?, NULL) FROM users", 20 | "obfuscator_config": { 21 | "replace_null": false 22 | }, 23 | "normalizer_config": { 24 | "remove_space_between_parentheses": true 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-extract-path-text.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT jsonb_extract_path_text(data, 'user', 'name') AS user_name FROM user_profiles;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT jsonb_extract_path_text ( data, ?, ? ) FROM user_profiles", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": [ 9 | "user_profiles" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT jsonb_extract_path_text(data, ?, ?) FROM user_profiles", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-extract-path.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT jsonb_extract_path(data, 'user', 'name') AS user_name FROM user_profiles;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT jsonb_extract_path ( data, ?, ? ) FROM user_profiles", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": [ 9 | "user_profiles" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT jsonb_extract_path(data, ?, ?) FROM user_profiles", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-pretty-print.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT jsonb_pretty(data) AS pretty_data FROM logs;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT jsonb_pretty ( data ) FROM logs", 6 | "statement_metadata": { 7 | "size": 10, 8 | "tables": [ 9 | "logs" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT jsonb_pretty(data) FROM logs", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/jsonb-set-new-value.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT jsonb_set(data, '{user,name}', '\"John Doe\"') AS updated_data FROM user_profiles;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT jsonb_set ( data, ?, ? ) FROM user_profiles", 6 | "statement_metadata": { 7 | "size": 19, 8 | "tables": [ 9 | "user_profiles" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT jsonb_set(data, ?, ?) FROM user_profiles", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/lateral-joins.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT u.name, json_agg(l) FROM users u, LATERAL (SELECT id, text FROM logs WHERE logs.user_id = u.id) AS l GROUP BY u.name;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT u.name, json_agg ( l ) FROM users u, LATERAL ( SELECT id, text FROM logs WHERE logs.user_id = u.id ) GROUP BY u.name", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": [ 9 | "users", 10 | "logs" 11 | ], 12 | "commands": [ 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | }, 19 | { 20 | "expected": "SELECT u.name, json_agg(l) FROM users u, LATERAL (SELECT id, text FROM logs WHERE logs.user_id = u.id) GROUP BY u.name", 21 | "normalizer_config": { 22 | "remove_space_between_parentheses": true 23 | } 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/limit-and-offset.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM users ORDER BY created_at DESC LIMIT 10 OFFSET 20;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/natural-joins.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM users NATURAL JOIN user_profiles;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM users NATURAL JOIN user_profiles", 6 | "statement_metadata": { 7 | "size": 28, 8 | "tables": [ 9 | "users", 10 | "user_profiles" 11 | ], 12 | "commands": [ 13 | "SELECT", 14 | "JOIN" 15 | ], 16 | "comments": [], 17 | "procedures": [] 18 | } 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/quoted-identifiers-case-sensitive.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT \"OrderId\", \"OrderDate\", \"CustomerName\" FROM \"Sales\".\"Orders\" WHERE \"OrderStatus\" = 'Shipped'", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT OrderId, OrderDate, CustomerName FROM Sales.Orders WHERE OrderStatus = ?", 6 | "statement_metadata": { 7 | "size": 18, 8 | "tables": ["Sales.Orders"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "normalizer_config": { 16 | "keep_identifier_quotation": true 17 | }, 18 | "expected": "SELECT \"OrderId\", \"OrderDate\", \"CustomerName\" FROM \"Sales\".\"Orders\" WHERE \"OrderStatus\" = ?" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/quoted-identifiers-special-characters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM \"Sales\".\"Order-Details\" WHERE \"Product#Name\" LIKE '%Gadget%'", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM Sales.Order-Details WHERE Product#Name LIKE ?", 6 | "statement_metadata": { 7 | "size": 25, 8 | "tables": ["Sales.Order-Details"], 9 | "commands": ["SELECT"], 10 | "comments": [], 11 | "procedures": [] 12 | } 13 | }, 14 | { 15 | "normalizer_config": { 16 | "keep_identifier_quotation": true 17 | }, 18 | "expected": "SELECT * FROM \"Sales\".\"Order-Details\" WHERE \"Product#Name\" LIKE ?" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/select-in-clause-positional-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM orders WHERE status IN ($1, $2, $3);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM orders WHERE status IN ( ? )" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false 10 | }, 11 | "expected": "SELECT * FROM orders WHERE status IN ( $1, $2, $3 )" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/select-multiple-conditions-positional-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM products WHERE category = $1 AND price < $2;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM products WHERE category = ? AND price < ?" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false 10 | }, 11 | "expected": "SELECT * FROM products WHERE category = $1 AND price < $2" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/select-only.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM ONLY users, ONLY orders WHERE users.id = orders.user_id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM ONLY users, ONLY orders WHERE users.id = orders.user_id", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "users", 10 | "orders" 11 | ], 12 | "commands": [ 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/select-with-positional-parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM users WHERE id = $1;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM users WHERE id = ?" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false 10 | }, 11 | "expected": "SELECT * FROM users WHERE id = $1" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/self-joins.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT a.name, b.name FROM employees a, employees b WHERE a.manager_id = b.id;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT a.name, b.name FROM employees a, employees b WHERE a.manager_id = b.id", 6 | "statement_metadata": { 7 | "size": 15, 8 | "tables": [ 9 | "employees" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/subquery-in-from.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT user_data.name FROM (SELECT name FROM users WHERE active = true) AS user_data;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT user_data.name FROM ( SELECT name FROM users WHERE active = ? )", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "SELECT user_data.name FROM ( SELECT name FROM users WHERE active = true )", 20 | "obfuscator_config": { 21 | "replace_boolean": false 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/subquery-in-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT name, (SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id) AS order_count FROM users;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT name, ( SELECT COUNT ( * ) FROM orders WHERE orders.user_id = users.id ) FROM users", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "orders", 10 | "users" 11 | ], 12 | "commands": [ 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/subquery-in-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT name FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 100);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT name FROM users WHERE id IN ( SELECT user_id FROM orders WHERE total > ? )", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "users", 10 | "orders" 11 | ], 12 | "commands": [ 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/select/tablesample-bernoulli.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM users TABLESAMPLE BERNOULLI (10);", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM users TABLESAMPLE BERNOULLI ( ? )", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-array-append.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE users SET favorite_numbers = array_append(favorite_numbers, 42) WHERE id = 5;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE users SET favorite_numbers = array_append ( favorite_numbers, ? ) WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "UPDATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-increment-numeric.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE accounts SET balance = balance + 100.0 WHERE user_id = 4;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE accounts SET balance = balance + ? WHERE user_id = ?", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "accounts" 10 | ], 11 | "commands": [ 12 | "UPDATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-json-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE events SET data = jsonb_set(data, '{location}', '\"New Location\"') WHERE data->>'event_id' = '123';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE events SET data = jsonb_set ( data, ?, ? ) WHERE data ->> ? = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "events" 10 | ], 11 | "commands": [ 12 | "UPDATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "UPDATE events SET data = jsonb_set(data, ?, ?) WHERE data ->> ? = ?", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-multiple-fields-positional-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "DELETE FROM sessions WHERE user_id = $1 AND expired = true;", 3 | "outputs": [ 4 | { 5 | "expected": "DELETE FROM sessions WHERE user_id = ? AND expired = ?" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false, 10 | "replace_boolean": false 11 | }, 12 | "expected": "DELETE FROM sessions WHERE user_id = $1 AND expired = true" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-positional-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE users SET email = $1 WHERE id = $2;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE users SET email = ? WHERE id = ?" 6 | }, 7 | { 8 | "obfuscator_config": { 9 | "replace_positional_parameter": false 10 | }, 11 | "expected": "UPDATE users SET email = $1 WHERE id = $2" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-returning.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE users SET last_login = NOW() WHERE id = 3 RETURNING last_login;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE users SET last_login = NOW ( ) WHERE id = ? RETURNING last_login", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "UPDATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | }, 18 | { 19 | "expected": "UPDATE users SET last_login = NOW() WHERE id = ? RETURNING last_login", 20 | "normalizer_config": { 21 | "remove_space_between_parentheses": true 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-set-multiple-columns.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE users SET name = 'Jane Updated', email = 'jane.updated@example.com' WHERE id = 2;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE users SET name = ?, email = ? WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "UPDATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-set-single-column.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE users SET name = 'John Updated' WHERE id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE users SET name = ? WHERE id = ?", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "UPDATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-using-join.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE orders SET total = total * 0.9 FROM users WHERE users.id = orders.user_id AND users.status = 'VIP';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE orders SET total = total * ? FROM users WHERE users.id = orders.user_id AND users.status = ?", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "orders", 10 | "users" 11 | ], 12 | "commands": [ 13 | "UPDATE" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-with-case.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE users SET status = CASE WHEN last_login < NOW() - INTERVAL '1 year' THEN 'inactive' ELSE status END;", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE users SET status = CASE WHEN last_login < NOW ( ) - INTERVAL ? THEN ? ELSE status END", 6 | "statement_metadata": { 7 | "size": 11, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "UPDATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-with-cte.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "WITH updated AS (\n UPDATE users SET name = 'CTE Updated' WHERE id = 6 RETURNING *\n)\nSELECT * FROM updated;", 3 | "outputs": [ 4 | { 5 | "expected": "WITH updated AS ( UPDATE users SET name = ? WHERE id = ? RETURNING * ) SELECT * FROM updated", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "users" 10 | ], 11 | "commands": [ 12 | "UPDATE", 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/postgresql/update/update-with-subquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "UPDATE products SET price = (SELECT MAX(price) FROM products) * 0.9 WHERE name = 'Old Product';", 3 | "outputs": [ 4 | { 5 | "expected": "UPDATE products SET price = ( SELECT MAX ( price ) FROM products ) * ? WHERE name = ?", 6 | "statement_metadata": { 7 | "size": 20, 8 | "tables": [ 9 | "products" 10 | ], 11 | "commands": [ 12 | "UPDATE", 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | }, 19 | { 20 | "expected": "UPDATE products SET price = (SELECT MAX(price) FROM products) * ? WHERE name = ?", 21 | "normalizer_config": { 22 | "remove_space_between_parentheses": true 23 | } 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/data-clone.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE TABLE new_table CLONE existing_table;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE TABLE new_table CLONE existing_table", 6 | "statement_metadata": { 7 | "size": 34, 8 | "tables": [ 9 | "new_table", 10 | "existing_table" 11 | ], 12 | "commands": [ 13 | "CREATE", 14 | "CLONE" 15 | ], 16 | "comments": [], 17 | "procedures": [] 18 | } 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/external-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE EXTERNAL TABLE ext_sales_data (sale_date DATE, product_id STRING, quantity_sold NUMBER) WITH LOCATION = @my_external_stage/sales_data/ FILE_FORMAT = (TYPE = 'CSV' FIELD_OPTIONALLY_ENCLOSED_BY = '\"');", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE EXTERNAL TABLE ext_sales_data ( sale_date DATE, product_id STRING, quantity_sold NUMBER ) WITH LOCATION = @my_external_stage/sales_data/ FILE_FORMAT = ( TYPE = ? FIELD_OPTIONALLY_ENCLOSED_BY = ? )", 6 | "statement_metadata": { 7 | "size": 20, 8 | "tables": [ 9 | "ext_sales_data" 10 | ], 11 | "commands": [ 12 | "CREATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/listagg.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT LISTAGG(product_name, ', ') WITHIN GROUP (ORDER BY product_name) AS product_list FROM products WHERE category_id = 1;", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT LISTAGG ( product_name, ? ) WITHIN GROUP ( ORDER BY product_name ) FROM products WHERE category_id = ?", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "products" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/materialized-view.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE MATERIALIZED VIEW mv_product_sales AS SELECT product_id, SUM(sales_amount) AS total_sales FROM sales GROUP BY product_id;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE MATERIALIZED VIEW mv_product_sales AS SELECT product_id, SUM ( sales_amount ) FROM sales GROUP BY product_id", 6 | "statement_metadata": { 7 | "size": 17, 8 | "tables": [ 9 | "sales" 10 | ], 11 | "commands": [ 12 | "CREATE", 13 | "SELECT" 14 | ], 15 | "comments": [], 16 | "procedures": [] 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/semi-structured-data-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT metadata:customerID::string AS customer_id FROM orders WHERE metadata:orderDate::date = '2023-01-01';", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT metadata : customerID :: string FROM orders WHERE metadata : orderDate :: date = ?", 6 | "statement_metadata": { 7 | "size": 12, 8 | "tables": [ 9 | "orders" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/stream.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE STREAM my_stream ON TABLE my_table;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE STREAM my_stream ON TABLE my_table", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "my_table" 10 | ], 11 | "commands": [ 12 | "CREATE" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/task.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "CREATE TASK /* my comment */ my_task WAREHOUSE = my_warehouse SCHEDULE = '15 MINUTE' AS INSERT INTO summary_table SELECT * FROM new_data_view;", 3 | "outputs": [ 4 | { 5 | "expected": "CREATE TASK my_task WAREHOUSE = my_warehouse SCHEDULE = ? AS INSERT INTO summary_table SELECT * FROM new_data_view", 6 | "statement_metadata": { 7 | "size": 60, 8 | "tables": [ 9 | "summary_table", 10 | "new_data_view" 11 | ], 12 | "commands": [ 13 | "CREATE", 14 | "INSERT", 15 | "SELECT" 16 | ], 17 | "comments": ["/* my comment */"], 18 | "procedures": [] 19 | } 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/time-travel.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "SELECT * FROM my_table AT (TIMESTAMP => '2023-03-15 14:30:00');", 3 | "outputs": [ 4 | { 5 | "expected": "SELECT * FROM my_table AT ( TIMESTAMP => ? )", 6 | "statement_metadata": { 7 | "size": 14, 8 | "tables": [ 9 | "my_table" 10 | ], 11 | "commands": [ 12 | "SELECT" 13 | ], 14 | "comments": [], 15 | "procedures": [] 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /testdata/snowflake/test-cases/warehouse-controls.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": "ALTER WAREHOUSE my_warehouse SET WAREHOUSE_SIZE = 'X-LARGE';", 3 | "outputs": [ 4 | { 5 | "expected": "ALTER WAREHOUSE my_warehouse SET WAREHOUSE_SIZE = ?", 6 | "statement_metadata": { 7 | "size": 5, 8 | "tables": [ 9 | ], 10 | "commands": [ 11 | "ALTER" 12 | ], 13 | "comments": [], 14 | "procedures": [] 15 | } 16 | } 17 | ] 18 | } --------------------------------------------------------------------------------