From 371377d7496c29ae8dd814dff1f326a2a516e53d Mon Sep 17 00:00:00 2001 From: Gert de Pagter Date: Sat, 12 Aug 2023 09:42:56 +0200 Subject: [PATCH 1/2] Allow the COLLATE keyword in WHERE clauses --- src/Components/Condition.php | 1 + tests/Parser/SelectStatementTest.php | 1 + tests/data/parser/parseSelectWhereCollate.in | 1 + tests/data/parser/parseSelectWhereCollate.out | 368 ++++++++++++++++++ 4 files changed, 371 insertions(+) create mode 100644 tests/data/parser/parseSelectWhereCollate.in create mode 100644 tests/data/parser/parseSelectWhereCollate.out diff --git a/src/Components/Condition.php b/src/Components/Condition.php index 78c005d60..2948fcdd5 100644 --- a/src/Components/Condition.php +++ b/src/Components/Condition.php @@ -43,6 +43,7 @@ class Condition extends Component 'ALL' => 1, 'AND' => 1, 'BETWEEN' => 1, + 'COLLATE' => 1, 'EXISTS' => 1, 'IF' => 1, 'IN' => 1, diff --git a/tests/Parser/SelectStatementTest.php b/tests/Parser/SelectStatementTest.php index c43fa0d36..f8e290ef9 100644 --- a/tests/Parser/SelectStatementTest.php +++ b/tests/Parser/SelectStatementTest.php @@ -90,6 +90,7 @@ public function selectProvider(): array ['parser/parseSelectUnion'], ['parser/parseSelectUnion2'], ['parser/parseSelectWhere'], + ['parser/parseSelectWhereCollate'], ['parser/parseSelectIndexHint1'], ['parser/parseSelectIndexHint2'], ['parser/parseSelectOrderByIsNull'], diff --git a/tests/data/parser/parseSelectWhereCollate.in b/tests/data/parser/parseSelectWhereCollate.in new file mode 100644 index 000000000..a1c97b9a7 --- /dev/null +++ b/tests/data/parser/parseSelectWhereCollate.in @@ -0,0 +1 @@ +SELECT 1 FROM my_table WHERE first_col = 'foo' AND second_col COLLATE utf8_bin = 'bar'; \ No newline at end of file diff --git a/tests/data/parser/parseSelectWhereCollate.out b/tests/data/parser/parseSelectWhereCollate.out new file mode 100644 index 000000000..7e3fd10ba --- /dev/null +++ b/tests/data/parser/parseSelectWhereCollate.out @@ -0,0 +1,368 @@ +{ + "query": "SELECT 1 FROM my_table WHERE first_col = 'foo' AND second_col COLLATE utf8_bin = 'bar';", + "lexer": { + "@type": "PhpMyAdmin\\SqlParser\\Lexer", + "str": "SELECT 1 FROM my_table WHERE first_col = 'foo' AND second_col COLLATE utf8_bin = 'bar';", + "len": 96, + "last": 96, + "list": { + "@type": "PhpMyAdmin\\SqlParser\\TokensList", + "tokens": [ + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "SELECT", + "value": "SELECT", + "keyword": "SELECT", + "type": 1, + "flags": 3, + "position": 0 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 6 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "1", + "value": 1, + "keyword": null, + "type": 6, + "flags": 0, + "position": 8 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 9 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "FROM", + "value": "FROM", + "keyword": "FROM", + "type": 1, + "flags": 3, + "position": 10 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 14 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "my_table", + "value": "my_table", + "keyword": null, + "type": 0, + "flags": 0, + "position": 17 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 25 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "WHERE", + "value": "WHERE", + "keyword": "WHERE", + "type": 1, + "flags": 3, + "position": 26 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 31 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "first_col", + "value": "first_col", + "keyword": null, + "type": 0, + "flags": 0, + "position": 34 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 43 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "=", + "value": "=", + "keyword": null, + "type": 2, + "flags": 2, + "position": 44 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 45 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "'foo'", + "value": "foo", + "keyword": null, + "type": 7, + "flags": 1, + "position": 46 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 51 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "AND", + "value": "AND", + "keyword": "AND", + "type": 1, + "flags": 3, + "position": 52 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 55 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "second_col", + "value": "second_col", + "keyword": null, + "type": 0, + "flags": 0, + "position": 60 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 70 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "COLLATE", + "value": "COLLATE", + "keyword": "COLLATE", + "type": 1, + "flags": 3, + "position": 71 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 78 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "utf8_bin", + "value": "utf8_bin", + "keyword": null, + "type": 0, + "flags": 0, + "position": 79 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 87 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "=", + "value": "=", + "keyword": null, + "type": 2, + "flags": 2, + "position": 88 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": " ", + "value": " ", + "keyword": null, + "type": 3, + "flags": 0, + "position": 89 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": "'bar'", + "value": "bar", + "keyword": null, + "type": 7, + "flags": 1, + "position": 90 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": ";", + "value": ";", + "keyword": null, + "type": 9, + "flags": 0, + "position": 95 + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Token", + "token": null, + "value": null, + "keyword": null, + "type": 9, + "flags": 0, + "position": null + } + ], + "count": 29, + "idx": 29 + }, + "delimiter": ";", + "delimiterLen": 1, + "strict": false, + "errors": [] + }, + "parser": { + "@type": "PhpMyAdmin\\SqlParser\\Parser", + "list": { + "@type": "@1" + }, + "statements": [ + { + "@type": "PhpMyAdmin\\SqlParser\\Statements\\SelectStatement", + "expr": [ + { + "@type": "PhpMyAdmin\\SqlParser\\Components\\Expression", + "database": null, + "table": null, + "column": null, + "expr": "1", + "alias": null, + "function": null, + "subquery": null + } + ], + "from": [ + { + "@type": "PhpMyAdmin\\SqlParser\\Components\\Expression", + "database": null, + "table": "my_table", + "column": null, + "expr": "my_table", + "alias": null, + "function": null, + "subquery": null + } + ], + "index_hints": null, + "partition": null, + "where": [ + { + "@type": "PhpMyAdmin\\SqlParser\\Components\\Condition", + "identifiers": [ + "first_col", + "foo" + ], + "isOperator": false, + "expr": "first_col = 'foo'" + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Components\\Condition", + "identifiers": [], + "isOperator": true, + "expr": "AND" + }, + { + "@type": "PhpMyAdmin\\SqlParser\\Components\\Condition", + "identifiers": [ + "second_col", + "utf8_bin", + "bar" + ], + "isOperator": false, + "expr": "second_col COLLATE utf8_bin = 'bar'" + } + ], + "group": null, + "group_options": null, + "having": null, + "order": null, + "limit": null, + "procedure": null, + "into": null, + "join": null, + "union": [], + "end_options": null, + "options": { + "@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray", + "options": [] + }, + "first": 0, + "last": 26 + } + ], + "brackets": 0, + "strict": false, + "errors": [] + }, + "errors": { + "lexer": [], + "parser": [] + } +} \ No newline at end of file From e93d9457e3a279b98c75a6a8d9feb92bb923501c Mon Sep 17 00:00:00 2001 From: William Desportes Date: Sat, 12 Aug 2023 23:31:37 +0200 Subject: [PATCH 2/2] Add a CHANGELOG entry for #491 Pull-request: #494 Signed-off-by: William Desportes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index febce0ed2..42636d70f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Fix `ALTER TABLE … MODIFY … ENUM('')` is being wrongly parsed (#234) - Fix `ALTER TABLE … MODIFY … ENUM('')` is being wrongly parsed (#478) - Fix MariaDB window function with alias gives bad linting errors (#283) +- Fix unrecognized keyword `COLLATE` in `WHERE` clauses (#491) ## [5.8.0] - 2023-06-05