github.com/runner-mei/ql@v1.1.0/parser.y (about) 1 %{ 2 // Copyright (c) 2014 The ql Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 // Initial yacc source generated by ebnf2y[1] 7 // at 2013-10-04 23:10:47.861401015 +0200 CEST 8 // 9 // $ ebnf2y -o ql.y -oe ql.ebnf -start StatementList -pkg ql -p _ 10 // 11 // [1]: http://github.com/cznic/ebnf2y 12 13 package ql 14 15 import ( 16 "fmt" 17 18 "github.com/cznic/mathutil" 19 ) 20 21 %} 22 23 %union { 24 line int 25 col int 26 item interface{} 27 list []interface{} 28 } 29 30 %token <item> 31 32 /*yy:token "1.%d" */ floatLit "floating-point literal" 33 /*yy:token "%c" */ identifier "identifier" 34 /*yy:token "%di" */ imaginaryLit "imaginary literal" 35 /*yy:token "%d" */ intLit "integer literal" 36 /*yy:token "$%d" */ qlParam "QL parameter" 37 /*yy:token "\"%c\"" */ stringLit "string literal" 38 39 add "ADD" 40 alter "ALTER" 41 and "AND" 42 andand "&&" 43 andnot "&^" 44 as "AS" 45 asc "ASC" 46 begin "BEGIN" 47 between "BETWEEN" 48 bigIntType "bigint" 49 bigRatType "bigrat" 50 blobType "blob" 51 boolType "bool" 52 by "BY" 53 byteType "byte" 54 column "COLUMN" 55 commit "COMMIT" 56 complex128Type "complex128" 57 complex64Type "complex64" 58 create "CREATE" 59 defaultKwd "DEFAULT" 60 deleteKwd "DELETE" 61 desc "DESC" 62 distinct "DISTINCT" 63 drop "DROP" 64 durationType "duration" 65 eq "==" 66 exists "EXISTS" 67 explain "EXPLAIN" 68 falseKwd "false" 69 floatType "float" 70 float32Type "float32" 71 float64Type "float64" 72 from "FROM" 73 full "FULL" 74 ge ">=" 75 group "GROUP" 76 ifKwd "IF" 77 in "IN" 78 index "INDEX" 79 insert "INSERT" 80 intType "int" 81 int16Type "int16" 82 int32Type "int32" 83 int64Type "int64" 84 int8Type "int8" 85 into "INTO" 86 is "IS" 87 join "JOIN" 88 le "<=" 89 left "LEFT" 90 like "LIKE" 91 limit "LIMIT" 92 lsh "<<" 93 neq "!=" 94 not "NOT" 95 null "NULL" 96 offset "OFFSET" 97 on "ON" 98 or "OR" 99 order "ORDER" 100 oror "||" 101 outer "OUTER" 102 right "RIGHT" 103 rollback "ROLLBACK" 104 rsh ">>" 105 runeType "rune" 106 selectKwd "SELECT" 107 set "SET" 108 stringType "string" 109 tableKwd "TABLE" 110 timeType "time" 111 transaction "TRANSACTION" 112 trueKwd "true" 113 truncate "TRUNCATE" 114 uintType "uint" 115 uint16Type "uint16" 116 uint32Type "uint32" 117 uint64Type "uint64" 118 uint8Type "uint8", 119 unique "UNIQUE" 120 update "UPDATE" 121 values "VALUES" 122 where "WHERE" 123 124 parseExpression "parse expression prefix" 125 126 %type <item> 127 AlterTableStmt "ALTER TABLE statement" 128 Assignment "assignment" 129 AssignmentList "assignment list" 130 AssignmentList1 "assignment list optional trailing comma" 131 BeginTransactionStmt "BEGIN TRANSACTION statement" 132 Call "function call" 133 Call1 "function call optional argument list" 134 ColumnDef "table column definition" 135 ColumnName "column name" 136 ColumnNameList "column name list" 137 ColumnNameList1 "column name list with optional trailing comma" 138 CommaOpt "optional comma" 139 CommitStmt "COMMIT statement" 140 Constraint "column value constraint" 141 ConstraintOpt "optional column value constraint" 142 Conversion "conversion" 143 CreateIndexStmt "CREATE INDEX statement" 144 CreateIndexIfNotExists "CREATE INDEX statement optional IF NOT EXISTS cluse" 145 CreateIndexStmtUnique "CREATE INDEX optional UNIQUE clause" 146 CreateTableStmt "CREATE TABLE statement" 147 CreateTableStmt1 "CREATE TABLE statement colum definition list" 148 Default "DEFAULT clause" 149 DefaultOpt "optional DEFAULT clause" 150 DeleteFromStmt "DELETE FROM statement" 151 DropIndexStmt "DROP INDEX statement" 152 DropIndexIfExists "DROP INDEX statement optional IF EXISTS clause" 153 DropTableStmt "DROP TABLE statement" 154 EmptyStmt "empty statement" 155 ExplainStmt "EXPLAIN statement" 156 Expression "expression" 157 ExpressionList "expression list" 158 ExpressionList1 "expression list expression" 159 Factor "expression factor" 160 Factor1 "binary expression factor" 161 Field "field expression" 162 Field1 "field expression optional AS clause" 163 FieldList "field expression list" 164 GroupByClause "GROUP BY clause" 165 Index "string index" 166 InsertIntoStmt "INSERT INTO statement" 167 InsertIntoStmt1 "INSERT INTO statement optional column list clause" 168 InsertIntoStmt2 "INSERT INTO statement optional values list" 169 JoinClause "SELECT statement JOIN clause" 170 JoinClauseOpt "SELECT statement optional JOIN clause" 171 JoinType "join type" 172 Literal "literal value" 173 logAnd "logical and operator" 174 logOr "logical or operator" 175 Operand "operand" 176 OrderBy "ORDER BY clause" 177 OrderBy1 "ORDER BY clause optional collation specification" 178 OuterOpt "optional OUTER clause" 179 QualifiedIdent "qualified identifier" 180 PrimaryExpression "primary expression" 181 PrimaryFactor "primary expression factor" 182 PrimaryTerm "primary expression term" 183 RecordSet "record set" 184 RecordSet1 "record set name or parenthesized SELECTECT statement" 185 RecordSet2 "record set optional AS clause" 186 RollbackStmt "ROLLBACK statement" 187 SelectStmt "SELECT statement" 188 SelectStmtDistinct "SELECT statement optional DISTINCT clause" 189 SelectStmtFieldList "SELECT statement field list" 190 SelectStmtLimit "SELECT statement optional LIMIT clause" 191 SelectStmtWhere "SELECT statement optional WHERE clause" 192 SelectStmtGroup "SELECT statement optional GROUP BY clause" 193 SelectStmtOffset "SELECT statement optional OFFSET clause" 194 SelectStmtOrder "SELECT statement optional ORDER BY clause" 195 Slice "string slice" 196 Statement "statement" 197 StatementList "statement list" 198 TableName "table name" 199 Term "expression term" 200 TruncateTableStmt "TRANSACTION TABLE statement" 201 Type "type" 202 UnaryExpr "unary expression" 203 UpdateStmt "UPDATE statement" 204 UpdateStmt1 "UPDATE statement optional WHERE clause" 205 WhereClause "WHERE clause" 206 207 %type <list> RecordSetList 208 209 %start Start 210 211 %% 212 213 Start: 214 StatementList 215 | parseExpression Expression 216 { 217 yylex.(*lexer).expr = expr($2) 218 } 219 220 AlterTableStmt: 221 "ALTER" "TABLE" TableName "ADD" ColumnDef 222 { 223 $$ = &alterTableAddStmt{tableName: $3.(string), c: $5.(*col)} 224 } 225 | "ALTER" "TABLE" TableName "DROP" "COLUMN" ColumnName 226 { 227 $$ = &alterTableDropColumnStmt{tableName: $3.(string), colName: $6.(string)} 228 } 229 230 Assignment: 231 ColumnName '=' Expression 232 { 233 $$ = assignment{colName: $1.(string), expr: expr($3)} 234 } 235 236 AssignmentList: 237 Assignment AssignmentList1 CommaOpt 238 { 239 $$ = append([]assignment{$1.(assignment)}, $2.([]assignment)...) 240 } 241 242 AssignmentList1: 243 /* EMPTY */ 244 { 245 $$ = []assignment{} 246 } 247 | AssignmentList1 ',' Assignment 248 { 249 $$ = append($1.([]assignment), $3.(assignment)) 250 } 251 252 BeginTransactionStmt: 253 "BEGIN" "TRANSACTION" 254 { 255 $$ = beginTransactionStmt{} 256 } 257 258 Call: 259 '(' Call1 ')' 260 { 261 $$ = $2 262 } 263 | '(' '*' ')' 264 { 265 $<item>$ = '*' 266 } 267 268 Call1: 269 /* EMPTY */ 270 { 271 $$ = []expression{} 272 } 273 | ExpressionList 274 275 ColumnDef: 276 ColumnName Type ConstraintOpt DefaultOpt 277 { 278 x := &col{name: $1.(string), typ: $2.(int), constraint: $3.(*constraint)} 279 if $4 != nil { 280 x.dflt = expr($4) 281 } 282 $$ = x 283 } 284 285 ColumnName: 286 identifier 287 288 ColumnNameList: 289 ColumnName ColumnNameList1 CommaOpt 290 { 291 $$ = append([]string{$1.(string)}, $2.([]string)...) 292 } 293 294 ColumnNameList1: 295 /* EMPTY */ 296 { 297 $$ = []string{} 298 } 299 | ColumnNameList1 ',' ColumnName 300 { 301 $$ = append($1.([]string), $3.(string)) 302 } 303 304 CommitStmt: 305 "COMMIT" 306 { 307 $$ = commitStmt{} 308 } 309 310 Constraint: 311 "NOT" "NULL" 312 { 313 $$ = &constraint{} 314 } 315 | Expression 316 { 317 $$ = &constraint{expr($1)} 318 } 319 320 ConstraintOpt: 321 { 322 $$ = (*constraint)(nil) 323 } 324 | Constraint 325 326 Conversion: 327 Type '(' Expression ')' 328 { 329 $$ = &conversion{typ: $1.(int), val: expr($3)} 330 } 331 332 CreateIndexStmt: 333 "CREATE" CreateIndexStmtUnique "INDEX" CreateIndexIfNotExists identifier "ON" identifier '(' ExpressionList ')' 334 { 335 indexName, tableName, exprList := $5.(string), $7.(string), $9.([]expression) 336 simpleIndex := len(exprList) == 1 337 var columnName string 338 if simpleIndex { 339 expr := exprList[0] 340 switch x := expr.(type) { 341 case *ident: 342 columnName = x.s 343 case *call: 344 if x.f == "id" && len(x.arg) == 0 { 345 columnName = "id()" 346 break 347 } 348 349 simpleIndex = false 350 default: 351 simpleIndex = false 352 } 353 } 354 355 if !simpleIndex { 356 columnName = "" 357 } 358 $$ = &createIndexStmt{unique: $2.(bool), ifNotExists: $4.(bool), indexName: indexName, tableName: tableName, colName: columnName, exprList: exprList} 359 360 if indexName == tableName || indexName == columnName { 361 yylex.(*lexer).err("index name collision: %s", indexName) 362 return 1 363 } 364 365 if yylex.(*lexer).root { 366 break 367 } 368 369 if isSystemName[indexName] || isSystemName[tableName] { 370 yylex.(*lexer).err("name is used for system tables: %s", indexName) 371 return 1 372 } 373 } 374 375 CreateIndexIfNotExists: 376 { 377 $$ = false 378 } 379 | "IF" "NOT" "EXISTS" 380 { 381 $$ = true 382 } 383 384 CreateIndexStmtUnique: 385 { 386 $$ = false 387 } 388 | "UNIQUE" 389 { 390 $$ = true 391 } 392 393 CreateTableStmt: 394 "CREATE" "TABLE" TableName '(' ColumnDef CreateTableStmt1 CommaOpt ')' 395 { 396 nm := $3.(string) 397 $$ = &createTableStmt{tableName: nm, cols: append([]*col{$5.(*col)}, $6.([]*col)...)} 398 399 if yylex.(*lexer).root { 400 break 401 } 402 403 if isSystemName[nm] { 404 yylex.(*lexer).err("name is used for system tables: %s", nm) 405 return 1 406 } 407 } 408 | "CREATE" "TABLE" "IF" "NOT" "EXISTS" TableName '(' ColumnDef CreateTableStmt1 CommaOpt ')' 409 { 410 nm := $6.(string) 411 $$ = &createTableStmt{ifNotExists: true, tableName: nm, cols: append([]*col{$8.(*col)}, $9.([]*col)...)} 412 413 if yylex.(*lexer).root { 414 break 415 } 416 417 if isSystemName[nm] { 418 yylex.(*lexer).err("name is used for system tables: %s", nm) 419 return 1 420 } 421 } 422 423 CreateTableStmt1: 424 /* EMPTY */ 425 { 426 $$ = []*col{} 427 } 428 | CreateTableStmt1 ',' ColumnDef 429 { 430 $$ = append($1.([]*col), $3.(*col)) 431 } 432 433 Default: 434 "DEFAULT" Expression 435 { 436 $$ = $2 437 } 438 439 DefaultOpt: 440 { 441 $$ = nil 442 } 443 | Default 444 445 DeleteFromStmt: 446 "DELETE" "FROM" TableName 447 { 448 $$ = &truncateTableStmt{$3.(string)} 449 450 if yylex.(*lexer).root { 451 break 452 } 453 454 if isSystemName[$3.(string)] { 455 yylex.(*lexer).err("name is used for system tables: %s", $3.(string)) 456 return 1 457 } 458 } 459 | "DELETE" "FROM" TableName WhereClause 460 { 461 $$ = &deleteStmt{tableName: $3.(string), where: $4.(*whereRset).expr} 462 463 if yylex.(*lexer).root { 464 break 465 } 466 467 if isSystemName[$3.(string)] { 468 yylex.(*lexer).err("name is used for system tables: %s", $3.(string)) 469 return 1 470 } 471 } 472 473 DropIndexStmt: 474 "DROP" "INDEX" DropIndexIfExists identifier 475 { 476 $$ = &dropIndexStmt{ifExists: $3.(bool), indexName: $4.(string)} 477 } 478 479 DropIndexIfExists: 480 { 481 $$ = false 482 } 483 | "IF" "EXISTS" 484 { 485 $$ = true 486 } 487 488 DropTableStmt: 489 "DROP" "TABLE" TableName 490 { 491 nm := $3.(string) 492 $$ = &dropTableStmt{tableName: nm} 493 494 if yylex.(*lexer).root { 495 break 496 } 497 498 if isSystemName[nm] { 499 yylex.(*lexer).err("name is used for system tables: %s", nm) 500 return 1 501 } 502 } 503 | "DROP" "TABLE" "IF" "EXISTS" TableName 504 { 505 nm := $5.(string) 506 $$ = &dropTableStmt{ifExists: true, tableName: nm} 507 508 if yylex.(*lexer).root { 509 break 510 } 511 512 if isSystemName[nm] { 513 yylex.(*lexer).err("name is used for system tables: %s", nm) 514 return 1 515 } 516 } 517 518 EmptyStmt: 519 /* EMPTY */ 520 { 521 $$ = nil 522 } 523 524 ExplainStmt: 525 "EXPLAIN" Statement 526 { 527 $$ = &explainStmt{$2.(stmt)} 528 } 529 530 Expression: 531 Term 532 | Expression logOr Term 533 { 534 var err error 535 if $$, err = newBinaryOperation(oror, $1, $3); err != nil { 536 yylex.(*lexer).err("%v", err) 537 return 1 538 } 539 } 540 541 logOr: 542 "||" 543 { 544 } 545 | "OR" 546 { 547 } 548 549 Eq: 550 "==" 551 | '=' 552 553 ExpressionList: 554 Expression ExpressionList1 CommaOpt 555 { 556 $$ = append([]expression{expr($1)}, $2.([]expression)...) 557 } 558 559 ExpressionList1: 560 /* EMPTY */ 561 { 562 $$ = []expression(nil) 563 } 564 | ExpressionList1 ',' Expression 565 { 566 $$ = append($1.([]expression), expr($3)) 567 } 568 569 Factor: 570 Factor1 571 | Factor1 "IN" '(' ExpressionList ')' 572 { 573 $$ = &pIn{expr: $1.(expression), list: $4.([]expression)} 574 } 575 | Factor1 "NOT" "IN" '(' ExpressionList ')' 576 { 577 $$ = &pIn{expr: $1.(expression), not: true, list: $5.([]expression)} 578 } 579 | Factor1 "IN" '(' SelectStmt semiOpt ')' 580 { 581 $$ = &pIn{expr: $1.(expression), sel: $4.(*selectStmt)} 582 } 583 | Factor1 "NOT" "IN" '(' SelectStmt semiOpt ')' 584 { 585 $$ = &pIn{expr: $1.(expression), not: true, sel: $5.(*selectStmt)} 586 } 587 | Factor1 "BETWEEN" PrimaryFactor "AND" PrimaryFactor 588 { 589 var err error 590 if $$, err = newBetween($1, $3, $5, false); err != nil { 591 yylex.(*lexer).err("%v", err) 592 return 1 593 } 594 } 595 | Factor1 "NOT" "BETWEEN" PrimaryFactor "AND" PrimaryFactor 596 { 597 var err error 598 if $$, err = newBetween($1, $4, $6, true); err != nil { 599 yylex.(*lexer).err("%v", err) 600 return 1 601 } 602 } 603 | Factor1 "IS" "NULL" 604 { 605 $$ = &isNull{expr: $1.(expression)} 606 } 607 | Factor1 "IS" "NOT" "NULL" 608 { 609 $$ = &isNull{expr: $1.(expression), not: true} 610 } 611 612 Factor1: 613 PrimaryFactor 614 | Factor1 ">=" PrimaryFactor 615 { 616 var err error 617 if $$, err = newBinaryOperation(ge, $1, $3); err != nil { 618 yylex.(*lexer).err("%v", err) 619 return 1 620 } 621 } 622 | Factor1 '>' PrimaryFactor 623 { 624 var err error 625 if $$, err = newBinaryOperation('>', $1, $3); err != nil { 626 yylex.(*lexer).err("%v", err) 627 return 1 628 } 629 } 630 | Factor1 "<=" PrimaryFactor 631 { 632 var err error 633 if $$, err = newBinaryOperation(le, $1, $3); err != nil { 634 yylex.(*lexer).err("%v", err) 635 return 1 636 } 637 } 638 | Factor1 '<' PrimaryFactor 639 { 640 var err error 641 if $$, err = newBinaryOperation('<', $1, $3); err != nil { 642 yylex.(*lexer).err("%v", err) 643 return 1 644 } 645 } 646 | Factor1 "!=" PrimaryFactor 647 { 648 var err error 649 if $$, err = newBinaryOperation(neq, $1, $3); err != nil { 650 yylex.(*lexer).err("%v", err) 651 return 1 652 } 653 } 654 | Factor1 Eq PrimaryFactor 655 { 656 var err error 657 if $$, err = newBinaryOperation(eq, $1, $3); err != nil { 658 yylex.(*lexer).err("%v", err) 659 return 1 660 } 661 } 662 | Factor1 "LIKE" PrimaryFactor 663 { 664 $$ = &pLike{expr: $1.(expression), pattern: $3.(expression)} 665 } 666 667 Field: 668 Expression Field1 669 { 670 expr, name := expr($1), $2.(string) 671 if name == "" { 672 s, ok := expr.(*ident) 673 if ok { 674 name = s.s 675 } 676 } 677 $$ = &fld{expr: expr, name: name} 678 } 679 680 Field1: 681 /* EMPTY */ 682 { 683 $$ = "" 684 } 685 | "AS" identifier 686 { 687 $$ = $2 688 } 689 690 FieldList: 691 Field 692 { 693 $$ = []*fld{$1.(*fld)} 694 } 695 | FieldList ',' Field 696 { 697 l, f := $1.([]*fld), $3.(*fld) 698 if f.name != "" { 699 if f := findFld(l, f.name); f != nil { 700 yylex.(*lexer).err("duplicate field name %q", f.name) 701 return 1 702 } 703 } 704 705 $$ = append($1.([]*fld), $3.(*fld)) 706 } 707 708 GroupByClause: 709 "GROUP" "BY" ColumnNameList 710 { 711 $$ = &groupByRset{colNames: $3.([]string)} 712 } 713 714 Index: 715 '[' Expression ']' 716 { 717 $$ = $2 718 } 719 720 InsertIntoStmt: 721 "INSERT" "INTO" TableName InsertIntoStmt1 "VALUES" '(' ExpressionList ')' InsertIntoStmt2 CommaOpt 722 { 723 $$ = &insertIntoStmt{tableName: $3.(string), colNames: $4.([]string), lists: append([][]expression{$7.([]expression)}, $9.([][]expression)...)} 724 725 if yylex.(*lexer).root { 726 break 727 } 728 729 if isSystemName[$3.(string)] { 730 yylex.(*lexer).err("name is used for system tables: %s", $3.(string)) 731 return 1 732 } 733 } 734 | "INSERT" "INTO" TableName InsertIntoStmt1 SelectStmt 735 { 736 $$ = &insertIntoStmt{tableName: $3.(string), colNames: $4.([]string), sel: $5.(*selectStmt)} 737 } 738 739 InsertIntoStmt1: 740 /* EMPTY */ 741 { 742 $$ = []string{} 743 } 744 | '(' ColumnNameList ')' 745 { 746 $$ = $2 747 } 748 749 InsertIntoStmt2: 750 /* EMPTY */ 751 { 752 $$ = [][]expression{} 753 } 754 | InsertIntoStmt2 ',' '(' ExpressionList ')' 755 { 756 $$ = append($1.([][]expression), $4.([]expression)) 757 } 758 759 Literal: 760 "false" 761 | "NULL" 762 | "true" 763 | floatLit 764 | imaginaryLit 765 | intLit 766 | stringLit 767 768 Operand: 769 Literal 770 { 771 $$ = value{$1} 772 } 773 | qlParam 774 { 775 n := $1.(int) 776 $$ = parameter{n} 777 l := yylex.(*lexer) 778 l.params = mathutil.Max(l.params, n) 779 if n == 0 { 780 l.err("parameter number must be non zero") 781 return 1 782 } 783 } 784 | QualifiedIdent 785 { 786 $$ = &ident{$1.(string)} 787 } 788 | '(' Expression ')' 789 { 790 $$ = &pexpr{expr: expr($2)} 791 } 792 793 OrderBy: 794 "ORDER" "BY" ExpressionList OrderBy1 795 { 796 $$ = &orderByRset{by: $3.([]expression), asc: $4.(bool)} 797 } 798 799 OrderBy1: 800 /* EMPTY */ 801 { 802 $$ = true // ASC by default 803 } 804 | "ASC" 805 { 806 $$ = true 807 } 808 | "DESC" 809 { 810 $$ = false 811 } 812 813 PrimaryExpression: 814 Operand 815 | Conversion 816 | PrimaryExpression Index 817 { 818 var err error 819 if $$, err = newIndex($1.(expression), expr($2)); err != nil { 820 yylex.(*lexer).err("%v", err) 821 return 1 822 } 823 } 824 | PrimaryExpression Slice 825 { 826 var err error 827 s := $2.([2]*expression) 828 if $$, err = newSlice($1.(expression), s[0], s[1]); err != nil { 829 yylex.(*lexer).err("%v", err) 830 return 1 831 } 832 } 833 | PrimaryExpression Call 834 { 835 x := yylex.(*lexer) 836 f, ok := $1.(*ident) 837 if !ok { 838 x.err("expected identifier or qualified identifier") 839 return 1 840 } 841 842 if r, ok := $2.(rune); ok { 843 if f.isQualified() || f.s != "count" || r != '*' { 844 x.err(fmt.Sprintf("invalid expression %s(%c)", f, r)) 845 return 1 846 } 847 848 $2 = []expression(nil) 849 } 850 851 var err error 852 var agg bool 853 if $$, agg, err = newCall(f.s, $2.([]expression)); err != nil { 854 x.err("%v", err) 855 return 1 856 } 857 if n := len(x.agg); n > 0 { 858 x.agg[n-1] = x.agg[n-1] || agg 859 } 860 } 861 862 PrimaryFactor: 863 PrimaryTerm 864 | PrimaryFactor '^' PrimaryTerm 865 { 866 var err error 867 if $$, err = newBinaryOperation('^', $1, $3); err != nil { 868 yylex.(*lexer).err("%v", err) 869 return 1 870 } 871 } 872 | PrimaryFactor '|' PrimaryTerm 873 { 874 var err error 875 if $$, err = newBinaryOperation('|', $1, $3); err != nil { 876 yylex.(*lexer).err("%v", err) 877 return 1 878 } 879 } 880 | PrimaryFactor '-' PrimaryTerm 881 { 882 var err error 883 if $$, err = newBinaryOperation('-', $1, $3); err != nil { 884 yylex.(*lexer).err("%v", err) 885 return 1 886 } 887 } 888 | PrimaryFactor '+' PrimaryTerm 889 { 890 var err error 891 $$, err = newBinaryOperation('+', $1, $3) 892 if err != nil { 893 yylex.(*lexer).err("%v", err) 894 return 1 895 } 896 } 897 898 PrimaryTerm: 899 UnaryExpr 900 | PrimaryTerm "&^" UnaryExpr 901 { 902 var err error 903 $$, err = newBinaryOperation(andnot, $1, $3) 904 if err != nil { 905 yylex.(*lexer).err("%v", err) 906 return 1 907 } 908 } 909 | PrimaryTerm '&' UnaryExpr 910 { 911 var err error 912 $$, err = newBinaryOperation('&', $1, $3) 913 if err != nil { 914 yylex.(*lexer).err("%v", err) 915 return 1 916 } 917 } 918 | PrimaryTerm "<<" UnaryExpr 919 { 920 var err error 921 $$, err = newBinaryOperation(lsh, $1, $3) 922 if err != nil { 923 yylex.(*lexer).err("%v", err) 924 return 1 925 } 926 } 927 | PrimaryTerm ">>" UnaryExpr 928 { 929 var err error 930 $$, err = newBinaryOperation(rsh, $1, $3) 931 if err != nil { 932 yylex.(*lexer).err("%v", err) 933 return 1 934 } 935 } 936 | PrimaryTerm '%' UnaryExpr 937 { 938 var err error 939 $$, err = newBinaryOperation('%', $1, $3) 940 if err != nil { 941 yylex.(*lexer).err("%v", err) 942 return 1 943 } 944 } 945 | PrimaryTerm '/' UnaryExpr 946 { 947 var err error 948 $$, err = newBinaryOperation('/', $1, $3) 949 if err != nil { 950 yylex.(*lexer).err("%v", err) 951 return 1 952 } 953 } 954 | PrimaryTerm '*' UnaryExpr 955 { 956 var err error 957 $$, err = newBinaryOperation('*', $1, $3) 958 if err != nil { 959 yylex.(*lexer).err("%v", err) 960 return 1 961 } 962 } 963 964 QualifiedIdent: 965 identifier 966 | identifier '.' identifier 967 { 968 $$ = fmt.Sprintf("%s.%s", $1.(string), $3.(string)) 969 } 970 971 RecordSet: 972 RecordSet1 RecordSet2 973 { 974 $$ = []interface{}{$1, $2} 975 } 976 977 RecordSet1: 978 identifier 979 | '(' SelectStmt semiOpt ')' 980 { 981 $$ = $2 982 } 983 984 semiOpt: 985 /* EMPTY */ 986 | ';' 987 988 RecordSet2: 989 /* EMPTY */ 990 { 991 $$ = "" 992 } 993 | "AS" identifier 994 { 995 $$ = $2 996 } 997 998 RecordSetList: 999 RecordSet 1000 { 1001 $$ = []interface{}{$1} 1002 } 1003 | RecordSetList ',' RecordSet 1004 { 1005 $$ = append($1, $3) 1006 } 1007 1008 RollbackStmt: 1009 "ROLLBACK" 1010 { 1011 $$ = rollbackStmt{} 1012 } 1013 1014 JoinType: 1015 "LEFT" 1016 { 1017 $$ = leftJoin 1018 } 1019 | "RIGHT" 1020 { 1021 $$ = rightJoin 1022 } 1023 | "FULL" 1024 { 1025 $$ = fullJoin 1026 } 1027 1028 OuterOpt: 1029 { 1030 $$ = nil 1031 } 1032 | "OUTER" 1033 1034 JoinClause: 1035 JoinType OuterOpt "JOIN" RecordSet "ON" Expression 1036 { 1037 $$ = []interface{}{$1, $4, $6} 1038 } 1039 1040 JoinClauseOpt: 1041 { 1042 $$ = nil 1043 } 1044 | JoinClause 1045 1046 SelectStmt: 1047 "SELECT" SelectStmtDistinct SelectStmtFieldList "FROM" RecordSetList 1048 CommaOpt JoinClauseOpt SelectStmtWhere SelectStmtGroup SelectStmtOrder 1049 SelectStmtLimit SelectStmtOffset 1050 { 1051 x := yylex.(*lexer) 1052 n := len(x.agg) 1053 join := &joinRset{sources: $5} 1054 if o := $7; o != nil { 1055 o := o.([]interface{}) 1056 join.typ = o[0].(int) 1057 join.sources = append(join.sources, o[1].([]interface{})) 1058 join.on = o[2].(expression) 1059 } 1060 $$ = &selectStmt{ 1061 distinct: $2.(bool), 1062 flds: $3.([]*fld), 1063 from: join, 1064 hasAggregates: x.agg[n-1], 1065 where: $8.(*whereRset), 1066 group: $9.(*groupByRset), 1067 order: $10.(*orderByRset), 1068 limit: $11.(*limitRset), 1069 offset: $12.(*offsetRset), 1070 } 1071 x.agg = x.agg[:n-1] 1072 } 1073 1074 SelectStmtLimit: 1075 { 1076 $$ = (*limitRset)(nil) 1077 } 1078 | "LIMIT" Expression 1079 { 1080 $$ = &limitRset{expr: expr($2)} 1081 } 1082 1083 SelectStmtOffset: 1084 { 1085 $$ = (*offsetRset)(nil) 1086 } 1087 | "OFFSET" Expression 1088 { 1089 $$ = &offsetRset{expr: expr($2)} 1090 } 1091 1092 SelectStmtDistinct: 1093 /* EMPTY */ 1094 { 1095 $$ = false 1096 } 1097 | "DISTINCT" 1098 { 1099 $$ = true 1100 } 1101 1102 SelectStmtFieldList: 1103 '*' 1104 { 1105 $$ = []*fld{} 1106 } 1107 | FieldList 1108 { 1109 $$ = $1 1110 } 1111 | FieldList ',' 1112 { 1113 $$ = $1 1114 } 1115 1116 SelectStmtWhere: 1117 /* EMPTY */ 1118 { 1119 $$ = (*whereRset)(nil) 1120 } 1121 | WhereClause 1122 1123 SelectStmtGroup: 1124 /* EMPTY */ 1125 { 1126 $$ = (*groupByRset)(nil) 1127 } 1128 | GroupByClause 1129 1130 SelectStmtOrder: 1131 /* EMPTY */ 1132 { 1133 $$ = (*orderByRset)(nil) 1134 } 1135 | OrderBy 1136 1137 Slice: 1138 '[' ':' ']' 1139 { 1140 $$ = [2]*expression{nil, nil} 1141 } 1142 | '[' ':' Expression ']' 1143 { 1144 hi := expr($3) 1145 $$ = [2]*expression{nil, &hi} 1146 } 1147 | '[' Expression ':' ']' 1148 { 1149 lo := expr($2) 1150 $$ = [2]*expression{&lo, nil} 1151 } 1152 | '[' Expression ':' Expression ']' 1153 { 1154 lo := expr($2) 1155 hi := expr($4) 1156 $$ = [2]*expression{&lo, &hi} 1157 } 1158 1159 Statement: 1160 EmptyStmt 1161 | AlterTableStmt 1162 | BeginTransactionStmt 1163 | CommitStmt 1164 | CreateIndexStmt 1165 | CreateTableStmt 1166 | DeleteFromStmt 1167 | DropIndexStmt 1168 | DropTableStmt 1169 | ExplainStmt 1170 | InsertIntoStmt 1171 | RollbackStmt 1172 | SelectStmt 1173 | TruncateTableStmt 1174 | UpdateStmt 1175 1176 StatementList: 1177 Statement 1178 { 1179 if $1 != nil { 1180 yylex.(*lexer).list = []stmt{$1.(stmt)} 1181 } 1182 } 1183 | StatementList ';' Statement 1184 { 1185 if $3 != nil { 1186 yylex.(*lexer).list = append(yylex.(*lexer).list, $3.(stmt)) 1187 } 1188 } 1189 1190 TableName: 1191 identifier 1192 1193 Term: 1194 Factor 1195 | Term logAnd Factor 1196 { 1197 var err error 1198 if $$, err = newBinaryOperation(andand, $1, $3); err != nil { 1199 yylex.(*lexer).err("%v", err) 1200 return 1 1201 } 1202 } 1203 1204 logAnd: 1205 "&&" 1206 { 1207 } 1208 | "AND" 1209 { 1210 } 1211 1212 TruncateTableStmt: 1213 "TRUNCATE" "TABLE" TableName 1214 { 1215 $$ = &truncateTableStmt{tableName: $3.(string)} 1216 } 1217 1218 Type: 1219 "bigint" 1220 | "bigrat" 1221 | "blob" 1222 | "bool" 1223 | "byte" 1224 | "complex128" 1225 | "complex64" 1226 | "duration" 1227 | "float" 1228 | "float32" 1229 | "float64" 1230 | "int" 1231 | "int16" 1232 | "int32" 1233 | "int64" 1234 | "int8" 1235 | "rune" 1236 | "string" 1237 | "time" 1238 | "uint" 1239 | "uint16" 1240 | "uint32" 1241 | "uint64" 1242 | "uint8" 1243 1244 UpdateStmt: 1245 "UPDATE" TableName SetOpt AssignmentList UpdateStmt1 1246 { 1247 var expr expression 1248 if w := $5; w != nil { 1249 expr = w.(*whereRset).expr 1250 } 1251 $$ = &updateStmt{tableName: $2.(string), list: $4.([]assignment), where: expr} 1252 1253 if yylex.(*lexer).root { 1254 break 1255 } 1256 1257 if isSystemName[$2.(string)] { 1258 yylex.(*lexer).err("name is used for system tables: %s", $2.(string)) 1259 return 1 1260 } 1261 } 1262 1263 UpdateStmt1: 1264 /* EMPTY */ 1265 { 1266 $$ = nil 1267 } 1268 | WhereClause 1269 1270 UnaryExpr: 1271 PrimaryExpression 1272 | '^' PrimaryExpression 1273 { 1274 var err error 1275 $$, err = newUnaryOperation('^', $2) 1276 if err != nil { 1277 yylex.(*lexer).err("%v", err) 1278 return 1 1279 } 1280 } 1281 | '!' PrimaryExpression 1282 { 1283 var err error 1284 $$, err = newUnaryOperation('!', $2) 1285 if err != nil { 1286 yylex.(*lexer).err("%v", err) 1287 return 1 1288 } 1289 } 1290 | '-' PrimaryExpression 1291 { 1292 var err error 1293 $$, err = newUnaryOperation('-', $2) 1294 if err != nil { 1295 yylex.(*lexer).err("%v", err) 1296 return 1 1297 } 1298 } 1299 | '+' PrimaryExpression 1300 { 1301 var err error 1302 $$, err = newUnaryOperation('+', $2) 1303 if err != nil { 1304 yylex.(*lexer).err("%v", err) 1305 return 1 1306 } 1307 } 1308 1309 WhereClause: 1310 "WHERE" Expression 1311 { 1312 $$ = &whereRset{expr: expr($2)} 1313 } 1314 1315 1316 SetOpt: 1317 { 1318 } 1319 | "SET" 1320 { 1321 } 1322 1323 CommaOpt: 1324 { 1325 } 1326 | ',' 1327 { 1328 } 1329 1330 %% 1331 1332 func expr(v interface{}) expression { 1333 e := v.(expression) 1334 for { 1335 x, ok := e.(*pexpr) 1336 if !ok { 1337 return e 1338 } 1339 e = x.expr 1340 } 1341 }