Skip to content

Commit d9d46ed

Browse files
Merge pull request #1822 from cchepelov/fix/regexp-on-snowflake
fix(snowflake): support the REGEXP / NOT REGEXP operator
2 parents 34c33ac + f3875ba commit d9d46ed

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

pegjs/snowflake.pegjs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,6 +3040,7 @@ logic_operator_expr
30403040
| 'BETWEEN' | 'NOT BETWEEN'
30413041
| 'IS' | 'IS NOT'
30423042
| 'LIKE'
3043+
| 'REGEXP' | 'NOT REGEXP'
30433044
| '@>' | '<@' | OPERATOR_CONCATENATION | DOUBLE_WELL_ARROW | WELL_ARROW | '?' | '?|' | '?&' | '#-'
30443045
export interface binary_expr {
30453046
type: 'binary_expr',
@@ -3218,13 +3219,8 @@ like_op
32183219
}
32193220

32203221
regex_op
3221-
= "!~*" / "~*" / "~" / "!~"
3222-
3223-
regex_op_right
3224-
= op:regex_op __ right:(literal / comparison_expr) {
3225-
// => { op: regex_op; right: literal | comparison_expr}
3226-
return { op: op, right: right };
3227-
}
3222+
= nk:(KW_NOT __ KW_REGEXP) { /* => 'REGEXP' */ return nk[0] + ' ' + nk[2]; }
3223+
/ KW_REGEXP
32283224

32293225
escape_op
32303226
= kw:'ESCAPE'i __ c:literal_string {
@@ -3266,6 +3262,14 @@ jsonb_op_right
32663262
}
32673263
}
32683264

3265+
3266+
regex_op_right
3267+
= op:regex_op __ right:(literal / comparison_expr) __ es:escape_op? {
3268+
// => { op: regex_op; right: (literal | comparison_expr) & { escape?: escape_op }; }
3269+
if (es) right.escape = es
3270+
return { op: op, right: right };
3271+
}
3272+
32693273
additive_expr
32703274
= head:multiplicative_expr
32713275
tail:(__ additive_operator __ multiplicative_expr)* {
@@ -4209,6 +4213,7 @@ KW_IS = "IS"i !ident_start { return 'IS'; }
42094213
KW_LIKE = "LIKE"i !ident_start { return 'LIKE'; }
42104214
KW_ILIKE = "ILIKE"i !ident_start { return 'ILIKE'; }
42114215
KW_EXISTS = "EXISTS"i !ident_start { /* => 'EXISTS' */ return 'EXISTS'; }
4216+
KW_REGEXP = "REGEXP"i !ident_start { return 'REGEXP'; }
42124217

42134218
KW_NOT = "NOT"i !ident_start { return 'NOT'; }
42144219
KW_AND = "AND"i !ident_start { return 'AND'; }

test/snowflake.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ describe('snowflake', () => {
119119
`SELECT "listing_id", "listing_name", "room_type", "host_id", REPLACE("price_str", '$')::NUMBER(10, 2) AS "price", "created_at", "updated_at" FROM "src_listings"`
120120
]
121121
},
122+
{
123+
title: 'regexp operator',
124+
sql: [
125+
`SELECT v
126+
FROM strings
127+
WHERE v REGEXP 'San* [fF].*'
128+
129+
UNION ALL
130+
131+
SELECT v
132+
FROM strings
133+
WHERE v NOT REGEXP 'San\\w+?o'`,
134+
'SELECT "v" FROM "strings" WHERE "v" REGEXP \'San* [fF].*\' UNION ALL SELECT "v" FROM "strings" WHERE "v" NOT REGEXP \'San\\w+?o\''
135+
]
136+
}
122137
]
123138
SQL_LIST.forEach(sqlInfo => {
124139
const { title, sql } = sqlInfo

0 commit comments

Comments
 (0)