From f4569be170efed332bc58860be81646d27db3fbb Mon Sep 17 00:00:00 2001 From: Stefano Scafiti Date: Fri, 29 Nov 2024 19:58:01 +0100 Subject: [PATCH] fix(embedded/sql): correctly handle logical operator precedence (NOT, AND, OR) Signed-off-by: Stefano Scafiti --- embedded/document/engine.go | 4 +- embedded/sql/parser.go | 13 +- embedded/sql/parser_test.go | 75 +++++-- embedded/sql/sql_grammar.y | 19 +- embedded/sql/sql_parser.go | 423 ++++++++++++++++++------------------ embedded/sql/stmt.go | 22 +- embedded/sql/stmt_test.go | 10 +- 7 files changed, 312 insertions(+), 254 deletions(-) diff --git a/embedded/document/engine.go b/embedded/document/engine.go index 2f752353ed..906bf408c3 100644 --- a/embedded/document/engine.go +++ b/embedded/document/engine.go @@ -1175,14 +1175,14 @@ func generateSQLFilteringExpression(expressions []*protomodel.QueryExpression, t if i == 0 { innerExp = fieldExp } else { - innerExp = sql.NewBinBoolExp(sql.AND, innerExp, fieldExp) + innerExp = sql.NewBinBoolExp(sql.And, innerExp, fieldExp) } } if i == 0 { outerExp = innerExp } else { - outerExp = sql.NewBinBoolExp(sql.OR, outerExp, innerExp) + outerExp = sql.NewBinBoolExp(sql.Or, outerExp, innerExp) } } diff --git a/embedded/sql/parser.go b/embedded/sql/parser.go index 7fb6f776f2..6b0e0b9277 100644 --- a/embedded/sql/parser.go +++ b/embedded/sql/parser.go @@ -83,6 +83,8 @@ var reservedWords = map[string]int{ "AS": AS, "ASC": ASC, "DESC": DESC, + "AND": AND, + "OR": OR, "NOT": NOT, "LIKE": LIKE, "EXISTS": EXISTS, @@ -157,11 +159,6 @@ var cmpOps = map[string]CmpOperator{ ">=": GE, } -var logicOps = map[string]LogicOperator{ - "AND": AND, - "OR": OR, -} - var ErrEitherNamedOrUnnamedParams = errors.New("either named or unnamed params") var ErrEitherPosOrNonPosParams = errors.New("either positional or non-positional named params") var ErrInvalidPositionalParameter = errors.New("invalid positional parameter") @@ -348,12 +345,6 @@ func (l *lexer) Lex(lval *yySymType) int { return BOOLEAN } - lop, ok := logicOps[tid] - if ok { - lval.logicOp = lop - return LOP - } - afn, ok := aggregateFns[tid] if ok { lval.aggFn = afn diff --git a/embedded/sql/parser_test.go b/embedded/sql/parser_test.go index 56c3ca0d9a..4c6efc679e 100644 --- a/embedded/sql/parser_test.go +++ b/embedded/sql/parser_test.go @@ -659,7 +659,7 @@ func TestInsertIntoStmt(t *testing.T) { }, targets: nil, where: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{op: GE, left: &ColSelector{col: "balance"}, right: &Integer{val: 0}}, right: &CmpBoolExp{op: EQ, left: &ColSelector{col: "deleted_at"}, right: &NullValue{t: AnyType}}, }, @@ -1009,9 +1009,9 @@ func TestSelectStmt(t *testing.T) { }, ds: &tableRef{table: "table1"}, where: &BinBoolExp{ - op: AND, + op: And, left: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{ op: EQ, left: &ColSelector{ @@ -1208,7 +1208,7 @@ func TestSelectStmt(t *testing.T) { }, ds: &tableRef{table: "table1"}, where: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{ op: GE, left: &ColSelector{ @@ -1421,7 +1421,7 @@ func TestParseExp(t *testing.T) { }, ds: &tableRef{table: "table1"}, where: &BinBoolExp{ - op: AND, + op: And, left: &NotBoolExp{ exp: &CmpBoolExp{ op: GT, @@ -1453,7 +1453,7 @@ func TestParseExp(t *testing.T) { ds: &tableRef{table: "table1"}, where: &NotBoolExp{ exp: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{ op: GT, left: &ColSelector{ @@ -1483,7 +1483,7 @@ func TestParseExp(t *testing.T) { }, ds: &tableRef{table: "table1"}, where: &BinBoolExp{ - op: OR, + op: Or, left: &NotBoolExp{ exp: &ColSelector{col: "active"}, }, @@ -1502,7 +1502,7 @@ func TestParseExp(t *testing.T) { }, ds: &tableRef{table: "table1"}, where: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{ op: GT, left: &ColSelector{ @@ -1572,9 +1572,9 @@ func TestParseExp(t *testing.T) { }, ds: &tableRef{table: "table1"}, where: &BinBoolExp{ - op: OR, + op: Or, left: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{ op: GT, left: &ColSelector{ @@ -1711,7 +1711,7 @@ func TestParseExp(t *testing.T) { whenThen: []whenThenClause{ { when: &BinBoolExp{ - op: OR, + op: Or, left: &ColSelector{col: "is_deleted"}, right: &ColSelector{col: "is_expired"}, }, @@ -1736,7 +1736,7 @@ func TestParseExp(t *testing.T) { whenThen: []whenThenClause{ { when: &BinBoolExp{ - op: OR, + op: Or, left: &ColSelector{col: "is_deleted"}, right: &ColSelector{col: "is_expired"}, }, @@ -1798,7 +1798,7 @@ func TestParseExp(t *testing.T) { }, { when: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{op: GE, left: &ColSelector{col: "stock"}, right: &Integer{10}}, right: &CmpBoolExp{op: LE, left: &ColSelector{col: "stock"}, right: &Integer{50}}, }, @@ -1898,7 +1898,7 @@ func TestMultiLineStmts(t *testing.T) { }, ds: &tableRef{table: "table1"}, where: &BinBoolExp{ - op: AND, + op: And, left: &CmpBoolExp{ op: GE, left: &ColSelector{ @@ -2033,7 +2033,7 @@ func TestGrantRevokeStmt(t *testing.T) { } } -func TestExprString(t *testing.T) { +func TestExpString(t *testing.T) { exps := []string{ "(1 + 1) / (2 * 5 - 10) % 2", "@param LIKE 'pattern'", @@ -2043,6 +2043,8 @@ func TestExprString(t *testing.T) { "CASE WHEN in_stock THEN 'In Stock' END", "CASE WHEN 1 > 0 THEN 1 ELSE 0 END", "CASE WHEN is_active THEN 'active' WHEN is_expired THEN 'expired' ELSE 'active' END", + "'text' LIKE 'pattern'", + "'text' NOT LIKE 'pattern'", } for i, e := range exps { @@ -2056,3 +2058,46 @@ func TestExprString(t *testing.T) { }) } } + +func TestLogicOperatorPrecedence(t *testing.T) { + type testCase struct { + input string + expected string + } + + testCases := []testCase{ + // simple precedence + {input: "NOT true", expected: "(NOT true)"}, + {input: "true AND false OR true", expected: "((true AND false) OR true)"}, + {input: "NOT true AND false", expected: "((NOT true) AND false)"}, + {input: "NOT true OR false", expected: "((NOT true) OR false)"}, + + // parentheses override precedence + {input: "(true OR false) AND true", expected: "((true OR false) AND true)"}, + + // multiple NOTs + {input: "NOT NOT true AND false", expected: "((NOT (NOT true)) AND false)"}, + + // complex nesting + {input: "true AND (false OR (NOT false))", expected: "(true AND (false OR (NOT false)))"}, + {input: "NOT (true AND false) OR true", expected: "((NOT (true AND false)) OR true)"}, + + // AND/OR with nested groups + {input: "(true AND false) AND (true OR false)", expected: "((true AND false) AND (true OR false))"}, + {input: "(true OR false) OR (NOT (true AND false))", expected: "((true OR false) OR (NOT (true AND false)))"}, + + // deep nesting + {input: "(true AND (false OR (NOT true))) OR (NOT false)", expected: "((true AND (false OR (NOT true))) OR (NOT false))"}, + + // chain of operators + {input: "true AND false OR true AND NOT false OR true", expected: "(((true AND false) OR (true AND (NOT false))) OR true)"}, + } + + for _, tc := range testCases { + t.Run(tc.input, func(t *testing.T) { + e, err := ParseExpFromString(tc.input) + require.NoError(t, err) + require.Equal(t, tc.expected, e.String()) + }) + } +} diff --git a/embedded/sql/sql_grammar.y b/embedded/sql/sql_grammar.y index fb29908ac8..2898e16412 100644 --- a/embedded/sql/sql_grammar.y +++ b/embedded/sql/sql_grammar.y @@ -86,7 +86,7 @@ func setResult(l yyLexer, stmts []SQLStmt) { %token NPARAM %token PPARAM %token JOINTYPE -%token LOP +%token AND OR %token CMPOP %token IDENTIFIER %token TYPE @@ -102,10 +102,14 @@ func setResult(l yyLexer, stmts []SQLStmt) { %left ',' %right AS -%left LOP + +%left OR +%left AND + %right LIKE %right NOT -%left CMPOP + +%left CMPOP %left '+' '-' %left '*' '/' '%' %left '.' @@ -1216,9 +1220,14 @@ binExp: $$ = &NumExp{left: $1, op: MODOP, right: $3} } | - exp LOP exp + exp AND exp + { + $$ = &BinBoolExp{left: $1, op: And, right: $3} + } +| + exp OR exp { - $$ = &BinBoolExp{left: $1, op: $2, right: $3} + $$ = &BinBoolExp{left: $1, op: Or, right: $3} } | exp CMPOP exp diff --git a/embedded/sql/sql_parser.go b/embedded/sql/sql_parser.go index bfe0d094d1..e19f1e3f05 100644 --- a/embedded/sql/sql_parser.go +++ b/embedded/sql/sql_parser.go @@ -151,20 +151,21 @@ const USERS = 57432 const NPARAM = 57433 const PPARAM = 57434 const JOINTYPE = 57435 -const LOP = 57436 -const CMPOP = 57437 -const IDENTIFIER = 57438 -const TYPE = 57439 -const INTEGER = 57440 -const FLOAT = 57441 -const VARCHAR = 57442 -const BOOLEAN = 57443 -const BLOB = 57444 -const AGGREGATE_FUNC = 57445 -const ERROR = 57446 -const DOT = 57447 -const ARROW = 57448 -const STMT_SEPARATOR = 57449 +const AND = 57436 +const OR = 57437 +const CMPOP = 57438 +const IDENTIFIER = 57439 +const TYPE = 57440 +const INTEGER = 57441 +const FLOAT = 57442 +const VARCHAR = 57443 +const BOOLEAN = 57444 +const BLOB = 57445 +const AGGREGATE_FUNC = 57446 +const ERROR = 57447 +const DOT = 57448 +const ARROW = 57449 +const STMT_SEPARATOR = 57450 var yyToknames = [...]string{ "$end", @@ -260,7 +261,8 @@ var yyToknames = [...]string{ "NPARAM", "PPARAM", "JOINTYPE", - "LOP", + "AND", + "OR", "CMPOP", "IDENTIFIER", "TYPE", @@ -301,136 +303,138 @@ var yyExca = [...]int16{ 78, 193, 81, 193, -2, 175, - -1, 268, + -1, 270, 59, 146, -2, 141, - -1, 318, + -1, 320, 59, 146, -2, 143, } const yyPrivate = 57344 -const yyLast = 593 +const yyLast = 611 var yyAct = [...]int16{ - 131, 431, 311, 107, 339, 153, 262, 355, 323, 201, - 115, 207, 322, 240, 245, 241, 317, 297, 306, 6, - 198, 71, 144, 22, 400, 147, 345, 260, 344, 260, - 419, 292, 130, 401, 362, 392, 403, 260, 384, 106, - 372, 260, 129, 363, 99, 161, 346, 101, 260, 391, - 301, 118, 114, 212, 21, 375, 371, 261, 116, 117, - 356, 369, 96, 119, 330, 109, 110, 111, 112, 113, - 108, 154, 155, 157, 156, 158, 100, 328, 327, 357, - 24, 325, 105, 178, 106, 291, 289, 288, 282, 99, - 259, 324, 101, 177, 296, 281, 118, 114, 177, 276, - 167, 168, 275, 116, 117, 274, 170, 172, 119, 149, - 109, 110, 111, 112, 113, 108, 273, 132, 210, 211, - 213, 100, 161, 247, 187, 180, 215, 105, 176, 175, - 169, 186, 143, 142, 159, 160, 145, 161, 430, 423, - 238, 362, 293, 292, 260, 209, 203, 420, 154, 155, - 157, 156, 158, 216, 236, 217, 218, 219, 220, 221, - 222, 223, 214, 152, 200, 157, 156, 158, 106, 204, - 184, 185, 83, 99, 234, 174, 101, 239, 242, 237, - 118, 114, 205, 178, 134, 287, 256, 116, 117, 230, - 249, 235, 119, 383, 109, 110, 111, 112, 113, 108, - 382, 337, 294, 32, 251, 100, 94, 267, 250, 342, - 33, 105, 341, 106, 265, 229, 238, 268, 99, 163, - 277, 101, 278, 199, 76, 118, 114, 378, 280, 271, - 269, 266, 116, 117, 286, 366, 350, 119, 349, 109, - 110, 111, 112, 113, 108, 348, 162, 329, 309, 148, - 100, 255, 254, 253, 252, 246, 105, 248, 243, 226, - 196, 195, 188, 181, 313, 150, 133, 122, 295, 120, - 91, 54, 315, 246, 303, 321, 161, 80, 79, 308, - 310, 308, 242, 78, 75, 334, 335, 70, 159, 160, - 320, 69, 31, 338, 77, 206, 22, 332, 166, 58, - 399, 331, 154, 155, 157, 156, 158, 165, 340, 381, - 231, 279, 398, 354, 60, 272, 380, 347, 358, 163, - 353, 225, 179, 161, 65, 242, 227, 21, 224, 228, - 121, 365, 161, 367, 368, 360, 370, 374, 364, 359, - 432, 433, 377, 333, 159, 160, 162, 284, 270, 285, - 233, 90, 55, 39, 414, 161, 22, 312, 154, 155, - 157, 156, 158, 161, 56, 57, 59, 159, 160, 49, - 263, 390, 214, 389, 393, 159, 160, 422, 386, 406, - 388, 154, 155, 157, 156, 158, 64, 21, 395, 154, - 155, 157, 156, 158, 145, 405, 307, 411, 408, 407, - 410, 361, 409, 151, 22, 52, 415, 62, 373, 412, - 417, 402, 385, 336, 66, 67, 161, 88, 51, 424, - 421, 161, 50, 428, 426, 425, 25, 429, 159, 160, - 82, 434, 92, 159, 160, 21, 435, 140, 396, 290, - 394, 161, 154, 155, 157, 156, 158, 154, 155, 157, - 156, 158, 161, 159, 160, 124, 208, 376, 189, 161, - 10, 12, 11, 342, 159, 160, 341, 154, 155, 157, - 156, 158, 160, 43, 47, 302, 53, 258, 154, 155, - 157, 156, 158, 13, 257, 154, 155, 157, 156, 158, - 192, 193, 14, 15, 190, 191, 48, 7, 137, 8, - 9, 16, 17, 418, 352, 18, 19, 85, 86, 87, - 26, 30, 22, 314, 44, 36, 182, 123, 46, 45, - 84, 135, 136, 81, 264, 42, 27, 29, 28, 68, - 34, 2, 35, 38, 326, 128, 127, 73, 74, 194, - 40, 183, 305, 21, 298, 299, 300, 138, 37, 125, - 304, 141, 139, 202, 23, 232, 63, 41, 351, 146, - 164, 379, 397, 413, 427, 343, 95, 93, 102, 387, - 98, 283, 97, 404, 171, 319, 318, 316, 126, 72, - 89, 61, 173, 103, 104, 416, 197, 244, 20, 5, - 4, 3, 1, + 131, 433, 313, 107, 341, 153, 264, 357, 325, 202, + 208, 115, 324, 242, 247, 243, 319, 308, 6, 299, + 199, 71, 144, 22, 402, 147, 347, 262, 346, 262, + 421, 294, 130, 403, 364, 394, 405, 262, 386, 106, + 374, 262, 129, 365, 99, 162, 348, 101, 262, 393, + 303, 118, 114, 377, 21, 373, 371, 263, 116, 117, + 332, 358, 96, 330, 119, 329, 109, 110, 111, 112, + 113, 108, 154, 155, 157, 156, 158, 100, 327, 293, + 359, 179, 291, 105, 106, 290, 284, 261, 326, 99, + 298, 178, 101, 283, 178, 278, 118, 114, 277, 276, + 168, 169, 275, 116, 117, 249, 171, 173, 149, 119, + 162, 109, 110, 111, 112, 113, 108, 132, 188, 181, + 177, 162, 100, 176, 161, 170, 143, 142, 105, 24, + 240, 187, 432, 159, 160, 161, 162, 154, 155, 157, + 156, 158, 425, 145, 238, 364, 204, 422, 154, 155, + 157, 156, 158, 217, 295, 218, 219, 220, 221, 222, + 223, 224, 225, 215, 201, 157, 156, 158, 294, 205, + 185, 186, 162, 262, 152, 83, 236, 175, 241, 244, + 239, 179, 213, 134, 159, 160, 161, 289, 258, 232, + 206, 339, 251, 237, 385, 384, 164, 296, 231, 154, + 155, 157, 156, 158, 32, 253, 240, 233, 269, 252, + 200, 33, 76, 380, 106, 267, 368, 352, 270, 99, + 351, 279, 101, 280, 163, 344, 118, 114, 343, 273, + 282, 271, 268, 116, 117, 350, 288, 331, 311, 119, + 148, 109, 110, 111, 112, 113, 108, 211, 212, 214, + 257, 256, 100, 94, 255, 254, 216, 248, 105, 250, + 245, 228, 197, 196, 189, 182, 315, 150, 133, 122, + 297, 120, 91, 54, 317, 210, 80, 323, 305, 79, + 310, 312, 310, 77, 244, 78, 75, 336, 337, 70, + 248, 69, 207, 322, 31, 340, 58, 22, 167, 334, + 401, 383, 333, 434, 435, 227, 281, 166, 382, 274, + 342, 60, 226, 309, 400, 356, 162, 180, 162, 349, + 360, 22, 355, 229, 121, 65, 230, 244, 21, 335, + 159, 160, 161, 367, 235, 369, 370, 362, 372, 376, + 366, 361, 272, 90, 379, 154, 155, 157, 156, 158, + 22, 314, 21, 39, 286, 55, 287, 416, 424, 106, + 265, 56, 57, 59, 99, 64, 408, 101, 390, 49, + 145, 118, 114, 392, 391, 215, 395, 407, 116, 117, + 388, 21, 363, 151, 119, 52, 109, 110, 111, 112, + 113, 108, 62, 66, 67, 414, 404, 100, 88, 413, + 410, 409, 412, 105, 411, 387, 51, 50, 417, 25, + 82, 92, 419, 344, 398, 164, 343, 396, 162, 378, + 190, 426, 423, 193, 194, 430, 428, 427, 162, 431, + 159, 160, 161, 436, 124, 191, 192, 140, 437, 137, + 159, 160, 161, 163, 397, 154, 155, 157, 156, 158, + 304, 260, 375, 259, 420, 154, 155, 157, 156, 158, + 162, 338, 135, 136, 354, 316, 183, 292, 123, 162, + 84, 81, 159, 160, 161, 266, 68, 328, 2, 195, + 162, 159, 160, 161, 128, 127, 184, 154, 155, 157, + 156, 158, 159, 160, 161, 138, 154, 155, 157, 156, + 158, 162, 36, 63, 43, 47, 162, 154, 155, 157, + 156, 158, 125, 159, 160, 161, 307, 34, 159, 35, + 161, 10, 12, 11, 38, 141, 209, 48, 154, 155, + 157, 156, 158, 154, 155, 157, 156, 158, 306, 37, + 73, 74, 139, 203, 13, 44, 53, 23, 234, 46, + 45, 41, 353, 14, 15, 146, 42, 165, 7, 381, + 8, 9, 16, 17, 26, 30, 18, 19, 399, 415, + 429, 40, 345, 22, 300, 301, 302, 85, 86, 87, + 27, 29, 28, 95, 93, 102, 389, 98, 285, 97, + 406, 172, 321, 320, 318, 126, 72, 89, 61, 174, + 103, 104, 418, 198, 21, 246, 20, 5, 4, 3, + 1, } var yyPact = [...]int16{ - 456, -1000, -1000, -34, -1000, -1000, -1000, 384, -1000, -1000, - 503, 196, 507, 525, 469, 469, 375, 371, 347, 175, - 282, 276, 350, -1000, 456, -1000, 245, 245, 245, 504, - 195, -1000, 191, 521, 188, 198, 187, 182, 181, 497, - 390, 65, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 494, - 175, 175, 175, 366, -1000, 280, -1000, -1000, 174, -1000, - 393, 96, -1000, -1000, 173, 253, 171, 491, 245, 540, - -1000, -1000, 517, 12, 12, -1000, 170, 79, -1000, 493, - 538, 545, -1000, 469, 544, 18, 17, 333, 153, 240, - -1000, -1000, 169, 345, -1000, 56, 250, 221, -1000, 141, - 141, 15, -1000, -1000, -1000, 141, 141, 69, 14, -1000, - -1000, -1000, -1000, -1000, 13, -1000, -1000, -1000, -1000, -22, - -1000, 242, 10, 167, 490, 531, -1000, 12, 12, -1000, - 141, 359, -1000, 9, 166, 427, 464, 459, 529, 165, - -1000, 164, 127, 127, 547, 141, 75, -1000, 200, -1000, - -1000, 30, 141, -1000, 141, 141, 141, 141, 141, 141, - 141, 244, -1000, 163, 248, 118, -1000, 377, 55, 240, - 194, 277, 359, 68, 91, 44, 141, 141, 162, -1000, - 159, 8, 161, 90, -1000, -1000, 359, 127, -1000, 159, - 158, 157, 156, 155, 86, 454, 447, -26, 37, -1000, - -59, 306, 499, 359, 547, 153, 141, 547, 521, 300, - 1, -10, -13, -16, 150, -17, 250, 55, 55, 241, - 241, 241, 377, -37, -1000, 227, -1000, 141, -20, -1000, - -28, -1000, 274, 141, 85, -1000, -29, -30, 78, 370, - -31, 36, 359, -1000, 35, -1000, 105, 127, -21, 533, - -66, -1000, -1000, 445, -1000, -1000, 533, 542, 534, 348, - 152, 348, 292, 141, 487, 306, -1000, 359, 197, 150, - -24, -35, 513, -38, -39, 151, -52, -1000, -1000, -1000, - 377, -33, -1000, 267, 141, 141, 339, -1000, -1000, -1000, - 104, -1000, 141, 177, -89, -70, 127, -1000, -1000, -1000, - -1000, -1000, 149, -1000, 142, 140, 478, -24, -1000, -1000, - -1000, -1000, 141, 359, -36, 292, 333, -1000, 197, 342, - -1000, -1000, -73, -1000, 141, 150, 139, 150, 150, -55, - 150, -60, -76, -1000, 334, 359, 141, -61, 359, 424, - -1000, 141, 131, 232, 102, 95, -1000, -78, -1000, -1000, - -1000, -1000, 360, 34, 359, -1000, -1000, 127, -1000, 318, - -1000, 30, -24, -1000, -67, -1000, -81, -1000, -1000, -1000, - -1000, -1000, -1000, 141, 359, -1000, 406, 281, 403, 229, - -1000, 216, -94, -83, -1000, 358, -80, 335, 316, 547, - -1000, -1000, 150, 359, -36, 431, 141, -1000, -1000, -1000, - -1000, -1000, 355, -1000, 288, 141, 120, 477, -1000, -86, - -1000, 40, -1000, 306, 314, 359, 32, -1000, 141, -1000, - 431, 292, 141, 120, 359, -1000, -1000, 31, 273, -1000, - 141, -1000, -1000, -1000, 273, -1000, + 517, -1000, -1000, 14, -1000, -1000, -1000, 367, -1000, -1000, + 557, 197, 494, 516, 500, 500, 360, 359, 327, 176, + 285, 273, 335, -1000, 517, -1000, 246, 246, 246, 451, + 194, -1000, 192, 524, 189, 186, 188, 182, 179, 445, + 370, 67, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 444, + 176, 176, 176, 347, -1000, 272, -1000, -1000, 175, -1000, + 372, 142, -1000, -1000, 174, 247, 172, 442, 246, 503, + -1000, -1000, 466, 12, 12, -1000, 171, 77, -1000, 434, + 486, 535, -1000, 500, 518, 11, 10, 309, 143, 241, + -1000, -1000, 170, 325, -1000, 66, 346, 221, -1000, 287, + 287, 9, -1000, -1000, -1000, 287, 287, 70, 7, -1000, + -1000, -1000, -1000, -1000, 4, -1000, -1000, -1000, -1000, -25, + -1000, 237, 3, 168, 440, 476, -1000, 12, 12, -1000, + 287, 419, -1000, 2, 167, 389, 405, 392, 469, 166, + -1000, 165, 113, 113, 537, 287, 82, -1000, 196, -1000, + -1000, 159, 287, -1000, 287, 287, 287, 287, 287, 287, + 287, 287, 228, -1000, 164, 245, 100, -1000, 28, 54, + 241, 90, 261, 419, 69, 92, 33, 287, 287, 163, + -1000, 160, -11, 162, 91, -1000, -1000, 419, 113, -1000, + 160, 158, 157, 154, 153, 87, 423, 421, -30, 65, + -1000, -60, 296, 450, 419, 537, 143, 287, 537, 524, + 294, -14, -17, -18, -21, 127, -22, 346, 54, 54, + 234, 234, 234, 28, 424, -37, -1000, 222, -1000, 287, + -23, -1000, -31, -1000, 281, 287, 86, -1000, -32, -35, + 75, 398, -38, 60, 419, -1000, 46, -1000, 99, 113, + -26, 563, -67, -1000, -1000, 420, -1000, -1000, 563, 530, + 508, 265, 141, 265, 286, 287, 439, 296, -1000, 419, + 200, 127, -28, -39, 456, -52, -54, 140, -57, -1000, + -1000, -1000, 28, -33, -1000, 253, 287, 287, 387, -1000, + -1000, -1000, 93, -1000, 287, 193, -90, -71, 113, -1000, + -1000, -1000, -1000, -1000, 138, -1000, 123, 120, 438, -28, + -1000, -1000, -1000, -1000, 287, 419, -36, 286, 309, -1000, + 200, 323, -1000, -1000, -74, -1000, 287, 127, 119, 127, + 127, -61, 127, -62, -77, -1000, 378, 419, 287, -64, + 419, 386, -1000, 287, 116, 224, 96, 95, -1000, -79, + -1000, -1000, -1000, -1000, 353, 37, 419, -1000, -1000, 113, + -1000, 306, -1000, 159, -28, -1000, -68, -1000, -82, -1000, + -1000, -1000, -1000, -1000, -1000, 287, 419, -1000, 383, 336, + 379, 231, -1000, 216, -95, -84, -1000, 343, -81, 317, + 303, 537, -1000, -1000, 127, 419, -36, 381, 287, -1000, + -1000, -1000, -1000, -1000, 341, -1000, 291, 287, 109, 428, + -1000, -87, -1000, 39, -1000, 296, 295, 419, 34, -1000, + 287, -1000, 381, 286, 287, 109, 419, -1000, -1000, 24, + 236, -1000, 287, -1000, -1000, -1000, 236, -1000, } var yyPgo = [...]int16{ - 0, 592, 531, 591, 590, 589, 19, 588, 587, 14, - 20, 7, 586, 585, 12, 8, 15, 13, 584, 10, - 583, 582, 3, 581, 580, 11, 18, 456, 21, 579, - 578, 42, 577, 16, 576, 575, 4, 0, 574, 22, - 573, 572, 571, 570, 569, 6, 2, 568, 567, 566, - 565, 5, 564, 563, 1, 9, 386, 562, 561, 560, - 25, 559, 558, 17, 557, 353, 555, 554, + 0, 610, 478, 609, 608, 607, 18, 606, 605, 14, + 20, 7, 603, 602, 12, 8, 15, 13, 601, 11, + 600, 599, 3, 598, 597, 10, 17, 526, 21, 596, + 595, 42, 594, 16, 593, 592, 4, 0, 591, 22, + 590, 589, 588, 587, 586, 6, 2, 585, 584, 583, + 572, 5, 570, 569, 1, 9, 365, 568, 559, 557, + 25, 555, 552, 19, 551, 353, 548, 547, } var yyR1 = [...]int8{ @@ -454,7 +458,7 @@ var yyR1 = [...]int8{ 36, 36, 36, 38, 38, 37, 37, 37, 37, 37, 37, 37, 37, 37, 47, 66, 66, 42, 42, 41, 41, 41, 41, 59, 59, 43, 43, 43, 43, 43, - 43, 43, 43, 43, + 43, 43, 43, 43, 43, } var yyR2 = [...]int8{ @@ -478,54 +482,54 @@ var yyR2 = [...]int8{ 0, 4, 6, 0, 1, 1, 1, 2, 2, 4, 4, 6, 6, 1, 5, 4, 5, 0, 2, 1, 1, 3, 3, 0, 1, 3, 3, 3, 3, 3, - 3, 3, 3, 4, + 3, 3, 3, 3, 4, } var yyChk = [...]int16{ -1000, -1, -2, -3, -4, -5, -6, 41, 43, 44, 4, 6, 5, 27, 36, 37, 45, 46, 49, 50, - -7, 87, 56, -67, 114, 42, 7, 23, 25, 24, - 8, 96, 7, 14, 23, 25, 8, 23, 8, -65, + -7, 87, 56, -67, 115, 42, 7, 23, 25, 24, + 8, 97, 7, 14, 23, 25, 8, 23, 8, -65, 71, -64, 56, 4, 45, 50, 49, 5, 27, -65, - 47, 47, 58, -27, 96, 70, 88, 89, 23, 90, - 38, -23, 57, -2, -56, 79, -56, -56, 25, 96, - 96, -28, -29, 16, 17, 96, 26, 96, 96, 96, - 96, 26, 40, 107, 26, -27, -27, -27, 51, -24, - 71, 96, 39, -48, 110, -49, -37, -41, -43, 77, - 109, 80, -47, -20, -18, 115, 72, -22, 103, 98, - 99, 100, 101, 102, 85, -19, 91, 92, 84, 96, - 96, 77, 96, 26, -56, 9, -30, 19, 18, -31, - 20, -37, -31, 96, 105, 28, 29, 5, 9, 7, - -65, 7, 115, 115, -39, 61, -61, -60, 96, -6, - 96, 58, 107, -51, 108, 109, 111, 110, 112, 94, - 95, 82, 96, 69, -59, 86, 77, -37, -37, 115, - -37, -38, -37, -21, 106, 115, 115, 115, 105, 80, - 115, 96, 26, 10, -31, -31, -37, 115, 96, 31, - 30, 31, 31, 32, 10, 96, 96, -12, -10, 96, - -10, -55, 6, -37, -39, 107, 95, -25, -27, 115, - 88, 89, 23, 90, -19, 96, -37, -37, -37, -37, - -37, -37, -37, -37, 84, 77, 96, 78, 81, 97, - -6, 116, -66, 73, 106, 100, 110, -22, 96, -37, - -17, -16, -37, 96, -8, -9, 96, 115, 96, 100, - -10, -9, 96, 96, 96, 96, 100, 30, 30, 116, - 107, 116, -45, 64, 25, -55, -60, -37, -55, -28, - 48, -6, 15, 115, 115, 115, 115, -51, -51, 84, - -37, 115, 116, -42, 73, 75, -37, 100, 116, 116, - 69, 116, 107, 107, 97, -10, 115, -63, 11, 12, - 13, 116, 30, -63, 8, 8, -26, 48, -6, 96, - -26, -46, 65, -37, 26, -45, -32, -33, -34, -35, - 93, -51, -14, -15, 115, 116, 21, 116, 116, 96, - 116, -6, -16, 76, -37, -37, 74, 97, -37, -36, - -9, 35, 32, -50, 117, 115, 116, -10, 96, 96, - 96, -62, 26, -14, -37, -11, 96, 115, -46, -39, - -33, 59, 107, 116, -17, -51, 96, -51, -51, 116, - -51, 116, 116, 74, -37, 116, 33, -37, 96, -58, - 84, 77, 98, 98, 116, 52, -10, -44, 62, -25, - -15, 116, 116, -37, 34, 107, 35, -57, 83, 84, - 118, 116, 53, 116, -40, 60, 63, -55, -51, -11, - -36, -37, 54, -53, 66, -37, -13, -22, 26, 116, - 107, -45, 63, 107, -37, -36, -46, -52, -37, -22, - 107, -54, 67, 68, -37, -54, + 47, 47, 58, -27, 97, 70, 88, 89, 23, 90, + 38, -23, 57, -2, -56, 79, -56, -56, 25, 97, + 97, -28, -29, 16, 17, 97, 26, 97, 97, 97, + 97, 26, 40, 108, 26, -27, -27, -27, 51, -24, + 71, 97, 39, -48, 111, -49, -37, -41, -43, 77, + 110, 80, -47, -20, -18, 116, 72, -22, 104, 99, + 100, 101, 102, 103, 85, -19, 91, 92, 84, 97, + 97, 77, 97, 26, -56, 9, -30, 19, 18, -31, + 20, -37, -31, 97, 106, 28, 29, 5, 9, 7, + -65, 7, 116, 116, -39, 61, -61, -60, 97, -6, + 97, 58, 108, -51, 109, 110, 112, 111, 113, 94, + 95, 96, 82, 97, 69, -59, 86, 77, -37, -37, + 116, -37, -38, -37, -21, 107, 116, 116, 116, 106, + 80, 116, 97, 26, 10, -31, -31, -37, 116, 97, + 31, 30, 31, 31, 32, 10, 97, 97, -12, -10, + 97, -10, -55, 6, -37, -39, 108, 96, -25, -27, + 116, 88, 89, 23, 90, -19, 97, -37, -37, -37, + -37, -37, -37, -37, -37, -37, 84, 77, 97, 78, + 81, 98, -6, 117, -66, 73, 107, 101, 111, -22, + 97, -37, -17, -16, -37, 97, -8, -9, 97, 116, + 97, 101, -10, -9, 97, 97, 97, 97, 101, 30, + 30, 117, 108, 117, -45, 64, 25, -55, -60, -37, + -55, -28, 48, -6, 15, 116, 116, 116, 116, -51, + -51, 84, -37, 116, 117, -42, 73, 75, -37, 101, + 117, 117, 69, 117, 108, 108, 98, -10, 116, -63, + 11, 12, 13, 117, 30, -63, 8, 8, -26, 48, + -6, 97, -26, -46, 65, -37, 26, -45, -32, -33, + -34, -35, 93, -51, -14, -15, 116, 117, 21, 117, + 117, 97, 117, -6, -16, 76, -37, -37, 74, 98, + -37, -36, -9, 35, 32, -50, 118, 116, 117, -10, + 97, 97, 97, -62, 26, -14, -37, -11, 97, 116, + -46, -39, -33, 59, 108, 117, -17, -51, 97, -51, + -51, 117, -51, 117, 117, 74, -37, 117, 33, -37, + 97, -58, 84, 77, 99, 99, 117, 52, -10, -44, + 62, -25, -15, 117, 117, -37, 34, 108, 35, -57, + 83, 84, 119, 117, 53, 117, -40, 60, 63, -55, + -51, -11, -36, -37, 54, -53, 66, -37, -13, -22, + 26, 117, 108, -45, 63, 108, -37, -36, -46, -52, + -37, -22, 108, -54, 67, 68, -37, -54, } var yyDef = [...]int16{ @@ -545,47 +549,47 @@ var yyDef = [...]int16{ 0, 140, 135, 0, 0, 0, 0, 0, 0, 0, 35, 0, 62, 0, 160, 0, 148, 59, 0, 98, 104, 0, 0, 112, 0, 0, 0, 0, 0, 0, - 0, 0, 168, 0, 0, 0, 194, 177, 178, 0, - 0, 0, 174, 115, 0, 0, 0, 71, 0, 48, - 0, 0, 0, 0, 137, 138, 139, 0, 22, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 67, - 0, 154, 0, 149, 160, 0, 0, 160, 133, 0, - 0, 0, 0, 0, 167, 131, 167, 195, 196, 197, - 198, 199, 200, 201, 202, 0, 169, 0, 0, 192, - 0, 191, 187, 0, 0, 118, 0, 0, 120, 0, - 0, 72, 73, 121, 0, 86, 0, 0, 0, 43, - 0, 23, 24, 0, 26, 27, 43, 0, 0, 0, - 0, 0, 156, 0, 0, 154, 60, 61, -2, 167, - 0, 0, 0, 0, 0, 0, 0, 129, 113, 203, - 179, 0, 180, 0, 0, 0, 0, 119, 116, 117, - 0, 85, 0, 170, 89, 0, 0, 28, 44, 45, - 46, 21, 0, 29, 0, 0, 57, 0, 56, 68, - 52, 53, 0, 155, 0, 156, 148, 142, -2, 0, - 147, 122, 0, 64, 71, 167, 0, 167, 167, 0, - 167, 0, 0, 184, 0, 188, 0, 0, 74, 0, - 87, 0, 0, 94, 0, 0, 19, 0, 25, 31, - 32, 51, 0, 55, 157, 161, 49, 0, 54, 150, - 144, 0, 0, 123, 0, 124, 0, 125, 126, 127, - 128, 181, 182, 0, 185, 80, 0, 0, 0, 92, - 95, 0, 0, 0, 20, 0, 0, 152, 0, 160, - 65, 66, 167, 186, 0, 170, 0, 88, 93, 96, - 90, 91, 0, 50, 158, 0, 0, 0, 130, 0, - 171, 0, 58, 154, 0, 153, 151, 69, 0, 17, - 170, 156, 0, 0, 145, 172, 105, 159, 164, 70, - 0, 162, 165, 166, 164, 163, + 0, 0, 0, 168, 0, 0, 0, 194, 177, 178, + 0, 0, 0, 174, 115, 0, 0, 0, 71, 0, + 48, 0, 0, 0, 0, 137, 138, 139, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 67, 0, 154, 0, 149, 160, 0, 0, 160, 133, + 0, 0, 0, 0, 0, 167, 131, 167, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 0, 169, 0, + 0, 192, 0, 191, 187, 0, 0, 118, 0, 0, + 120, 0, 0, 72, 73, 121, 0, 86, 0, 0, + 0, 43, 0, 23, 24, 0, 26, 27, 43, 0, + 0, 0, 0, 0, 156, 0, 0, 154, 60, 61, + -2, 167, 0, 0, 0, 0, 0, 0, 0, 129, + 113, 204, 179, 0, 180, 0, 0, 0, 0, 119, + 116, 117, 0, 85, 0, 170, 89, 0, 0, 28, + 44, 45, 46, 21, 0, 29, 0, 0, 57, 0, + 56, 68, 52, 53, 0, 155, 0, 156, 148, 142, + -2, 0, 147, 122, 0, 64, 71, 167, 0, 167, + 167, 0, 167, 0, 0, 184, 0, 188, 0, 0, + 74, 0, 87, 0, 0, 94, 0, 0, 19, 0, + 25, 31, 32, 51, 0, 55, 157, 161, 49, 0, + 54, 150, 144, 0, 0, 123, 0, 124, 0, 125, + 126, 127, 128, 181, 182, 0, 185, 80, 0, 0, + 0, 92, 95, 0, 0, 0, 20, 0, 0, 152, + 0, 160, 65, 66, 167, 186, 0, 170, 0, 88, + 93, 96, 90, 91, 0, 50, 158, 0, 0, 0, + 130, 0, 171, 0, 58, 154, 0, 153, 151, 69, + 0, 17, 170, 156, 0, 0, 145, 172, 105, 159, + 164, 70, 0, 162, 165, 166, 164, 163, } var yyTok1 = [...]int8{ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 112, 3, 3, - 115, 116, 110, 108, 107, 109, 113, 111, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 113, 3, 3, + 116, 117, 111, 109, 108, 110, 114, 112, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 117, 3, 118, + 3, 118, 3, 119, } var yyTok2 = [...]int8{ @@ -599,7 +603,7 @@ var yyTok2 = [...]int8{ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 114, + 102, 103, 104, 105, 106, 107, 115, } var yyTok3 = [...]int8{ @@ -1960,19 +1964,24 @@ yydefault: case 200: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.binExp = &BinBoolExp{left: yyDollar[1].exp, op: yyDollar[2].logicOp, right: yyDollar[3].exp} + yyVAL.binExp = &BinBoolExp{left: yyDollar[1].exp, op: And, right: yyDollar[3].exp} } case 201: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.binExp = &CmpBoolExp{left: yyDollar[1].exp, op: yyDollar[2].cmpOp, right: yyDollar[3].exp} + yyVAL.binExp = &BinBoolExp{left: yyDollar[1].exp, op: Or, right: yyDollar[3].exp} } case 202: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.binExp = &CmpBoolExp{left: yyDollar[1].exp, op: EQ, right: &NullValue{t: AnyType}} + yyVAL.binExp = &CmpBoolExp{left: yyDollar[1].exp, op: yyDollar[2].cmpOp, right: yyDollar[3].exp} } case 203: + yyDollar = yyS[yypt-3 : yypt+1] + { + yyVAL.binExp = &CmpBoolExp{left: yyDollar[1].exp, op: EQ, right: &NullValue{t: AnyType}} + } + case 204: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.binExp = &CmpBoolExp{left: yyDollar[1].exp, op: NE, right: &NullValue{t: AnyType}} diff --git a/embedded/sql/stmt.go b/embedded/sql/stmt.go index c6cbe46d6c..3e51e83f1b 100644 --- a/embedded/sql/stmt.go +++ b/embedded/sql/stmt.go @@ -157,12 +157,12 @@ func CmpOperatorToString(op CmpOperator) string { type LogicOperator = int const ( - AND LogicOperator = iota - OR + And LogicOperator = iota + Or ) func LogicOperatorToString(op LogicOperator) string { - if op == AND { + if op == And { return "AND" } return "OR" @@ -4411,7 +4411,7 @@ func (bexp *NotBoolExp) selectorRanges(table *Table, asTable string, params map[ } func (bexp *NotBoolExp) String() string { - return "NOT " + bexp.exp.String() + return fmt.Sprintf("(NOT %s)", bexp.exp.String()) } type LikeBoolExp struct { @@ -4533,7 +4533,11 @@ func (bexp *LikeBoolExp) selectorRanges(table *Table, asTable string, params map } func (bexp *LikeBoolExp) String() string { - return fmt.Sprintf("(%s LIKE %s)", bexp.val.String(), bexp.pattern.String()) + fmtStr := "(%s LIKE %s)" + if bexp.notLike { + fmtStr = "(%s NOT LIKE %s)" + } + return fmt.Sprintf(fmtStr, bexp.val.String(), bexp.pattern.String()) } type CmpBoolExp struct { @@ -4887,7 +4891,7 @@ func (bexp *BinBoolExp) reduce(tx *SQLTx, row *Row, implicitTable string) (Typed } // short-circuit evaluation - if (bl.val && bexp.op == OR) || (!bl.val && bexp.op == AND) { + if (bl.val && bexp.op == Or) || (!bl.val && bexp.op == And) { return &Bool{val: bl.val}, nil } @@ -4902,11 +4906,11 @@ func (bexp *BinBoolExp) reduce(tx *SQLTx, row *Row, implicitTable string) (Typed } switch bexp.op { - case AND: + case And: { return &Bool{val: bl.val && br.val}, nil } - case OR: + case Or: { return &Bool{val: bl.val || br.val}, nil } @@ -4932,7 +4936,7 @@ func (bexp *BinBoolExp) isConstant() bool { } func (bexp *BinBoolExp) selectorRanges(table *Table, asTable string, params map[string]interface{}, rangesByColID map[uint32]*typedValueRange) error { - if bexp.op == AND { + if bexp.op == And { err := bexp.left.selectorRanges(table, asTable, params, rangesByColID) if err != nil { return err diff --git a/embedded/sql/stmt_test.go b/embedded/sql/stmt_test.go index 5f344ad63e..a3ecc3350d 100644 --- a/embedded/sql/stmt_test.go +++ b/embedded/sql/stmt_test.go @@ -717,7 +717,7 @@ func TestRequiresTypeBinValueExp(t *testing.T) { expectedError error }{ { - exp: &BinBoolExp{op: AND, left: &Bool{val: true}, right: &Bool{val: false}}, + exp: &BinBoolExp{op: And, left: &Bool{val: true}, right: &Bool{val: false}}, cols: cols, params: params, implicitTable: "mytable", @@ -725,7 +725,7 @@ func TestRequiresTypeBinValueExp(t *testing.T) { expectedError: nil, }, { - exp: &BinBoolExp{op: AND, left: &Bool{val: true}, right: &Bool{val: false}}, + exp: &BinBoolExp{op: And, left: &Bool{val: true}, right: &Bool{val: false}}, cols: cols, params: params, implicitTable: "mytable", @@ -733,7 +733,7 @@ func TestRequiresTypeBinValueExp(t *testing.T) { expectedError: ErrInvalidTypes, }, { - exp: &BinBoolExp{op: AND, left: &Integer{val: 1}, right: &Bool{val: false}}, + exp: &BinBoolExp{op: And, left: &Integer{val: 1}, right: &Bool{val: false}}, cols: cols, params: params, implicitTable: "mytable", @@ -741,7 +741,7 @@ func TestRequiresTypeBinValueExp(t *testing.T) { expectedError: ErrInvalidTypes, }, { - exp: &BinBoolExp{op: AND, left: &Bool{val: false}, right: &Integer{val: 1}}, + exp: &BinBoolExp{op: And, left: &Bool{val: false}, right: &Integer{val: 1}}, cols: cols, params: params, implicitTable: "mytable", @@ -1089,7 +1089,7 @@ func TestIsConstant(t *testing.T) { require.False(t, (&AggColSelector{}).isConstant()) require.True(t, (&NumExp{ - op: AND, + op: And, left: &Integer{val: 1}, right: &Integer{val: 2}, }).isConstant())