Skip to content

Commit 3da8aed

Browse files
fix(mysql): support null safe equal operator (<=>) (spaceship operator)
1 parent e47b10e commit 3da8aed

3 files changed

Lines changed: 20 additions & 6 deletions

File tree

pegjs/mariadb.pegjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,7 +2696,7 @@ interval_expr
26962696
* | +, - | identity, negation |
26972697
* | *, / | multiplication, division |
26982698
* | +, - | addition, subtraction, concatenation |
2699-
* | =, <, >, <=, >=, <>, !=, IS, LIKE, BETWEEN, IN | comparion |
2699+
* | <=>, =, <, >, <=, >=, <>, !=, IS, LIKE, BETWEEN, IN | comparion |
27002700
* | !, NOT | logical negation |
27012701
* | AND | conjunction |
27022702
* | OR | inclusion |
@@ -2810,7 +2810,7 @@ arithmetic_op_right
28102810
}
28112811

28122812
arithmetic_comparison_operator
2813-
= ">=" / ">" / "<=" / "<>" / "<" / "=" / "!="
2813+
= "<=>" / ">=" / ">" / "<=" / "<>" / "<" / "=" / "!="
28142814

28152815
is_op_right
28162816
= KW_IS __ right:additive_expr {

pegjs/mysql.pegjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3073,7 +3073,7 @@ arithmetic_op_right
30733073
}
30743074

30753075
arithmetic_comparison_operator
3076-
= ">=" / ">" / "<=" / "<>" / "<" / "=" / "!="
3076+
= "<=>" / ">=" / ">" / "<=" / "<>" / "<" / "=" / "!="
30773077

30783078
is_op_right
30793079
= KW_IS __ right:additive_expr {

test/mysql-mariadb.spec.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,20 @@ describe('mysql', () => {
13541354
"SELECT * FROM `T1`"
13551355
]
13561356
},
1357+
{
1358+
title: 'null safe equal operator',
1359+
sql: [
1360+
"SELECT * FROM T1 WHERE a <=> b",
1361+
"SELECT * FROM `T1` WHERE `a` <=> `b`"
1362+
]
1363+
},
1364+
{
1365+
title: 'null safe equal operator with null',
1366+
sql: [
1367+
"SELECT * FROM T1 WHERE a <=> NULL",
1368+
"SELECT * FROM `T1` WHERE `a` <=> NULL"
1369+
]
1370+
},
13571371
]
13581372
SQL_LIST.forEach(sqlInfo => {
13591373
const { title, sql } = sqlInfo
@@ -1367,10 +1381,10 @@ describe('mysql', () => {
13671381

13681382
it('should throw error when args is not right', () => {
13691383
let sql = `select convert(json_unquote(json_extract('{"thing": "252"}', "$.thing")));`
1370-
expect(parser.astify.bind(parser, sql)).to.throw('Expected "!=", "#", "#-", "#>", "#>>", "%", "&", "&&", "*", "+", ",", "-", "--", "->", "->>", "/", "/*", "<", "<<", "<=", "<>", "<@", "=", ">", ">=", ">>", "?", "?&", "?|", "@>", "AND", "BETWEEN", "COLLATE", "IN", "IS", "LIKE", "NOT", "ON", "OR", "OVER", "REGEXP", "RLIKE", "USING", "XOR", "^", "div", "mod", "|", "||", or [ \\t\\n\\r] but ")" found.')
1371-
expect(parser.astify.bind(parser, 'select convert("");')).to.throw('Expected "!=", "#", "#-", "#>", "#>>", "%", "&", "&&", "*", "+", ",", "-", "--", "->", "->>", "/", "/*", "<", "<<", "<=", "<>", "<@", "=", ">", ">=", ">>", "?", "?&", "?|", "@>", "AND", "BETWEEN", "COLLATE", "IN", "IS", "LIKE", "NOT", "OR", "REGEXP", "RLIKE", "USING", "XOR", "^", "div", "mod", "|", "||", or [ \\t\\n\\r] but ")" found.')
1384+
expect(parser.astify.bind(parser, sql)).to.throw('Expected "!=", "#", "#-", "#>", "#>>", "%", "&", "&&", "*", "+", ",", "-", "--", "->", "->>", "/", "/*", "<", "<<", "<=", "<=>", "<>", "<@", "=", ">", ">=", ">>", "?", "?&", "?|", "@>", "AND", "BETWEEN", "COLLATE", "IN", "IS", "LIKE", "NOT", "ON", "OR", "OVER", "REGEXP", "RLIKE", "USING", "XOR", "^", "div", "mod", "|", "||", or [ \\t\\n\\r] but ")" found.')
1385+
expect(parser.astify.bind(parser, 'select convert("");')).to.throw('Expected "!=", "#", "#-", "#>", "#>>", "%", "&", "&&", "*", "+", ",", "-", "--", "->", "->>", "/", "/*", "<", "<<", "<=", "<=>", "<>", "<@", "=", ">", ">=", ">>", "?", "?&", "?|", "@>", "AND", "BETWEEN", "COLLATE", "IN", "IS", "LIKE", "NOT", "OR", "REGEXP", "RLIKE", "USING", "XOR", "^", "div", "mod", "|", "||", or [ \\t\\n\\r] but ")" found.')
13721386
sql = 'SELECT AVG(Quantity,age) FROM table1;'
1373-
expect(parser.astify.bind(parser, sql)).to.throw('Expected "!=", "#", "#-", "#>", "#>>", "%", "&", "&&", "(", ")", "*", "+", "-", "--", "->", "->>", ".", "/", "/*", "<", "<<", "<=", "<>", "<@", "=", ">", ">=", ">>", "?", "?&", "?|", "@>", "AND", "BETWEEN", "COLLATE", "IN", "IS", "LIKE", "NOT", "OR", "REGEXP", "RLIKE", "XOR", "^", "div", "mod", "|", "||", [ \\t\\n\\r], [A-Za-z0-9_$\\x80-], or [A-Za-z0-9_:一-龥À-ſ] but "," found')
1387+
expect(parser.astify.bind(parser, sql)).to.throw('Expected "!=", "#", "#-", "#>", "#>>", "%", "&", "&&", "(", ")", "*", "+", "-", "--", "->", "->>", ".", "/", "/*", "<", "<<", "<=", "<=>", "<>", "<@", "=", ">", ">=", ">>", "?", "?&", "?|", "@>", "AND", "BETWEEN", "COLLATE", "IN", "IS", "LIKE", "NOT", "OR", "REGEXP", "RLIKE", "XOR", "^", "div", "mod", "|", "||", [ \\t\\n\\r], [A-Za-z0-9_$\\x80-], or [A-Za-z0-9_:一-龥À-ſ] but "," found')
13741388
})
13751389

13761390
it('should join multiple table with comma', () => {

0 commit comments

Comments
 (0)