Skip to content

Commit 0a2f37a

Browse files
committed
fix: fix case when expr in db
1 parent aac9684 commit 0a2f37a

File tree

8 files changed

+138
-19
lines changed

8 files changed

+138
-19
lines changed

pegjs/athena.pegjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,9 +1879,16 @@ unary_expr_or_primary
18791879
unary_operator
18801880
= '!' / '-' / '+' / '~'
18811881

1882+
primary_array_index
1883+
= e:primary __ a:array_index_list? {
1884+
// => primary & { array_index: array_index }
1885+
if (a) e.array_index = a
1886+
return e
1887+
}
1888+
18821889
jsonb_expr
1883-
= head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / SINGLE_ARROW / '@>' / '<@') __ primary)* {
1884-
// => primary | binary_expr
1890+
= head:primary_array_index __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / SINGLE_ARROW / '@>' / '<@') __ primary_array_index)* {
1891+
// => primary_array_index | binary_expr
18851892
if (!tail || tail.length === 0) return head
18861893
return createBinaryExprChain(head, tail)
18871894
}

pegjs/flinksql.pegjs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,28 @@ column_clause
17251725
return createList(head, tail);
17261726
}
17271727

1728+
array_index
1729+
= LBRAKE __ n:(literal_numeric / literal_string) __ RBRAKE {
1730+
// => { brackets: boolean, number: number }
1731+
return {
1732+
brackets: true,
1733+
index: n
1734+
}
1735+
}
1736+
1737+
array_index_list
1738+
= head:array_index tail:(__ array_index)* {
1739+
// => array_index[]
1740+
return createList(head, tail, 1)
1741+
}
1742+
1743+
expr_item
1744+
= e:binary_column_expr __ a:array_index_list? {
1745+
// => binary_column_expr & { array_index: array_index }
1746+
if (a) e.array_index = a
1747+
return e
1748+
}
1749+
17281750
column_list_item
17291751
= e:binary_column_expr s:KW_DOUBLE_COLON t:data_type {
17301752
// => { type: 'cast'; expr: expr; symbol: '::'; target: data_type; as?: null; }
@@ -2336,7 +2358,7 @@ case_when_then_list
23362358
}
23372359

23382360
case_when_then
2339-
= KW_WHEN __ condition:or_and_where_expr __ KW_THEN __ result:expr {
2361+
= KW_WHEN __ condition:or_and_where_expr __ KW_THEN __ result:expr_item {
23402362
// => { type: 'when'; cond: expr; result: expr; }
23412363
return {
23422364
type: 'when',
@@ -2633,9 +2655,16 @@ unary_expr_or_primary
26332655
unary_operator
26342656
= '!' / '-' / '+' / '~'
26352657

2658+
primary_array_index
2659+
= e:primary __ a:array_index_list? {
2660+
// => primary & { array_index: array_index }
2661+
if (a) e.array_index = a
2662+
return e
2663+
}
2664+
26362665
jsonb_expr
2637-
= head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary)* {
2638-
// => primary | binary_expr
2666+
= head:primary_array_index __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary_array_index)* {
2667+
// => primary_array_index | binary_expr
26392668
if (!tail || tail.length === 0) return head
26402669
return createBinaryExprChain(head, tail)
26412670
}

pegjs/noql.pegjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,9 +3939,16 @@ unary_expr_or_primary
39393939
unary_operator
39403940
= '!' / '-' / '+' / '~'
39413941

3942+
primary_array_index
3943+
= e:primary __ a:array_index_list? {
3944+
// => primary & { array_index: array_index }
3945+
if (a) e.array_index = a
3946+
return e
3947+
}
3948+
39423949
jsonb_expr
3943-
= head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary)* {
3944-
// => primary | binary_expr
3950+
= head:primary_array_index __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary_array_index)* {
3951+
// => primary_array_index | binary_expr
39453952
if (!tail || tail.length === 0) return head
39463953
return createBinaryExprChain(head, tail)
39473954
}

pegjs/postgresql.pegjs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4343,8 +4343,8 @@ case_when_then_list
43434343
}
43444344

