SQL Expressions: Allow more MySQL AST node-types (#102973)

* SQL Expressions: Add Null-literal node

* Retain some order in the code - put NullVal with BoolVal

* Add support for `IN` keyword

* Add GROUP_CONCAT keyword

* Add COLLATE keyword

From Claude:

The test case demonstrates a simple use of COLLATE with a string
literal, but in real MySQL queries, COLLATE is often used in more
complex scenarios like:

1. String comparisons:
   `SELECT * FROM table WHERE name COLLATE utf8mb4_bin = 'John'`
2. Sorting:
   `SELECT * FROM table ORDER BY name COLLATE utf8mb4_unicode_ci`
3. JOINs:
   `SELECT * FROM table1 JOIN table2 ON table1.name COLLATE utf8mb4_bin = table2.name`

The COLLATE clause is particularly useful when you need case-sensitive
comparisons (utf8mb4_bin) or specific language-aware sorting rules.
This commit is contained in:
Sam Jewell
2025-03-27 11:32:48 +00:00
committed by GitHub
parent e1e1d3fd9f
commit c9e929e2e6
2 changed files with 33 additions and 1 deletions

View File

@ -42,6 +42,26 @@ func TestAllowQuery(t *testing.T) {
q: `SELECT * FROM a_table WHERE a_column IS NOT NULL`,
err: nil,
},
{
name: "null literal",
q: `SELECT 1 as id, NULL as null_col`,
err: nil,
},
{
name: "val tuple in read query",
q: `SELECT 1 WHERE 1 IN (1, 2, 3)`,
err: nil,
},
{
name: "group concat in read query",
q: `SELECT 1 as id, GROUP_CONCAT('will_', 'concatenate') as concat_val`,
err: nil,
},
{
name: "collate in read query",
q: `SELECT 'some text' COLLATE utf8mb4_bin`,
err: nil,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {