From 7f13bc212d458d516fc4db796f017c7c90b2e415 Mon Sep 17 00:00:00 2001 From: Zhengda Lu Date: Tue, 21 Nov 2023 21:50:34 -0500 Subject: [PATCH] create mysql test suite --- dbms_test.go | 1 + sqllexer_utils.go | 46 ++++++++++--------- .../super-complex-poorly-written-sql.json | 16 +++++++ .../super-complex-sql-multiple-joins.json | 16 +++++++ .../super-complex-sql-nested-subqueries.json | 15 ++++++ testdata/mysql/delete/delete-basic.json | 16 +++++++ testdata/mysql/delete/delete-cascade.json | 16 +++++++ .../delete/delete-cascading-triggers.json | 16 +++++++ .../delete/delete-conditional-logic.json | 16 +++++++ .../delete-foreign-key-constraints.json | 16 +++++++ .../mysql/delete/delete-free-disk-space.json | 16 +++++++ .../delete-join-multiple-conditions.json | 16 +++++++ testdata/mysql/delete/delete-lock-tables.json | 16 +++++++ .../mysql/delete/delete-multiple-tables.json | 16 +++++++ .../delete/delete-optimized-conditions.json | 16 +++++++ .../mysql/delete/delete-order-by-limit.json | 16 +++++++ .../mysql/delete/delete-range-conditions.json | 16 +++++++ .../delete/delete-regular-expressions.json | 16 +++++++ .../mysql/delete/delete-safe-update-mode.json | 16 +++++++ .../delete/delete-subquery-optimization.json | 16 +++++++ testdata/mysql/delete/delete-truncate.json | 16 +++++++ .../mysql/delete/delete-using-subquery.json | 16 +++++++ testdata/mysql/delete/delete-with-join.json | 16 +++++++ testdata/mysql/delete/delete-with-limit.json | 16 +++++++ .../delete/delete-with-user-variables.json | 16 +++++++ .../insert/batch-insert-multiple-rows.json | 16 +++++++ .../mysql/insert/insert-auto-increment.json | 16 +++++++ testdata/mysql/insert/insert-basic.json | 16 +++++++ testdata/mysql/insert/insert-blob-data.json | 16 +++++++ testdata/mysql/insert/insert-enum-data.json | 16 +++++++ testdata/mysql/insert/insert-ignore.json | 16 +++++++ testdata/mysql/insert/insert-json-data.json | 16 +++++++ .../mysql/insert/insert-on-duplicate-key.json | 16 +++++++ .../mysql/insert/insert-select-union.json | 16 +++++++ .../mysql/insert/insert-spatial-data.json | 16 +++++++ .../insert/insert-using-last-insert-id.json | 16 +++++++ .../mysql/insert/insert-using-subquery.json | 16 +++++++ .../insert/insert-with-conditional-logic.json | 16 +++++++ .../insert/insert-with-curdate-curtime.json | 16 +++++++ .../insert-with-encryption-functions.json | 16 +++++++ .../insert/insert-with-generated-columns.json | 15 ++++++ .../mysql/insert/insert-with-replace.json | 16 +++++++ .../mysql/insert/insert-with-set-syntax.json | 16 +++++++ .../insert/insert-with-spatial-data.json | 16 +++++++ .../mysql/insert/insert-with-timestamp.json | 16 +++++++ .../complex-procedure-error-handling.json | 16 +++++++ .../procedure/stored-procedure-basic.json | 15 ++++++ ...ored-procedure-conditional-logic-loop.json | 15 ++++++ .../procedure/stored-procedure-cursor.json | 16 +++++++ .../stored-procedure-dynamic-sql.json | 16 +++++++ .../stored-procedure-error-handling.json | 16 +++++++ ...red-procedure-input-output-parameters.json | 16 +++++++ .../stored-procedure-loop-control.json | 15 ++++++ .../stored-procedure-parameters.json | 15 ++++++ ...ored-procedure-transaction-management.json | 15 ++++++ testdata/mysql/select/bit-data-type.json | 16 +++++++ .../mysql/select/blob-text-data-types.json | 16 +++++++ testdata/mysql/select/decimal-data-type.json | 16 +++++++ .../mysql/select/enum-set-data-types.json | 16 +++++++ .../mysql/select/full-text-search-innodb.json | 16 +++++++ .../select/select-aggregate-functions.json | 16 +++++++ testdata/mysql/select/select-basic.json | 16 +++++++ .../mysql/select/select-case-statement.json | 16 +++++++ .../select/select-coalesce-function.json | 16 +++++++ .../mysql/select/select-conditional-case.json | 16 +++++++ .../mysql/select/select-date-functions.json | 16 +++++++ testdata/mysql/select/select-distinct.json | 16 +++++++ .../mysql/select/select-full-text-search.json | 16 +++++++ .../mysql/select/select-geospatial-data.json | 16 +++++++ .../mysql/select/select-group-concat.json | 16 +++++++ .../mysql/select/select-join-aliases.json | 16 +++++++ testdata/mysql/select/select-join.json | 16 +++++++ .../mysql/select/select-json-functions.json | 16 +++++++ .../mysql/select/select-limit-offset.json | 16 +++++++ .../select/select-lock-in-share-mode.json | 16 +++++++ .../mysql/select/select-natural-join.json | 16 +++++++ .../select/select-parameter-binding.json | 16 +++++++ testdata/mysql/select/select-regex.json | 16 +++++++ .../mysql/select/select-straight-join.json | 16 +++++++ .../mysql/select/select-string-functions.json | 16 +++++++ testdata/mysql/select/select-subquery.json | 16 +++++++ .../select/select-user-defined-variables.json | 16 +++++++ .../select/select-variable-assignment.json | 16 +++++++ .../mysql/select/select-window-functions.json | 16 +++++++ .../select/spatial-data-types-functions.json | 16 +++++++ .../select/spatial-geometry-data-types.json | 16 +++++++ .../mysql/select/system-versioned-tables.json | 16 +++++++ .../mysql/select/using-temporary-tables.json | 16 +++++++ .../select/virtual-generated-columns.json | 16 +++++++ .../bulk-update-multiple-conditions.json | 16 +++++++ .../mysql/update/conditional-update-case.json | 16 +++++++ testdata/mysql/update/update-basic.json | 15 ++++++ .../update-case-aggregate-functions.json | 16 +++++++ .../update/update-date-time-functions.json | 16 +++++++ .../update/update-encryption-functions.json | 16 +++++++ testdata/mysql/update/update-enum-data.json | 16 +++++++ .../mysql/update/update-json-functions.json | 16 +++++++ testdata/mysql/update/update-json-modify.json | 16 +++++++ testdata/mysql/update/update-lock-tables.json | 16 +++++++ .../mysql/update/update-math-functions.json | 16 +++++++ .../update/update-optimizing-conditions.json | 16 +++++++ .../mysql/update/update-order-by-limit.json | 16 +++++++ .../update/update-regular-expressions.json | 16 +++++++ .../mysql/update/update-spatial-data.json | 16 +++++++ .../mysql/update/update-string-functions.json | 16 +++++++ .../update/update-user-defined-variables.json | 16 +++++++ .../mysql/update/update-using-variables.json | 16 +++++++ testdata/mysql/update/update-with-join.json | 16 +++++++ .../mysql/update/update-with-subquery.json | 16 +++++++ 109 files changed, 1729 insertions(+), 22 deletions(-) create mode 100644 testdata/mysql/complex/super-complex-poorly-written-sql.json create mode 100644 testdata/mysql/complex/super-complex-sql-multiple-joins.json create mode 100644 testdata/mysql/complex/super-complex-sql-nested-subqueries.json create mode 100644 testdata/mysql/delete/delete-basic.json create mode 100644 testdata/mysql/delete/delete-cascade.json create mode 100644 testdata/mysql/delete/delete-cascading-triggers.json create mode 100644 testdata/mysql/delete/delete-conditional-logic.json create mode 100644 testdata/mysql/delete/delete-foreign-key-constraints.json create mode 100644 testdata/mysql/delete/delete-free-disk-space.json create mode 100644 testdata/mysql/delete/delete-join-multiple-conditions.json create mode 100644 testdata/mysql/delete/delete-lock-tables.json create mode 100644 testdata/mysql/delete/delete-multiple-tables.json create mode 100644 testdata/mysql/delete/delete-optimized-conditions.json create mode 100644 testdata/mysql/delete/delete-order-by-limit.json create mode 100644 testdata/mysql/delete/delete-range-conditions.json create mode 100644 testdata/mysql/delete/delete-regular-expressions.json create mode 100644 testdata/mysql/delete/delete-safe-update-mode.json create mode 100644 testdata/mysql/delete/delete-subquery-optimization.json create mode 100644 testdata/mysql/delete/delete-truncate.json create mode 100644 testdata/mysql/delete/delete-using-subquery.json create mode 100644 testdata/mysql/delete/delete-with-join.json create mode 100644 testdata/mysql/delete/delete-with-limit.json create mode 100644 testdata/mysql/delete/delete-with-user-variables.json create mode 100644 testdata/mysql/insert/batch-insert-multiple-rows.json create mode 100644 testdata/mysql/insert/insert-auto-increment.json create mode 100644 testdata/mysql/insert/insert-basic.json create mode 100644 testdata/mysql/insert/insert-blob-data.json create mode 100644 testdata/mysql/insert/insert-enum-data.json create mode 100644 testdata/mysql/insert/insert-ignore.json create mode 100644 testdata/mysql/insert/insert-json-data.json create mode 100644 testdata/mysql/insert/insert-on-duplicate-key.json create mode 100644 testdata/mysql/insert/insert-select-union.json create mode 100644 testdata/mysql/insert/insert-spatial-data.json create mode 100644 testdata/mysql/insert/insert-using-last-insert-id.json create mode 100644 testdata/mysql/insert/insert-using-subquery.json create mode 100644 testdata/mysql/insert/insert-with-conditional-logic.json create mode 100644 testdata/mysql/insert/insert-with-curdate-curtime.json create mode 100644 testdata/mysql/insert/insert-with-encryption-functions.json create mode 100644 testdata/mysql/insert/insert-with-generated-columns.json create mode 100644 testdata/mysql/insert/insert-with-replace.json create mode 100644 testdata/mysql/insert/insert-with-set-syntax.json create mode 100644 testdata/mysql/insert/insert-with-spatial-data.json create mode 100644 testdata/mysql/insert/insert-with-timestamp.json create mode 100644 testdata/mysql/procedure/complex-procedure-error-handling.json create mode 100644 testdata/mysql/procedure/stored-procedure-basic.json create mode 100644 testdata/mysql/procedure/stored-procedure-conditional-logic-loop.json create mode 100644 testdata/mysql/procedure/stored-procedure-cursor.json create mode 100644 testdata/mysql/procedure/stored-procedure-dynamic-sql.json create mode 100644 testdata/mysql/procedure/stored-procedure-error-handling.json create mode 100644 testdata/mysql/procedure/stored-procedure-input-output-parameters.json create mode 100644 testdata/mysql/procedure/stored-procedure-loop-control.json create mode 100644 testdata/mysql/procedure/stored-procedure-parameters.json create mode 100644 testdata/mysql/procedure/stored-procedure-transaction-management.json create mode 100644 testdata/mysql/select/bit-data-type.json create mode 100644 testdata/mysql/select/blob-text-data-types.json create mode 100644 testdata/mysql/select/decimal-data-type.json create mode 100644 testdata/mysql/select/enum-set-data-types.json create mode 100644 testdata/mysql/select/full-text-search-innodb.json create mode 100644 testdata/mysql/select/select-aggregate-functions.json create mode 100644 testdata/mysql/select/select-basic.json create mode 100644 testdata/mysql/select/select-case-statement.json create mode 100644 testdata/mysql/select/select-coalesce-function.json create mode 100644 testdata/mysql/select/select-conditional-case.json create mode 100644 testdata/mysql/select/select-date-functions.json create mode 100644 testdata/mysql/select/select-distinct.json create mode 100644 testdata/mysql/select/select-full-text-search.json create mode 100644 testdata/mysql/select/select-geospatial-data.json create mode 100644 testdata/mysql/select/select-group-concat.json create mode 100644 testdata/mysql/select/select-join-aliases.json create mode 100644 testdata/mysql/select/select-join.json create mode 100644 testdata/mysql/select/select-json-functions.json create mode 100644 testdata/mysql/select/select-limit-offset.json create mode 100644 testdata/mysql/select/select-lock-in-share-mode.json create mode 100644 testdata/mysql/select/select-natural-join.json create mode 100644 testdata/mysql/select/select-parameter-binding.json create mode 100644 testdata/mysql/select/select-regex.json create mode 100644 testdata/mysql/select/select-straight-join.json create mode 100644 testdata/mysql/select/select-string-functions.json create mode 100644 testdata/mysql/select/select-subquery.json create mode 100644 testdata/mysql/select/select-user-defined-variables.json create mode 100644 testdata/mysql/select/select-variable-assignment.json create mode 100644 testdata/mysql/select/select-window-functions.json create mode 100644 testdata/mysql/select/spatial-data-types-functions.json create mode 100644 testdata/mysql/select/spatial-geometry-data-types.json create mode 100644 testdata/mysql/select/system-versioned-tables.json create mode 100644 testdata/mysql/select/using-temporary-tables.json create mode 100644 testdata/mysql/select/virtual-generated-columns.json create mode 100644 testdata/mysql/update/bulk-update-multiple-conditions.json create mode 100644 testdata/mysql/update/conditional-update-case.json create mode 100644 testdata/mysql/update/update-basic.json create mode 100644 testdata/mysql/update/update-case-aggregate-functions.json create mode 100644 testdata/mysql/update/update-date-time-functions.json create mode 100644 testdata/mysql/update/update-encryption-functions.json create mode 100644 testdata/mysql/update/update-enum-data.json create mode 100644 testdata/mysql/update/update-json-functions.json create mode 100644 testdata/mysql/update/update-json-modify.json create mode 100644 testdata/mysql/update/update-lock-tables.json create mode 100644 testdata/mysql/update/update-math-functions.json create mode 100644 testdata/mysql/update/update-optimizing-conditions.json create mode 100644 testdata/mysql/update/update-order-by-limit.json create mode 100644 testdata/mysql/update/update-regular-expressions.json create mode 100644 testdata/mysql/update/update-spatial-data.json create mode 100644 testdata/mysql/update/update-string-functions.json create mode 100644 testdata/mysql/update/update-user-defined-variables.json create mode 100644 testdata/mysql/update/update-using-variables.json create mode 100644 testdata/mysql/update/update-with-join.json create mode 100644 testdata/mysql/update/update-with-subquery.json diff --git a/dbms_test.go b/dbms_test.go index d78da9c..52d2353 100644 --- a/dbms_test.go +++ b/dbms_test.go @@ -37,6 +37,7 @@ func TestQueriesPerDBMS(t *testing.T) { DBMSPostgres, DBMSOracle, DBMSSQLServer, + DBMSMySQL, } for _, dbms := range dbmsTypes { diff --git a/sqllexer_utils.go b/sqllexer_utils.go index 49bd7a7..7283872 100644 --- a/sqllexer_utils.go +++ b/sqllexer_utils.go @@ -19,31 +19,33 @@ const ( ) var commands = map[string]bool{ - "SELECT": true, - "INSERT": true, - "UPDATE": true, - "DELETE": true, - "CREATE": true, - "ALTER": true, - "DROP": true, - "JOIN": true, - "GRANT": true, - "REVOKE": true, - "COMMIT": true, - "BEGIN": true, - "TRUNCATE": true, - "MERGE": true, - "EXECUTE": true, - "EXEC": true, - "EXPLAIN": true, + "SELECT": true, + "INSERT": true, + "UPDATE": true, + "DELETE": true, + "CREATE": true, + "ALTER": true, + "DROP": true, + "JOIN": true, + "GRANT": true, + "REVOKE": true, + "COMMIT": true, + "BEGIN": true, + "TRUNCATE": true, + "MERGE": true, + "EXECUTE": true, + "EXEC": true, + "EXPLAIN": true, + "STRAIGHT_JOIN": true, } var tableIndicators = map[string]bool{ - "FROM": true, - "JOIN": true, - "INTO": true, - "UPDATE": true, - "TABLE": true, + "FROM": true, + "JOIN": true, + "INTO": true, + "UPDATE": true, + "TABLE": true, + "STRAIGHT_JOIN": true, // MySQL } var keywords = map[string]bool{ diff --git a/testdata/mysql/complex/super-complex-poorly-written-sql.json b/testdata/mysql/complex/super-complex-poorly-written-sql.json new file mode 100644 index 0000000..39a0d7f --- /dev/null +++ b/testdata/mysql/complex/super-complex-poorly-written-sql.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT a.*, b.totalAmount, CASE WHEN c.id IS NOT NULL THEN d.description ELSE 'N/A' END AS description\n-- Joining table a with b to get total amounts. If c.id is not null, get description from d\nFROM (SELECT id, name, status, customer_id\n FROM orders\n WHERE order_date > DATE_ADD(CURDATE(), INTERVAL -6 MONTH)\n AND status IN ('Pending', 'Completed')\n AND customer_id IN (SELECT customer_id FROM customers WHERE region IN ('East', 'West') AND last_order_date > DATE_ADD(CURDATE(), INTERVAL -1 YEAR))\n ORDER BY name DESC) a\nINNER JOIN (SELECT order_id, SUM(amount) AS totalAmount FROM order_details GROUP BY order_id) b ON a.id = b.order_id\nLEFT JOIN audit_log c ON a.id = c.order_id\nLEFT JOIN (SELECT DISTINCT status, description FROM status_descriptions) d ON a.status = d.status\nWHERE a.name LIKE '%test%'\n-- Filtering on name containing 'test'\nAND (b.totalAmount > 1000 OR b.totalAmount IS NULL)\nORDER BY a.order_date DESC, a.name;", + "outputs": [ + { + "expected": "SELECT a. *, b.totalAmount, CASE WHEN c.id IS NOT ? THEN d.description ELSE ? END FROM ( SELECT id, name, status, customer_id FROM orders WHERE order_date > DATE_ADD ( CURDATE ( ), INTERVAL ? MONTH ) AND status IN ( ? ) AND customer_id IN ( SELECT customer_id FROM customers WHERE region IN ( ? ) AND last_order_date > DATE_ADD ( CURDATE ( ), INTERVAL ? YEAR ) ) ORDER BY name DESC ) a INNER JOIN ( SELECT order_id, SUM ( amount ) FROM order_details GROUP BY order_id ) b ON a.id = b.order_id LEFT JOIN audit_log c ON a.id = c.order_id LEFT JOIN ( SELECT DISTINCT status, description FROM status_descriptions ) d ON a.status = d.status WHERE a.name LIKE ? AND ( b.totalAmount > ? OR b.totalAmount IS ? ) ORDER BY a.order_date DESC, a.name", + "statement_metadata": { + "size": 195, + "tables": ["orders", "customers", "order_details", "audit_log", "status_descriptions"], + "commands": ["SELECT", "JOIN"], + "comments": ["-- Joining table a with b to get total amounts. If c.id is not null, get description from d", "-- Filtering on name containing 'test'"], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/complex/super-complex-sql-multiple-joins.json b/testdata/mysql/complex/super-complex-sql-multiple-joins.json new file mode 100644 index 0000000..e0bde0b --- /dev/null +++ b/testdata/mysql/complex/super-complex-sql-multiple-joins.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT a.id, a.name, IFNULL(b.totalAmount, 0) AS totalAmount, c.comment, d.productCount, e.latestOrderDate\n-- Extremely complex query combining multiple joins, subqueries, and inline views\nFROM (SELECT id, name FROM customers WHERE status = 'Active') a\nJOIN (SELECT customer_id, SUM(amount) AS totalAmount FROM orders GROUP BY customer_id) b ON a.id = b.customer_id\nLEFT JOIN (SELECT customer_id, comment FROM customer_feedback WHERE rating = 5 ORDER BY feedback_date DESC LIMIT 1) c ON a.id = c.customer_id\nLEFT JOIN (SELECT customer_id, COUNT(*) AS productCount FROM order_details GROUP BY customer_id) d ON a.id = d.customer_id\nLEFT JOIN (SELECT customer_id, MAX(order_date) AS latestOrderDate FROM orders WHERE status IN ('Completed', 'Shipped') GROUP BY customer_id) e ON a.id = e.customer_id\nWHERE a.name LIKE '%Corp%' AND (b.totalAmount > 1000 OR d.productCount > 5)\nORDER BY a.name, totalAmount DESC;", + "outputs": [ + { + "expected": "SELECT a.id, a.name, IFNULL ( b.totalAmount, ? ), c.comment, d.productCount, e.latestOrderDate FROM ( SELECT id, name FROM customers WHERE status = ? ) a JOIN ( SELECT customer_id, SUM ( amount ) FROM orders GROUP BY customer_id ) b ON a.id = b.customer_id LEFT JOIN ( SELECT customer_id, comment FROM customer_feedback WHERE rating = ? ORDER BY feedback_date DESC LIMIT ? ) c ON a.id = c.customer_id LEFT JOIN ( SELECT customer_id, COUNT ( * ) FROM order_details GROUP BY customer_id ) d ON a.id = d.customer_id LEFT JOIN ( SELECT customer_id, MAX ( order_date ) FROM orders WHERE status IN ( ? ) GROUP BY customer_id ) e ON a.id = e.customer_id WHERE a.name LIKE ? AND ( b.totalAmount > ? OR d.productCount > ? ) ORDER BY a.name, totalAmount DESC", + "statement_metadata": { + "size": 136, + "tables": ["customers", "orders", "customer_feedback", "order_details"], + "commands": ["SELECT", "JOIN"], + "comments": ["-- Extremely complex query combining multiple joins, subqueries, and inline views"], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/complex/super-complex-sql-nested-subqueries.json b/testdata/mysql/complex/super-complex-sql-nested-subqueries.json new file mode 100644 index 0000000..a086430 --- /dev/null +++ b/testdata/mysql/complex/super-complex-sql-nested-subqueries.json @@ -0,0 +1,15 @@ +{ + "input": "SELECT t1.id, t1.status, t3.totalAmount, t4.commentsCount, CASE WHEN t5.latestCommentDate IS NOT NULL THEN t5.latestCommentDate ELSE 'No Comments' END AS latestComment\n-- Complex query joining multiple subqueries and using conditional logic\nFROM (SELECT id, status FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE region = 'North') AND order_date > (SELECT MAX(order_date) FROM orders WHERE status = 'Pending')) t1\nJOIN (SELECT order_id, SUM(amount) AS totalAmount FROM order_details WHERE product_id IN (SELECT id FROM products WHERE name LIKE '%Premium%') GROUP BY order_id) t3 ON t1.id = t3.order_id\nLEFT JOIN (SELECT order_id, COUNT(*) AS commentsCount FROM order_comments GROUP BY order_id) t4 ON t1.id = t4.order_id\nLEFT JOIN (SELECT order_id, MAX(comment_date) AS latestCommentDate FROM order_comments WHERE comment LIKE '%urgent%' GROUP BY order_id) t5 ON t1.id = t5.order_id\nWHERE t1.status NOT IN ('Cancelled', 'Returned') AND (t3.totalAmount > 500 OR t4.commentsCount > 10)\nORDER BY t1.id, latestComment DESC;", + "outputs": [ + { + "expected": "SELECT t?.id, t?.status, t?.totalAmount, t?.commentsCount, CASE WHEN t?.latestCommentDate IS NOT ? THEN t?.latestCommentDate ELSE ? END FROM ( SELECT id, status FROM orders WHERE customer_id IN ( SELECT id FROM customers WHERE region = ? ) AND order_date > ( SELECT MAX ( order_date ) FROM orders WHERE status = ? ) ) t? JOIN ( SELECT order_id, SUM ( amount ) FROM order_details WHERE product_id IN ( SELECT id FROM products WHERE name LIKE ? ) GROUP BY order_id ) t? ON t?.id = t?.order_id LEFT JOIN ( SELECT order_id, COUNT ( * ) FROM order_comments GROUP BY order_id ) t? ON t?.id = t?.order_id LEFT JOIN ( SELECT order_id, MAX ( comment_date ) FROM order_comments WHERE comment LIKE ? GROUP BY order_id ) t? ON t?.id = t?.order_id WHERE t?.status NOT IN ( ? ) AND ( t?.totalAmount > ? OR t?.commentsCount > ? ) ORDER BY t?.id, latestComment DESC", + "statement_metadata": { + "size": 132, + "tables": ["orders", "customers", "order_details", "products", "order_comments"], + "commands": ["SELECT", "JOIN"], + "comments": ["-- Complex query joining multiple subqueries and using conditional logic"], + "procedures": [] + } + } + ] +} diff --git a/testdata/mysql/delete/delete-basic.json b/testdata/mysql/delete/delete-basic.json new file mode 100644 index 0000000..eb9025d --- /dev/null +++ b/testdata/mysql/delete/delete-basic.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE status = 'Cancelled';", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-cascade.json b/testdata/mysql/delete/delete-cascade.json new file mode 100644 index 0000000..2e4a3b5 --- /dev/null +++ b/testdata/mysql/delete/delete-cascade.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM customers WHERE region = 'North'; -- Assuming CASCADE DELETE is set up on the foreign key in the orders table", + "outputs": [ + { + "expected": "DELETE FROM customers WHERE region = ?", + "statement_metadata": { + "size": 90, + "tables": ["customers"], + "commands": ["DELETE"], + "comments": ["-- Assuming CASCADE DELETE is set up on the foreign key in the orders table"], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-cascading-triggers.json b/testdata/mysql/delete/delete-cascading-triggers.json new file mode 100644 index 0000000..6ebeb03 --- /dev/null +++ b/testdata/mysql/delete/delete-cascading-triggers.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM customers WHERE id = 1; -- Assumes a trigger exists for cascading delete to orders", + "outputs": [ + { + "expected": "DELETE FROM customers WHERE id = ?", + "statement_metadata": { + "size": 73, + "tables": ["customers"], + "commands": ["DELETE"], + "comments": ["-- Assumes a trigger exists for cascading delete to orders"], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-conditional-logic.json b/testdata/mysql/delete/delete-conditional-logic.json new file mode 100644 index 0000000..27eb228 --- /dev/null +++ b/testdata/mysql/delete/delete-conditional-logic.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE status = IF(DAYOFWEEK(CURDATE()) = 1, 'Pending', 'Completed');", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE status = IF ( DAYOFWEEK ( CURDATE ( ) ) = ?, ?, ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-foreign-key-constraints.json b/testdata/mysql/delete/delete-foreign-key-constraints.json new file mode 100644 index 0000000..c5ab710 --- /dev/null +++ b/testdata/mysql/delete/delete-foreign-key-constraints.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE id IN (SELECT order_id FROM order_details WHERE quantity = 0);", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE id IN ( SELECT order_id FROM order_details WHERE quantity = ? )", + "statement_metadata": { + "size": 31, + "tables": ["orders", "order_details"], + "commands": ["DELETE", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-free-disk-space.json b/testdata/mysql/delete/delete-free-disk-space.json new file mode 100644 index 0000000..b2507bb --- /dev/null +++ b/testdata/mysql/delete/delete-free-disk-space.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE order_date < '2020-01-01'; OPTIMIZE TABLE orders;", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE order_date < ?; OPTIMIZE TABLE orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-join-multiple-conditions.json b/testdata/mysql/delete/delete-join-multiple-conditions.json new file mode 100644 index 0000000..b6f629c --- /dev/null +++ b/testdata/mysql/delete/delete-join-multiple-conditions.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'Completed' AND c.region = 'South';", + "outputs": [ + { + "expected": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = ? AND c.region = ?", + "statement_metadata": { + "size": 25, + "tables": ["orders", "customers"], + "commands": ["DELETE", "JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-lock-tables.json b/testdata/mysql/delete/delete-lock-tables.json new file mode 100644 index 0000000..84e1c59 --- /dev/null +++ b/testdata/mysql/delete/delete-lock-tables.json @@ -0,0 +1,16 @@ +{ + "input": "LOCK TABLES orders WRITE; DELETE FROM orders WHERE status = 'Failed'; UNLOCK TABLES;", + "outputs": [ + { + "expected": "LOCK TABLES orders WRITE; DELETE FROM orders WHERE status = ?; UNLOCK TABLES", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-multiple-tables.json b/testdata/mysql/delete/delete-multiple-tables.json new file mode 100644 index 0000000..d90a73b --- /dev/null +++ b/testdata/mysql/delete/delete-multiple-tables.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE orders, order_details FROM orders INNER JOIN order_details ON orders.id = order_details.order_id WHERE orders.status = 'Obsolete';", + "outputs": [ + { + "expected": "DELETE orders, order_details FROM orders INNER JOIN order_details ON orders.id = order_details.order_id WHERE orders.status = ?", + "statement_metadata": { + "size": 29, + "tables": ["orders", "order_details"], + "commands": ["DELETE", "JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-optimized-conditions.json b/testdata/mysql/delete/delete-optimized-conditions.json new file mode 100644 index 0000000..e521eb5 --- /dev/null +++ b/testdata/mysql/delete/delete-optimized-conditions.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE status = 'Completed' AND order_date < DATE_SUB(NOW(), INTERVAL 1 YEAR);", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE status = ? AND order_date < DATE_SUB ( NOW ( ), INTERVAL ? YEAR )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-order-by-limit.json b/testdata/mysql/delete/delete-order-by-limit.json new file mode 100644 index 0000000..3f054e3 --- /dev/null +++ b/testdata/mysql/delete/delete-order-by-limit.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE status = 'Completed' ORDER BY order_date DESC LIMIT 5;", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE status = ? ORDER BY order_date DESC LIMIT ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-range-conditions.json b/testdata/mysql/delete/delete-range-conditions.json new file mode 100644 index 0000000..0c41e2d --- /dev/null +++ b/testdata/mysql/delete/delete-range-conditions.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE amount BETWEEN 100 AND 500;", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE amount BETWEEN ? AND ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-regular-expressions.json b/testdata/mysql/delete/delete-regular-expressions.json new file mode 100644 index 0000000..7fa55b7 --- /dev/null +++ b/testdata/mysql/delete/delete-regular-expressions.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE status REGEXP '^C.*';", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE status REGEXP ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-safe-update-mode.json b/testdata/mysql/delete/delete-safe-update-mode.json new file mode 100644 index 0000000..9abb281 --- /dev/null +++ b/testdata/mysql/delete/delete-safe-update-mode.json @@ -0,0 +1,16 @@ +{ + "input": "SET SQL_SAFE_UPDATES = 0; DELETE FROM orders WHERE customer_id = 1; SET SQL_SAFE_UPDATES = 1;", + "outputs": [ + { + "expected": "SET SQL_SAFE_UPDATES = ?; DELETE FROM orders WHERE customer_id = ?; SET SQL_SAFE_UPDATES = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-subquery-optimization.json b/testdata/mysql/delete/delete-subquery-optimization.json new file mode 100644 index 0000000..14944ce --- /dev/null +++ b/testdata/mysql/delete/delete-subquery-optimization.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE id IN (SELECT id FROM orders WHERE status = 'Failed' LIMIT 10);", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE id IN ( SELECT id FROM orders WHERE status = ? LIMIT ? )", + "statement_metadata": { + "size": 18, + "tables": ["orders"], + "commands": ["DELETE", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-truncate.json b/testdata/mysql/delete/delete-truncate.json new file mode 100644 index 0000000..6a7053a --- /dev/null +++ b/testdata/mysql/delete/delete-truncate.json @@ -0,0 +1,16 @@ +{ + "input": "TRUNCATE TABLE order_details;", + "outputs": [ + { + "expected": "TRUNCATE TABLE order_details", + "statement_metadata": { + "size": 21, + "tables": ["order_details"], + "commands": ["TRUNCATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-using-subquery.json b/testdata/mysql/delete/delete-using-subquery.json new file mode 100644 index 0000000..2d739ca --- /dev/null +++ b/testdata/mysql/delete/delete-using-subquery.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE region = 'West');", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE customer_id IN ( SELECT id FROM customers WHERE region = ? )", + "statement_metadata": { + "size": 27, + "tables": ["orders", "customers"], + "commands": ["DELETE", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-with-join.json b/testdata/mysql/delete/delete-with-join.json new file mode 100644 index 0000000..c6def56 --- /dev/null +++ b/testdata/mysql/delete/delete-with-join.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.region = 'East' AND o.status = 'Pending';", + "outputs": [ + { + "expected": "DELETE o FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.region = ? AND o.status = ?", + "statement_metadata": { + "size": 25, + "tables": ["orders", "customers"], + "commands": ["DELETE", "JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-with-limit.json b/testdata/mysql/delete/delete-with-limit.json new file mode 100644 index 0000000..60b9976 --- /dev/null +++ b/testdata/mysql/delete/delete-with-limit.json @@ -0,0 +1,16 @@ +{ + "input": "DELETE FROM orders WHERE status = 'Pending' LIMIT 10;", + "outputs": [ + { + "expected": "DELETE FROM orders WHERE status = ? LIMIT ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/delete/delete-with-user-variables.json b/testdata/mysql/delete/delete-with-user-variables.json new file mode 100644 index 0000000..a0c41cc --- /dev/null +++ b/testdata/mysql/delete/delete-with-user-variables.json @@ -0,0 +1,16 @@ +{ + "input": "SET @max_id = (SELECT MAX(id) FROM orders); DELETE FROM orders WHERE id = @max_id;", + "outputs": [ + { + "expected": "SET @max_id = ( SELECT MAX ( id ) FROM orders ); DELETE FROM orders WHERE id = @max_id", + "statement_metadata": { + "size": 18, + "tables": ["orders"], + "commands": ["SELECT", "DELETE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/batch-insert-multiple-rows.json b/testdata/mysql/insert/batch-insert-multiple-rows.json new file mode 100644 index 0000000..6ff42c6 --- /dev/null +++ b/testdata/mysql/insert/batch-insert-multiple-rows.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status) VALUES (1, 'Pending'), (2, 'Completed'), (3, 'Processing');", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status ) VALUES ( ? ), ( ? ), ( ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-auto-increment.json b/testdata/mysql/insert/insert-auto-increment.json new file mode 100644 index 0000000..0c86686 --- /dev/null +++ b/testdata/mysql/insert/insert-auto-increment.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status) VALUES (3, 'Processing');", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status ) VALUES ( ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-basic.json b/testdata/mysql/insert/insert-basic.json new file mode 100644 index 0000000..7fce164 --- /dev/null +++ b/testdata/mysql/insert/insert-basic.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, order_date, status) VALUES (1, NOW(), 'Pending');", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, order_date, status ) VALUES ( ?, NOW ( ), ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-blob-data.json b/testdata/mysql/insert/insert-blob-data.json new file mode 100644 index 0000000..10f1fe2 --- /dev/null +++ b/testdata/mysql/insert/insert-blob-data.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, document) VALUES (5, 'Pending', LOAD_FILE('/path/to/file'));", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, document ) VALUES ( ?, LOAD_FILE ( ? ) )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-enum-data.json b/testdata/mysql/insert/insert-enum-data.json new file mode 100644 index 0000000..2297c9b --- /dev/null +++ b/testdata/mysql/insert/insert-enum-data.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, order_type) VALUES (7, 'Pending', 'Express');", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, order_type ) VALUES ( ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-ignore.json b/testdata/mysql/insert/insert-ignore.json new file mode 100644 index 0000000..706788a --- /dev/null +++ b/testdata/mysql/insert/insert-ignore.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT IGNORE INTO orders (id, customer_id, status) VALUES (1, 10, 'Cancelled');", + "outputs": [ + { + "expected": "INSERT IGNORE INTO orders ( id, customer_id, status ) VALUES ( ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-json-data.json b/testdata/mysql/insert/insert-json-data.json new file mode 100644 index 0000000..4356668 --- /dev/null +++ b/testdata/mysql/insert/insert-json-data.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, details) VALUES (1, 'Pending', '{\"items\": [\"item1\", \"item2\"]}');", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, details ) VALUES ( ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-on-duplicate-key.json b/testdata/mysql/insert/insert-on-duplicate-key.json new file mode 100644 index 0000000..4dc3f78 --- /dev/null +++ b/testdata/mysql/insert/insert-on-duplicate-key.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (id, customer_id, status) VALUES (100, 2, 'Pending') ON DUPLICATE KEY UPDATE status = 'Pending';", + "outputs": [ + { + "expected": "INSERT INTO orders ( id, customer_id, status ) VALUES ( ? ) ON DUPLICATE KEY UPDATE status = ?", + "statement_metadata": { + "size": 24, + "tables": ["orders", "status"], + "commands": ["INSERT", "UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-select-union.json b/testdata/mysql/insert/insert-select-union.json new file mode 100644 index 0000000..f9a2417 --- /dev/null +++ b/testdata/mysql/insert/insert-select-union.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status) SELECT customer_id, status FROM archived_orders UNION ALL SELECT customer_id, status FROM special_orders;", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status ) SELECT customer_id, status FROM archived_orders UNION ALL SELECT customer_id, status FROM special_orders", + "statement_metadata": { + "size": 47, + "tables": ["orders", "archived_orders", "special_orders"], + "commands": ["INSERT", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-spatial-data.json b/testdata/mysql/insert/insert-spatial-data.json new file mode 100644 index 0000000..e7a245e --- /dev/null +++ b/testdata/mysql/insert/insert-spatial-data.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, location) VALUES (6, 'Delivered', ST_GeomFromText('POINT(1 1)'));", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, location ) VALUES ( ?, ST_GeomFromText ( ? ) )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-using-last-insert-id.json b/testdata/mysql/insert/insert-using-last-insert-id.json new file mode 100644 index 0000000..63eaa52 --- /dev/null +++ b/testdata/mysql/insert/insert-using-last-insert-id.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO customers (name) VALUES ('John Doe'); INSERT INTO orders (customer_id, status) VALUES (LAST_INSERT_ID(), 'Pending');", + "outputs": [ + { + "expected": "INSERT INTO customers ( name ) VALUES ( ? ); INSERT INTO orders ( customer_id, status ) VALUES ( LAST_INSERT_ID ( ), ? )", + "statement_metadata": { + "size": 21, + "tables": ["customers", "orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-using-subquery.json b/testdata/mysql/insert/insert-using-subquery.json new file mode 100644 index 0000000..03fbae9 --- /dev/null +++ b/testdata/mysql/insert/insert-using-subquery.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO order_audit (order_id, status) SELECT id, status FROM orders WHERE customer_id = 1;", + "outputs": [ + { + "expected": "INSERT INTO order_audit ( order_id, status ) SELECT id, status FROM orders WHERE customer_id = ?", + "statement_metadata": { + "size": 29, + "tables": ["order_audit", "orders"], + "commands": ["INSERT", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-conditional-logic.json b/testdata/mysql/insert/insert-with-conditional-logic.json new file mode 100644 index 0000000..61d6087 --- /dev/null +++ b/testdata/mysql/insert/insert-with-conditional-logic.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, amount) SELECT id, 'New', IF(region = 'West', 100, 50) FROM customers;", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, amount ) SELECT id, ?, IF ( region = ?, ?, ? ) FROM customers", + "statement_metadata": { + "size": 27, + "tables": ["orders", "customers"], + "commands": ["INSERT", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-curdate-curtime.json b/testdata/mysql/insert/insert-with-curdate-curtime.json new file mode 100644 index 0000000..1eb52da --- /dev/null +++ b/testdata/mysql/insert/insert-with-curdate-curtime.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, order_date, order_time) VALUES (15, 'Pending', CURDATE(), CURTIME());", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, order_date, order_time ) VALUES ( ?, CURDATE ( ), CURTIME ( ) )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-encryption-functions.json b/testdata/mysql/insert/insert-with-encryption-functions.json new file mode 100644 index 0000000..40427ea --- /dev/null +++ b/testdata/mysql/insert/insert-with-encryption-functions.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, encrypted_note) VALUES (13, 'Pending', AES_ENCRYPT('Confidential note', 'encryption_key'));", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, encrypted_note ) VALUES ( ?, AES_ENCRYPT ( ? ) )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-generated-columns.json b/testdata/mysql/insert/insert-with-generated-columns.json new file mode 100644 index 0000000..7e6b9f5 --- /dev/null +++ b/testdata/mysql/insert/insert-with-generated-columns.json @@ -0,0 +1,15 @@ +{ + "input": "INSERT INTO orders (customer_id, status, total_incl_tax) VALUES (12, 'Pending', 150); -- total_incl_tax is a generated column", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, total_incl_tax ) VALUES ( ? )", + "statement_metadata": { + "size": 51, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": ["-- total_incl_tax is a generated column"], + "procedures": [] + } + } + ] + } \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-replace.json b/testdata/mysql/insert/insert-with-replace.json new file mode 100644 index 0000000..651ee69 --- /dev/null +++ b/testdata/mysql/insert/insert-with-replace.json @@ -0,0 +1,16 @@ +{ + "input": "REPLACE INTO orders (id, customer_id, status) VALUES (1, 9, 'Completed');", + "outputs": [ + { + "expected": "REPLACE INTO orders ( id, customer_id, status ) VALUES ( ? )", + "statement_metadata": { + "size": 6, + "tables": ["orders"], + "commands": [], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-set-syntax.json b/testdata/mysql/insert/insert-with-set-syntax.json new file mode 100644 index 0000000..21afae7 --- /dev/null +++ b/testdata/mysql/insert/insert-with-set-syntax.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders SET customer_id = 8, status = 'Processing', order_date = CURDATE();", + "outputs": [ + { + "expected": "INSERT INTO orders SET customer_id = ?, status = ?, order_date = CURDATE ( )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-spatial-data.json b/testdata/mysql/insert/insert-with-spatial-data.json new file mode 100644 index 0000000..4059132 --- /dev/null +++ b/testdata/mysql/insert/insert-with-spatial-data.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, location) VALUES (14, 'Pending', ST_GeomFromText('POINT(1 1)'));", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, location ) VALUES ( ?, ST_GeomFromText ( ? ) )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/insert/insert-with-timestamp.json b/testdata/mysql/insert/insert-with-timestamp.json new file mode 100644 index 0000000..e93ee97 --- /dev/null +++ b/testdata/mysql/insert/insert-with-timestamp.json @@ -0,0 +1,16 @@ +{ + "input": "INSERT INTO orders (customer_id, status, created_at) VALUES (4, 'Shipped', CURRENT_TIMESTAMP);", + "outputs": [ + { + "expected": "INSERT INTO orders ( customer_id, status, created_at ) VALUES ( ?, CURRENT_TIMESTAMP )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["INSERT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/procedure/complex-procedure-error-handling.json b/testdata/mysql/procedure/complex-procedure-error-handling.json new file mode 100644 index 0000000..7137fbb --- /dev/null +++ b/testdata/mysql/procedure/complex-procedure-error-handling.json @@ -0,0 +1,16 @@ +{ + "input": "CREATE PROCEDURE UpdateOrderStatus(IN orderId INT, IN newStatus VARCHAR(20)) BEGIN\n DECLARE EXIT HANDLER FOR SQLEXCEPTION\n BEGIN\n -- Handle error\n ROLLBACK;\n END;\n START TRANSACTION;\n UPDATE orders SET status = newStatus WHERE id = orderId;\n IF ROW_COUNT() = 0 THEN\n SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No rows updated';\n END IF;\n COMMIT;\n END;", + "outputs": [ + { + "expected": "CREATE PROCEDURE UpdateOrderStatus ( IN orderId INT, IN newStatus VARCHAR ( ? ) ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; END; START TRANSACTION; UPDATE orders SET status = newStatus WHERE id = orderId; IF ROW_COUNT ( ) = ? THEN SIGNAL SQLSTATE ? SET MESSAGE_TEXT = ?; END IF; COMMIT; END", + "statement_metadata": { + "size": 61, + "tables": ["orders"], + "commands": ["CREATE", "BEGIN", "UPDATE", "COMMIT"], + "comments": ["-- Handle error"], + "procedures": ["UpdateOrderStatus"] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-basic.json b/testdata/mysql/procedure/stored-procedure-basic.json new file mode 100644 index 0000000..e8487b6 --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-basic.json @@ -0,0 +1,15 @@ +{ + "input": "CREATE PROCEDURE GetAllOrders() BEGIN SELECT * FROM orders; END;", + "outputs": [ + { + "expected": "CREATE PROCEDURE GetAllOrders ( ) BEGIN SELECT * FROM orders; END", + "statement_metadata": { + "size": 35, + "tables": ["orders"], + "commands": ["CREATE", "BEGIN", "SELECT"], + "comments": [], + "procedures": ["GetAllOrders"] + } + } + ] + } \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-conditional-logic-loop.json b/testdata/mysql/procedure/stored-procedure-conditional-logic-loop.json new file mode 100644 index 0000000..cb2b88e --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-conditional-logic-loop.json @@ -0,0 +1,15 @@ +{ + "input": "CREATE PROCEDURE ProcessOrders() BEGIN\n DECLARE done INT DEFAULT 0;\n DECLARE a INT;\n DECLARE cur1 CURSOR FOR SELECT id FROM orders WHERE status = 'Pending';\n DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;\n OPEN cur1;\n read_loop: LOOP\n FETCH cur1 INTO a;\n IF done THEN\n LEAVE read_loop;\n END IF;\n UPDATE orders SET status = 'Processing' WHERE id = a;\n END LOOP;\n CLOSE cur1;\n END;", + "outputs": [ + { + "expected": "CREATE PROCEDURE ProcessOrders ( ) BEGIN DECLARE done INT DEFAULT ?; DECLARE a INT; DECLARE cur? CURSOR FOR SELECT id FROM orders WHERE status = ?; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = ?; OPEN cur?; read_loop : LOOP FETCH cur? INTO a; IF done THEN LEAVE read_loop; END IF; UPDATE orders SET status = ? WHERE id = a; END LOOP; CLOSE cur?; END", + "statement_metadata": { + "size": 43, + "tables": ["orders", "a"], + "commands": ["CREATE", "BEGIN", "SELECT", "UPDATE"], + "comments": [], + "procedures": ["ProcessOrders"] + } + } + ] + } \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-cursor.json b/testdata/mysql/procedure/stored-procedure-cursor.json new file mode 100644 index 0000000..d0e3462 --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-cursor.json @@ -0,0 +1,16 @@ +{ + "input": "CREATE PROCEDURE FetchOrders() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE cur CURSOR FOR SELECT id FROM orders; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO order_id; IF done THEN LEAVE read_loop; END IF; /* process each order */ END LOOP; CLOSE cur; END;", + "outputs": [ + { + "expected": "CREATE PROCEDURE FetchOrders ( ) BEGIN DECLARE done INT DEFAULT ?; DECLARE cur CURSOR FOR SELECT id FROM orders; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = ?; OPEN cur; read_loop : LOOP FETCH cur INTO order_id; IF done THEN LEAVE read_loop; END IF; END LOOP; CLOSE cur; END", + "statement_metadata": { + "size": 66, + "tables": ["orders", "order_id"], + "commands": ["CREATE", "BEGIN", "SELECT"], + "comments": ["/* process each order */"], + "procedures": ["FetchOrders"] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-dynamic-sql.json b/testdata/mysql/procedure/stored-procedure-dynamic-sql.json new file mode 100644 index 0000000..42128dc --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-dynamic-sql.json @@ -0,0 +1,16 @@ +{ + "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;", + "outputs": [ + { + "expected": "CREATE PROCEDURE DynamicQuery ( IN tbl_name VARCHAR ( ? ) ) BEGIN SET @s = CONCAT ( ?, tbl_name ); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; END", + "statement_metadata": { + "size": 30, + "tables": [], + "commands": ["CREATE", "BEGIN", "EXECUTE"], + "comments": [], + "procedures": ["DynamicQuery"] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-error-handling.json b/testdata/mysql/procedure/stored-procedure-error-handling.json new file mode 100644 index 0000000..82fdd16 --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-error-handling.json @@ -0,0 +1,16 @@ +{ + "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;", + "outputs": [ + { + "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", + "statement_metadata": { + "size": 48, + "tables": ["orders"], + "commands": ["CREATE", "BEGIN", "UPDATE"], + "comments": ["-- handle error"], + "procedures": ["SafeUpdate"] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-input-output-parameters.json b/testdata/mysql/procedure/stored-procedure-input-output-parameters.json new file mode 100644 index 0000000..2671135 --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-input-output-parameters.json @@ -0,0 +1,16 @@ +{ + "input": "CREATE PROCEDURE GetTotalOrders(OUT total INT) BEGIN SELECT COUNT(*) INTO total FROM orders; END;", + "outputs": [ + { + "expected": "CREATE PROCEDURE GetTotalOrders ( OUT total INT ) BEGIN SELECT COUNT ( * ) INTO total FROM orders; END", + "statement_metadata": { + "size": 42, + "tables": ["total", "orders"], + "commands": ["CREATE", "BEGIN", "SELECT"], + "comments": [], + "procedures": ["GetTotalOrders"] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-loop-control.json b/testdata/mysql/procedure/stored-procedure-loop-control.json new file mode 100644 index 0000000..fc8f688 --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-loop-control.json @@ -0,0 +1,15 @@ +{ + "input": "CREATE PROCEDURE ProcessOrders() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE cur CURSOR FOR SELECT id FROM orders; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO order_id; IF done THEN LEAVE read_loop; END IF; UPDATE orders SET status = 'Processed' WHERE id = order_id; END LOOP; CLOSE cur; END;", + "outputs": [ + { + "expected": "CREATE PROCEDURE ProcessOrders ( ) BEGIN DECLARE done INT DEFAULT ?; DECLARE cur CURSOR FOR SELECT id FROM orders; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = ?; OPEN cur; read_loop : LOOP FETCH cur INTO order_id; IF done THEN LEAVE read_loop; END IF; UPDATE orders SET status = ? WHERE id = order_id; END LOOP; CLOSE cur; END", + "statement_metadata": { + "size": 50, + "tables": ["orders", "order_id"], + "commands": ["CREATE", "BEGIN", "SELECT", "UPDATE"], + "comments": [], + "procedures": ["ProcessOrders"] + } + } + ] +} diff --git a/testdata/mysql/procedure/stored-procedure-parameters.json b/testdata/mysql/procedure/stored-procedure-parameters.json new file mode 100644 index 0000000..fc98aa4 --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-parameters.json @@ -0,0 +1,15 @@ +{ + "input": "CREATE PROCEDURE GetOrdersByStatus(IN status VARCHAR(20)) BEGIN SELECT * FROM orders WHERE orders.status = status; END;", + "outputs": [ + { + "expected": "CREATE PROCEDURE GetOrdersByStatus ( IN status VARCHAR ( ? ) ) BEGIN SELECT * FROM orders WHERE orders.status = status; END", + "statement_metadata": { + "size": 40, + "tables": ["orders"], + "commands": ["CREATE", "BEGIN", "SELECT"], + "comments": [], + "procedures": ["GetOrdersByStatus"] + } + } + ] + } \ No newline at end of file diff --git a/testdata/mysql/procedure/stored-procedure-transaction-management.json b/testdata/mysql/procedure/stored-procedure-transaction-management.json new file mode 100644 index 0000000..75aace9 --- /dev/null +++ b/testdata/mysql/procedure/stored-procedure-transaction-management.json @@ -0,0 +1,15 @@ +{ + "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;", + "outputs": [ + { + "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", + "statement_metadata": { + "size": 51, + "tables": ["orders"], + "commands": ["CREATE", "BEGIN", "UPDATE", "COMMIT"], + "comments": [], + "procedures": ["UpdateOrderTransaction"] + } + } + ] + } \ No newline at end of file diff --git a/testdata/mysql/select/bit-data-type.json b/testdata/mysql/select/bit-data-type.json new file mode 100644 index 0000000..c39da7e --- /dev/null +++ b/testdata/mysql/select/bit-data-type.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, status, (is_paid & 1) AS isPaidFlag FROM orders;", + "outputs": [ + { + "expected": "SELECT id, status, ( is_paid & ? ) FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/blob-text-data-types.json b/testdata/mysql/select/blob-text-data-types.json new file mode 100644 index 0000000..d80018d --- /dev/null +++ b/testdata/mysql/select/blob-text-data-types.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, SUBSTRING(order_notes, 1, 100) AS short_notes FROM orders WHERE LENGTH(document_blob) > 1024;", + "outputs": [ + { + "expected": "SELECT id, SUBSTRING ( order_notes, ?, ? ) FROM orders WHERE LENGTH ( document_blob ) > ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/decimal-data-type.json b/testdata/mysql/select/decimal-data-type.json new file mode 100644 index 0000000..e3b6557 --- /dev/null +++ b/testdata/mysql/select/decimal-data-type.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, ROUND(total_amount, 2) AS rounded_total FROM orders;", + "outputs": [ + { + "expected": "SELECT id, ROUND ( total_amount, ? ) FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/enum-set-data-types.json b/testdata/mysql/select/enum-set-data-types.json new file mode 100644 index 0000000..cfccc93 --- /dev/null +++ b/testdata/mysql/select/enum-set-data-types.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, order_type, status_flags FROM order_details WHERE order_type = 'Standard' AND FIND_IN_SET('urgent', status_flags);", + "outputs": [ + { + "expected": "SELECT id, order_type, status_flags FROM order_details WHERE order_type = ? AND FIND_IN_SET ( ?, status_flags )", + "statement_metadata": { + "size": 19, + "tables": ["order_details"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/full-text-search-innodb.json b/testdata/mysql/select/full-text-search-innodb.json new file mode 100644 index 0000000..1374d83 --- /dev/null +++ b/testdata/mysql/select/full-text-search-innodb.json @@ -0,0 +1,16 @@ +{ + "input": "CREATE FULLTEXT INDEX ft_index ON orders (description); SELECT * FROM orders WHERE MATCH(description) AGAINST ('+delivery -return' IN BOOLEAN MODE);", + "outputs": [ + { + "expected": "CREATE FULLTEXT INDEX ft_index ON orders ( description ); SELECT * FROM orders WHERE MATCH ( description ) AGAINST ( ? IN BOOLEAN MODE )", + "statement_metadata": { + "size": 18, + "tables": ["orders"], + "commands": ["CREATE", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-aggregate-functions.json b/testdata/mysql/select/select-aggregate-functions.json new file mode 100644 index 0000000..a8880b7 --- /dev/null +++ b/testdata/mysql/select/select-aggregate-functions.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT customer_id, COUNT(*) AS total_orders FROM orders GROUP BY customer_id HAVING COUNT(*) > 5;", + "outputs": [ + { + "expected": "SELECT customer_id, COUNT ( * ) FROM orders GROUP BY customer_id HAVING COUNT ( * ) > ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-basic.json b/testdata/mysql/select/select-basic.json new file mode 100644 index 0000000..be6c606 --- /dev/null +++ b/testdata/mysql/select/select-basic.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, customer_id, order_date, status FROM orders WHERE status = 'Pending';", + "outputs": [ + { + "expected": "SELECT id, customer_id, order_date, status FROM orders WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-case-statement.json b/testdata/mysql/select/select-case-statement.json new file mode 100644 index 0000000..68202df --- /dev/null +++ b/testdata/mysql/select/select-case-statement.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, CASE WHEN status = 'Pending' THEN 'P' WHEN status = 'Completed' THEN 'C' ELSE 'Other' END AS status_code FROM orders;", + "outputs": [ + { + "expected": "SELECT id, CASE WHEN status = ? THEN ? WHEN status = ? THEN ? ELSE ? END FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-coalesce-function.json b/testdata/mysql/select/select-coalesce-function.json new file mode 100644 index 0000000..d6dc561 --- /dev/null +++ b/testdata/mysql/select/select-coalesce-function.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, COALESCE(comments, 'No comments') AS order_comments FROM orders;", + "outputs": [ + { + "expected": "SELECT id, COALESCE ( comments, ? ) FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-conditional-case.json b/testdata/mysql/select/select-conditional-case.json new file mode 100644 index 0000000..68202df --- /dev/null +++ b/testdata/mysql/select/select-conditional-case.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, CASE WHEN status = 'Pending' THEN 'P' WHEN status = 'Completed' THEN 'C' ELSE 'Other' END AS status_code FROM orders;", + "outputs": [ + { + "expected": "SELECT id, CASE WHEN status = ? THEN ? WHEN status = ? THEN ? ELSE ? END FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-date-functions.json b/testdata/mysql/select/select-date-functions.json new file mode 100644 index 0000000..482f9a2 --- /dev/null +++ b/testdata/mysql/select/select-date-functions.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, YEAR(order_date) AS order_year FROM orders WHERE MONTH(order_date) = 1;", + "outputs": [ + { + "expected": "SELECT id, YEAR ( order_date ) FROM orders WHERE MONTH ( order_date ) = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-distinct.json b/testdata/mysql/select/select-distinct.json new file mode 100644 index 0000000..6552154 --- /dev/null +++ b/testdata/mysql/select/select-distinct.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT DISTINCT status FROM orders;", + "outputs": [ + { + "expected": "SELECT DISTINCT status FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-full-text-search.json b/testdata/mysql/select/select-full-text-search.json new file mode 100644 index 0000000..c5dfd17 --- /dev/null +++ b/testdata/mysql/select/select-full-text-search.json @@ -0,0 +1,16 @@ +{ + "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;", + "outputs": [ + { + "expected": "SELECT id, MATCH ( description ) AGAINST ( ? IN BOOLEAN MODE ) FROM orders WHERE MATCH ( description ) AGAINST ( ? IN BOOLEAN MODE ) > ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-geospatial-data.json b/testdata/mysql/select/select-geospatial-data.json new file mode 100644 index 0000000..cb807f3 --- /dev/null +++ b/testdata/mysql/select/select-geospatial-data.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, ST_AsText(location) AS location FROM orders WHERE ST_Distance_Sphere(location, ST_GeomFromText('POINT(10 20)')) < 10000;", + "outputs": [ + { + "expected": "SELECT id, ST_AsText ( location ) FROM orders WHERE ST_Distance_Sphere ( location, ST_GeomFromText ( ? ) ) < ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-group-concat.json b/testdata/mysql/select/select-group-concat.json new file mode 100644 index 0000000..50c4d10 --- /dev/null +++ b/testdata/mysql/select/select-group-concat.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT customer_id, GROUP_CONCAT(status ORDER BY order_date DESC SEPARATOR ', ') AS order_statuses FROM orders GROUP BY customer_id;", + "outputs": [ + { + "expected": "SELECT customer_id, GROUP_CONCAT ( status ORDER BY order_date DESC SEPARATOR ? ) FROM orders GROUP BY customer_id", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-join-aliases.json b/testdata/mysql/select/select-join-aliases.json new file mode 100644 index 0000000..54f27bf --- /dev/null +++ b/testdata/mysql/select/select-join-aliases.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT o.id, c.name AS customer_name, o.status FROM orders o LEFT JOIN customers c ON o.customer_id = c.id;", + "outputs": [ + { + "expected": "SELECT o.id, c.name, o.status FROM orders o LEFT JOIN customers c ON o.customer_id = c.id", + "statement_metadata": { + "size": 25, + "tables": ["orders", "customers"], + "commands": ["SELECT", "JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-join.json b/testdata/mysql/select/select-join.json new file mode 100644 index 0000000..5aa1860 --- /dev/null +++ b/testdata/mysql/select/select-join.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT o.id, c.name, o.status FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'Completed';", + "outputs": [ + { + "expected": "SELECT o.id, c.name, o.status FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = ?", + "statement_metadata": { + "size": 25, + "tables": ["orders", "customers"], + "commands": ["SELECT", "JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-json-functions.json b/testdata/mysql/select/select-json-functions.json new file mode 100644 index 0000000..1e55031 --- /dev/null +++ b/testdata/mysql/select/select-json-functions.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, JSON_EXTRACT(order_details, '$.items[0].name') AS first_item_name FROM orders WHERE JSON_CONTAINS(order_details, '\"Active\"', '$.status');", + "outputs": [ + { + "expected": "SELECT id, JSON_EXTRACT ( order_details, ? ) FROM orders WHERE JSON_CONTAINS ( order_details, ?, ? )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-limit-offset.json b/testdata/mysql/select/select-limit-offset.json new file mode 100644 index 0000000..d7af084 --- /dev/null +++ b/testdata/mysql/select/select-limit-offset.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT * FROM orders ORDER BY order_date DESC LIMIT 10 OFFSET 5;", + "outputs": [ + { + "expected": "SELECT * FROM orders ORDER BY order_date DESC LIMIT ? OFFSET ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-lock-in-share-mode.json b/testdata/mysql/select/select-lock-in-share-mode.json new file mode 100644 index 0000000..703bf31 --- /dev/null +++ b/testdata/mysql/select/select-lock-in-share-mode.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT * FROM orders WHERE status = 'Pending' LOCK IN SHARE MODE;", + "outputs": [ + { + "expected": "SELECT * FROM orders WHERE status = ? LOCK IN SHARE MODE", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-natural-join.json b/testdata/mysql/select/select-natural-join.json new file mode 100644 index 0000000..9e52639 --- /dev/null +++ b/testdata/mysql/select/select-natural-join.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT * FROM orders NATURAL JOIN customers;", + "outputs": [ + { + "expected": "SELECT * FROM orders NATURAL JOIN customers", + "statement_metadata": { + "size": 25, + "tables": ["orders", "customers"], + "commands": ["SELECT", "JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-parameter-binding.json b/testdata/mysql/select/select-parameter-binding.json new file mode 100644 index 0000000..4db2716 --- /dev/null +++ b/testdata/mysql/select/select-parameter-binding.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, status FROM orders WHERE customer_id = ?;", + "outputs": [ + { + "expected": "SELECT id, status FROM orders WHERE customer_id = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-regex.json b/testdata/mysql/select/select-regex.json new file mode 100644 index 0000000..969c50c --- /dev/null +++ b/testdata/mysql/select/select-regex.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, customer_id FROM orders WHERE status REGEXP '^Comp.*';", + "outputs": [ + { + "expected": "SELECT id, customer_id FROM orders WHERE status REGEXP ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-straight-join.json b/testdata/mysql/select/select-straight-join.json new file mode 100644 index 0000000..eba10c9 --- /dev/null +++ b/testdata/mysql/select/select-straight-join.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT * FROM orders STRAIGHT_JOIN customers ON orders.customer_id = customers.id;", + "outputs": [ + { + "expected": "SELECT * FROM orders STRAIGHT_JOIN customers ON orders.customer_id = customers.id", + "statement_metadata": { + "size": 34, + "tables": ["orders", "customers"], + "commands": ["SELECT", "STRAIGHT_JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-string-functions.json b/testdata/mysql/select/select-string-functions.json new file mode 100644 index 0000000..6e3f96c --- /dev/null +++ b/testdata/mysql/select/select-string-functions.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, UPPER(status) AS status_upper FROM orders;", + "outputs": [ + { + "expected": "SELECT id, UPPER ( status ) FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-subquery.json b/testdata/mysql/select/select-subquery.json new file mode 100644 index 0000000..2929072 --- /dev/null +++ b/testdata/mysql/select/select-subquery.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, (SELECT name FROM customers WHERE id = orders.customer_id) AS customer_name FROM orders;", + "outputs": [ + { + "expected": "SELECT id, ( SELECT name FROM customers WHERE id = orders.customer_id ) FROM orders", + "statement_metadata": { + "size": 21, + "tables": ["customers", "orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-user-defined-variables.json b/testdata/mysql/select/select-user-defined-variables.json new file mode 100644 index 0000000..2593abf --- /dev/null +++ b/testdata/mysql/select/select-user-defined-variables.json @@ -0,0 +1,16 @@ +{ + "input": "SET @orderRank := 0; SELECT @orderRank := @orderRank + 1 AS rank, id, status FROM orders ORDER BY id;", + "outputs": [ + { + "expected": "SET @orderRank := ?; SELECT @orderRank := @orderRank + ?, id, status FROM orders ORDER BY id", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-variable-assignment.json b/testdata/mysql/select/select-variable-assignment.json new file mode 100644 index 0000000..44f417c --- /dev/null +++ b/testdata/mysql/select/select-variable-assignment.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT @orderCount := COUNT(*) FROM orders WHERE status = 'Completed';", + "outputs": [ + { + "expected": "SELECT @orderCount := COUNT ( * ) FROM orders WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/select-window-functions.json b/testdata/mysql/select/select-window-functions.json new file mode 100644 index 0000000..981fa15 --- /dev/null +++ b/testdata/mysql/select/select-window-functions.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, status, RANK() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rank FROM orders;", + "outputs": [ + { + "expected": "SELECT id, status, RANK ( ) OVER ( PARTITION BY customer_id ORDER BY order_date DESC ) FROM orders", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/spatial-data-types-functions.json b/testdata/mysql/select/spatial-data-types-functions.json new file mode 100644 index 0000000..cb807f3 --- /dev/null +++ b/testdata/mysql/select/spatial-data-types-functions.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, ST_AsText(location) AS location FROM orders WHERE ST_Distance_Sphere(location, ST_GeomFromText('POINT(10 20)')) < 10000;", + "outputs": [ + { + "expected": "SELECT id, ST_AsText ( location ) FROM orders WHERE ST_Distance_Sphere ( location, ST_GeomFromText ( ? ) ) < ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/spatial-geometry-data-types.json b/testdata/mysql/select/spatial-geometry-data-types.json new file mode 100644 index 0000000..7516075 --- /dev/null +++ b/testdata/mysql/select/spatial-geometry-data-types.json @@ -0,0 +1,16 @@ +{ + "input": "SELECT id, ST_AsText(location) FROM orders WHERE ST_Distance(location, ST_GeomFromText('POINT(1 1)')) < 100;", + "outputs": [ + { + "expected": "SELECT id, ST_AsText ( location ) FROM orders WHERE ST_Distance ( location, ST_GeomFromText ( ? ) ) < ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/system-versioned-tables.json b/testdata/mysql/select/system-versioned-tables.json new file mode 100644 index 0000000..ee38318 --- /dev/null +++ b/testdata/mysql/select/system-versioned-tables.json @@ -0,0 +1,16 @@ +{ + "input": "CREATE TABLE orders_with_history (id INT, status VARCHAR(20)) WITH SYSTEM VERSIONING;", + "outputs": [ + { + "expected": "CREATE TABLE orders_with_history ( id INT, status VARCHAR ( ? ) ) WITH SYSTEM VERSIONING", + "statement_metadata": { + "size": 25, + "tables": ["orders_with_history"], + "commands": ["CREATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/using-temporary-tables.json b/testdata/mysql/select/using-temporary-tables.json new file mode 100644 index 0000000..dd43656 --- /dev/null +++ b/testdata/mysql/select/using-temporary-tables.json @@ -0,0 +1,16 @@ +{ + "input": "CREATE TEMPORARY TABLE temp_orders SELECT * FROM orders; SELECT * FROM temp_orders WHERE status = 'Pending'; DROP TEMPORARY TABLE temp_orders;", + "outputs": [ + { + "expected": "CREATE TEMPORARY TABLE temp_orders SELECT * FROM orders; SELECT * FROM temp_orders WHERE status = ?; DROP TEMPORARY TABLE temp_orders", + "statement_metadata": { + "size": 33, + "tables": ["temp_orders", "orders"], + "commands": ["CREATE", "SELECT", "DROP"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/select/virtual-generated-columns.json b/testdata/mysql/select/virtual-generated-columns.json new file mode 100644 index 0000000..a03d91d --- /dev/null +++ b/testdata/mysql/select/virtual-generated-columns.json @@ -0,0 +1,16 @@ +{ + "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);", + "outputs": [ + { + "expected": "CREATE TABLE orders_with_virtual ( id INT, amount DECIMAL ( ? ), total_incl_tax DECIMAL ( ? ) GENERATED ALWAYS AS ( amount * ? ) STORED )", + "statement_metadata": { + "size": 25, + "tables": ["orders_with_virtual"], + "commands": ["CREATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/bulk-update-multiple-conditions.json b/testdata/mysql/update/bulk-update-multiple-conditions.json new file mode 100644 index 0000000..2e236f7 --- /dev/null +++ b/testdata/mysql/update/bulk-update-multiple-conditions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET status = IF(amount > 1000, 'High Value', 'Regular'), order_date = IF(status = 'Pending', CURDATE(), order_date);", + "outputs": [ + { + "expected": "UPDATE orders SET status = IF ( amount > ?, ?, ? ), order_date = IF ( status = ?, CURDATE ( ), order_date )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/conditional-update-case.json b/testdata/mysql/update/conditional-update-case.json new file mode 100644 index 0000000..38bfb7a --- /dev/null +++ b/testdata/mysql/update/conditional-update-case.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET status = CASE WHEN amount > 100 THEN 'High Value' ELSE 'Regular' END;", + "outputs": [ + { + "expected": "UPDATE orders SET status = CASE WHEN amount > ? THEN ? ELSE ? END", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-basic.json b/testdata/mysql/update/update-basic.json new file mode 100644 index 0000000..480f7a7 --- /dev/null +++ b/testdata/mysql/update/update-basic.json @@ -0,0 +1,15 @@ +{ + "input": "UPDATE orders SET status = 'Completed' WHERE status = 'Pending';", + "outputs": [ + { + "expected": "UPDATE orders SET status = ? WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } \ No newline at end of file diff --git a/testdata/mysql/update/update-case-aggregate-functions.json b/testdata/mysql/update/update-case-aggregate-functions.json new file mode 100644 index 0000000..adf83e9 --- /dev/null +++ b/testdata/mysql/update/update-case-aggregate-functions.json @@ -0,0 +1,16 @@ +{ + "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;", + "outputs": [ + { + "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", + "statement_metadata": { + "size": 18, + "tables": ["orders"], + "commands": ["UPDATE", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-date-time-functions.json b/testdata/mysql/update/update-date-time-functions.json new file mode 100644 index 0000000..3155a4a --- /dev/null +++ b/testdata/mysql/update/update-date-time-functions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET order_date = CURDATE(), order_time = CURTIME() WHERE status = 'Pending';", + "outputs": [ + { + "expected": "UPDATE orders SET order_date = CURDATE ( ), order_time = CURTIME ( ) WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-encryption-functions.json b/testdata/mysql/update/update-encryption-functions.json new file mode 100644 index 0000000..06ebd69 --- /dev/null +++ b/testdata/mysql/update/update-encryption-functions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET encrypted_note = AES_ENCRYPT('Confidential', 'key') WHERE id = 1;", + "outputs": [ + { + "expected": "UPDATE orders SET encrypted_note = AES_ENCRYPT ( ? ) WHERE id = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-enum-data.json b/testdata/mysql/update/update-enum-data.json new file mode 100644 index 0000000..bd64530 --- /dev/null +++ b/testdata/mysql/update/update-enum-data.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET order_type = 'Standard' WHERE order_type = 'Express';", + "outputs": [ + { + "expected": "UPDATE orders SET order_type = ? WHERE order_type = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-json-functions.json b/testdata/mysql/update/update-json-functions.json new file mode 100644 index 0000000..d28de61 --- /dev/null +++ b/testdata/mysql/update/update-json-functions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET details = JSON_SET(details, '$.shippingMethod', 'Express') WHERE id = 1;", + "outputs": [ + { + "expected": "UPDATE orders SET details = JSON_SET ( details, ?, ? ) WHERE id = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-json-modify.json b/testdata/mysql/update/update-json-modify.json new file mode 100644 index 0000000..56cb60e --- /dev/null +++ b/testdata/mysql/update/update-json-modify.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET details = JSON_SET(details, '$.status', 'Updated') WHERE JSON_EXTRACT(details, '$.priority') = 'High';", + "outputs": [ + { + "expected": "UPDATE orders SET details = JSON_SET ( details, ?, ? ) WHERE JSON_EXTRACT ( details, ? ) = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-lock-tables.json b/testdata/mysql/update/update-lock-tables.json new file mode 100644 index 0000000..1aa721b --- /dev/null +++ b/testdata/mysql/update/update-lock-tables.json @@ -0,0 +1,16 @@ +{ + "input": "LOCK TABLES orders WRITE; UPDATE orders SET status = 'Cancelled' WHERE status = 'Pending'; UNLOCK TABLES;", + "outputs": [ + { + "expected": "LOCK TABLES orders WRITE; UPDATE orders SET status = ? WHERE status = ?; UNLOCK TABLES", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-math-functions.json b/testdata/mysql/update/update-math-functions.json new file mode 100644 index 0000000..c5fe1b5 --- /dev/null +++ b/testdata/mysql/update/update-math-functions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET amount = amount * 1.1 WHERE status = 'Completed';", + "outputs": [ + { + "expected": "UPDATE orders SET amount = amount * ? WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-optimizing-conditions.json b/testdata/mysql/update/update-optimizing-conditions.json new file mode 100644 index 0000000..56f3924 --- /dev/null +++ b/testdata/mysql/update/update-optimizing-conditions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET status = 'Archived' WHERE status = 'Completed' AND order_date < DATE_SUB(NOW(), INTERVAL 1 YEAR);", + "outputs": [ + { + "expected": "UPDATE orders SET status = ? WHERE status = ? AND order_date < DATE_SUB ( NOW ( ), INTERVAL ? YEAR )", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-order-by-limit.json b/testdata/mysql/update/update-order-by-limit.json new file mode 100644 index 0000000..28f2fa3 --- /dev/null +++ b/testdata/mysql/update/update-order-by-limit.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET status = 'Cancelled' WHERE status = 'Pending' ORDER BY order_date ASC LIMIT 10;", + "outputs": [ + { + "expected": "UPDATE orders SET status = ? WHERE status = ? ORDER BY order_date ASC LIMIT ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-regular-expressions.json b/testdata/mysql/update/update-regular-expressions.json new file mode 100644 index 0000000..2863fb2 --- /dev/null +++ b/testdata/mysql/update/update-regular-expressions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET status = 'Query' WHERE status REGEXP '^Q.*';", + "outputs": [ + { + "expected": "UPDATE orders SET status = ? WHERE status REGEXP ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-spatial-data.json b/testdata/mysql/update/update-spatial-data.json new file mode 100644 index 0000000..e93dd7b --- /dev/null +++ b/testdata/mysql/update/update-spatial-data.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET location = ST_GeomFromText('POINT(1 1)') WHERE id = 1;", + "outputs": [ + { + "expected": "UPDATE orders SET location = ST_GeomFromText ( ? ) WHERE id = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-string-functions.json b/testdata/mysql/update/update-string-functions.json new file mode 100644 index 0000000..6a21969 --- /dev/null +++ b/testdata/mysql/update/update-string-functions.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET status = CONCAT(status, ' - Updated') WHERE id = 1;", + "outputs": [ + { + "expected": "UPDATE orders SET status = CONCAT ( status, ? ) WHERE id = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-user-defined-variables.json b/testdata/mysql/update/update-user-defined-variables.json new file mode 100644 index 0000000..b204f0c --- /dev/null +++ b/testdata/mysql/update/update-user-defined-variables.json @@ -0,0 +1,16 @@ +{ + "input": "SET @new_status = 'Delayed'; UPDATE orders SET status = @new_status WHERE status = 'Pending';", + "outputs": [ + { + "expected": "SET @new_status = ?; UPDATE orders SET status = @new_status WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-using-variables.json b/testdata/mysql/update/update-using-variables.json new file mode 100644 index 0000000..e79e587 --- /dev/null +++ b/testdata/mysql/update/update-using-variables.json @@ -0,0 +1,16 @@ +{ + "input": "SET @new_status = 'Shipped'; UPDATE orders SET status = @new_status WHERE status = 'Processing';", + "outputs": [ + { + "expected": "SET @new_status = ?; UPDATE orders SET status = @new_status WHERE status = ?", + "statement_metadata": { + "size": 12, + "tables": ["orders"], + "commands": ["UPDATE"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-with-join.json b/testdata/mysql/update/update-with-join.json new file mode 100644 index 0000000..81da8f1 --- /dev/null +++ b/testdata/mysql/update/update-with-join.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders o JOIN customers c ON o.customer_id = c.id SET o.status = 'Processing' WHERE c.region = 'East';", + "outputs": [ + { + "expected": "UPDATE orders o JOIN customers c ON o.customer_id = c.id SET o.status = ? WHERE c.region = ?", + "statement_metadata": { + "size": 25, + "tables": ["orders", "customers"], + "commands": ["UPDATE", "JOIN"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file diff --git a/testdata/mysql/update/update-with-subquery.json b/testdata/mysql/update/update-with-subquery.json new file mode 100644 index 0000000..9cdd870 --- /dev/null +++ b/testdata/mysql/update/update-with-subquery.json @@ -0,0 +1,16 @@ +{ + "input": "UPDATE orders SET status = 'Archived' WHERE id IN (SELECT id FROM orders WHERE order_date < '2020-01-01');", + "outputs": [ + { + "expected": "UPDATE orders SET status = ? WHERE id IN ( SELECT id FROM orders WHERE order_date < ? )", + "statement_metadata": { + "size": 18, + "tables": ["orders"], + "commands": ["UPDATE", "SELECT"], + "comments": [], + "procedures": [] + } + } + ] + } + \ No newline at end of file