43454345
case_when_then
4346-
= KW_WHEN __ condition:or_and_where_expr __ KW_THEN __ result:expr {
4347-
// => { type: 'when'; cond: or_and_where_expr; result: expr; }
4346+
= KW_WHEN __ condition:or_and_expr __ KW_THEN __ result:expr_item {
4347+
// => { type: 'when'; cond: or_and_expr; result: expr_item; }
43484348
return {
43494349
type: 'when',
43504350
cond: condition,
@@ -4635,9 +4635,16 @@ unary_expr_or_primary
46354635
unary_operator
46364636
= '!' / '-' / '+' / '~'
46374637

4638+
primary_array_index
4639+
= e:primary __ a:array_index_list? {
4640+
// => primary & { array_index: array_index }
4641+
if (a) e.array_index = a
4642+
return e
4643+
}
4644+
46384645
jsonb_expr
4639-
= head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary)* {
4640-
// => primary | binary_expr
4646+
= head:primary_array_index __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary_array_index)* {
4647+
// => primary_array_index | binary_expr
46414648
if (!tail || tail.length === 0) return head
46424649
return createBinaryExprChain(head, tail)
46434650
}
@@ -5046,6 +5053,32 @@ aggr_array_agg
50465053
star_expr
50475054
= "*" { /* => { type: 'star'; value: '*' } */ return { type: 'star', value: '*' }; }
50485055

5056+
position_func_args
5057+
= s:literal_string __ KW_IN __ e:expr start:(__ KW_FROM __ literal_numeric)? {
5058+
// => expr_list
5059+
let value = [s, { type: 'origin', value: 'in' }, e]
5060+
if (start) {
5061+
value.push({ type: 'origin', value: 'from' })
5062+
value.push(start[3])
5063+
}
5064+
return {
5065+
type: 'expr_list',
5066+
value,
5067+
}
5068+
}
5069+
5070+
position_func_clause
5071+
= 'POSITION'i __ LPAREN __ args:position_func_args __ RPAREN {
5072+
// => { type: 'function'; name: string; args: expr_list; }
5073+
return {
5074+
type: 'function',
5075+
name: { name: [{ type: 'origin', value: 'position' }]},
5076+
separator: ' ',
5077+
args,
5078+
...getLocationObject(),
5079+
};
5080+
}
5081+
50495082
trim_position
50505083
= 'BOTH'i / 'LEADING'i / 'TRAILING'i
50515084

@@ -5165,7 +5198,7 @@ make_interval_func_clause
51655198
}
51665199

51675200
func_call
5168-
= trim_func_clause / tablefunc_clause / substring_funcs_clause / make_interval_func_clause
5201+
= position_func_clause / trim_func_clause / tablefunc_clause / substring_funcs_clause / make_interval_func_clause
51695202
/ name:'now'i __ LPAREN __ l:expr_list? __ RPAREN __ 'at'i __ KW_TIME __ 'zone'i __ z:literal_string {
51705203
// => { type: 'function'; name: proc_func_name; args: expr_list; suffix: literal_string; }
51715204
z.prefix = 'at time zone'

pegjs/redshift.pegjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3970,9 +3970,16 @@ unary_expr_or_primary
39703970
unary_operator
39713971
= '!' / '-' / '+' / '~'
39723972

3973+
primary_array_index
3974+
= e:primary __ a:array_index_list? {
3975+
// => primary & { array_index: array_index }
3976+
if (a) e.array_index = a
3977+
return e
3978+
}
3979+
39733980
jsonb_expr
3974-
= head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary)* {
3975-
// => primary | binary_expr
3981+
= head:primary_array_index __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary_array_index)* {
3982+
// => primary_array_index | binary_expr
39763983
if (!tail || tail.length === 0) return head
39773984
return createBinaryExprChain(head, tail)
39783985
}

pegjs/snowflake.pegjs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,7 +3116,7 @@ case_when_then_list
31163116
}
31173117

