Commit ce24551f authored by cznic's avatar cznic

Outer joins first cut: scanner, parser, docs. Updates #91.

parent 20dce3ea
......@@ -220,17 +220,18 @@
//
// The following keywords are reserved and may not be used as identifiers.
//
// ADD BY duration INDEX NULL TRUNCATE
// ALTER byte EXISTS INSERT OFFSET uint
// AND COLUMN false int ON uint16
// AS complex128 float int16 ORDER uint32
// ASC complex64 float32 int32 SELECT uint64
// BETWEEN CREATE float64 int64 SET uint8
// bigint DEFAULT FROM int8 string UNIQUE
// bigrat DELETE GROUP INTO TABLE UPDATE
// blob DESC IF LIMIT time VALUES
// bool DISTINCT IN LIKE true WHERE
// DROP NOT OR
// ADD COLUMN float int64 OUTER uint32
// ALTER complex128 float3 int8 RIGHT uint64
// AND complex64 float6 INTO SELECT uint8
// AS CREATE FROM 2 JOIN SET UNIQUE
// ASC DEFAULT GROUP 4 LEFT string UPDATE
// BETWEEN DELETE IF LIMIT TABLE VALUES
// bigint DESC IN LIKE time WHERE
// bigrat DISTINCT INDEX NOT true
// blob DROP INSERT NULL OR
// bool duration int OFFSET TRUNCATE
// BY EXISTS int16 ON uint
// byte false int32 ORDER uint16
//
// Keywords are not case sensitive.
//
......@@ -1596,7 +1597,9 @@
// clause.
//
// SelectStmt = "SELECT" [ "DISTINCT" ] ( "*" | FieldList ) "FROM" RecordSetList
// [ WhereClause ] [ GroupByClause ] [ OrderBy ] [ Limit ] [ Offset ].
// [ JoinClause ] [ WhereClause ] [ GroupByClause ] [ OrderBy ] [ Limit ] [ Offset ].
//
// JoinClause = ( "LEFT" | "RIGHT" | "FULL" ) [ "OUTER" ] "JOIN" RecordSet "ON" Expression .
//
// RecordSet = ( TableName | "(" SelectStmt [ ";" ] ")" ) [ "AS" identifier ] .
// RecordSetList = RecordSet { "," RecordSet } [ "," ] .
......@@ -1779,26 +1782,30 @@
// 1. The FROM clause is evaluated, producing a Cartesian product of its source
// record sets (tables or nested SELECT statements).
//
// 2. If present, the WHERE clause is evaluated on the result set of the
// 2. If present, the JOIN cluase is evaluated on the result set of the
// previous evaluation and the recordset specified by the JOIN clause. (...
// JOIN Recordset ON ...)
//
// 3. If present, the WHERE clause is evaluated on the result set of the
// previous evaluation.
//
// 3. If present, the GROUP BY clause is evaluated on the result set of the
// 4. If present, the GROUP BY clause is evaluated on the result set of the
// previous evaluation(s).
//
// 4. The SELECT field expressions are evaluated on the result set of the
// 5. The SELECT field expressions are evaluated on the result set of the
// previous evaluation(s).
//
// 5. If present, the DISTINCT modifier is evaluated on the result set of the
// 6. If present, the DISTINCT modifier is evaluated on the result set of the
// previous evaluation(s).
//
// 6. If present, the ORDER BY clause is evaluated on the result set of the
// 7. If present, the ORDER BY clause is evaluated on the result set of the
// previous evaluation(s).
//
// 7. If present, the OFFSET clause is evaluated on the result set of the
// 8. If present, the OFFSET clause is evaluated on the result set of the
// previous evaluation(s). The offset expression is evaluated once for the
// first record produced by the previous evaluations.
//
// 8. If present, the LIMIT clause is evaluated on the result set of the
// 9. If present, the LIMIT clause is evaluated on the result set of the
// previous evaluation(s). The limit expression is evaluated once for the first
// record produced by the previous evaluations.
//
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -36,10 +36,11 @@ import (
column commit complex128Type complex64Type create
defaultKwd deleteKwd desc distinct drop durationType
eq exists
falseKwd floatType float32Type float64Type floatLit from
falseKwd floatType float32Type float64Type floatLit from
ge group
identifier ifKwd imaginaryLit in index insert intType int16Type
int32Type int64Type int8Type into intLit is
join
le like limit lsh
neq not null
offset on or order oror
......@@ -52,7 +53,7 @@ import (
where
%token <item>
floatLit imaginaryLit intLit stringLit
floatLit imaginaryLit intLit stringLit left right full outer
%token <item>
bigIntType bigRatType blobType boolType byteType
......@@ -80,8 +81,9 @@ import (
Factor Factor1 Field Field1 FieldList
GroupByClause
Index InsertIntoStmt InsertIntoStmt1 InsertIntoStmt2
JoinClause JoinClauseOpt JoinType
Literal
Operand OrderBy OrderBy1
Operand OrderBy OrderBy1 OuterOpt
QualifiedIdent
PrimaryExpression PrimaryFactor PrimaryTerm
RecordSet RecordSet1 RecordSet2 RollbackStmt
......@@ -115,7 +117,7 @@ Assignment:
}
AssignmentList:
Assignment AssignmentList1 AssignmentList2
Assignment AssignmentList1 CommaOpt
{
$$ = append([]assignment{$1.(assignment)}, $2.([]assignment)...)
}
......@@ -130,10 +132,6 @@ AssignmentList1:
$$ = append($1.([]assignment), $3.(assignment))
}
AssignmentList2:
/* EMPTY */
| ','
BeginTransactionStmt:
begin transaction
{
......@@ -167,7 +165,7 @@ ColumnName:
identifier
ColumnNameList:
ColumnName ColumnNameList1 ColumnNameList2
ColumnName ColumnNameList1 CommaOpt
{
$$ = append([]string{$1.(string)}, $2.([]string)...)
}
......@@ -182,10 +180,6 @@ ColumnNameList1:
$$ = append($1.([]string), $3.(string))
}
ColumnNameList2:
/* EMPTY */
| ','
CommitStmt:
commit
{
......@@ -276,7 +270,7 @@ CreateIndexStmtUnique:
}
CreateTableStmt:
create tableKwd TableName '(' ColumnDef CreateTableStmt1 CreateTableStmt2 ')'
create tableKwd TableName '(' ColumnDef CreateTableStmt1 CommaOpt ')'
{
nm := $3.(string)
$$ = &createTableStmt{tableName: nm, cols: append([]*col{$5.(*col)}, $6.([]*col)...)}
......@@ -290,7 +284,7 @@ CreateTableStmt:
return 1
}
}
| create tableKwd ifKwd not exists TableName '(' ColumnDef CreateTableStmt1 CreateTableStmt2 ')'
| create tableKwd ifKwd not exists TableName '(' ColumnDef CreateTableStmt1 CommaOpt ')'
{
nm := $6.(string)
$$ = &createTableStmt{ifNotExists: true, tableName: nm, cols: append([]*col{$8.(*col)}, $9.([]*col)...)}
......@@ -315,10 +309,6 @@ CreateTableStmt1:
$$ = append($1.([]*col), $3.(*col))
}
CreateTableStmt2:
/* EMPTY */
| ','
Default:
defaultKwd Expression
{
......@@ -426,7 +416,7 @@ logOr:
| or
ExpressionList:
Expression ExpressionList1 ExpressionList2
Expression ExpressionList1 CommaOpt
{
$$ = append([]expression{$1.(expression)}, $2.([]expression)...)
}
......@@ -441,10 +431,6 @@ ExpressionList1:
$$ = append($1.([]expression), $3.(expression))
}
ExpressionList2:
/* EMPTY */
| ','
Factor:
Factor1
| Factor1 in '(' ExpressionList ')'
......@@ -597,7 +583,7 @@ Index:
}
InsertIntoStmt:
insert into TableName InsertIntoStmt1 values '(' ExpressionList ')' InsertIntoStmt2 InsertIntoStmt3
insert into TableName InsertIntoStmt1 values '(' ExpressionList ')' InsertIntoStmt2 CommaOpt
{
$$ = &insertIntoStmt{tableName: $3.(string), colNames: $4.([]string), lists: append([][]expression{$7.([]expression)}, $9.([][]expression)...)}
......@@ -635,10 +621,6 @@ InsertIntoStmt2:
$$ = append($1.([][]expression), $4.([]expression))
}
InsertIntoStmt3:
| ','
Literal:
falseKwd
| null
......@@ -885,27 +867,30 @@ RollbackStmt:
$$ = rollbackStmt{}
}
SelectStmt:
selectKwd SelectStmtDistinct SelectStmtFieldList from RecordSetList
SelectStmtWhere SelectStmtGroup SelectStmtOrder SelectStmtLimit SelectStmtOffset
JoinType:
left
| right
| full
OuterOpt:
{
x := yylex.(*lexer)
n := len(x.agg)
$$ = &selectStmt{
distinct: $2.(bool),
flds: $3.([]*fld),
from: &crossJoinRset{sources: $5},
hasAggregates: x.agg[n-1],
where: $6.(*whereRset),
group: $7.(*groupByRset),
order: $8.(*orderByRset),
limit: $9.(*limitRset),
offset: $10.(*offsetRset),
}
x.agg = x.agg[:n-1]
$$ = nil
}
| outer
JoinClause:
JoinType OuterOpt on Expression
JoinClauseOpt:
{
$$ = nil
}
| selectKwd SelectStmtDistinct SelectStmtFieldList from RecordSetList ','
SelectStmtWhere SelectStmtGroup SelectStmtOrder SelectStmtLimit SelectStmtOffset
| JoinClause
SelectStmt:
selectKwd SelectStmtDistinct SelectStmtFieldList from RecordSetList
CommaOpt JoinClauseOpt SelectStmtWhere SelectStmtGroup SelectStmtOrder
SelectStmtLimit SelectStmtOffset
{
x := yylex.(*lexer)
n := len(x.agg)
......@@ -914,11 +899,11 @@ SelectStmt:
flds: $3.([]*fld),
from: &crossJoinRset{sources: $5},
hasAggregates: x.agg[n-1],
where: $7.(*whereRset),
group: $8.(*groupByRset),
order: $9.(*orderByRset),
limit: $10.(*limitRset),
offset: $11.(*offsetRset),
where: $8.(*whereRset),
group: $9.(*groupByRset),
order: $10.(*orderByRset),
limit: $11.(*limitRset),
offset: $12.(*offsetRset),
}
x.agg = x.agg[:n-1]
}
......@@ -1089,7 +1074,7 @@ Type:
| uint8Type
UpdateStmt:
update TableName oSet AssignmentList UpdateStmt1
update TableName SetOpt AssignmentList UpdateStmt1
{
$$ = &updateStmt{tableName: $2.(string), list: $4.([]assignment), where: $5.(*whereRset).expr}
......@@ -1156,5 +1141,8 @@ WhereClause:
}
oSet:
SetOpt:
| set
CommaOpt:
| ','
......@@ -108,6 +108,11 @@ IndexName = identifier .
InsertIntoStmt = "INSERT" "INTO" TableName [
"(" ColumnNameList ")"
] ( Values | SelectStmt ) .
JoinClause = (
"LEFT"
| "RIGHT"
| "FULL"
) [ "OUTER" ] "JOIN" RecordSet "ON" Expression .
Limit = "Limit" Expression .
Literal = "FALSE"
| "NULL"
......@@ -162,7 +167,7 @@ RecordSet = (
) [ "AS" identifier ] .
RecordSetList = RecordSet { "," RecordSet } [ "," ] .
RollbackStmt = "ROLLBACK" .
SelectStmt = "SELECT" [ "DISTINCT" ] ( "*" | FieldList ) "FROM" RecordSetList [ WhereClause ] [ GroupByClause ] [ OrderBy ] [ Limit ] [ Offset ] .
SelectStmt = "SELECT" [ "DISTINCT" ] ( "*" | FieldList ) "FROM" RecordSetList [ JoinClause ] [ WhereClause ] [ GroupByClause ] [ OrderBy ] [ Limit ] [ Offset ] .
Slice = "[" [ Expression ] ":" [ Expression ] "]" .
Statement = EmptyStmt
| AlterTableStmt
......
This diff is collapsed.
......@@ -152,6 +152,7 @@ distinct {d}{i}{s}{t}{i}{n}{c}{t}
drop {d}{r}{o}{p}
exists {e}{x}{i}{s}{t}{s}
from {f}{r}{o}{m}
full {f}{u}{l}{l}
group {g}{r}{o}{u}{p}
if {i}{f}
in {i}{n}
......@@ -159,6 +160,8 @@ index {i}{n}{d}{e}{x}
insert {i}{n}{s}{e}{r}{t}
into {i}{n}{t}{o}
is {i}{s}
join {j}{o}{i}{n}
left {l}{e}{f}{t}
like {l}{i}{k}{e}
limit {l}{i}{m}{i}{t}
not {n}{o}{t}
......@@ -166,6 +169,8 @@ offset {o}{f}{f}{s}{e}{t}
on {o}{n}
or {o}{r}
order {o}{r}{d}{e}{r}
outer {o}{u}{t}{e}{r}
right {r}{i}{g}{h}{t}
rollback {r}{o}{l}{l}{b}{a}{c}{k}
select {s}{e}{l}{e}{c}{t}
set {s}{e}{t}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment