mirror of
https://github.com/pikami/cosmium.git
synced 2024-11-24 22:47:11 +00:00
Implement STARTSWITH, ENDSWITH functions
This commit is contained in:
parent
9bf3dc22ed
commit
790192bf5a
@ -84,6 +84,8 @@ const (
|
|||||||
FunctionCallIsDefined FunctionCallType = "IsDefined"
|
FunctionCallIsDefined FunctionCallType = "IsDefined"
|
||||||
FunctionCallConcat FunctionCallType = "Concat"
|
FunctionCallConcat FunctionCallType = "Concat"
|
||||||
FunctionCallContains FunctionCallType = "Contains"
|
FunctionCallContains FunctionCallType = "Contains"
|
||||||
|
FunctionCallEndsWith FunctionCallType = "EndsWith"
|
||||||
|
FunctionCallStartsWith FunctionCallType = "StartsWith"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FunctionCall struct {
|
type FunctionCall struct {
|
||||||
|
@ -1587,110 +1587,123 @@ var g = &grammar{
|
|||||||
alternatives: []any{
|
alternatives: []any{
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 309, col: 17, offset: 8931},
|
pos: position{line: 309, col: 17, offset: 8931},
|
||||||
name: "StringEqualsExpression",
|
name: "StringFunctions",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 309, col: 42, offset: 8956},
|
pos: position{line: 309, col: 35, offset: 8949},
|
||||||
name: "ConcatExpression",
|
|
||||||
},
|
|
||||||
&ruleRefExpr{
|
|
||||||
pos: position{line: 309, col: 61, offset: 8975},
|
|
||||||
name: "ContainsExpression",
|
|
||||||
},
|
|
||||||
&ruleRefExpr{
|
|
||||||
pos: position{line: 309, col: 82, offset: 8996},
|
|
||||||
name: "IsDefined",
|
name: "IsDefined",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "StringFunctions",
|
||||||
|
pos: position{line: 311, col: 1, offset: 8960},
|
||||||
|
expr: &choiceExpr{
|
||||||
|
pos: position{line: 311, col: 20, offset: 8979},
|
||||||
|
alternatives: []any{
|
||||||
|
&ruleRefExpr{
|
||||||
|
pos: position{line: 311, col: 20, offset: 8979},
|
||||||
|
name: "StringEqualsExpression",
|
||||||
|
},
|
||||||
|
&ruleRefExpr{
|
||||||
|
pos: position{line: 312, col: 7, offset: 9008},
|
||||||
|
name: "ConcatExpression",
|
||||||
|
},
|
||||||
|
&ruleRefExpr{
|
||||||
|
pos: position{line: 313, col: 7, offset: 9031},
|
||||||
|
name: "ThreeArgumentStringFunctionExpression",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "StringEqualsExpression",
|
name: "StringEqualsExpression",
|
||||||
pos: position{line: 311, col: 1, offset: 9007},
|
pos: position{line: 315, col: 1, offset: 9070},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 311, col: 27, offset: 9033},
|
pos: position{line: 315, col: 27, offset: 9096},
|
||||||
run: (*parser).callonStringEqualsExpression1,
|
run: (*parser).callonStringEqualsExpression1,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 311, col: 27, offset: 9033},
|
pos: position{line: 315, col: 27, offset: 9096},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 311, col: 27, offset: 9033},
|
pos: position{line: 315, col: 27, offset: 9096},
|
||||||
name: "StringEquals",
|
name: "StringEquals",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 311, col: 40, offset: 9046},
|
pos: position{line: 315, col: 40, offset: 9109},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 311, col: 43, offset: 9049},
|
pos: position{line: 315, col: 43, offset: 9112},
|
||||||
val: "(",
|
val: "(",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"(\"",
|
want: "\"(\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 311, col: 47, offset: 9053},
|
pos: position{line: 315, col: 47, offset: 9116},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 311, col: 50, offset: 9056},
|
pos: position{line: 315, col: 50, offset: 9119},
|
||||||
label: "ex1",
|
label: "ex1",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 311, col: 54, offset: 9060},
|
pos: position{line: 315, col: 54, offset: 9123},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 311, col: 65, offset: 9071},
|
pos: position{line: 315, col: 65, offset: 9134},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 311, col: 68, offset: 9074},
|
pos: position{line: 315, col: 68, offset: 9137},
|
||||||
val: ",",
|
val: ",",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\",\"",
|
want: "\",\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 311, col: 72, offset: 9078},
|
pos: position{line: 315, col: 72, offset: 9141},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 311, col: 75, offset: 9081},
|
pos: position{line: 315, col: 75, offset: 9144},
|
||||||
label: "ex2",
|
label: "ex2",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 311, col: 79, offset: 9085},
|
pos: position{line: 315, col: 79, offset: 9148},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 311, col: 90, offset: 9096},
|
pos: position{line: 315, col: 90, offset: 9159},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 311, col: 93, offset: 9099},
|
pos: position{line: 315, col: 93, offset: 9162},
|
||||||
label: "ignoreCase",
|
label: "ignoreCase",
|
||||||
expr: &zeroOrOneExpr{
|
expr: &zeroOrOneExpr{
|
||||||
pos: position{line: 311, col: 104, offset: 9110},
|
pos: position{line: 315, col: 104, offset: 9173},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 311, col: 105, offset: 9111},
|
pos: position{line: 315, col: 105, offset: 9174},
|
||||||
run: (*parser).callonStringEqualsExpression17,
|
run: (*parser).callonStringEqualsExpression17,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 311, col: 105, offset: 9111},
|
pos: position{line: 315, col: 105, offset: 9174},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 311, col: 105, offset: 9111},
|
pos: position{line: 315, col: 105, offset: 9174},
|
||||||
val: ",",
|
val: ",",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\",\"",
|
want: "\",\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 311, col: 109, offset: 9115},
|
pos: position{line: 315, col: 109, offset: 9178},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 311, col: 112, offset: 9118},
|
pos: position{line: 315, col: 112, offset: 9181},
|
||||||
label: "boolean",
|
label: "boolean",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 311, col: 120, offset: 9126},
|
pos: position{line: 315, col: 120, offset: 9189},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1700,7 +1713,7 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 311, col: 157, offset: 9163},
|
pos: position{line: 315, col: 157, offset: 9226},
|
||||||
val: ")",
|
val: ")",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\")\"",
|
want: "\")\"",
|
||||||
@ -1711,71 +1724,71 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ConcatExpression",
|
name: "ConcatExpression",
|
||||||
pos: position{line: 315, col: 1, offset: 9297},
|
pos: position{line: 319, col: 1, offset: 9360},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 315, col: 21, offset: 9317},
|
pos: position{line: 319, col: 21, offset: 9380},
|
||||||
run: (*parser).callonConcatExpression1,
|
run: (*parser).callonConcatExpression1,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 315, col: 21, offset: 9317},
|
pos: position{line: 319, col: 21, offset: 9380},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 315, col: 21, offset: 9317},
|
pos: position{line: 319, col: 21, offset: 9380},
|
||||||
val: "concat",
|
val: "concat",
|
||||||
ignoreCase: true,
|
ignoreCase: true,
|
||||||
want: "\"CONCAT\"i",
|
want: "\"CONCAT\"i",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 315, col: 31, offset: 9327},
|
pos: position{line: 319, col: 31, offset: 9390},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 315, col: 34, offset: 9330},
|
pos: position{line: 319, col: 34, offset: 9393},
|
||||||
val: "(",
|
val: "(",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"(\"",
|
want: "\"(\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 315, col: 38, offset: 9334},
|
pos: position{line: 319, col: 38, offset: 9397},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 315, col: 41, offset: 9337},
|
pos: position{line: 319, col: 41, offset: 9400},
|
||||||
label: "ex1",
|
label: "ex1",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 315, col: 45, offset: 9341},
|
pos: position{line: 319, col: 45, offset: 9404},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 315, col: 56, offset: 9352},
|
pos: position{line: 319, col: 56, offset: 9415},
|
||||||
label: "others",
|
label: "others",
|
||||||
expr: &oneOrMoreExpr{
|
expr: &oneOrMoreExpr{
|
||||||
pos: position{line: 315, col: 63, offset: 9359},
|
pos: position{line: 319, col: 63, offset: 9422},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 315, col: 64, offset: 9360},
|
pos: position{line: 319, col: 64, offset: 9423},
|
||||||
run: (*parser).callonConcatExpression11,
|
run: (*parser).callonConcatExpression11,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 315, col: 64, offset: 9360},
|
pos: position{line: 319, col: 64, offset: 9423},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 315, col: 64, offset: 9360},
|
pos: position{line: 319, col: 64, offset: 9423},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 315, col: 67, offset: 9363},
|
pos: position{line: 319, col: 67, offset: 9426},
|
||||||
val: ",",
|
val: ",",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\",\"",
|
want: "\",\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 315, col: 71, offset: 9367},
|
pos: position{line: 319, col: 71, offset: 9430},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 315, col: 74, offset: 9370},
|
pos: position{line: 319, col: 74, offset: 9433},
|
||||||
label: "ex",
|
label: "ex",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 315, col: 77, offset: 9373},
|
pos: position{line: 319, col: 77, offset: 9436},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1785,11 +1798,11 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 315, col: 109, offset: 9405},
|
pos: position{line: 319, col: 109, offset: 9468},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 315, col: 112, offset: 9408},
|
pos: position{line: 319, col: 112, offset: 9471},
|
||||||
val: ")",
|
val: ")",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\")\"",
|
want: "\")\"",
|
||||||
@ -1799,94 +1812,96 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ContainsExpression",
|
name: "ThreeArgumentStringFunctionExpression",
|
||||||
pos: position{line: 320, col: 1, offset: 9581},
|
pos: position{line: 324, col: 1, offset: 9644},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 320, col: 23, offset: 9603},
|
pos: position{line: 324, col: 42, offset: 9685},
|
||||||
run: (*parser).callonContainsExpression1,
|
run: (*parser).callonThreeArgumentStringFunctionExpression1,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 320, col: 23, offset: 9603},
|
pos: position{line: 324, col: 42, offset: 9685},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&litMatcher{
|
&labeledExpr{
|
||||||
pos: position{line: 320, col: 23, offset: 9603},
|
pos: position{line: 324, col: 42, offset: 9685},
|
||||||
val: "contains",
|
label: "function",
|
||||||
ignoreCase: true,
|
expr: &ruleRefExpr{
|
||||||
want: "\"CONTAINS\"i",
|
pos: position{line: 324, col: 51, offset: 9694},
|
||||||
|
name: "ThreeArgumentStringFunction",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 320, col: 35, offset: 9615},
|
pos: position{line: 324, col: 79, offset: 9722},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 320, col: 38, offset: 9618},
|
pos: position{line: 324, col: 82, offset: 9725},
|
||||||
val: "(",
|
val: "(",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"(\"",
|
want: "\"(\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 320, col: 42, offset: 9622},
|
pos: position{line: 324, col: 86, offset: 9729},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 320, col: 45, offset: 9625},
|
pos: position{line: 324, col: 89, offset: 9732},
|
||||||
label: "ex1",
|
label: "ex1",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 320, col: 49, offset: 9629},
|
pos: position{line: 324, col: 93, offset: 9736},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 320, col: 60, offset: 9640},
|
pos: position{line: 324, col: 104, offset: 9747},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 320, col: 63, offset: 9643},
|
pos: position{line: 324, col: 107, offset: 9750},
|
||||||
val: ",",
|
val: ",",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\",\"",
|
want: "\",\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 320, col: 67, offset: 9647},
|
pos: position{line: 324, col: 111, offset: 9754},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 320, col: 70, offset: 9650},
|
pos: position{line: 324, col: 114, offset: 9757},
|
||||||
label: "ex2",
|
label: "ex2",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 320, col: 74, offset: 9654},
|
pos: position{line: 324, col: 118, offset: 9761},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 320, col: 85, offset: 9665},
|
pos: position{line: 324, col: 129, offset: 9772},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 320, col: 88, offset: 9668},
|
pos: position{line: 324, col: 132, offset: 9775},
|
||||||
label: "ignoreCase",
|
label: "ignoreCase",
|
||||||
expr: &zeroOrOneExpr{
|
expr: &zeroOrOneExpr{
|
||||||
pos: position{line: 320, col: 99, offset: 9679},
|
pos: position{line: 324, col: 143, offset: 9786},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 320, col: 100, offset: 9680},
|
pos: position{line: 324, col: 144, offset: 9787},
|
||||||
run: (*parser).callonContainsExpression17,
|
run: (*parser).callonThreeArgumentStringFunctionExpression18,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 320, col: 100, offset: 9680},
|
pos: position{line: 324, col: 144, offset: 9787},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 320, col: 100, offset: 9680},
|
pos: position{line: 324, col: 144, offset: 9787},
|
||||||
val: ",",
|
val: ",",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\",\"",
|
want: "\",\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 320, col: 104, offset: 9684},
|
pos: position{line: 324, col: 148, offset: 9791},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 320, col: 107, offset: 9687},
|
pos: position{line: 324, col: 151, offset: 9794},
|
||||||
label: "boolean",
|
label: "boolean",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 320, col: 115, offset: 9695},
|
pos: position{line: 324, col: 159, offset: 9802},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1896,7 +1911,7 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 320, col: 152, offset: 9732},
|
pos: position{line: 324, col: 196, offset: 9839},
|
||||||
val: ")",
|
val: ")",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\")\"",
|
want: "\")\"",
|
||||||
@ -1905,49 +1920,76 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ThreeArgumentStringFunction",
|
||||||
|
pos: position{line: 340, col: 1, offset: 10313},
|
||||||
|
expr: &choiceExpr{
|
||||||
|
pos: position{line: 340, col: 32, offset: 10344},
|
||||||
|
alternatives: []any{
|
||||||
|
&litMatcher{
|
||||||
|
pos: position{line: 340, col: 32, offset: 10344},
|
||||||
|
val: "contains",
|
||||||
|
ignoreCase: true,
|
||||||
|
want: "\"CONTAINS\"i",
|
||||||
|
},
|
||||||
|
&litMatcher{
|
||||||
|
pos: position{line: 340, col: 46, offset: 10358},
|
||||||
|
val: "endswith",
|
||||||
|
ignoreCase: true,
|
||||||
|
want: "\"ENDSWITH\"i",
|
||||||
|
},
|
||||||
|
&litMatcher{
|
||||||
|
pos: position{line: 340, col: 60, offset: 10372},
|
||||||
|
val: "startswith",
|
||||||
|
ignoreCase: true,
|
||||||
|
want: "\"STARTSWITH\"i",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "IsDefined",
|
name: "IsDefined",
|
||||||
pos: position{line: 324, col: 1, offset: 9862},
|
pos: position{line: 342, col: 1, offset: 10387},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 324, col: 14, offset: 9875},
|
pos: position{line: 342, col: 14, offset: 10400},
|
||||||
run: (*parser).callonIsDefined1,
|
run: (*parser).callonIsDefined1,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 324, col: 14, offset: 9875},
|
pos: position{line: 342, col: 14, offset: 10400},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 324, col: 14, offset: 9875},
|
pos: position{line: 342, col: 14, offset: 10400},
|
||||||
val: "is_defined",
|
val: "is_defined",
|
||||||
ignoreCase: true,
|
ignoreCase: true,
|
||||||
want: "\"IS_DEFINED\"i",
|
want: "\"IS_DEFINED\"i",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 324, col: 28, offset: 9889},
|
pos: position{line: 342, col: 28, offset: 10414},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 324, col: 31, offset: 9892},
|
pos: position{line: 342, col: 31, offset: 10417},
|
||||||
val: "(",
|
val: "(",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"(\"",
|
want: "\"(\"",
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 324, col: 35, offset: 9896},
|
pos: position{line: 342, col: 35, offset: 10421},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 324, col: 38, offset: 9899},
|
pos: position{line: 342, col: 38, offset: 10424},
|
||||||
label: "ex",
|
label: "ex",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 324, col: 41, offset: 9902},
|
pos: position{line: 342, col: 41, offset: 10427},
|
||||||
name: "SelectItem",
|
name: "SelectItem",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&ruleRefExpr{
|
&ruleRefExpr{
|
||||||
pos: position{line: 324, col: 52, offset: 9913},
|
pos: position{line: 342, col: 52, offset: 10438},
|
||||||
name: "ws",
|
name: "ws",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 324, col: 55, offset: 9916},
|
pos: position{line: 342, col: 55, offset: 10441},
|
||||||
val: ")",
|
val: ")",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\")\"",
|
want: "\")\"",
|
||||||
@ -1958,14 +2000,14 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Integer",
|
name: "Integer",
|
||||||
pos: position{line: 328, col: 1, offset: 10029},
|
pos: position{line: 346, col: 1, offset: 10554},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 328, col: 12, offset: 10040},
|
pos: position{line: 346, col: 12, offset: 10565},
|
||||||
run: (*parser).callonInteger1,
|
run: (*parser).callonInteger1,
|
||||||
expr: &oneOrMoreExpr{
|
expr: &oneOrMoreExpr{
|
||||||
pos: position{line: 328, col: 12, offset: 10040},
|
pos: position{line: 346, col: 12, offset: 10565},
|
||||||
expr: &charClassMatcher{
|
expr: &charClassMatcher{
|
||||||
pos: position{line: 328, col: 12, offset: 10040},
|
pos: position{line: 346, col: 12, offset: 10565},
|
||||||
val: "[0-9]",
|
val: "[0-9]",
|
||||||
ranges: []rune{'0', '9'},
|
ranges: []rune{'0', '9'},
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
@ -1976,29 +2018,29 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "StringCharacter",
|
name: "StringCharacter",
|
||||||
pos: position{line: 332, col: 1, offset: 10092},
|
pos: position{line: 350, col: 1, offset: 10617},
|
||||||
expr: &choiceExpr{
|
expr: &choiceExpr{
|
||||||
pos: position{line: 332, col: 20, offset: 10111},
|
pos: position{line: 350, col: 20, offset: 10636},
|
||||||
alternatives: []any{
|
alternatives: []any{
|
||||||
&actionExpr{
|
&actionExpr{
|
||||||
pos: position{line: 332, col: 20, offset: 10111},
|
pos: position{line: 350, col: 20, offset: 10636},
|
||||||
run: (*parser).callonStringCharacter2,
|
run: (*parser).callonStringCharacter2,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 332, col: 20, offset: 10111},
|
pos: position{line: 350, col: 20, offset: 10636},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
¬Expr{
|
¬Expr{
|
||||||
pos: position{line: 332, col: 20, offset: 10111},
|
pos: position{line: 350, col: 20, offset: 10636},
|
||||||
expr: &choiceExpr{
|
expr: &choiceExpr{
|
||||||
pos: position{line: 332, col: 22, offset: 10113},
|
pos: position{line: 350, col: 22, offset: 10638},
|
||||||
alternatives: []any{
|
alternatives: []any{
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 332, col: 22, offset: 10113},
|
pos: position{line: 350, col: 22, offset: 10638},
|
||||||
val: "\"",
|
val: "\"",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"\\\"\"",
|
want: "\"\\\"\"",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 332, col: 28, offset: 10119},
|
pos: position{line: 350, col: 28, offset: 10644},
|
||||||
val: "\\",
|
val: "\\",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"\\\\\"",
|
want: "\"\\\\\"",
|
||||||
@ -2007,28 +2049,28 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&anyMatcher{
|
&anyMatcher{
|
||||||
line: 332, col: 34, offset: 10125,
|
line: 350, col: 34, offset: 10650,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&actionExpr{
|
&actionExpr{
|
||||||
pos: position{line: 333, col: 5, offset: 10162},
|
pos: position{line: 351, col: 5, offset: 10687},
|
||||||
run: (*parser).callonStringCharacter9,
|
run: (*parser).callonStringCharacter9,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 333, col: 5, offset: 10162},
|
pos: position{line: 351, col: 5, offset: 10687},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 333, col: 5, offset: 10162},
|
pos: position{line: 351, col: 5, offset: 10687},
|
||||||
val: "\\",
|
val: "\\",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"\\\\\"",
|
want: "\"\\\\\"",
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 333, col: 10, offset: 10167},
|
pos: position{line: 351, col: 10, offset: 10692},
|
||||||
label: "seq",
|
label: "seq",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 333, col: 14, offset: 10171},
|
pos: position{line: 351, col: 14, offset: 10696},
|
||||||
name: "EscapeSequenceCharacter",
|
name: "EscapeSequenceCharacter",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2040,85 +2082,85 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "EscapeSequenceCharacter",
|
name: "EscapeSequenceCharacter",
|
||||||
pos: position{line: 335, col: 1, offset: 10216},
|
pos: position{line: 353, col: 1, offset: 10741},
|
||||||
expr: &labeledExpr{
|
expr: &labeledExpr{
|
||||||
pos: position{line: 335, col: 28, offset: 10243},
|
pos: position{line: 353, col: 28, offset: 10768},
|
||||||
label: "char",
|
label: "char",
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 335, col: 33, offset: 10248},
|
pos: position{line: 353, col: 33, offset: 10773},
|
||||||
name: "EscapeCharacter",
|
name: "EscapeCharacter",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "EscapeCharacter",
|
name: "EscapeCharacter",
|
||||||
pos: position{line: 337, col: 1, offset: 10265},
|
pos: position{line: 355, col: 1, offset: 10790},
|
||||||
expr: &choiceExpr{
|
expr: &choiceExpr{
|
||||||
pos: position{line: 337, col: 20, offset: 10284},
|
pos: position{line: 355, col: 20, offset: 10809},
|
||||||
alternatives: []any{
|
alternatives: []any{
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 337, col: 20, offset: 10284},
|
pos: position{line: 355, col: 20, offset: 10809},
|
||||||
val: "'",
|
val: "'",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"'\"",
|
want: "\"'\"",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 338, col: 5, offset: 10292},
|
pos: position{line: 356, col: 5, offset: 10817},
|
||||||
val: "\"",
|
val: "\"",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"\\\"\"",
|
want: "\"\\\"\"",
|
||||||
},
|
},
|
||||||
&litMatcher{
|
&litMatcher{
|
||||||
pos: position{line: 339, col: 5, offset: 10300},
|
pos: position{line: 357, col: 5, offset: 10825},
|
||||||
val: "\\",
|
val: "\\",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"\\\\\"",
|
want: "\"\\\\\"",
|
||||||
},
|
},
|
||||||
&actionExpr{
|
&actionExpr{
|
||||||
pos: position{line: 340, col: 5, offset: 10309},
|
pos: position{line: 358, col: 5, offset: 10834},
|
||||||
run: (*parser).callonEscapeCharacter5,
|
run: (*parser).callonEscapeCharacter5,
|
||||||
expr: &litMatcher{
|
expr: &litMatcher{
|
||||||
pos: position{line: 340, col: 5, offset: 10309},
|
pos: position{line: 358, col: 5, offset: 10834},
|
||||||
val: "b",
|
val: "b",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"b\"",
|
want: "\"b\"",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&actionExpr{
|
&actionExpr{
|
||||||
pos: position{line: 341, col: 5, offset: 10338},
|
pos: position{line: 359, col: 5, offset: 10863},
|
||||||
run: (*parser).callonEscapeCharacter7,
|
run: (*parser).callonEscapeCharacter7,
|
||||||
expr: &litMatcher{
|
expr: &litMatcher{
|
||||||
pos: position{line: 341, col: 5, offset: 10338},
|
pos: position{line: 359, col: 5, offset: 10863},
|
||||||
val: "f",
|
val: "f",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"f\"",
|
want: "\"f\"",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&actionExpr{
|
&actionExpr{
|
||||||
pos: position{line: 342, col: 5, offset: 10367},
|
pos: position{line: 360, col: 5, offset: 10892},
|
||||||
run: (*parser).callonEscapeCharacter9,
|
run: (*parser).callonEscapeCharacter9,
|
||||||
expr: &litMatcher{
|
expr: &litMatcher{
|
||||||
pos: position{line: 342, col: 5, offset: 10367},
|
pos: position{line: 360, col: 5, offset: 10892},
|
||||||
val: "n",
|
val: "n",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"n\"",
|
want: "\"n\"",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&actionExpr{
|
&actionExpr{
|
||||||
pos: position{line: 343, col: 5, offset: 10396},
|
pos: position{line: 361, col: 5, offset: 10921},
|
||||||
run: (*parser).callonEscapeCharacter11,
|
run: (*parser).callonEscapeCharacter11,
|
||||||
expr: &litMatcher{
|
expr: &litMatcher{
|
||||||
pos: position{line: 343, col: 5, offset: 10396},
|
pos: position{line: 361, col: 5, offset: 10921},
|
||||||
val: "r",
|
val: "r",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"r\"",
|
want: "\"r\"",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&actionExpr{
|
&actionExpr{
|
||||||
pos: position{line: 344, col: 5, offset: 10425},
|
pos: position{line: 362, col: 5, offset: 10950},
|
||||||
run: (*parser).callonEscapeCharacter13,
|
run: (*parser).callonEscapeCharacter13,
|
||||||
expr: &litMatcher{
|
expr: &litMatcher{
|
||||||
pos: position{line: 344, col: 5, offset: 10425},
|
pos: position{line: 362, col: 5, offset: 10950},
|
||||||
val: "t",
|
val: "t",
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
want: "\"t\"",
|
want: "\"t\"",
|
||||||
@ -2129,25 +2171,25 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "non_escape_character",
|
name: "non_escape_character",
|
||||||
pos: position{line: 346, col: 1, offset: 10451},
|
pos: position{line: 364, col: 1, offset: 10976},
|
||||||
expr: &actionExpr{
|
expr: &actionExpr{
|
||||||
pos: position{line: 346, col: 25, offset: 10475},
|
pos: position{line: 364, col: 25, offset: 11000},
|
||||||
run: (*parser).callonnon_escape_character1,
|
run: (*parser).callonnon_escape_character1,
|
||||||
expr: &seqExpr{
|
expr: &seqExpr{
|
||||||
pos: position{line: 346, col: 25, offset: 10475},
|
pos: position{line: 364, col: 25, offset: 11000},
|
||||||
exprs: []any{
|
exprs: []any{
|
||||||
¬Expr{
|
¬Expr{
|
||||||
pos: position{line: 346, col: 25, offset: 10475},
|
pos: position{line: 364, col: 25, offset: 11000},
|
||||||
expr: &ruleRefExpr{
|
expr: &ruleRefExpr{
|
||||||
pos: position{line: 346, col: 27, offset: 10477},
|
pos: position{line: 364, col: 27, offset: 11002},
|
||||||
name: "escape_character",
|
name: "escape_character",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&labeledExpr{
|
&labeledExpr{
|
||||||
pos: position{line: 346, col: 45, offset: 10495},
|
pos: position{line: 364, col: 45, offset: 11020},
|
||||||
label: "char",
|
label: "char",
|
||||||
expr: &anyMatcher{
|
expr: &anyMatcher{
|
||||||
line: 346, col: 50, offset: 10500,
|
line: 364, col: 50, offset: 11025,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2156,11 +2198,11 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ws",
|
name: "ws",
|
||||||
pos: position{line: 349, col: 1, offset: 10539},
|
pos: position{line: 367, col: 1, offset: 11064},
|
||||||
expr: &zeroOrMoreExpr{
|
expr: &zeroOrMoreExpr{
|
||||||
pos: position{line: 349, col: 7, offset: 10545},
|
pos: position{line: 367, col: 7, offset: 11070},
|
||||||
expr: &charClassMatcher{
|
expr: &charClassMatcher{
|
||||||
pos: position{line: 349, col: 7, offset: 10545},
|
pos: position{line: 367, col: 7, offset: 11070},
|
||||||
val: "[ \\t\\n\\r]",
|
val: "[ \\t\\n\\r]",
|
||||||
chars: []rune{' ', '\t', '\n', '\r'},
|
chars: []rune{' ', '\t', '\n', '\r'},
|
||||||
ignoreCase: false,
|
ignoreCase: false,
|
||||||
@ -2170,11 +2212,11 @@ var g = &grammar{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "EOF",
|
name: "EOF",
|
||||||
pos: position{line: 351, col: 1, offset: 10557},
|
pos: position{line: 369, col: 1, offset: 11082},
|
||||||
expr: ¬Expr{
|
expr: ¬Expr{
|
||||||
pos: position{line: 351, col: 8, offset: 10564},
|
pos: position{line: 369, col: 8, offset: 11089},
|
||||||
expr: &anyMatcher{
|
expr: &anyMatcher{
|
||||||
line: 351, col: 9, offset: 10565,
|
line: 369, col: 9, offset: 11090,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2654,24 +2696,36 @@ func (p *parser) callonConcatExpression1() (any, error) {
|
|||||||
return p.cur.onConcatExpression1(stack["ex1"], stack["others"])
|
return p.cur.onConcatExpression1(stack["ex1"], stack["others"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *current) onContainsExpression17(boolean any) (any, error) {
|
func (c *current) onThreeArgumentStringFunctionExpression18(boolean any) (any, error) {
|
||||||
return boolean, nil
|
return boolean, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) callonContainsExpression17() (any, error) {
|
func (p *parser) callonThreeArgumentStringFunctionExpression18() (any, error) {
|
||||||
stack := p.vstack[len(p.vstack)-1]
|
stack := p.vstack[len(p.vstack)-1]
|
||||||
_ = stack
|
_ = stack
|
||||||
return p.cur.onContainsExpression17(stack["boolean"])
|
return p.cur.onThreeArgumentStringFunctionExpression18(stack["boolean"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *current) onContainsExpression1(ex1, ex2, ignoreCase any) (any, error) {
|
func (c *current) onThreeArgumentStringFunctionExpression1(function, ex1, ex2, ignoreCase any) (any, error) {
|
||||||
return parsers.FunctionCall{Type: parsers.FunctionCallContains, Arguments: []interface{}{ex1, ex2, ignoreCase}}, nil
|
var functionType parsers.FunctionCallType
|
||||||
|
|
||||||
|
lowerFunction := strings.ToUpper(function.(string))
|
||||||
|
switch lowerFunction {
|
||||||
|
case "CONTAINS":
|
||||||
|
functionType = parsers.FunctionCallContains
|
||||||
|
case "ENDSWITH":
|
||||||
|
functionType = parsers.FunctionCallEndsWith
|
||||||
|
case "STARTSWITH":
|
||||||
|
functionType = parsers.FunctionCallStartsWith
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsers.FunctionCall{Type: functionType, Arguments: []interface{}{ex1, ex2, ignoreCase}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) callonContainsExpression1() (any, error) {
|
func (p *parser) callonThreeArgumentStringFunctionExpression1() (any, error) {
|
||||||
stack := p.vstack[len(p.vstack)-1]
|
stack := p.vstack[len(p.vstack)-1]
|
||||||
_ = stack
|
_ = stack
|
||||||
return p.cur.onContainsExpression1(stack["ex1"], stack["ex2"], stack["ignoreCase"])
|
return p.cur.onThreeArgumentStringFunctionExpression1(stack["function"], stack["ex1"], stack["ex2"], stack["ignoreCase"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *current) onIsDefined1(ex any) (any, error) {
|
func (c *current) onIsDefined1(ex any) (any, error) {
|
||||||
|
@ -306,7 +306,11 @@ BooleanLiteral <- ("true"i / "false"i) {
|
|||||||
return parsers.Constant{Type: parsers.ConstantTypeBoolean, Value: boolValue}, nil
|
return parsers.Constant{Type: parsers.ConstantTypeBoolean, Value: boolValue}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCall <- StringEqualsExpression / ConcatExpression / ContainsExpression / IsDefined
|
FunctionCall <- StringFunctions / IsDefined
|
||||||
|
|
||||||
|
StringFunctions <- StringEqualsExpression
|
||||||
|
/ ConcatExpression
|
||||||
|
/ ThreeArgumentStringFunctionExpression
|
||||||
|
|
||||||
StringEqualsExpression <- StringEquals ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws ignoreCase:("," ws boolean:SelectItem { return boolean, nil })? ")" {
|
StringEqualsExpression <- StringEquals ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws ignoreCase:("," ws boolean:SelectItem { return boolean, nil })? ")" {
|
||||||
return parsers.FunctionCall{Type: parsers.FunctionCallStringEquals, Arguments: []interface{}{ex1, ex2, ignoreCase}}, nil
|
return parsers.FunctionCall{Type: parsers.FunctionCallStringEquals, Arguments: []interface{}{ex1, ex2, ignoreCase}}, nil
|
||||||
@ -317,10 +321,24 @@ ConcatExpression <- "CONCAT"i ws "(" ws ex1:SelectItem others:(ws "," ws ex:Sele
|
|||||||
return parsers.FunctionCall{Type: parsers.FunctionCallConcat, Arguments: arguments}, nil
|
return parsers.FunctionCall{Type: parsers.FunctionCallConcat, Arguments: arguments}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ContainsExpression <- "CONTAINS"i ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws ignoreCase:("," ws boolean:SelectItem { return boolean, nil })? ")" {
|
ThreeArgumentStringFunctionExpression <- function:ThreeArgumentStringFunction ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws ignoreCase:("," ws boolean:SelectItem { return boolean, nil })? ")" {
|
||||||
return parsers.FunctionCall{Type: parsers.FunctionCallContains, Arguments: []interface{}{ex1, ex2, ignoreCase}}, nil
|
var functionType parsers.FunctionCallType
|
||||||
|
|
||||||
|
lowerFunction := strings.ToUpper(function.(string))
|
||||||
|
switch lowerFunction {
|
||||||
|
case "CONTAINS":
|
||||||
|
functionType = parsers.FunctionCallContains
|
||||||
|
case "ENDSWITH":
|
||||||
|
functionType = parsers.FunctionCallEndsWith
|
||||||
|
case "STARTSWITH":
|
||||||
|
functionType = parsers.FunctionCallStartsWith
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsers.FunctionCall{Type: functionType, Arguments: []interface{}{ex1, ex2, ignoreCase}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThreeArgumentStringFunction <- "CONTAINS"i / "ENDSWITH"i / "STARTSWITH"i
|
||||||
|
|
||||||
IsDefined <- "IS_DEFINED"i ws "(" ws ex:SelectItem ws ")" {
|
IsDefined <- "IS_DEFINED"i ws "(" ws ex:SelectItem ws ")" {
|
||||||
return parsers.FunctionCall{Type: parsers.FunctionCallIsDefined, Arguments: []interface{}{ex}}, nil
|
return parsers.FunctionCall{Type: parsers.FunctionCallIsDefined, Arguments: []interface{}{ex}}, nil
|
||||||
}
|
}
|
||||||
|
@ -150,4 +150,80 @@ func Test_Execute_StringFunctions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should parse function ENDSWITH()", func(t *testing.T) {
|
||||||
|
testQueryParse(
|
||||||
|
t,
|
||||||
|
`SELECT ENDSWITH(c.id, "123", true) FROM c`,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{
|
||||||
|
Type: parsers.SelectItemTypeFunctionCall,
|
||||||
|
Value: parsers.FunctionCall{
|
||||||
|
Type: parsers.FunctionCallEndsWith,
|
||||||
|
Arguments: []interface{}{
|
||||||
|
parsers.SelectItem{
|
||||||
|
Path: []string{"c", "id"},
|
||||||
|
Type: parsers.SelectItemTypeField,
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeString,
|
||||||
|
Value: "123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeBoolean,
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should parse function STARTSWITH()", func(t *testing.T) {
|
||||||
|
testQueryParse(
|
||||||
|
t,
|
||||||
|
`SELECT STARTSWITH(c.id, "123", true) FROM c`,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{
|
||||||
|
Type: parsers.SelectItemTypeFunctionCall,
|
||||||
|
Value: parsers.FunctionCall{
|
||||||
|
Type: parsers.FunctionCallStartsWith,
|
||||||
|
Arguments: []interface{}{
|
||||||
|
parsers.SelectItem{
|
||||||
|
Path: []string{"c", "id"},
|
||||||
|
Type: parsers.SelectItemTypeField,
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeString,
|
||||||
|
Value: "123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeBoolean,
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,10 @@ func getFieldValue(field parsers.SelectItem, queryParameters map[string]interfac
|
|||||||
return strings_StringEquals(typedValue.Arguments, queryParameters, row)
|
return strings_StringEquals(typedValue.Arguments, queryParameters, row)
|
||||||
case parsers.FunctionCallContains:
|
case parsers.FunctionCallContains:
|
||||||
return strings_Contains(typedValue.Arguments, queryParameters, row)
|
return strings_Contains(typedValue.Arguments, queryParameters, row)
|
||||||
|
case parsers.FunctionCallEndsWith:
|
||||||
|
return strings_EndsWith(typedValue.Arguments, queryParameters, row)
|
||||||
|
case parsers.FunctionCallStartsWith:
|
||||||
|
return strings_StartsWith(typedValue.Arguments, queryParameters, row)
|
||||||
case parsers.FunctionCallConcat:
|
case parsers.FunctionCallConcat:
|
||||||
return strings_Concat(typedValue.Arguments, queryParameters, row)
|
return strings_Concat(typedValue.Arguments, queryParameters, row)
|
||||||
case parsers.FunctionCallIsDefined:
|
case parsers.FunctionCallIsDefined:
|
||||||
|
@ -199,4 +199,100 @@ func Test_Execute_StringFunctions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should execute function ENDSWITH()", func(t *testing.T) {
|
||||||
|
testQueryExecute(
|
||||||
|
t,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{
|
||||||
|
Path: []string{"c", "id"},
|
||||||
|
Type: parsers.SelectItemTypeField,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Alias: "ends",
|
||||||
|
Type: parsers.SelectItemTypeFunctionCall,
|
||||||
|
Value: parsers.FunctionCall{
|
||||||
|
Type: parsers.FunctionCallEndsWith,
|
||||||
|
Arguments: []interface{}{
|
||||||
|
parsers.SelectItem{
|
||||||
|
Path: []string{"c", "id"},
|
||||||
|
Type: parsers.SelectItemTypeField,
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeString,
|
||||||
|
Value: "3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeBoolean,
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
},
|
||||||
|
mockData,
|
||||||
|
[]memoryexecutor.RowType{
|
||||||
|
map[string]interface{}{"id": "123", "ends": true},
|
||||||
|
map[string]interface{}{"id": "456", "ends": false},
|
||||||
|
map[string]interface{}{"id": "789", "ends": false},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should execute function STARTSWITH()", func(t *testing.T) {
|
||||||
|
testQueryExecute(
|
||||||
|
t,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{
|
||||||
|
Path: []string{"c", "id"},
|
||||||
|
Type: parsers.SelectItemTypeField,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Alias: "starts",
|
||||||
|
Type: parsers.SelectItemTypeFunctionCall,
|
||||||
|
Value: parsers.FunctionCall{
|
||||||
|
Type: parsers.FunctionCallStartsWith,
|
||||||
|
Arguments: []interface{}{
|
||||||
|
parsers.SelectItem{
|
||||||
|
Path: []string{"c", "id"},
|
||||||
|
Type: parsers.SelectItemTypeField,
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeString,
|
||||||
|
Value: "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
parsers.SelectItem{
|
||||||
|
Type: parsers.SelectItemTypeConstant,
|
||||||
|
Value: parsers.Constant{
|
||||||
|
Type: parsers.ConstantTypeBoolean,
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
},
|
||||||
|
mockData,
|
||||||
|
[]memoryexecutor.RowType{
|
||||||
|
map[string]interface{}{"id": "123", "starts": true},
|
||||||
|
map[string]interface{}{"id": "456", "starts": false},
|
||||||
|
map[string]interface{}{"id": "789", "starts": false},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -8,30 +8,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func strings_StringEquals(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
func strings_StringEquals(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||||
ignoreCase := false
|
str1 := parseString(arguments[0], queryParameters, row)
|
||||||
if len(arguments) > 2 && arguments[2] != nil {
|
str2 := parseString(arguments[1], queryParameters, row)
|
||||||
ignoreCaseItem := arguments[2].(parsers.SelectItem)
|
ignoreCase := getBoolFlag(arguments, queryParameters, row)
|
||||||
if value, ok := getFieldValue(ignoreCaseItem, queryParameters, row).(bool); ok {
|
|
||||||
ignoreCase = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ex1Item := arguments[0].(parsers.SelectItem)
|
|
||||||
ex2Item := arguments[1].(parsers.SelectItem)
|
|
||||||
|
|
||||||
ex1 := getFieldValue(ex1Item, queryParameters, row)
|
|
||||||
ex2 := getFieldValue(ex2Item, queryParameters, row)
|
|
||||||
|
|
||||||
var ok bool
|
|
||||||
var str1 string
|
|
||||||
var str2 string
|
|
||||||
|
|
||||||
if str1, ok = ex1.(string); !ok {
|
|
||||||
fmt.Println("StringEquals got parameters of wrong type")
|
|
||||||
}
|
|
||||||
if str2, ok = ex2.(string); !ok {
|
|
||||||
fmt.Println("StringEquals got parameters of wrong type")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ignoreCase {
|
if ignoreCase {
|
||||||
return strings.EqualFold(str1, str2)
|
return strings.EqualFold(str1, str2)
|
||||||
@ -41,30 +20,9 @@ func strings_StringEquals(arguments []interface{}, queryParameters map[string]in
|
|||||||
}
|
}
|
||||||
|
|
||||||
func strings_Contains(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
func strings_Contains(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||||
ignoreCase := false
|
str1 := parseString(arguments[0], queryParameters, row)
|
||||||
if len(arguments) > 2 && arguments[2] != nil {
|
str2 := parseString(arguments[1], queryParameters, row)
|
||||||
ignoreCaseItem := arguments[2].(parsers.SelectItem)
|
ignoreCase := getBoolFlag(arguments, queryParameters, row)
|
||||||
if value, ok := getFieldValue(ignoreCaseItem, queryParameters, row).(bool); ok {
|
|
||||||
ignoreCase = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ex1Item := arguments[0].(parsers.SelectItem)
|
|
||||||
ex2Item := arguments[1].(parsers.SelectItem)
|
|
||||||
|
|
||||||
ex1 := getFieldValue(ex1Item, queryParameters, row)
|
|
||||||
ex2 := getFieldValue(ex2Item, queryParameters, row)
|
|
||||||
|
|
||||||
var ok bool
|
|
||||||
var str1 string
|
|
||||||
var str2 string
|
|
||||||
|
|
||||||
if str1, ok = ex1.(string); !ok {
|
|
||||||
fmt.Println("StringEquals got parameters of wrong type")
|
|
||||||
}
|
|
||||||
if str2, ok = ex2.(string); !ok {
|
|
||||||
fmt.Println("StringEquals got parameters of wrong type")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ignoreCase {
|
if ignoreCase {
|
||||||
str1 = strings.ToLower(str1)
|
str1 = strings.ToLower(str1)
|
||||||
@ -74,6 +32,32 @@ func strings_Contains(arguments []interface{}, queryParameters map[string]interf
|
|||||||
return strings.Contains(str1, str2)
|
return strings.Contains(str1, str2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func strings_EndsWith(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||||
|
str1 := parseString(arguments[0], queryParameters, row)
|
||||||
|
str2 := parseString(arguments[1], queryParameters, row)
|
||||||
|
ignoreCase := getBoolFlag(arguments, queryParameters, row)
|
||||||
|
|
||||||
|
if ignoreCase {
|
||||||
|
str1 = strings.ToLower(str1)
|
||||||
|
str2 = strings.ToLower(str2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.HasSuffix(str1, str2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func strings_StartsWith(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||||
|
str1 := parseString(arguments[0], queryParameters, row)
|
||||||
|
str2 := parseString(arguments[1], queryParameters, row)
|
||||||
|
ignoreCase := getBoolFlag(arguments, queryParameters, row)
|
||||||
|
|
||||||
|
if ignoreCase {
|
||||||
|
str1 = strings.ToLower(str1)
|
||||||
|
str2 = strings.ToLower(str2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.HasPrefix(str1, str2)
|
||||||
|
}
|
||||||
|
|
||||||
func strings_Concat(arguments []interface{}, queryParameters map[string]interface{}, row RowType) string {
|
func strings_Concat(arguments []interface{}, queryParameters map[string]interface{}, row RowType) string {
|
||||||
result := ""
|
result := ""
|
||||||
|
|
||||||
@ -87,6 +71,29 @@ func strings_Concat(arguments []interface{}, queryParameters map[string]interfac
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getBoolFlag(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||||
|
ignoreCase := false
|
||||||
|
if len(arguments) > 2 && arguments[2] != nil {
|
||||||
|
ignoreCaseItem := arguments[2].(parsers.SelectItem)
|
||||||
|
if value, ok := getFieldValue(ignoreCaseItem, queryParameters, row).(bool); ok {
|
||||||
|
ignoreCase = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ignoreCase
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseString(argument interface{}, queryParameters map[string]interface{}, row RowType) string {
|
||||||
|
exItem := argument.(parsers.SelectItem)
|
||||||
|
ex := getFieldValue(exItem, queryParameters, row)
|
||||||
|
if str1, ok := ex.(string); ok {
|
||||||
|
fmt.Println("StringEquals got parameters of wrong type")
|
||||||
|
return str1
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func convertToString(value interface{}) string {
|
func convertToString(value interface{}) string {
|
||||||
switch v := value.(type) {
|
switch v := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
|
Loading…
Reference in New Issue
Block a user