31183118
case_when_then
3119-
= KW_WHEN __ condition:or_and_where_expr __ KW_THEN __ result:or_and_where_expr {
3119+
= KW_WHEN __ condition:or_and_where_expr __ KW_THEN __ result:expr_item {
31203120
// => { type: 'when'; cond: binary_expr; result: expr; }
31213121
return {
31223122
type: 'when',
@@ -3408,9 +3408,16 @@ unary_expr_or_primary
34083408
unary_operator
34093409
= '!' / '-' / '+' / '~'
34103410

3411+
primary_array_index
3412+
= e:primary __ a:array_index_list? {
3413+
// => primary & { array_index: array_index }
3414+
if (a) e.array_index = a
3415+
return e
3416+
}
3417+
34113418
jsonb_expr
3412-
= head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary)* {
3413-
// => primary | binary_expr
3419+
= head:primary_array_index __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary_array_index)* {
3420+
// => primary_array_index | binary_expr
34143421
if (!tail || tail.length === 0) return head
34153422
return createBinaryExprChain(head, tail)
34163423
}
@@ -3890,6 +3897,7 @@ json_visit_list
38903897
value: createList(head, tail, 1)
38913898
}
38923899
}
3900+
38933901
position_func_args
38943902
= s:literal_string __ KW_IN __ e:expr start:(__ KW_FROM __ literal_numeric)? {
38953903
// => expr_list

pegjs/trino.pegjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,9 +3376,16 @@ unary_expr_or_primary
33763376
unary_operator
33773377
= '!' / '-' / '+' / '~'
33783378

3379+
primary_array_index
3380+
= e:primary __ a:array_index_list? {
3381+
// => primary & { array_index: array_index }
3382+
if (a) e.array_index = a
3383+
return e
3384+
}
3385+
33793386
jsonb_expr
3380-
= head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary)* {
3381-
// => primary | binary_expr
3387+
= head:primary_array_index __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / DOUBLE_ARROW / SINGLE_ARROW / '@>' / '<@') __ primary_array_index)* {
3388+
// => primary_array_index | binary_expr
33823389
if (!tail || tail.length === 0) return head
33833390
return createBinaryExprChain(head, tail)
33843391
}

test/postgres.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,27 @@ describe('Postgres', () => {
18331833
'ALTER SEQUENCE "serial" SET SCHEMA postgres'
18341834
]
18351835
},
1836+
{
1837+
title: 'case when then array index',
1838+
sql: [
1839+
"SELECT CASE WHEN POSITION(' - ' in col) > 0 THEN SPLIT(col, ' - ')[0] ELSE col END FROM DUAL",
1840+
"SELECT CASE WHEN POSITION(' - ' IN col) > 0 THEN SPLIT(col, ' - ')[0] ELSE col END FROM DUAL"
1841+
]
1842+
},
1843+
{
1844+
title: 'case when then else',
1845+
sql: [
1846+
"SELECT CASE WHEN a[0] = '1' THEN '1' ELSE '2' END FROM DUAL",
1847+
"SELECT CASE WHEN a[0] = '1' THEN '1' ELSE '2' END FROM DUAL"
1848+
]
1849+
},
1850+
{
1851+
title: 'case when expr with array index',
1852+
sql: [
1853+
"SELECT CASE WHEN SPLIT('a - b', ' - ')[0] = 'a' THEN '1' ELSE '2' END FROM DUAL",
1854+
"SELECT CASE WHEN SPLIT('a - b', ' - ')[0] = 'a' THEN '1' ELSE '2' END FROM DUAL"
1855+
]
1856+
},
18361857
]
18371858
function neatlyNestTestedSQL(sqlList){
18381859
sqlList.forEach(sqlInfo => {

0 commit comments

Comments
 (0)