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  }