Fix IN clause with function calls

This commit is contained in:
Pijus Kamandulis 2025-02-20 18:45:20 +02:00
parent d27c633e1d
commit 851b3ca3a8
4 changed files with 401 additions and 191 deletions

View File

@ -112,6 +112,38 @@ func Test_Parse(t *testing.T) {
) )
}) })
t.Run("Should parse IN function with function call", func(t *testing.T) {
testQueryParse(
t,
`Select c.id FROM c WHERE (ToString(c.id) IN ("123", "456"))`,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
testutils.SelectItem_Path("c", "id"),
},
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
Filters: parsers.SelectItem{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallIn,
Arguments: []interface{}{
parsers.SelectItem{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallToString,
Arguments: []interface{}{
testutils.SelectItem_Path("c", "id"),
},
},
},
testutils.SelectItem_Constant_String("123"),
testutils.SelectItem_Constant_String("456"),
},
},
},
},
)
})
t.Run("Should parse IN selector", func(t *testing.T) { t.Run("Should parse IN selector", func(t *testing.T) {
testQueryParse( testQueryParse(
t, t,

View File

@ -7203,9 +7203,12 @@ var g = &grammar{
{ {
name: "InFunction", name: "InFunction",
pos: position{line: 719, col: 1, offset: 27240}, pos: position{line: 719, col: 1, offset: 27240},
expr: &actionExpr{ expr: &choiceExpr{
pos: position{line: 719, col: 15, offset: 27254}, pos: position{line: 719, col: 15, offset: 27254},
run: (*parser).callonInFunction1, alternatives: []any{
&actionExpr{
pos: position{line: 719, col: 15, offset: 27254},
run: (*parser).callonInFunction2,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 719, col: 15, offset: 27254}, pos: position{line: 719, col: 15, offset: 27254},
exprs: []any{ exprs: []any{
@ -7254,7 +7257,7 @@ var g = &grammar{
pos: position{line: 719, col: 72, offset: 27311}, pos: position{line: 719, col: 72, offset: 27311},
expr: &actionExpr{ expr: &actionExpr{
pos: position{line: 719, col: 73, offset: 27312}, pos: position{line: 719, col: 73, offset: 27312},
run: (*parser).callonInFunction14, run: (*parser).callonInFunction15,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 719, col: 73, offset: 27312}, pos: position{line: 719, col: 73, offset: 27312},
exprs: []any{ exprs: []any{
@ -7298,46 +7301,163 @@ var g = &grammar{
}, },
}, },
}, },
}, &actionExpr{
{ pos: position{line: 721, col: 5, offset: 27484},
name: "AvgAggregateExpression", run: (*parser).callonInFunction24,
pos: position{line: 723, col: 1, offset: 27483},
expr: &actionExpr{
pos: position{line: 723, col: 29, offset: 27511},
run: (*parser).callonAvgAggregateExpression1,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 723, col: 29, offset: 27511}, pos: position{line: 721, col: 5, offset: 27484},
exprs: []any{ exprs: []any{
&litMatcher{ &litMatcher{
pos: position{line: 723, col: 29, offset: 27511}, pos: position{line: 721, col: 5, offset: 27484},
val: "avg",
ignoreCase: true,
want: "\"AVG\"i",
},
&litMatcher{
pos: position{line: 723, col: 36, offset: 27518},
val: "(", val: "(",
ignoreCase: false, ignoreCase: false,
want: "\"(\"", want: "\"(\"",
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 723, col: 40, offset: 27522}, pos: position{line: 721, col: 9, offset: 27488},
name: "ws", name: "ws",
}, },
&labeledExpr{ &labeledExpr{
pos: position{line: 723, col: 43, offset: 27525}, pos: position{line: 721, col: 12, offset: 27491},
label: "ex", label: "ex1",
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 723, col: 46, offset: 27528}, pos: position{line: 721, col: 16, offset: 27495},
name: "SelectItem", name: "SelectItem",
}, },
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 723, col: 58, offset: 27540}, pos: position{line: 721, col: 27, offset: 27506},
name: "ws",
},
&ruleRefExpr{
pos: position{line: 721, col: 30, offset: 27509},
name: "In",
},
&ruleRefExpr{
pos: position{line: 721, col: 33, offset: 27512},
name: "ws", name: "ws",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 723, col: 61, offset: 27543}, pos: position{line: 721, col: 36, offset: 27515},
val: "(",
ignoreCase: false,
want: "\"(\"",
},
&ruleRefExpr{
pos: position{line: 721, col: 40, offset: 27519},
name: "ws",
},
&labeledExpr{
pos: position{line: 721, col: 43, offset: 27522},
label: "ex2",
expr: &ruleRefExpr{
pos: position{line: 721, col: 47, offset: 27526},
name: "SelectItem",
},
},
&labeledExpr{
pos: position{line: 721, col: 58, offset: 27537},
label: "others",
expr: &zeroOrMoreExpr{
pos: position{line: 721, col: 65, offset: 27544},
expr: &actionExpr{
pos: position{line: 721, col: 66, offset: 27545},
run: (*parser).callonInFunction39,
expr: &seqExpr{
pos: position{line: 721, col: 66, offset: 27545},
exprs: []any{
&ruleRefExpr{
pos: position{line: 721, col: 66, offset: 27545},
name: "ws",
},
&litMatcher{
pos: position{line: 721, col: 69, offset: 27548},
val: ",",
ignoreCase: false,
want: "\",\"",
},
&ruleRefExpr{
pos: position{line: 721, col: 73, offset: 27552},
name: "ws",
},
&labeledExpr{
pos: position{line: 721, col: 76, offset: 27555},
label: "ex",
expr: &ruleRefExpr{
pos: position{line: 721, col: 79, offset: 27558},
name: "SelectItem",
},
},
},
},
},
},
},
&ruleRefExpr{
pos: position{line: 721, col: 111, offset: 27590},
name: "ws",
},
&litMatcher{
pos: position{line: 721, col: 114, offset: 27593},
val: ")",
ignoreCase: false,
want: "\")\"",
},
&ruleRefExpr{
pos: position{line: 721, col: 118, offset: 27597},
name: "ws",
},
&litMatcher{
pos: position{line: 721, col: 121, offset: 27600},
val: ")",
ignoreCase: false,
want: "\")\"",
},
},
},
},
},
},
},
{
name: "AvgAggregateExpression",
pos: position{line: 725, col: 1, offset: 27723},
expr: &actionExpr{
pos: position{line: 725, col: 29, offset: 27751},
run: (*parser).callonAvgAggregateExpression1,
expr: &seqExpr{
pos: position{line: 725, col: 29, offset: 27751},
exprs: []any{
&litMatcher{
pos: position{line: 725, col: 29, offset: 27751},
val: "avg",
ignoreCase: true,
want: "\"AVG\"i",
},
&litMatcher{
pos: position{line: 725, col: 36, offset: 27758},
val: "(",
ignoreCase: false,
want: "\"(\"",
},
&ruleRefExpr{
pos: position{line: 725, col: 40, offset: 27762},
name: "ws",
},
&labeledExpr{
pos: position{line: 725, col: 43, offset: 27765},
label: "ex",
expr: &ruleRefExpr{
pos: position{line: 725, col: 46, offset: 27768},
name: "SelectItem",
},
},
&ruleRefExpr{
pos: position{line: 725, col: 58, offset: 27780},
name: "ws",
},
&litMatcher{
pos: position{line: 725, col: 61, offset: 27783},
val: ")", val: ")",
ignoreCase: false, ignoreCase: false,
want: "\")\"", want: "\")\"",
@ -7348,43 +7468,43 @@ var g = &grammar{
}, },
{ {
name: "CountAggregateExpression", name: "CountAggregateExpression",
pos: position{line: 727, col: 1, offset: 27635}, pos: position{line: 729, col: 1, offset: 27875},
expr: &actionExpr{ expr: &actionExpr{
pos: position{line: 727, col: 29, offset: 27663}, pos: position{line: 729, col: 29, offset: 27903},
run: (*parser).callonCountAggregateExpression1, run: (*parser).callonCountAggregateExpression1,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 727, col: 29, offset: 27663}, pos: position{line: 729, col: 29, offset: 27903},
exprs: []any{ exprs: []any{
&litMatcher{ &litMatcher{
pos: position{line: 727, col: 29, offset: 27663}, pos: position{line: 729, col: 29, offset: 27903},
val: "count", val: "count",
ignoreCase: true, ignoreCase: true,
want: "\"COUNT\"i", want: "\"COUNT\"i",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 727, col: 38, offset: 27672}, pos: position{line: 729, col: 38, offset: 27912},
val: "(", val: "(",
ignoreCase: false, ignoreCase: false,
want: "\"(\"", want: "\"(\"",
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 727, col: 42, offset: 27676}, pos: position{line: 729, col: 42, offset: 27916},
name: "ws", name: "ws",
}, },
&labeledExpr{ &labeledExpr{
pos: position{line: 727, col: 45, offset: 27679}, pos: position{line: 729, col: 45, offset: 27919},
label: "ex", label: "ex",
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 727, col: 48, offset: 27682}, pos: position{line: 729, col: 48, offset: 27922},
name: "SelectItem", name: "SelectItem",
}, },
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 727, col: 59, offset: 27693}, pos: position{line: 729, col: 59, offset: 27933},
name: "ws", name: "ws",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 727, col: 62, offset: 27696}, pos: position{line: 729, col: 62, offset: 27936},
val: ")", val: ")",
ignoreCase: false, ignoreCase: false,
want: "\")\"", want: "\")\"",
@ -7395,43 +7515,43 @@ var g = &grammar{
}, },
{ {
name: "MaxAggregateExpression", name: "MaxAggregateExpression",
pos: position{line: 731, col: 1, offset: 27790}, pos: position{line: 733, col: 1, offset: 28030},
expr: &actionExpr{ expr: &actionExpr{
pos: position{line: 731, col: 29, offset: 27818}, pos: position{line: 733, col: 29, offset: 28058},
run: (*parser).callonMaxAggregateExpression1, run: (*parser).callonMaxAggregateExpression1,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 731, col: 29, offset: 27818}, pos: position{line: 733, col: 29, offset: 28058},
exprs: []any{ exprs: []any{
&litMatcher{ &litMatcher{
pos: position{line: 731, col: 29, offset: 27818}, pos: position{line: 733, col: 29, offset: 28058},
val: "max", val: "max",
ignoreCase: true, ignoreCase: true,
want: "\"MAX\"i", want: "\"MAX\"i",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 731, col: 36, offset: 27825}, pos: position{line: 733, col: 36, offset: 28065},
val: "(", val: "(",
ignoreCase: false, ignoreCase: false,
want: "\"(\"", want: "\"(\"",
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 731, col: 40, offset: 27829}, pos: position{line: 733, col: 40, offset: 28069},
name: "ws", name: "ws",
}, },
&labeledExpr{ &labeledExpr{
pos: position{line: 731, col: 43, offset: 27832}, pos: position{line: 733, col: 43, offset: 28072},
label: "ex", label: "ex",
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 731, col: 46, offset: 27835}, pos: position{line: 733, col: 46, offset: 28075},
name: "SelectItem", name: "SelectItem",
}, },
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 731, col: 57, offset: 27846}, pos: position{line: 733, col: 57, offset: 28086},
name: "ws", name: "ws",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 731, col: 60, offset: 27849}, pos: position{line: 733, col: 60, offset: 28089},
val: ")", val: ")",
ignoreCase: false, ignoreCase: false,
want: "\")\"", want: "\")\"",
@ -7442,43 +7562,43 @@ var g = &grammar{
}, },
{ {
name: "MinAggregateExpression", name: "MinAggregateExpression",
pos: position{line: 735, col: 1, offset: 27941}, pos: position{line: 737, col: 1, offset: 28181},
expr: &actionExpr{ expr: &actionExpr{
pos: position{line: 735, col: 29, offset: 27969}, pos: position{line: 737, col: 29, offset: 28209},
run: (*parser).callonMinAggregateExpression1, run: (*parser).callonMinAggregateExpression1,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 735, col: 29, offset: 27969}, pos: position{line: 737, col: 29, offset: 28209},
exprs: []any{ exprs: []any{
&litMatcher{ &litMatcher{
pos: position{line: 735, col: 29, offset: 27969}, pos: position{line: 737, col: 29, offset: 28209},
val: "min", val: "min",
ignoreCase: true, ignoreCase: true,
want: "\"MIN\"i", want: "\"MIN\"i",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 735, col: 36, offset: 27976}, pos: position{line: 737, col: 36, offset: 28216},
val: "(", val: "(",
ignoreCase: false, ignoreCase: false,
want: "\"(\"", want: "\"(\"",
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 735, col: 40, offset: 27980}, pos: position{line: 737, col: 40, offset: 28220},
name: "ws", name: "ws",
}, },
&labeledExpr{ &labeledExpr{
pos: position{line: 735, col: 43, offset: 27983}, pos: position{line: 737, col: 43, offset: 28223},
label: "ex", label: "ex",
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 735, col: 46, offset: 27986}, pos: position{line: 737, col: 46, offset: 28226},
name: "SelectItem", name: "SelectItem",
}, },
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 735, col: 57, offset: 27997}, pos: position{line: 737, col: 57, offset: 28237},
name: "ws", name: "ws",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 735, col: 60, offset: 28000}, pos: position{line: 737, col: 60, offset: 28240},
val: ")", val: ")",
ignoreCase: false, ignoreCase: false,
want: "\")\"", want: "\")\"",
@ -7489,43 +7609,43 @@ var g = &grammar{
}, },
{ {
name: "SumAggregateExpression", name: "SumAggregateExpression",
pos: position{line: 739, col: 1, offset: 28092}, pos: position{line: 741, col: 1, offset: 28332},
expr: &actionExpr{ expr: &actionExpr{
pos: position{line: 739, col: 29, offset: 28120}, pos: position{line: 741, col: 29, offset: 28360},
run: (*parser).callonSumAggregateExpression1, run: (*parser).callonSumAggregateExpression1,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 739, col: 29, offset: 28120}, pos: position{line: 741, col: 29, offset: 28360},
exprs: []any{ exprs: []any{
&litMatcher{ &litMatcher{
pos: position{line: 739, col: 29, offset: 28120}, pos: position{line: 741, col: 29, offset: 28360},
val: "sum", val: "sum",
ignoreCase: true, ignoreCase: true,
want: "\"SUM\"i", want: "\"SUM\"i",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 739, col: 36, offset: 28127}, pos: position{line: 741, col: 36, offset: 28367},
val: "(", val: "(",
ignoreCase: false, ignoreCase: false,
want: "\"(\"", want: "\"(\"",
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 739, col: 40, offset: 28131}, pos: position{line: 741, col: 40, offset: 28371},
name: "ws", name: "ws",
}, },
&labeledExpr{ &labeledExpr{
pos: position{line: 739, col: 43, offset: 28134}, pos: position{line: 741, col: 43, offset: 28374},
label: "ex", label: "ex",
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 739, col: 46, offset: 28137}, pos: position{line: 741, col: 46, offset: 28377},
name: "SelectItem", name: "SelectItem",
}, },
}, },
&ruleRefExpr{ &ruleRefExpr{
pos: position{line: 739, col: 57, offset: 28148}, pos: position{line: 741, col: 57, offset: 28388},
name: "ws", name: "ws",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 739, col: 60, offset: 28151}, pos: position{line: 741, col: 60, offset: 28391},
val: ")", val: ")",
ignoreCase: false, ignoreCase: false,
want: "\")\"", want: "\")\"",
@ -7536,14 +7656,14 @@ var g = &grammar{
}, },
{ {
name: "Integer", name: "Integer",
pos: position{line: 743, col: 1, offset: 28243}, pos: position{line: 745, col: 1, offset: 28483},
expr: &actionExpr{ expr: &actionExpr{
pos: position{line: 743, col: 12, offset: 28254}, pos: position{line: 745, col: 12, offset: 28494},
run: (*parser).callonInteger1, run: (*parser).callonInteger1,
expr: &oneOrMoreExpr{ expr: &oneOrMoreExpr{
pos: position{line: 743, col: 12, offset: 28254}, pos: position{line: 745, col: 12, offset: 28494},
expr: &charClassMatcher{ expr: &charClassMatcher{
pos: position{line: 743, col: 12, offset: 28254}, pos: position{line: 745, col: 12, offset: 28494},
val: "[0-9]", val: "[0-9]",
ranges: []rune{'0', '9'}, ranges: []rune{'0', '9'},
ignoreCase: false, ignoreCase: false,
@ -7554,29 +7674,29 @@ var g = &grammar{
}, },
{ {
name: "StringCharacter", name: "StringCharacter",
pos: position{line: 747, col: 1, offset: 28306}, pos: position{line: 749, col: 1, offset: 28546},
expr: &choiceExpr{ expr: &choiceExpr{
pos: position{line: 747, col: 20, offset: 28325}, pos: position{line: 749, col: 20, offset: 28565},
alternatives: []any{ alternatives: []any{
&actionExpr{ &actionExpr{
pos: position{line: 747, col: 20, offset: 28325}, pos: position{line: 749, col: 20, offset: 28565},
run: (*parser).callonStringCharacter2, run: (*parser).callonStringCharacter2,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 747, col: 20, offset: 28325}, pos: position{line: 749, col: 20, offset: 28565},
exprs: []any{ exprs: []any{
&notExpr{ &notExpr{
pos: position{line: 747, col: 20, offset: 28325}, pos: position{line: 749, col: 20, offset: 28565},
expr: &choiceExpr{ expr: &choiceExpr{
pos: position{line: 747, col: 22, offset: 28327}, pos: position{line: 749, col: 22, offset: 28567},
alternatives: []any{ alternatives: []any{
&litMatcher{ &litMatcher{
pos: position{line: 747, col: 22, offset: 28327}, pos: position{line: 749, col: 22, offset: 28567},
val: "\"", val: "\"",
ignoreCase: false, ignoreCase: false,
want: "\"\\\"\"", want: "\"\\\"\"",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 747, col: 28, offset: 28333}, pos: position{line: 749, col: 28, offset: 28573},
val: "\\", val: "\\",
ignoreCase: false, ignoreCase: false,
want: "\"\\\\\"", want: "\"\\\\\"",
@ -7585,28 +7705,28 @@ var g = &grammar{
}, },
}, },
&anyMatcher{ &anyMatcher{
line: 747, col: 34, offset: 28339, line: 749, col: 34, offset: 28579,
}, },
}, },
}, },
}, },
&actionExpr{ &actionExpr{
pos: position{line: 748, col: 5, offset: 28376}, pos: position{line: 750, col: 5, offset: 28616},
run: (*parser).callonStringCharacter9, run: (*parser).callonStringCharacter9,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 748, col: 5, offset: 28376}, pos: position{line: 750, col: 5, offset: 28616},
exprs: []any{ exprs: []any{
&litMatcher{ &litMatcher{
pos: position{line: 748, col: 5, offset: 28376}, pos: position{line: 750, col: 5, offset: 28616},
val: "\\", val: "\\",
ignoreCase: false, ignoreCase: false,
want: "\"\\\\\"", want: "\"\\\\\"",
}, },
&labeledExpr{ &labeledExpr{
pos: position{line: 748, col: 10, offset: 28381}, pos: position{line: 750, col: 10, offset: 28621},
label: "seq", label: "seq",
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 748, col: 14, offset: 28385}, pos: position{line: 750, col: 14, offset: 28625},
name: "EscapeSequenceCharacter", name: "EscapeSequenceCharacter",
}, },
}, },
@ -7618,85 +7738,85 @@ var g = &grammar{
}, },
{ {
name: "EscapeSequenceCharacter", name: "EscapeSequenceCharacter",
pos: position{line: 750, col: 1, offset: 28430}, pos: position{line: 752, col: 1, offset: 28670},
expr: &labeledExpr{ expr: &labeledExpr{
pos: position{line: 750, col: 28, offset: 28457}, pos: position{line: 752, col: 28, offset: 28697},
label: "char", label: "char",
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 750, col: 33, offset: 28462}, pos: position{line: 752, col: 33, offset: 28702},
name: "EscapeCharacter", name: "EscapeCharacter",
}, },
}, },
}, },
{ {
name: "EscapeCharacter", name: "EscapeCharacter",
pos: position{line: 752, col: 1, offset: 28479}, pos: position{line: 754, col: 1, offset: 28719},
expr: &choiceExpr{ expr: &choiceExpr{
pos: position{line: 752, col: 20, offset: 28498}, pos: position{line: 754, col: 20, offset: 28738},
alternatives: []any{ alternatives: []any{
&litMatcher{ &litMatcher{
pos: position{line: 752, col: 20, offset: 28498}, pos: position{line: 754, col: 20, offset: 28738},
val: "'", val: "'",
ignoreCase: false, ignoreCase: false,
want: "\"'\"", want: "\"'\"",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 753, col: 5, offset: 28506}, pos: position{line: 755, col: 5, offset: 28746},
val: "\"", val: "\"",
ignoreCase: false, ignoreCase: false,
want: "\"\\\"\"", want: "\"\\\"\"",
}, },
&litMatcher{ &litMatcher{
pos: position{line: 754, col: 5, offset: 28514}, pos: position{line: 756, col: 5, offset: 28754},
val: "\\", val: "\\",
ignoreCase: false, ignoreCase: false,
want: "\"\\\\\"", want: "\"\\\\\"",
}, },
&actionExpr{ &actionExpr{
pos: position{line: 755, col: 5, offset: 28523}, pos: position{line: 757, col: 5, offset: 28763},
run: (*parser).callonEscapeCharacter5, run: (*parser).callonEscapeCharacter5,
expr: &litMatcher{ expr: &litMatcher{
pos: position{line: 755, col: 5, offset: 28523}, pos: position{line: 757, col: 5, offset: 28763},
val: "b", val: "b",
ignoreCase: false, ignoreCase: false,
want: "\"b\"", want: "\"b\"",
}, },
}, },
&actionExpr{ &actionExpr{
pos: position{line: 756, col: 5, offset: 28552}, pos: position{line: 758, col: 5, offset: 28792},
run: (*parser).callonEscapeCharacter7, run: (*parser).callonEscapeCharacter7,
expr: &litMatcher{ expr: &litMatcher{
pos: position{line: 756, col: 5, offset: 28552}, pos: position{line: 758, col: 5, offset: 28792},
val: "f", val: "f",
ignoreCase: false, ignoreCase: false,
want: "\"f\"", want: "\"f\"",
}, },
}, },
&actionExpr{ &actionExpr{
pos: position{line: 757, col: 5, offset: 28581}, pos: position{line: 759, col: 5, offset: 28821},
run: (*parser).callonEscapeCharacter9, run: (*parser).callonEscapeCharacter9,
expr: &litMatcher{ expr: &litMatcher{
pos: position{line: 757, col: 5, offset: 28581}, pos: position{line: 759, col: 5, offset: 28821},
val: "n", val: "n",
ignoreCase: false, ignoreCase: false,
want: "\"n\"", want: "\"n\"",
}, },
}, },
&actionExpr{ &actionExpr{
pos: position{line: 758, col: 5, offset: 28610}, pos: position{line: 760, col: 5, offset: 28850},
run: (*parser).callonEscapeCharacter11, run: (*parser).callonEscapeCharacter11,
expr: &litMatcher{ expr: &litMatcher{
pos: position{line: 758, col: 5, offset: 28610}, pos: position{line: 760, col: 5, offset: 28850},
val: "r", val: "r",
ignoreCase: false, ignoreCase: false,
want: "\"r\"", want: "\"r\"",
}, },
}, },
&actionExpr{ &actionExpr{
pos: position{line: 759, col: 5, offset: 28639}, pos: position{line: 761, col: 5, offset: 28879},
run: (*parser).callonEscapeCharacter13, run: (*parser).callonEscapeCharacter13,
expr: &litMatcher{ expr: &litMatcher{
pos: position{line: 759, col: 5, offset: 28639}, pos: position{line: 761, col: 5, offset: 28879},
val: "t", val: "t",
ignoreCase: false, ignoreCase: false,
want: "\"t\"", want: "\"t\"",
@ -7707,25 +7827,25 @@ var g = &grammar{
}, },
{ {
name: "non_escape_character", name: "non_escape_character",
pos: position{line: 761, col: 1, offset: 28665}, pos: position{line: 763, col: 1, offset: 28905},
expr: &actionExpr{ expr: &actionExpr{
pos: position{line: 761, col: 25, offset: 28689}, pos: position{line: 763, col: 25, offset: 28929},
run: (*parser).callonnon_escape_character1, run: (*parser).callonnon_escape_character1,
expr: &seqExpr{ expr: &seqExpr{
pos: position{line: 761, col: 25, offset: 28689}, pos: position{line: 763, col: 25, offset: 28929},
exprs: []any{ exprs: []any{
&notExpr{ &notExpr{
pos: position{line: 761, col: 25, offset: 28689}, pos: position{line: 763, col: 25, offset: 28929},
expr: &ruleRefExpr{ expr: &ruleRefExpr{
pos: position{line: 761, col: 27, offset: 28691}, pos: position{line: 763, col: 27, offset: 28931},
name: "escape_character", name: "escape_character",
}, },
}, },
&labeledExpr{ &labeledExpr{
pos: position{line: 761, col: 45, offset: 28709}, pos: position{line: 763, col: 45, offset: 28949},
label: "char", label: "char",
expr: &anyMatcher{ expr: &anyMatcher{
line: 761, col: 50, offset: 28714, line: 763, col: 50, offset: 28954,
}, },
}, },
}, },
@ -7734,11 +7854,11 @@ var g = &grammar{
}, },
{ {
name: "ws", name: "ws",
pos: position{line: 764, col: 1, offset: 28753}, pos: position{line: 766, col: 1, offset: 28993},
expr: &zeroOrMoreExpr{ expr: &zeroOrMoreExpr{
pos: position{line: 764, col: 7, offset: 28759}, pos: position{line: 766, col: 7, offset: 28999},
expr: &charClassMatcher{ expr: &charClassMatcher{
pos: position{line: 764, col: 7, offset: 28759}, pos: position{line: 766, col: 7, offset: 28999},
val: "[ \\t\\n\\r]", val: "[ \\t\\n\\r]",
chars: []rune{' ', '\t', '\n', '\r'}, chars: []rune{' ', '\t', '\n', '\r'},
ignoreCase: false, ignoreCase: false,
@ -7748,11 +7868,11 @@ var g = &grammar{
}, },
{ {
name: "wss", name: "wss",
pos: position{line: 766, col: 1, offset: 28771}, pos: position{line: 768, col: 1, offset: 29011},
expr: &oneOrMoreExpr{ expr: &oneOrMoreExpr{
pos: position{line: 766, col: 8, offset: 28778}, pos: position{line: 768, col: 8, offset: 29018},
expr: &charClassMatcher{ expr: &charClassMatcher{
pos: position{line: 766, col: 8, offset: 28778}, pos: position{line: 768, col: 8, offset: 29018},
val: "[ \\t\\n\\r]", val: "[ \\t\\n\\r]",
chars: []rune{' ', '\t', '\n', '\r'}, chars: []rune{' ', '\t', '\n', '\r'},
ignoreCase: false, ignoreCase: false,
@ -7762,11 +7882,11 @@ var g = &grammar{
}, },
{ {
name: "EOF", name: "EOF",
pos: position{line: 768, col: 1, offset: 28790}, pos: position{line: 770, col: 1, offset: 29030},
expr: &notExpr{ expr: &notExpr{
pos: position{line: 768, col: 8, offset: 28797}, pos: position{line: 770, col: 8, offset: 29037},
expr: &anyMatcher{ expr: &anyMatcher{
line: 768, col: 9, offset: 28798, line: 770, col: 9, offset: 29038,
}, },
}, },
}, },
@ -9232,24 +9352,44 @@ func (p *parser) callonMathRandExpression1() (any, error) {
return p.cur.onMathRandExpression1() return p.cur.onMathRandExpression1()
} }
func (c *current) onInFunction14(ex any) (any, error) { func (c *current) onInFunction15(ex any) (any, error) {
return ex, nil return ex, nil
} }
func (p *parser) callonInFunction14() (any, error) { func (p *parser) callonInFunction15() (any, error) {
stack := p.vstack[len(p.vstack)-1] stack := p.vstack[len(p.vstack)-1]
_ = stack _ = stack
return p.cur.onInFunction14(stack["ex"]) return p.cur.onInFunction15(stack["ex"])
} }
func (c *current) onInFunction1(ex1, ex2, others any) (any, error) { func (c *current) onInFunction2(ex1, ex2, others any) (any, error) {
return createFunctionCall(parsers.FunctionCallIn, append([]interface{}{ex1, ex2}, others.([]interface{})...)) return createFunctionCall(parsers.FunctionCallIn, append([]interface{}{ex1, ex2}, others.([]interface{})...))
} }
func (p *parser) callonInFunction1() (any, error) { func (p *parser) callonInFunction2() (any, error) {
stack := p.vstack[len(p.vstack)-1] stack := p.vstack[len(p.vstack)-1]
_ = stack _ = stack
return p.cur.onInFunction1(stack["ex1"], stack["ex2"], stack["others"]) return p.cur.onInFunction2(stack["ex1"], stack["ex2"], stack["others"])
}
func (c *current) onInFunction39(ex any) (any, error) {
return ex, nil
}
func (p *parser) callonInFunction39() (any, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onInFunction39(stack["ex"])
}
func (c *current) onInFunction24(ex1, ex2, others any) (any, error) {
return createFunctionCall(parsers.FunctionCallIn, append([]interface{}{ex1, ex2}, others.([]interface{})...))
}
func (p *parser) callonInFunction24() (any, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onInFunction24(stack["ex1"], stack["ex2"], stack["others"])
} }
func (c *current) onAvgAggregateExpression1(ex any) (any, error) { func (c *current) onAvgAggregateExpression1(ex any) (any, error) {

View File

@ -718,6 +718,8 @@ MathRandExpression <- "RAND"i ws "(" ws ")" { return createFunctionCall(parsers.
InFunction <- ex1:SelectProperty ws In ws "(" ws ex2:SelectItem others:(ws "," ws ex:SelectItem { return ex, nil })* ws ")" { InFunction <- ex1:SelectProperty ws In ws "(" ws ex2:SelectItem others:(ws "," ws ex:SelectItem { return ex, nil })* ws ")" {
return createFunctionCall(parsers.FunctionCallIn, append([]interface{}{ex1, ex2}, others.([]interface{})...)) return createFunctionCall(parsers.FunctionCallIn, append([]interface{}{ex1, ex2}, others.([]interface{})...))
} / "(" ws ex1:SelectItem ws In ws "(" ws ex2:SelectItem others:(ws "," ws ex:SelectItem { return ex, nil })* ws ")" ws ")" {
return createFunctionCall(parsers.FunctionCallIn, append([]interface{}{ex1, ex2}, others.([]interface{})...))
} }
AvgAggregateExpression <- "AVG"i "(" ws ex:SelectItem ws ")" { AvgAggregateExpression <- "AVG"i "(" ws ex:SelectItem ws ")" {

View File

@ -126,6 +126,42 @@ func Test_Execute(t *testing.T) {
) )
}) })
t.Run("Should execute IN function with function call", func(t *testing.T) {
testQueryExecute(
t,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
testutils.SelectItem_Path("c", "id"),
},
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
Filters: parsers.SelectItem{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallIn,
Arguments: []interface{}{
parsers.SelectItem{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallToString,
Arguments: []interface{}{
testutils.SelectItem_Path("c", "id"),
},
},
},
testutils.SelectItem_Constant_String("123"),
testutils.SelectItem_Constant_String("456"),
},
},
},
},
mockData,
[]memoryexecutor.RowType{
map[string]interface{}{"id": "456"},
map[string]interface{}{"id": "123"},
},
)
})
t.Run("Should execute IN selector", func(t *testing.T) { t.Run("Should execute IN selector", func(t *testing.T) {
testQueryExecute( testQueryExecute(
t, t,