diff --git a/main.go b/main.go index ea66cf9..35a473d 100644 --- a/main.go +++ b/main.go @@ -1,22 +1,40 @@ package main import ( - "fmt" + . "miniSQL/src/Interpreter/lexer" "strings" - - "miniSQL/src/parser" ) +// // 解析的结果 +// type LexerResult struct { +// Token int +// Literal string +// } + func main() { s := strings.NewReader("creat table tabel_name where key <= 1") - l := parser.NewScanner(s) + l := NewScanner(s) + p := NewTokenizer() + result := &LexerResult{} + lastToken := 0 for { tok, str := l.Scan() - fmt.Print(tok) - fmt.Print(" ") - fmt.Println(str) - if tok == 1 { - break + // fmt.Print(tok) + // fmt.Print(" ") + // fmt.Println(str) + // if tok == 1 { + // break + // } + switch tok { + case T_EOF: + // Stop lex + case T_IDENT, T_INTEGER, T_FLOAT, T_STRING, T_LEFT_PARENTHESIS, T_RIGHT_PARENTHESIS, T_COMMA, T_SEMICOLON, T_EQUAL, T_ANGLE_LEFT, T_ANGLE_RIGHT, T_ANGLE_LEFT_EQUAL, T_ANGLE_RIGHT_EQUAL, T_NOT_EQUAL, T_ASTERISK, T_POINT: + result.Literal = str + // default: + // log.Printf("UnexpectedToken: tok is %d, lit is %s\n", tok, lit) + // return nil, UnexpectedTokenErr } + + result.Token = p.FromStrLit(str, tok, lastToken) } } diff --git a/src/Interpreter/lexer/lexer.go b/src/Interpreter/lexer/lexer.go new file mode 100644 index 0000000..f22d9f2 --- /dev/null +++ b/src/Interpreter/lexer/lexer.go @@ -0,0 +1,60 @@ +package lexer + +import ( + "io" + "log" +) + +type Token int + +// 工具类:接受由Scanner传入的经过基本处理的token,通过lookahead来赋予该token更多信息 +type Tokenizer interface { + FromStrLit(lit string, TokenType Token, lastToken int) int +} + +// 工具类:初步处理输入,得到基础的token +type Scanner interface { + Scan() (tok Token, lit string) +} + +// 模块类:将输入解析为token的总体工具类 +type LexerImpl struct { + scanner Scanner // 处理输入的工具类 + tokenizer Tokenizer // 进一步赋予token信息的工具类 + Result interface{} +} + +// 存储类:存储token解析的结果,最终的Lex()主要利用这个对象来返回结果 +type LexerResult struct { + Token int + Literal string +} + +// 新建一个“将输入解析为token”的总体工具类的实例化对象 +func NewLexerImpl(r io.Reader) *LexerImpl { + return &LexerImpl{ + scanner: NewScanner(r), + tokenizer: NewTokenizer(), + } +} + +func (li *LexerImpl) Lex(lastToken int) (*LexerResult, error) { + result := &LexerResult{} + + tok, lit := li.scanner.Scan() // 这里的scanner已经完成了输入流的基础token化 + + switch tok { + case T_EOF: + // Stop lex + case T_IDENT, T_INTEGER, T_FLOAT, T_STRING, T_LEFT_PARENTHESIS, T_RIGHT_PARENTHESIS, T_COMMA, T_SEMICOLON, T_EQUAL, T_ANGLE_LEFT, T_ANGLE_RIGHT, T_ANGLE_LEFT_EQUAL, T_ANGLE_RIGHT_EQUAL, T_NOT_EQUAL, T_ASTERISK, T_POINT: + result.Literal = lit + default: + log.Printf("UnexpectedToken: tok is %d, lit is %s\n", tok, lit) + // return nil, UnexpectedTokenErr // ToDo:这里的错误机制需要完善 + return nil, nil + } + + result.Token = li.tokenizer.FromStrLit(lit, tok, lastToken) + + return result, nil +} diff --git a/src/Interpreter/lexer/lexer_test.go b/src/Interpreter/lexer/lexer_test.go new file mode 100644 index 0000000..ff04cae --- /dev/null +++ b/src/Interpreter/lexer/lexer_test.go @@ -0,0 +1,46 @@ +package lexer + +import ( + "log" + "strings" + "testing" +) + +var sql_strings = []string{ + // "create table 1_a", + " ", + "create table cxz(" + + "afsdfsad int unique," + + "what char(30) not null," + + "primary key (what)" + + ");", + "select a,b,c,d,e,f,g from cxz where a=123 and b=456 or c=234;", +} + +//DoTo:这里有个bug就是我们无法正确地停止输入 +func TestLexerLex(t *testing.T) { + for _, str := range sql_strings { + LastToken := 0 + io := strings.NewReader(str) // 组装io + impl := NewLexerImpl(io) // 组装待测试的LexerImpl + for LastToken != int(T_EOF) { + r, _ := impl.Lex(LastToken) + + tokVal := r.Token + literal := r.Literal + LastToken = tokVal + + // log.Print(tokVal) + // log.Print(" ") + log.Print(literal) + // log.Print(" ") + // log.Print(LastToken) + if tokVal == 0 { + // 检测是否到达输入末尾 + break + } + } + + } + t.Errorf("不要慌,我只是想要一个log而已\n") +} diff --git a/src/Interpreter/lexer/scanner.go b/src/Interpreter/lexer/scanner.go new file mode 100644 index 0000000..4bbdbe7 --- /dev/null +++ b/src/Interpreter/lexer/scanner.go @@ -0,0 +1,226 @@ +package lexer + +import ( + "bufio" + "bytes" + "io" +) + +// type Token int + +// 词法分析中的初步结果(部分内容可以经过tokenize来形成语义更加明确的token) +const ( + // 特殊标记 + T_ILLEGAL Token = iota + T_EOF + WS // 空白字符 + // 常规类型数据 + T_IDENT // ID,此时我们并不区分关键词,而是归类到同一类 + T_INTEGER // 整数 + T_FLOAT // 浮点数 + T_STRING // 字符串 + // 其他标记 + T_ASTERISK // * + T_COMMA // , + T_LEFT_PARENTHESIS // ( + T_RIGHT_PARENTHESIS // ) + T_SEMICOLON // ; + T_EQUAL // = + T_ANGLE_LEFT // < + T_ANGLE_LEFT_EQUAL //<= + T_ANGLE_RIGHT_EQUAL //>= + T_ANGLE_RIGHT // > + T_NOT_EQUAL // <> or != + T_POINT // . +) + +type State int // 状态机的状态 + +const ( + STATE_INIT State = iota + STATE_INTEGER + STATE_POINT + STATE_FRACTION + STATE_IDENT + STATE_ANGLE_LEFT + STATE_ANGLE_RIGHT + STATE_END +) + +type CharType int // 单个字符的数据类型 + +const ( + NUM CharType = iota + CHAR + SPECIAL_SYMBOL + ILLEGAL_SYMBOL + SPACE + UNDERLINE +) + +// eof represents a marker rune for the end of the reader. +var eof = rune(0) + +type InputScanner struct { + r *bufio.Reader + apostropne bool // apostropne is true means +} + +func NewScanner(r io.Reader) *InputScanner { + return &InputScanner{r: bufio.NewReader(r), apostropne: false} +} + +// scanner不断从输入流中读取数据,尝试拼接出一个个初步解析的token +func (s *InputScanner) Scan() (tok Token, lit string) { + ch := s.read() + var buf bytes.Buffer + state := STATE_INIT + for state != STATE_END { + if checkCharType(ch) == ILLEGAL_SYMBOL { + return T_ILLEGAL, string(ch) + } + // buf.WriteRune(ch) + switch state { + case STATE_INIT: + switch checkCharType(ch) { + case NUM: + buf.WriteRune(ch) + state = STATE_INTEGER + case CHAR: + buf.WriteRune(ch) + state = STATE_IDENT + case SPECIAL_SYMBOL: + switch ch { + case eof: + return T_EOF, "" + case '.': + return T_POINT, string(ch) + case '*': + return T_ASTERISK, string(ch) + case ',': + return T_COMMA, string(ch) + case '(': + return T_LEFT_PARENTHESIS, string(ch) + case ')': + return T_RIGHT_PARENTHESIS, string(ch) + case ';': + return T_SEMICOLON, string(ch) + case '=': + return T_EQUAL, string(ch) + case '<': + buf.WriteRune(ch) + state = STATE_ANGLE_LEFT + case '>': + buf.WriteRune(ch) + state = STATE_ANGLE_RIGHT + } + case SPACE: + case UNDERLINE: + return T_ILLEGAL, string(ch) + } + case STATE_INTEGER: + switch checkCharType(ch) { + case NUM: + buf.WriteRune(ch) + case CHAR, SPACE, UNDERLINE: + s.unread() + return T_INTEGER, buf.String() + case SPECIAL_SYMBOL: + if ch == '.' { + buf.WriteRune(ch) + state = STATE_POINT + } else { + s.unread() + return T_INTEGER, buf.String() + } + } + case STATE_POINT: + switch checkCharType(ch) { + case NUM: + buf.WriteRune(ch) + state = STATE_FRACTION + case CHAR, SPECIAL_SYMBOL, SPACE, UNDERLINE: + return T_ILLEGAL, string(ch) + } + case STATE_FRACTION: + switch checkCharType(ch) { + case NUM: + buf.WriteRune(ch) + case CHAR, SPECIAL_SYMBOL, SPACE, UNDERLINE: + s.unread() + return T_FLOAT, buf.String() + } + case STATE_IDENT: + switch checkCharType(ch) { + case NUM, CHAR, UNDERLINE: + buf.WriteRune(ch) + case SPECIAL_SYMBOL, SPACE: + s.unread() + return T_IDENT, buf.String() + } + case STATE_ANGLE_LEFT: + switch checkCharType(ch) { + case NUM, CHAR, SPACE: + s.unread() + return T_ANGLE_LEFT, buf.String() + case SPECIAL_SYMBOL: + // ch = s.read() + if ch == '=' { + return T_ANGLE_LEFT_EQUAL, "<=" + } else if ch == '>' { + return T_NOT_EQUAL, "<>" + } else { + s.unread() + return T_ANGLE_LEFT, buf.String() + } + } + case STATE_ANGLE_RIGHT: + switch checkCharType(ch) { + case NUM, CHAR, SPACE: + s.unread() + return T_ANGLE_RIGHT, buf.String() + case SPECIAL_SYMBOL: + // ch = s.read() + if ch == '=' { + return T_ANGLE_RIGHT_EQUAL, ">=" + } else { + s.unread() + return T_ANGLE_RIGHT, buf.String() + } + } + } + ch = s.read() + } + + return T_ILLEGAL, string(ch) +} + +// read reads the next rune from the buffered reader. +// Returns the rune(0) if an error occurs (or io.T_EOF is returned). +func (s *InputScanner) read() rune { + ch, _, err := s.r.ReadRune() + if err != nil { + return eof + } + return ch +} + +// unread places the previously read rune back on the reader. +func (s *InputScanner) unread() { _ = s.r.UnreadRune() } + +func checkCharType(ch rune) CharType { + if ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' { + return CHAR + } else if ch >= '0' && ch <= '9' { + // fmt.Println("检测到数字") + return NUM + } else if ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' { + return SPACE + } else if ch == '.' || ch == '*' || ch == ',' || ch == '(' || ch == ')' || ch == ';' || ch == '=' || ch == '<' || ch == '>' || ch == eof { + return SPECIAL_SYMBOL + } else if ch == '_' { + return UNDERLINE + } else { + return ILLEGAL_SYMBOL + } +} diff --git a/src/Interpreter/lexer/scanner_test.go b/src/Interpreter/lexer/scanner_test.go new file mode 100644 index 0000000..317ad0f --- /dev/null +++ b/src/Interpreter/lexer/scanner_test.go @@ -0,0 +1,9 @@ +package lexer + +import ( + "testing" +) + +func TestScan(t *testing.T) { + // ToDo:现在我是懒得写了 +} diff --git a/src/Interpreter/lexer/temp.go b/src/Interpreter/lexer/temp.go new file mode 100644 index 0000000..5b4c05f --- /dev/null +++ b/src/Interpreter/lexer/temp.go @@ -0,0 +1,62 @@ +package lexer + +const IDENT = 57346 +const IDENT_LEGAL = 57347 +const PRIMARY = 57348 +const KEY = 57349 +const ASC = 57350 +const DESC = 57351 +const IN = 57352 +const INTERLEAVE = 57353 +const AND = 57354 +const OR = 57355 +const NOT = 57356 +const NULL = 57357 +const ON = 57358 +const CASCADE = 57359 +const NO = 57360 +const ACTION = 57361 +const MAX = 57362 +const UNIQUE = 57363 +const ADD = 57364 +const COLUMN = 57365 +const SET = 57366 +const TRUE = 57367 +const FALSE = 57368 +const allow_commit_timestamp = 57369 +const LE = 57370 +const GE = 57371 +const NE = 57372 +const CREATE = 57373 +const DROP = 57374 +const EXECFILE = 57375 +const USE = 57376 +const DATABASE = 57377 +const TABLE = 57378 +const INDEX = 57379 +const STORING = 57380 +const SELECT = 57381 +const WHERE = 57382 +const FROM = 57383 +const LIMIT = 57384 +const OFFSET = 57385 +const VALUES = 57386 +const INSERT = 57387 +const INTO = 57388 +const UPDATE = 57389 +const DELETE = 57390 +const BOOL = 57391 +const INT64 = 57392 +const FLOAT64 = 57393 +const STRING = 57394 +const BYTES = 57395 +const DATE = 57396 +const TIMESTAMP = 57397 +const database_id = 57398 +const table_name = 57399 +const column_name = 57400 +const index_name = 57401 +const decimal_value = 57402 +const hex_value = 57403 +const float_value = 57404 +const string_value = 57405 diff --git a/src/Interpreter/lexer/tokenizer.go b/src/Interpreter/lexer/tokenizer.go new file mode 100644 index 0000000..c9213c6 --- /dev/null +++ b/src/Interpreter/lexer/tokenizer.go @@ -0,0 +1,209 @@ +package lexer + +import ( + // . "miniSQL/src/types" + "regexp" + "strconv" +) + +const ( + LEFT_PARENTHESIS_TOKEN = int('(') + RIGHT_PARENTHESIS_TOKEN = int(')') + COMMA_TOKEN = int(',') + SEMICOLON_TOKEN = int(';') + EQUAL_TOKEN = int('=') + ANGLE_LEFT_TOKEN = int('<') + ANGLE_RIGHT_TOKEN = int('>') + ASTERISK_TOKEN = int('*') + POINT_TOKEN = int('.') +) + +var keywords = map[string]int{ + "CREATE": CREATE, + "create": CREATE, + "DROP": DROP, + "drop": DROP, + "use": USE, + "USE": USE, + "DATABASE": DATABASE, + "database": DATABASE, + "TABLE": TABLE, + "table": TABLE, + "INDEX": INDEX, + "index": INDEX, + "PRIMARY": PRIMARY, + "primary": PRIMARY, + "KEY": KEY, + "key": KEY, + "ASC": ASC, + "asc": ASC, + "DESC": DESC, + "desc": DESC, + "IN": IN, + "in": IN, + "NOT": NOT, + "not": NOT, + "AND": AND, + "and": AND, + "or": OR, + "OR": OR, + + "STORING": STORING, + "storing": STORING, + "INTERLEAVE": INTERLEAVE, + "interleave": INTERLEAVE, + "NULL": NULL, + "null": NULL, + + "ON": ON, + "on": ON, + + "CASCADE": CASCADE, + "cascade": CASCADE, + "NO": NO, + "no": NO, + "ACTION": ACTION, + "MAX": MAX, + "max": MAX, + "UNIQUE": UNIQUE, + "unique": UNIQUE, + "ADD": ADD, + "add": ADD, + "COLUMN": COLUMN, + "column": COLUMN, + "SET": SET, + "set": SET, + "TRUE": TRUE, + "true": TRUE, + "FALSE": FALSE, + "false": FALSE, + "allow_commit_timestamp": allow_commit_timestamp, + "BOOL": BOOL, + "bool": BOOL, + "INT64": INT64, + "INT": INT64, + "int": INT64, + "FLOAT64": FLOAT64, + "float64": FLOAT64, + "FLOAT": FLOAT64, + "float": FLOAT64, + + "BYTES": BYTES, + "bytes": BYTES, + "char": BYTES, + "CHAR": BYTES, + "DATE": DATE, + "date": DATE, + "TIMESTAMP": TIMESTAMP, + "timestamp": TIMESTAMP, + "database_id": database_id, + "decimal_value": decimal_value, + "hex_value": hex_value, + "table_name": table_name, + "column_name": column_name, + "index_name": index_name, + "insert": INSERT, + "INSERT": INSERT, + "INTO": INTO, + "into": INTO, + "UPDATE": UPDATE, + "update": UPDATE, + "DELETE": DELETE, + "delete": DELETE, + "SELECT": SELECT, + "select": SELECT, + "WHERE": WHERE, + "where": WHERE, + "VALUES": VALUES, + "values": VALUES, + "FROM": FROM, + "from": FROM, + "LIMIT": LIMIT, + "limit": LIMIT, + "OFFSET": OFFSET, + "offset": OFFSET, + "execfile": EXECFILE, + "EXECFILE": EXECFILE, +} + +var symbols = map[string]int{ + "(": LEFT_PARENTHESIS_TOKEN, + ")": RIGHT_PARENTHESIS_TOKEN, + ",": COMMA_TOKEN, + ";": SEMICOLON_TOKEN, + "=": EQUAL_TOKEN, + "<": ANGLE_LEFT_TOKEN, + ">": ANGLE_RIGHT_TOKEN, + "*": ASTERISK_TOKEN, + "<>": NE, + "<=": LE, + ">=": GE, + ".": POINT_TOKEN, +} + +var ( + databaseIdRegexp = regexp.MustCompile(`[a-zA-Z0-9][a-z0-9_\-]*[a-z0-9]*`) + nameAttrRegexp = regexp.MustCompile(`[a-zA-Z][a-zA-Z0-9_]*`) +) + +type keywordTokenizer struct{} + +func NewTokenizer() *keywordTokenizer { + return &keywordTokenizer{} +} + +// FromStrLit tokenize lit to a token pre-defined by goyacc with last token as a hint. +// TODO Check some literals satisfy regexp specs. +func (kt *keywordTokenizer) FromStrLit(lit string, TokenType Token, lastToken int) int { + tokVal := 0 + switch TokenType { + case T_IDENT: + if v, ok := keywords[lit]; ok { + tokVal = v + } else { + switch lastToken { + case DATABASE: + if databaseIdRegexp.MatchString(lit) { + tokVal = database_id + } + case TABLE, INTO, UPDATE, ON: + if nameAttrRegexp.MatchString(lit) { + tokVal = table_name + } + case INDEX: + if nameAttrRegexp.MatchString(lit) { + tokVal = index_name + } + } + if tokVal == 0 { + if nameAttrRegexp.MatchString(lit) { + tokVal = IDENT_LEGAL + } else { + tokVal = IDENT + } + } + } + + case T_INTEGER: + if _, err := strconv.ParseInt(lit, 10, 0); err == nil { + tokVal = decimal_value + } else if len(lit) >= 3 && lit[:2] == "0x" { + if _, err := strconv.ParseInt(lit[2:], 16, 0); err == nil { + tokVal = hex_value + } + } + case T_FLOAT: + if _, err := strconv.ParseFloat(lit, 0); err == nil { + //fmt.Println(i) + tokVal = float_value + } + case T_STRING: + tokVal = string_value + default: + if v, ok := symbols[lit]; ok { + tokVal = v + } + } + + return tokVal +} diff --git a/src/Interpreter/lexer/tokenizer_test.go b/src/Interpreter/lexer/tokenizer_test.go new file mode 100644 index 0000000..9225e97 --- /dev/null +++ b/src/Interpreter/lexer/tokenizer_test.go @@ -0,0 +1,42 @@ +package lexer + +import ( + "testing" +) + +func TestFromStrLit(t *testing.T) { + cases := []struct { + lit string + TokenType Token + lastToken int + expect int + }{ + { + "10", + T_INTEGER, + 0, + decimal_value, + }, + { + "0xff", + T_INTEGER, + 0, + hex_value, + }, + // Not hex value + { + "ff", + T_INTEGER, + 0, + 0, + }, + } + + tk := keywordTokenizer{} + for _, c := range cases { + actual := tk.FromStrLit(c.lit, c.TokenType, c.lastToken) + if actual != c.expect { + t.Errorf("Expected: %v, but actual: %v\n", c.expect, actual) + } + } +} diff --git a/src/Interpreter/parser/error.go b/src/Interpreter/parser/error.go new file mode 100644 index 0000000..0bfe2c2 --- /dev/null +++ b/src/Interpreter/parser/error.go @@ -0,0 +1 @@ +package parser diff --git a/src/Interpreter/parser/lexerWrapper.go b/src/Interpreter/parser/lexerWrapper.go new file mode 100644 index 0000000..e82cacc --- /dev/null +++ b/src/Interpreter/parser/lexerWrapper.go @@ -0,0 +1,42 @@ +package parser + +import ( + "log" + "miniSQL/src/Interpreter/lexer" + "miniSQL/src/Interpreter/types" +) + +// lex的包装类 +type lexerWrapper struct { + impl *lexer.LexerImpl + channelSend chan<- types.DStatements + lastLiteral string // 向前看一位 + err error +} + +func newLexerWrapper(li *lexer.LexerImpl, channel chan<- types.DStatements) *lexerWrapper { + return &lexerWrapper{ + impl: li, + channelSend: channel, + } +} + +// 真正实现了parser需要的Lex接口 +func (l *lexerWrapper) Lex(lval *yySymType) int { + r, err := l.impl.Lex(lval.LastToken) + if err != nil { + log.Fatal(err) + } + l.lastLiteral = r.Literal + + tokVal := r.Token + lval.str = r.Literal + lval.LastToken = tokVal + return tokVal +} + +// 真正实现了parser需要的Error接口 +// ToDo:完善错误提示机制 +func (l *lexerWrapper) Error(errStr string) { + // l.err = wrapParseError(l.lastLiteral, errStr) +} diff --git a/src/Interpreter/parser/parse_test.go b/src/Interpreter/parser/parse_test.go new file mode 100644 index 0000000..cae1886 --- /dev/null +++ b/src/Interpreter/parser/parse_test.go @@ -0,0 +1,38 @@ +package parser + +import ( + "miniSQL/src/Interpreter/types" + "strings" + "testing" +) + +var sql_strings = []string{ + "create table cxz(" + + "afsdfsad int unique," + + "what char(30) not null," + + "primary key (what)" + + ");", + "select a,b,c,d,e,f,g from cxz where a=123 and b=456 or c=234;", +} + +func TestParser(t *testing.T) { + ch := make(chan types.DStatements) + go func() { + // 通过通道通知main的goroutine + for _, sql := range sql_strings { + io := strings.NewReader(sql) // 组装io + Parse(io, ch) + } + }() + + // for stmt := range ch { + // log.Println(stmt.GetOperationType()) + // log.Println("有了") + // } + // data := <-ch + // log.Print("能不能输出") + // log.Print(data.GetOperationType()) + // cdb := data.(types.CreateTableStatement) + // log.Print(cdb.TableName) + t.Errorf("不要慌,我只是想要一个log而已\n") +} diff --git a/src/Interpreter/parser/parser.go b/src/Interpreter/parser/parser.go new file mode 100644 index 0000000..5c4b8d6 --- /dev/null +++ b/src/Interpreter/parser/parser.go @@ -0,0 +1,18 @@ +package parser + +import ( + "io" + "miniSQL/src/Interpreter/lexer" + "miniSQL/src/Interpreter/types" +) + +// Parse returns parsed Spanner DDL statements. +func Parse(r io.Reader, channel chan<- types.DStatements) error { + impl := lexer.NewLexerImpl(r) + l := newLexerWrapper(impl, channel) + yyParse(l) + if l.err != nil { + return l.err + } + return nil +} diff --git a/src/Interpreter/parser/y.output b/src/Interpreter/parser/y.output new file mode 100644 index 0000000..7dbf08b --- /dev/null +++ b/src/Interpreter/parser/y.output @@ -0,0 +1,1552 @@ + +state 0 + $accept: .statements $end + + CREATE shift 15 + DROP shift 17 + EXECFILE shift 22 + USE shift 16 + SELECT shift 18 + INSERT shift 19 + UPDATE shift 20 + DELETE shift 21 + . error + + statements goto 1 + statement goto 2 + create_database goto 3 + use_database goto 4 + create_table goto 5 + create_index goto 6 + drop_database goto 7 + drop_table goto 8 + drop_index goto 9 + select_stmt goto 10 + insert_stmt goto 11 + update_stmt goto 12 + delete_stmt goto 13 + execfile_stmt goto 14 + +state 1 + $accept: statements.$end + statements: statements.statement + + $end accept + CREATE shift 15 + DROP shift 17 + EXECFILE shift 22 + USE shift 16 + SELECT shift 18 + INSERT shift 19 + UPDATE shift 20 + DELETE shift 21 + . error + + statement goto 23 + create_database goto 3 + use_database goto 4 + create_table goto 5 + create_index goto 6 + drop_database goto 7 + drop_table goto 8 + drop_index goto 9 + select_stmt goto 10 + insert_stmt goto 11 + update_stmt goto 12 + delete_stmt goto 13 + execfile_stmt goto 14 + +state 2 + statements: statement. (1) + + . reduce 1 (src line 103) + + +state 3 + statement: create_database.';' + + ';' shift 24 + . error + + +state 4 + statement: use_database.';' + + ';' shift 25 + . error + + +state 5 + statement: create_table.';' + + ';' shift 26 + . error + + +state 6 + statement: create_index.';' + + ';' shift 27 + . error + + +state 7 + statement: drop_database.';' + + ';' shift 28 + . error + + +state 8 + statement: drop_table.';' + + ';' shift 29 + . error + + +state 9 + statement: drop_index.';' + + ';' shift 30 + . error + + +state 10 + statement: select_stmt.';' + + ';' shift 31 + . error + + +state 11 + statement: insert_stmt.';' + + ';' shift 32 + . error + + +state 12 + statement: update_stmt.';' + + ';' shift 33 + . error + + +state 13 + statement: delete_stmt.';' + + ';' shift 34 + . error + + +state 14 + statement: execfile_stmt.';' + + ';' shift 35 + . error + + +state 15 + create_database: CREATE.DATABASE database_id + create_table: CREATE.TABLE table_name '(' column_def_list ',' primary_key ')' + create_table: CREATE.TABLE table_name '(' column_def_list ')' + create_index: CREATE.unique_opt INDEX index_name ON table_name '(' key_part_list ')' + unique_opt: . (43) + + UNIQUE shift 39 + DATABASE shift 36 + TABLE shift 37 + . reduce 43 (src line 370) + + unique_opt goto 38 + +state 16 + use_database: USE.DATABASE database_id + + DATABASE shift 40 + . error + + +state 17 + drop_database: DROP.DATABASE database_id + drop_table: DROP.TABLE table_name + drop_index: DROP.INDEX index_name ON table_name + + DATABASE shift 41 + TABLE shift 42 + INDEX shift 43 + . error + + +state 18 + select_stmt: SELECT.sel_field_list FROM table_name_list where_opt limit_opt + + IDENT_LEGAL shift 47 + '*' shift 45 + . error + + column_name_list goto 46 + sel_field_list goto 44 + +state 19 + insert_stmt: INSERT.INTO table_name VALUES '(' value_list ')' + insert_stmt: INSERT.INTO table_name '(' column_name_list ')' VALUES '(' value_list ')' + + INTO shift 48 + . error + + +state 20 + update_stmt: UPDATE.table_name SET set_opt_list where_opt + + table_name shift 49 + . error + + +state 21 + delete_stmt: DELETE.FROM IDENT_ALL where_opt + + FROM shift 50 + . error + + +state 22 + execfile_stmt: EXECFILE.IDENT_ALL + execfile_stmt: EXECFILE.IDENT_ALL '.' IDENT_ALL + execfile_stmt: EXECFILE.string_value + + IDENT shift 53 + IDENT_LEGAL shift 54 + string_value shift 52 + . error + + IDENT_ALL goto 51 + +state 23 + statements: statements statement. (2) + + . reduce 2 (src line 105) + + +state 24 + statement: create_database ';'. (3) + + . reduce 3 (src line 107) + + +state 25 + statement: use_database ';'. (4) + + . reduce 4 (src line 109) + + +state 26 + statement: create_table ';'. (5) + + . reduce 5 (src line 110) + + +state 27 + statement: create_index ';'. (6) + + . reduce 6 (src line 111) + + +state 28 + statement: drop_database ';'. (7) + + . reduce 7 (src line 112) + + +state 29 + statement: drop_table ';'. (8) + + . reduce 8 (src line 113) + + +state 30 + statement: drop_index ';'. (9) + + . reduce 9 (src line 114) + + +state 31 + statement: select_stmt ';'. (10) + + . reduce 10 (src line 115) + + +state 32 + statement: insert_stmt ';'. (11) + + . reduce 11 (src line 116) + + +state 33 + statement: update_stmt ';'. (12) + + . reduce 12 (src line 117) + + +state 34 + statement: delete_stmt ';'. (13) + + . reduce 13 (src line 118) + + +state 35 + statement: execfile_stmt ';'. (14) + + . reduce 14 (src line 119) + + +state 36 + create_database: CREATE DATABASE.database_id + + database_id shift 55 + . error + + +state 37 + create_table: CREATE TABLE.table_name '(' column_def_list ',' primary_key ')' + create_table: CREATE TABLE.table_name '(' column_def_list ')' + + table_name shift 56 + . error + + +state 38 + create_index: CREATE unique_opt.INDEX index_name ON table_name '(' key_part_list ')' + + INDEX shift 57 + . error + + +state 39 + unique_opt: UNIQUE. (44) + + . reduce 44 (src line 375) + + +state 40 + use_database: USE DATABASE.database_id + + database_id shift 58 + . error + + +state 41 + drop_database: DROP DATABASE.database_id + + database_id shift 59 + . error + + +state 42 + drop_table: DROP TABLE.table_name + + table_name shift 60 + . error + + +state 43 + drop_index: DROP INDEX.index_name ON table_name + + index_name shift 61 + . error + + +state 44 + select_stmt: SELECT sel_field_list.FROM table_name_list where_opt limit_opt + + FROM shift 62 + . error + + +state 45 + sel_field_list: '*'. (58) + + . reduce 58 (src line 524) + + +state 46 + column_name_list: column_name_list.',' IDENT_LEGAL + sel_field_list: column_name_list. (59) + + ',' shift 63 + . reduce 59 (src line 531) + + +state 47 + column_name_list: IDENT_LEGAL. (45) + + . reduce 45 (src line 397) + + +state 48 + insert_stmt: INSERT INTO.table_name VALUES '(' value_list ')' + insert_stmt: INSERT INTO.table_name '(' column_name_list ')' VALUES '(' value_list ')' + + table_name shift 64 + . error + + +state 49 + update_stmt: UPDATE table_name.SET set_opt_list where_opt + + SET shift 65 + . error + + +state 50 + delete_stmt: DELETE FROM.IDENT_ALL where_opt + + IDENT shift 53 + IDENT_LEGAL shift 54 + . error + + IDENT_ALL goto 66 + +state 51 + execfile_stmt: EXECFILE IDENT_ALL. (15) + execfile_stmt: EXECFILE IDENT_ALL.'.' IDENT_ALL + + '.' shift 67 + . reduce 15 (src line 122) + + +state 52 + execfile_stmt: EXECFILE string_value. (17) + + . reduce 17 (src line 136) + + +state 53 + IDENT_ALL: IDENT. (96) + + . reduce 96 (src line 691) + + +state 54 + IDENT_ALL: IDENT_LEGAL. (97) + + . reduce 97 (src line 696) + + +state 55 + create_database: CREATE DATABASE database_id. (18) + + . reduce 18 (src line 143) + + +state 56 + create_table: CREATE TABLE table_name.'(' column_def_list ',' primary_key ')' + create_table: CREATE TABLE table_name.'(' column_def_list ')' + + '(' shift 68 + . error + + +state 57 + create_index: CREATE unique_opt INDEX.index_name ON table_name '(' key_part_list ')' + + index_name shift 69 + . error + + +state 58 + use_database: USE DATABASE database_id. (19) + + . reduce 19 (src line 151) + + +state 59 + drop_database: DROP DATABASE database_id. (47) + + . reduce 47 (src line 429) + + +state 60 + drop_table: DROP TABLE table_name. (48) + + . reduce 48 (src line 438) + + +state 61 + drop_index: DROP INDEX index_name.ON table_name + + ON shift 70 + . error + + +state 62 + select_stmt: SELECT sel_field_list FROM.table_name_list where_opt limit_opt + + IDENT shift 53 + IDENT_LEGAL shift 54 + . error + + IDENT_ALL goto 72 + table_name_list goto 71 + +state 63 + column_name_list: column_name_list ','.IDENT_LEGAL + + IDENT_LEGAL shift 73 + . error + + +state 64 + insert_stmt: INSERT INTO table_name.VALUES '(' value_list ')' + insert_stmt: INSERT INTO table_name.'(' column_name_list ')' VALUES '(' value_list ')' + + '(' shift 75 + VALUES shift 74 + . error + + +state 65 + update_stmt: UPDATE table_name SET.set_opt_list where_opt + + IDENT_LEGAL shift 78 + . error + + set_opt goto 77 + set_opt_list goto 76 + +state 66 + delete_stmt: DELETE FROM IDENT_ALL.where_opt + where_opt: . (62) + + WHERE shift 80 + . reduce 62 (src line 550) + + where_opt goto 79 + +state 67 + execfile_stmt: EXECFILE IDENT_ALL '.'.IDENT_ALL + + IDENT shift 53 + IDENT_LEGAL shift 54 + . error + + IDENT_ALL goto 81 + +state 68 + create_table: CREATE TABLE table_name '('.column_def_list ',' primary_key ')' + create_table: CREATE TABLE table_name '('.column_def_list ')' + column_def_list: . (22) + + IDENT_LEGAL shift 84 + . reduce 22 (src line 191) + + column_def goto 83 + column_def_list goto 82 + +state 69 + create_index: CREATE unique_opt INDEX index_name.ON table_name '(' key_part_list ')' + + ON shift 85 + . error + + +state 70 + drop_index: DROP INDEX index_name ON.table_name + + table_name shift 86 + . error + + +state 71 + select_stmt: SELECT sel_field_list FROM table_name_list.where_opt limit_opt + table_name_list: table_name_list.',' IDENT_ALL + where_opt: . (62) + + ',' shift 88 + WHERE shift 80 + . reduce 62 (src line 550) + + where_opt goto 87 + +state 72 + table_name_list: IDENT_ALL. (60) + + . reduce 60 (src line 539) + + +state 73 + column_name_list: column_name_list ',' IDENT_LEGAL. (46) + + . reduce 46 (src line 403) + + +state 74 + insert_stmt: INSERT INTO table_name VALUES.'(' value_list ')' + + '(' shift 89 + . error + + +state 75 + insert_stmt: INSERT INTO table_name '('.column_name_list ')' VALUES '(' value_list ')' + + IDENT_LEGAL shift 47 + . error + + column_name_list goto 90 + +state 76 + update_stmt: UPDATE table_name SET set_opt_list.where_opt + set_opt_list: set_opt_list.',' set_opt + where_opt: . (62) + + ',' shift 92 + WHERE shift 80 + . reduce 62 (src line 550) + + where_opt goto 91 + +state 77 + set_opt_list: set_opt. (53) + + . reduce 53 (src line 486) + + +state 78 + set_opt: IDENT_LEGAL.'=' Value + + '=' shift 93 + . error + + +state 79 + delete_stmt: DELETE FROM IDENT_ALL where_opt. (56) + + . reduce 56 (src line 504) + + +state 80 + where_opt: WHERE.expr_opt + Value: . (74) + + IDENT shift 53 + IDENT_LEGAL shift 54 + NOT shift 98 + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + '(' shift 95 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + IDENT_ALL goto 96 + expr_opt goto 94 + Value goto 97 + +state 81 + execfile_stmt: EXECFILE IDENT_ALL '.' IDENT_ALL. (16) + + . reduce 16 (src line 130) + + +state 82 + create_table: CREATE TABLE table_name '(' column_def_list.',' primary_key ')' + create_table: CREATE TABLE table_name '(' column_def_list.')' + column_def_list: column_def_list.',' column_def + + ',' shift 108 + ')' shift 109 + . error + + +state 83 + column_def_list: column_def. (23) + + . reduce 23 (src line 196) + + +state 84 + column_def: IDENT_LEGAL.column_type unique_opt not_null_opt + + BOOL shift 112 + INT64 shift 113 + FLOAT64 shift 114 + BYTES shift 115 + DATE shift 116 + TIMESTAMP shift 117 + . error + + column_type goto 110 + scalar_type goto 111 + +state 85 + create_index: CREATE unique_opt INDEX index_name ON.table_name '(' key_part_list ')' + + table_name shift 118 + . error + + +state 86 + drop_index: DROP INDEX index_name ON table_name. (49) + + . reduce 49 (src line 447) + + +state 87 + select_stmt: SELECT sel_field_list FROM table_name_list where_opt.limit_opt + limit_opt: . (87) + + LIMIT shift 120 + . reduce 87 (src line 645) + + limit_opt goto 119 + +state 88 + table_name_list: table_name_list ','.IDENT_ALL + + IDENT shift 53 + IDENT_LEGAL shift 54 + . error + + IDENT_ALL goto 121 + +state 89 + insert_stmt: INSERT INTO table_name VALUES '('.value_list ')' + Value: . (74) + + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + Value goto 123 + value_list goto 122 + +state 90 + column_name_list: column_name_list.',' IDENT_LEGAL + insert_stmt: INSERT INTO table_name '(' column_name_list.')' VALUES '(' value_list ')' + + ',' shift 63 + ')' shift 124 + . error + + +state 91 + update_stmt: UPDATE table_name SET set_opt_list where_opt. (52) + + . reduce 52 (src line 476) + + +state 92 + set_opt_list: set_opt_list ','.set_opt + + IDENT_LEGAL shift 78 + . error + + set_opt goto 125 + +state 93 + set_opt: IDENT_LEGAL '='.Value + Value: . (74) + + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + Value goto 126 + +state 94 + where_opt: WHERE expr_opt. (63) + expr_opt: expr_opt.AND expr_opt + expr_opt: expr_opt.OR expr_opt + + AND shift 127 + OR shift 128 + . reduce 63 (src line 554) + + +state 95 + expr_opt: '('.expr_opt ')' + Value: . (74) + + IDENT shift 53 + IDENT_LEGAL shift 54 + NOT shift 98 + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + '(' shift 95 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + IDENT_ALL goto 96 + expr_opt goto 129 + Value goto 97 + +state 96 + expr_opt: IDENT_ALL.compare_type Value + expr_opt: IDENT_ALL.compare_type IDENT_ALL + + '=' shift 131 + '<' shift 132 + '>' shift 133 + LE shift 134 + GE shift 135 + NE shift 136 + . error + + compare_type goto 130 + +state 97 + expr_opt: Value.compare_type IDENT_ALL + expr_opt: Value.compare_type Value + + '=' shift 131 + '<' shift 132 + '>' shift 133 + LE shift 134 + GE shift 135 + NE shift 136 + . error + + compare_type goto 137 + +state 98 + expr_opt: NOT.expr_opt + Value: . (74) + + IDENT shift 53 + IDENT_LEGAL shift 54 + NOT shift 98 + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + '(' shift 95 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + IDENT_ALL goto 96 + expr_opt goto 138 + Value goto 97 + +state 99 + Value: string_value. (75) + + . reduce 75 (src line 612) + + +state 100 + Value: int64_value. (76) + + . reduce 76 (src line 616) + + +state 101 + Value: float64_value. (77) + + . reduce 77 (src line 620) + + +state 102 + Value: TRUE. (78) + + . reduce 78 (src line 624) + + +state 103 + Value: FALSE. (79) + + . reduce 79 (src line 628) + + +state 104 + Value: NULL. (80) + + . reduce 80 (src line 632) + + +state 105 + int64_value: decimal_value. (93) + + . reduce 93 (src line 672) + + +state 106 + int64_value: hex_value. (94) + + . reduce 94 (src line 678) + + +state 107 + float64_value: float_value. (95) + + . reduce 95 (src line 684) + + +state 108 + create_table: CREATE TABLE table_name '(' column_def_list ','.primary_key ')' + column_def_list: column_def_list ','.column_def + primary_key: . (26) + + IDENT_LEGAL shift 84 + PRIMARY shift 141 + . reduce 26 (src line 212) + + column_def goto 140 + primary_key goto 139 + +state 109 + create_table: CREATE TABLE table_name '(' column_def_list ')'. (21) + + . reduce 21 (src line 176) + + +state 110 + column_def: IDENT_LEGAL column_type.unique_opt not_null_opt + unique_opt: . (43) + + UNIQUE shift 39 + . reduce 43 (src line 370) + + unique_opt goto 142 + +state 111 + column_type: scalar_type. (31) + + . reduce 31 (src line 286) + + +state 112 + scalar_type: BOOL. (32) + + . reduce 32 (src line 293) + + +state 113 + scalar_type: INT64. (33) + + . reduce 33 (src line 298) + + +state 114 + scalar_type: FLOAT64. (34) + + . reduce 34 (src line 302) + + +state 115 + scalar_type: BYTES.'(' length ')' + + '(' shift 143 + . error + + +state 116 + scalar_type: DATE. (36) + + . reduce 36 (src line 311) + + +state 117 + scalar_type: TIMESTAMP. (37) + + . reduce 37 (src line 315) + + +state 118 + create_index: CREATE unique_opt INDEX index_name ON table_name.'(' key_part_list ')' + + '(' shift 144 + . error + + +state 119 + select_stmt: SELECT sel_field_list FROM table_name_list where_opt limit_opt. (57) + + . reduce 57 (src line 513) + + +state 120 + limit_opt: LIMIT.int_value + limit_opt: LIMIT.int_value ',' int_value + limit_opt: LIMIT.int_value OFFSET int_value + + decimal_value shift 146 + hex_value shift 147 + . error + + int_value goto 145 + +state 121 + table_name_list: table_name_list ',' IDENT_ALL. (61) + + . reduce 61 (src line 545) + + +state 122 + insert_stmt: INSERT INTO table_name VALUES '(' value_list.')' + value_list: value_list.',' Value + + ',' shift 149 + ')' shift 148 + . error + + +state 123 + value_list: Value. (72) + + . reduce 72 (src line 597) + + +state 124 + insert_stmt: INSERT INTO table_name '(' column_name_list ')'.VALUES '(' value_list ')' + + VALUES shift 150 + . error + + +state 125 + set_opt_list: set_opt_list ',' set_opt. (54) + + . reduce 54 (src line 492) + + +state 126 + set_opt: IDENT_LEGAL '=' Value. (55) + + . reduce 55 (src line 496) + + +state 127 + expr_opt: expr_opt AND.expr_opt + Value: . (74) + + IDENT shift 53 + IDENT_LEGAL shift 54 + NOT shift 98 + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + '(' shift 95 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + IDENT_ALL goto 96 + expr_opt goto 151 + Value goto 97 + +state 128 + expr_opt: expr_opt OR.expr_opt + Value: . (74) + + IDENT shift 53 + IDENT_LEGAL shift 54 + NOT shift 98 + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + '(' shift 95 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + IDENT_ALL goto 96 + expr_opt goto 152 + Value goto 97 + +state 129 + expr_opt: '(' expr_opt.')' + expr_opt: expr_opt.AND expr_opt + expr_opt: expr_opt.OR expr_opt + + AND shift 127 + OR shift 128 + ')' shift 153 + . error + + +state 130 + expr_opt: IDENT_ALL compare_type.Value + expr_opt: IDENT_ALL compare_type.IDENT_ALL + Value: . (74) + + IDENT shift 53 + IDENT_LEGAL shift 54 + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + IDENT_ALL goto 155 + Value goto 154 + +state 131 + compare_type: '='. (81) + + . reduce 81 (src line 636) + + +state 132 + compare_type: '<'. (82) + + . reduce 82 (src line 638) + + +state 133 + compare_type: '>'. (83) + + . reduce 83 (src line 639) + + +state 134 + compare_type: LE. (84) + + . reduce 84 (src line 640) + + +state 135 + compare_type: GE. (85) + + . reduce 85 (src line 641) + + +state 136 + compare_type: NE. (86) + + . reduce 86 (src line 642) + + +state 137 + expr_opt: Value compare_type.IDENT_ALL + expr_opt: Value compare_type.Value + Value: . (74) + + IDENT shift 53 + IDENT_LEGAL shift 54 + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + IDENT_ALL goto 156 + Value goto 157 + +138: shift/reduce conflict (shift 127(0), red'n 71(0)) on AND +138: shift/reduce conflict (shift 128(0), red'n 71(0)) on OR +state 138 + expr_opt: expr_opt.AND expr_opt + expr_opt: expr_opt.OR expr_opt + expr_opt: NOT expr_opt. (71) + + AND shift 127 + OR shift 128 + . reduce 71 (src line 591) + + +state 139 + create_table: CREATE TABLE table_name '(' column_def_list ',' primary_key.')' + + ')' shift 158 + . error + + +state 140 + column_def_list: column_def_list ',' column_def. (24) + + . reduce 24 (src line 201) + + +state 141 + primary_key: PRIMARY.KEY '(' key_part_list ')' + + KEY shift 159 + . error + + +state 142 + column_def: IDENT_LEGAL column_type unique_opt.not_null_opt + not_null_opt: . (40) + + NOT shift 161 + . reduce 40 (src line 346) + + not_null_opt goto 160 + +state 143 + scalar_type: BYTES '('.length ')' + + MAX shift 164 + decimal_value shift 146 + hex_value shift 147 + . error + + length goto 162 + int_value goto 163 + +state 144 + create_index: CREATE unique_opt INDEX index_name ON table_name '('.key_part_list ')' + + IDENT_LEGAL shift 167 + . error + + key_part goto 166 + key_part_list goto 165 + +state 145 + limit_opt: LIMIT int_value. (88) + limit_opt: LIMIT int_value.',' int_value + limit_opt: LIMIT int_value.OFFSET int_value + + ',' shift 168 + OFFSET shift 169 + . reduce 88 (src line 649) + + +state 146 + int_value: decimal_value. (91) + + . reduce 91 (src line 661) + + +state 147 + int_value: hex_value. (92) + + . reduce 92 (src line 667) + + +state 148 + insert_stmt: INSERT INTO table_name VALUES '(' value_list ')'. (50) + + . reduce 50 (src line 457) + + +state 149 + value_list: value_list ','.Value + Value: . (74) + + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + Value goto 170 + +state 150 + insert_stmt: INSERT INTO table_name '(' column_name_list ')' VALUES.'(' value_list ')' + + '(' shift 171 + . error + + +151: shift/reduce conflict (shift 127(0), red'n 69(0)) on AND +151: shift/reduce conflict (shift 128(0), red'n 69(0)) on OR +state 151 + expr_opt: expr_opt.AND expr_opt + expr_opt: expr_opt AND expr_opt. (69) + expr_opt: expr_opt.OR expr_opt + + AND shift 127 + OR shift 128 + . reduce 69 (src line 579) + + +152: shift/reduce conflict (shift 127(0), red'n 70(0)) on AND +152: shift/reduce conflict (shift 128(0), red'n 70(0)) on OR +state 152 + expr_opt: expr_opt.AND expr_opt + expr_opt: expr_opt.OR expr_opt + expr_opt: expr_opt OR expr_opt. (70) + + AND shift 127 + OR shift 128 + . reduce 70 (src line 585) + + +state 153 + expr_opt: '(' expr_opt ')'. (64) + + . reduce 64 (src line 558) + + +state 154 + expr_opt: IDENT_ALL compare_type Value. (65) + + . reduce 65 (src line 563) + + +state 155 + expr_opt: IDENT_ALL compare_type IDENT_ALL. (68) + + . reduce 68 (src line 575) + + +state 156 + expr_opt: Value compare_type IDENT_ALL. (66) + + . reduce 66 (src line 567) + + +state 157 + expr_opt: Value compare_type Value. (67) + + . reduce 67 (src line 571) + + +state 158 + create_table: CREATE TABLE table_name '(' column_def_list ',' primary_key ')'. (20) + + . reduce 20 (src line 159) + + +state 159 + primary_key: PRIMARY KEY.'(' key_part_list ')' + + '(' shift 172 + . error + + +state 160 + column_def: IDENT_LEGAL column_type unique_opt not_null_opt. (25) + + . reduce 25 (src line 206) + + +state 161 + not_null_opt: NOT.NULL + + NULL shift 173 + . error + + +state 162 + scalar_type: BYTES '(' length.')' + + ')' shift 174 + . error + + +state 163 + length: int_value. (38) + + . reduce 38 (src line 320) + + +state 164 + length: MAX. (39) + + . reduce 39 (src line 325) + + +state 165 + key_part_list: key_part_list.',' key_part + create_index: CREATE unique_opt INDEX index_name ON table_name '(' key_part_list.')' + + ',' shift 175 + ')' shift 176 + . error + + +state 166 + key_part_list: key_part. (28) + + . reduce 28 (src line 221) + + +state 167 + key_part: IDENT_LEGAL. (30) + + . reduce 30 (src line 232) + + +state 168 + limit_opt: LIMIT int_value ','.int_value + + decimal_value shift 146 + hex_value shift 147 + . error + + int_value goto 177 + +state 169 + limit_opt: LIMIT int_value OFFSET.int_value + + decimal_value shift 146 + hex_value shift 147 + . error + + int_value goto 178 + +state 170 + value_list: value_list ',' Value. (73) + + . reduce 73 (src line 603) + + +state 171 + insert_stmt: INSERT INTO table_name '(' column_name_list ')' VALUES '('.value_list ')' + Value: . (74) + + NULL shift 104 + TRUE shift 102 + FALSE shift 103 + decimal_value shift 105 + hex_value shift 106 + float_value shift 107 + string_value shift 99 + . reduce 74 (src line 608) + + int64_value goto 100 + float64_value goto 101 + Value goto 123 + value_list goto 179 + +state 172 + primary_key: PRIMARY KEY '('.key_part_list ')' + + IDENT_LEGAL shift 167 + . error + + key_part goto 166 + key_part_list goto 180 + +state 173 + not_null_opt: NOT NULL. (41) + + . reduce 41 (src line 351) + + +state 174 + scalar_type: BYTES '(' length ')'. (35) + + . reduce 35 (src line 307) + + +state 175 + key_part_list: key_part_list ','.key_part + + IDENT_LEGAL shift 167 + . error + + key_part goto 181 + +state 176 + create_index: CREATE unique_opt INDEX index_name ON table_name '(' key_part_list ')'. (42) + + . reduce 42 (src line 356) + + +state 177 + limit_opt: LIMIT int_value ',' int_value. (89) + + . reduce 89 (src line 653) + + +state 178 + limit_opt: LIMIT int_value OFFSET int_value. (90) + + . reduce 90 (src line 657) + + +state 179 + insert_stmt: INSERT INTO table_name '(' column_name_list ')' VALUES '(' value_list.')' + value_list: value_list.',' Value + + ',' shift 149 + ')' shift 182 + . error + + +state 180 + primary_key: PRIMARY KEY '(' key_part_list.')' + key_part_list: key_part_list.',' key_part + + ',' shift 175 + ')' shift 183 + . error + + +state 181 + key_part_list: key_part_list ',' key_part. (29) + + . reduce 29 (src line 227) + + +state 182 + insert_stmt: INSERT INTO table_name '(' column_name_list ')' VALUES '(' value_list ')'. (51) + + . reduce 51 (src line 467) + + +state 183 + primary_key: PRIMARY KEY '(' key_part_list ')'. (27) + + . reduce 27 (src line 216) + + +72 terminals, 40 nonterminals +98 grammar rules, 184/16000 states +6 shift/reduce, 0 reduce/reduce conflicts reported +89 working sets used +memory: parser 120/240000 +19 extra closures +253 shift entries, 1 exceptions +70 goto entries +41 entries saved by goto default +Optimizer space used: output 216/240000 +216 table entries, 0 zero +maximum spread: 72, maximum offset: 175 diff --git a/src/Interpreter/parser/yacc.go b/src/Interpreter/parser/yacc.go new file mode 100644 index 0000000..ee10f11 --- /dev/null +++ b/src/Interpreter/parser/yacc.go @@ -0,0 +1,1294 @@ +// Code generated by goyacc -o yacc.go yacc.y. DO NOT EDIT. + +//line yacc.y:2 +package parser + +import __yyfmt__ "fmt" + +//line yacc.y:2 + +import ( + "miniSQL/src/types" + Value "miniSQL/src/value" + "strconv" +) + +//line yacc.y:11 +type yySymType struct { + yys int + empty struct{} + flag bool + i64 int64 + int int + f64 float64 + str string + strs []string + col types.Column + cols []types.Column + coltype types.ColumnType + key types.Key + keys []types.Key + // keyorder types.KeyOrder + // clstr types.Cluster + // ondelete types.OnDelete + // stcls types.StoringClause + // intlr types.Interleave + // intlrs []types.Interleave + fieldsname types.FieldsName + LastToken int + expr types.Expr + where *types.Where + limit types.Limit + compare Value.CompareType + valuetype Value.Value + valuetypelist []Value.Value + setexpr types.SetExpr + setexprlist []types.SetExpr +} + +const IDENT = 57346 +const IDENT_LEGAL = 57347 +const PRIMARY = 57348 +const KEY = 57349 +const ASC = 57350 +const DESC = 57351 +const IN = 57352 +const INTERLEAVE = 57353 +const AND = 57354 +const OR = 57355 +const NOT = 57356 +const NULL = 57357 +const ON = 57358 +const CASCADE = 57359 +const NO = 57360 +const ACTION = 57361 +const MAX = 57362 +const UNIQUE = 57363 +const ADD = 57364 +const COLUMN = 57365 +const SET = 57366 +const TRUE = 57367 +const FALSE = 57368 +const allow_commit_timestamp = 57369 +const LE = 57370 +const GE = 57371 +const NE = 57372 +const CREATE = 57373 +const DROP = 57374 +const EXECFILE = 57375 +const USE = 57376 +const DATABASE = 57377 +const TABLE = 57378 +const INDEX = 57379 +const STORING = 57380 +const SELECT = 57381 +const WHERE = 57382 +const FROM = 57383 +const LIMIT = 57384 +const OFFSET = 57385 +const VALUES = 57386 +const INSERT = 57387 +const INTO = 57388 +const UPDATE = 57389 +const DELETE = 57390 +const BOOL = 57391 +const INT64 = 57392 +const FLOAT64 = 57393 +const STRING = 57394 +const BYTES = 57395 +const DATE = 57396 +const TIMESTAMP = 57397 +const database_id = 57398 +const table_name = 57399 +const column_name = 57400 +const index_name = 57401 +const decimal_value = 57402 +const hex_value = 57403 +const float_value = 57404 +const string_value = 57405 + +var yyToknames = [...]string{ + "$end", + "error", + "$unk", + "IDENT", + "IDENT_LEGAL", + "PRIMARY", + "KEY", + "ASC", + "DESC", + "IN", + "INTERLEAVE", + "AND", + "OR", + "NOT", + "NULL", + "ON", + "CASCADE", + "NO", + "ACTION", + "MAX", + "UNIQUE", + "ADD", + "COLUMN", + "SET", + "TRUE", + "FALSE", + "allow_commit_timestamp", + "'('", + "','", + "')'", + "';'", + "'*'", + "'.'", + "'='", + "'<'", + "'>'", + "LE", + "GE", + "NE", + "CREATE", + "DROP", + "EXECFILE", + "USE", + "DATABASE", + "TABLE", + "INDEX", + "STORING", + "SELECT", + "WHERE", + "FROM", + "LIMIT", + "OFFSET", + "VALUES", + "INSERT", + "INTO", + "UPDATE", + "DELETE", + "BOOL", + "INT64", + "FLOAT64", + "STRING", + "BYTES", + "DATE", + "TIMESTAMP", + "database_id", + "table_name", + "column_name", + "index_name", + "decimal_value", + "hex_value", + "float_value", + "string_value", +} + +var yyStatenames = [...]string{} + +const yyEofCode = 1 +const yyErrCode = 2 +const yyInitialStackSize = 16 + +//line yacctab:1 +var yyExca = [...]int8{ + -1, 1, + 1, -1, + -2, 0, +} + +const yyPrivate = 57344 + +const yyLast = 216 + +var yyAct = [...]uint8{ + 97, 166, 165, 96, 122, 38, 83, 94, 77, 145, + 130, 53, 54, 104, 79, 164, 53, 54, 69, 46, + 61, 98, 104, 102, 103, 118, 51, 104, 53, 54, + 146, 147, 102, 103, 86, 95, 64, 102, 103, 112, + 113, 114, 60, 115, 116, 117, 56, 48, 49, 59, + 58, 55, 168, 150, 66, 75, 120, 40, 62, 50, + 80, 41, 42, 43, 146, 147, 72, 105, 106, 107, + 99, 81, 57, 92, 93, 169, 105, 106, 107, 99, + 74, 105, 106, 107, 99, 67, 87, 88, 175, 183, + 123, 91, 121, 80, 126, 90, 52, 15, 17, 22, + 16, 125, 39, 129, 35, 18, 138, 80, 137, 34, + 47, 19, 174, 20, 21, 140, 142, 131, 132, 133, + 134, 135, 136, 149, 182, 36, 37, 127, 128, 175, + 176, 154, 149, 148, 155, 151, 152, 45, 157, 63, + 124, 156, 108, 109, 158, 153, 65, 33, 32, 31, + 170, 30, 29, 163, 28, 27, 26, 25, 24, 63, + 172, 171, 144, 143, 89, 68, 39, 85, 70, 173, + 127, 128, 123, 161, 159, 180, 179, 181, 177, 178, + 84, 141, 53, 54, 167, 78, 47, 84, 73, 2, + 14, 23, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 1, 76, 119, 44, 71, 160, 139, + 101, 100, 162, 111, 110, 82, +} + +var yyPact = [...]int16{ + 57, 57, -1000, 127, 126, 125, 124, 123, 121, 120, + 118, 117, 116, 78, 73, 81, 13, 17, 105, -8, + -18, 9, 24, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -14, -20, 26, -1000, + -15, -16, -24, -48, 8, -1000, 130, -1000, -30, 122, + 178, 52, -1000, -1000, -1000, -1000, 137, -50, -1000, -1000, + -1000, 152, 178, 183, 27, 180, 11, 178, 182, 151, + -32, 58, -1000, -1000, 136, 181, 44, -1000, 40, -1000, + 7, -1000, 113, -1000, -19, -41, -1000, 5, 178, -2, + 110, -1000, 180, -2, 158, 7, 83, 83, 7, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 175, -1000, + 145, -1000, -1000, -1000, -1000, 135, -1000, -1000, 134, -1000, + -39, -1000, 103, -1000, 0, -1000, -1000, 7, 7, 115, + 12, -1000, -1000, -1000, -1000, -1000, -1000, 12, 158, 114, + -1000, 167, 159, -5, 179, 23, -1000, -1000, -1000, -2, + 133, 158, 158, -1000, -1000, -1000, -1000, -1000, -1000, 132, + -1000, 154, 82, -1000, -1000, 100, -1000, -1000, -39, -39, + -1000, -2, 179, -1000, -1000, 179, -1000, -1000, -1000, 94, + 59, -1000, -1000, -1000, +} + +var yyPgo = [...]uint8{ + 0, 6, 215, 214, 213, 212, 211, 210, 1, 2, + 209, 208, 5, 3, 19, 207, 206, 7, 205, 10, + 0, 9, 14, 8, 204, 4, 203, 189, 202, 201, + 200, 199, 198, 197, 196, 195, 194, 193, 192, 190, +} + +var yyR1 = [...]int8{ + 0, 26, 26, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 39, 39, 39, 28, 29, + 30, 30, 2, 2, 2, 1, 10, 10, 9, 9, + 8, 3, 4, 4, 4, 4, 4, 4, 5, 5, + 11, 11, 31, 12, 12, 14, 14, 32, 33, 34, + 36, 36, 37, 24, 24, 23, 38, 35, 16, 16, + 15, 15, 22, 22, 17, 17, 17, 17, 17, 17, + 17, 17, 25, 25, 20, 20, 20, 20, 20, 20, + 20, 19, 19, 19, 19, 19, 19, 18, 18, 18, + 18, 21, 21, 6, 6, 7, 13, 13, +} + +var yyR2 = [...]int8{ + 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 3, 3, + 8, 6, 0, 1, 3, 4, 0, 5, 1, 3, + 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, + 0, 2, 9, 0, 1, 1, 3, 3, 3, 5, + 7, 10, 5, 1, 3, 3, 4, 6, 1, 1, + 1, 3, 0, 2, 3, 3, 3, 3, 3, 3, + 3, 2, 1, 3, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 2, 4, + 4, 1, 1, 1, 1, 1, 1, 1, +} + +var yyChk = [...]int16{ + -1000, -26, -27, -28, -29, -30, -31, -32, -33, -34, + -35, -36, -37, -38, -39, 40, 43, 41, 48, 54, + 56, 57, 42, -27, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 44, 45, -12, 21, + 44, 44, 45, 46, -16, 32, -14, 5, 55, 66, + 50, -13, 72, 4, 5, 65, 66, 46, 65, 65, + 66, 68, 50, 29, 66, 24, -13, 33, 28, 68, + 16, -15, -13, 5, 53, 28, -24, -23, 5, -22, + 49, -13, -2, -1, 5, 16, 66, -22, 29, 28, + -14, -22, 29, 34, -17, 28, -13, -20, 14, 72, + -6, -7, 25, 26, 15, 69, 70, 71, 29, 30, + -3, -4, 58, 59, 60, 62, 63, 64, 66, -18, + 51, -13, -25, -20, 30, -23, -20, 12, 13, -17, + -19, 34, 35, 36, 37, 38, 39, -19, -17, -10, + -1, 6, -12, 28, 28, -21, 69, 70, 30, 29, + 53, -17, -17, 30, -20, -13, -13, -20, 30, 7, + -11, 14, -5, -21, 20, -9, -8, 5, 29, 52, + -20, 28, 28, 15, 30, 29, 30, -21, -21, -25, + -9, -8, 30, 30, +} + +var yyDef = [...]int8{ + 0, -2, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, + 0, 0, 0, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 0, 0, 0, 44, + 0, 0, 0, 0, 0, 58, 59, 45, 0, 0, + 0, 15, 17, 96, 97, 18, 0, 0, 19, 47, + 48, 0, 0, 0, 0, 0, 62, 0, 22, 0, + 0, 62, 60, 46, 0, 0, 62, 53, 0, 56, + 74, 16, 0, 23, 0, 0, 49, 87, 0, 74, + 0, 52, 0, 74, 63, 74, 0, 0, 74, 75, + 76, 77, 78, 79, 80, 93, 94, 95, 26, 21, + 43, 31, 32, 33, 34, 0, 36, 37, 0, 57, + 0, 61, 0, 72, 0, 54, 55, 74, 74, 0, + 74, 81, 82, 83, 84, 85, 86, 74, 71, 0, + 24, 0, 40, 0, 0, 88, 91, 92, 50, 74, + 0, 69, 70, 64, 65, 68, 66, 67, 20, 0, + 25, 0, 0, 38, 39, 0, 28, 30, 0, 0, + 73, 74, 0, 41, 35, 0, 42, 89, 90, 0, + 0, 29, 51, 27, +} + +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, 3, 3, 3, + 28, 30, 32, 3, 29, 3, 33, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 31, + 35, 34, 36, +} + +var yyTok2 = [...]int8{ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, +} + +var yyTok3 = [...]int8{ + 0, +} + +var yyErrorMessages = [...]struct { + state int + token int + msg string +}{} + +//line yaccpar:1 + +/* parser for yacc output */ + +var ( + yyDebug = 0 + yyErrorVerbose = false +) + +type yyLexer interface { + Lex(lval *yySymType) int + Error(s string) +} + +type yyParser interface { + Parse(yyLexer) int + Lookahead() int +} + +type yyParserImpl struct { + lval yySymType + stack [yyInitialStackSize]yySymType + char int +} + +func (p *yyParserImpl) Lookahead() int { + return p.char +} + +func yyNewParser() yyParser { + return &yyParserImpl{} +} + +const yyFlag = -1000 + +func yyTokname(c int) string { + if c >= 1 && c-1 < len(yyToknames) { + if yyToknames[c-1] != "" { + return yyToknames[c-1] + } + } + return __yyfmt__.Sprintf("tok-%v", c) +} + +func yyStatname(s int) string { + if s >= 0 && s < len(yyStatenames) { + if yyStatenames[s] != "" { + return yyStatenames[s] + } + } + return __yyfmt__.Sprintf("state-%v", s) +} + +func yyErrorMessage(state, lookAhead int) string { + const TOKSTART = 4 + + if !yyErrorVerbose { + return "syntax error" + } + + for _, e := range yyErrorMessages { + if e.state == state && e.token == lookAhead { + return "syntax error: " + e.msg + } + } + + res := "syntax error: unexpected " + yyTokname(lookAhead) + + // To match Bison, suggest at most four expected tokens. + expected := make([]int, 0, 4) + + // Look for shiftable tokens. + base := int(yyPact[state]) + for tok := TOKSTART; tok-1 < len(yyToknames); tok++ { + if n := base + tok; n >= 0 && n < yyLast && int(yyChk[int(yyAct[n])]) == tok { + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + } + + if yyDef[state] == -2 { + i := 0 + for yyExca[i] != -1 || int(yyExca[i+1]) != state { + i += 2 + } + + // Look for tokens that we accept or reduce. + for i += 2; yyExca[i] >= 0; i += 2 { + tok := int(yyExca[i]) + if tok < TOKSTART || yyExca[i+1] == 0 { + continue + } + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + + // If the default action is to accept or reduce, give up. + if yyExca[i+1] != 0 { + return res + } + } + + for i, tok := range expected { + if i == 0 { + res += ", expecting " + } else { + res += " or " + } + res += yyTokname(tok) + } + return res +} + +func yylex1(lex yyLexer, lval *yySymType) (char, token int) { + token = 0 + char = lex.Lex(lval) + if char <= 0 { + token = int(yyTok1[0]) + goto out + } + if char < len(yyTok1) { + token = int(yyTok1[char]) + goto out + } + if char >= yyPrivate { + if char < yyPrivate+len(yyTok2) { + token = int(yyTok2[char-yyPrivate]) + goto out + } + } + for i := 0; i < len(yyTok3); i += 2 { + token = int(yyTok3[i+0]) + if token == char { + token = int(yyTok3[i+1]) + goto out + } + } + +out: + if token == 0 { + token = int(yyTok2[1]) /* unknown char */ + } + if yyDebug >= 3 { + __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char)) + } + return char, token +} + +func yyParse(yylex yyLexer) int { + return yyNewParser().Parse(yylex) +} + +func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int { + var yyn int + var yyVAL yySymType + var yyDollar []yySymType + _ = yyDollar // silence set and not used + yyS := yyrcvr.stack[:] + + Nerrs := 0 /* number of errors */ + Errflag := 0 /* error recovery flag */ + yystate := 0 + yyrcvr.char = -1 + yytoken := -1 // yyrcvr.char translated into internal numbering + defer func() { + // Make sure we report no lookahead when not parsing. + yystate = -1 + yyrcvr.char = -1 + yytoken = -1 + }() + yyp := -1 + goto yystack + +ret0: + return 0 + +ret1: + return 1 + +yystack: + /* put a state and value onto the stack */ + if yyDebug >= 4 { + __yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate)) + } + + yyp++ + if yyp >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyS[yyp] = yyVAL + yyS[yyp].yys = yystate + +yynewstate: + yyn = int(yyPact[yystate]) + if yyn <= yyFlag { + goto yydefault /* simple state */ + } + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + yyn += yytoken + if yyn < 0 || yyn >= yyLast { + goto yydefault + } + yyn = int(yyAct[yyn]) + if int(yyChk[yyn]) == yytoken { /* valid shift */ + yyrcvr.char = -1 + yytoken = -1 + yyVAL = yyrcvr.lval + yystate = yyn + if Errflag > 0 { + Errflag-- + } + goto yystack + } + +yydefault: + /* default state action */ + yyn = int(yyDef[yystate]) + if yyn == -2 { + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + + /* look through exception table */ + xi := 0 + for { + if yyExca[xi+0] == -1 && int(yyExca[xi+1]) == yystate { + break + } + xi += 2 + } + for xi += 2; ; xi += 2 { + yyn = int(yyExca[xi+0]) + if yyn < 0 || yyn == yytoken { + break + } + } + yyn = int(yyExca[xi+1]) + if yyn < 0 { + goto ret0 + } + } + if yyn == 0 { + /* error ... attempt to resume parsing */ + switch Errflag { + case 0: /* brand new error */ + yylex.Error(yyErrorMessage(yystate, yytoken)) + Nerrs++ + if yyDebug >= 1 { + __yyfmt__.Printf("%s", yyStatname(yystate)) + __yyfmt__.Printf(" saw %s\n", yyTokname(yytoken)) + } + fallthrough + + case 1, 2: /* incompletely recovered error ... try again */ + Errflag = 3 + + /* find a state where "error" is a legal shift action */ + for yyp >= 0 { + yyn = int(yyPact[yyS[yyp].yys]) + yyErrCode + if yyn >= 0 && yyn < yyLast { + yystate = int(yyAct[yyn]) /* simulate a shift of "error" */ + if int(yyChk[yystate]) == yyErrCode { + goto yystack + } + } + + /* the current p has no shift on "error", pop stack */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys) + } + yyp-- + } + /* there is no state on the stack with an error shift ... abort */ + goto ret1 + + case 3: /* no shift yet; clobber input char */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken)) + } + if yytoken == yyEofCode { + goto ret1 + } + yyrcvr.char = -1 + yytoken = -1 + goto yynewstate /* try again in the same state */ + } + } + + /* reduction by production yyn */ + if yyDebug >= 2 { + __yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) + } + + yynt := yyn + yypt := yyp + _ = yypt // guard against "declared and not used" + + yyp -= int(yyR2[yyn]) + // yyp is now the index of $0. Perform the default action. Iff the + // reduced production is ε, $1 is possibly out of range. + if yyp+1 >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyVAL = yyS[yyp+1] + + /* consult goto table to find next state */ + yyn = int(yyR1[yyn]) + yyg := int(yyPgo[yyn]) + yyj := yyg + yyS[yyp].yys + 1 + + if yyj >= yyLast { + yystate = int(yyAct[yyg]) + } else { + yystate = int(yyAct[yyj]) + if int(yyChk[yystate]) != -yyn { + yystate = int(yyAct[yyg]) + } + } + // dummy call; replaced with literal code + switch yynt { + + case 15: + yyDollar = yyS[yypt-2 : yypt+1] +//line yacc.y:124 + { + s := types.ExecFileStatement{ + FileName: yyDollar[2].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 16: + yyDollar = yyS[yypt-4 : yypt+1] +//line yacc.y:130 + { + s := types.ExecFileStatement{ + FileName: yyDollar[2].str + "." + yyDollar[4].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 17: + yyDollar = yyS[yypt-2 : yypt+1] +//line yacc.y:136 + { + s := types.ExecFileStatement{ + FileName: yyDollar[2].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 18: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:145 + { + s := types.CreateDatabaseStatement{ + DatabaseId: yyDollar[3].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 19: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:153 + { + s := types.UseDatabaseStatement{ + DatabaseId: yyDollar[3].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 20: + yyDollar = yyS[yypt-8 : yypt+1] +//line yacc.y:161 + { + tmpmap := make(map[string]types.Column) + for index, item := range yyDollar[5].cols { + item.ColumnPos = index + tmpmap[item.Name] = item + } + + s := types.CreateTableStatement{ + TableName: yyDollar[3].str, + ColumnsMap: tmpmap, + PrimaryKeys: yyDollar[7].keys, + // Cluster: $9, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 21: + yyDollar = yyS[yypt-6 : yypt+1] +//line yacc.y:177 + { + tmpmap := make(map[string]types.Column) + for index, item := range yyDollar[5].cols { + item.ColumnPos = index + tmpmap[item.Name] = item + } + s := types.CreateTableStatement{ + TableName: yyDollar[3].str, + ColumnsMap: tmpmap, + // Cluster: $7, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 22: + yyDollar = yyS[yypt-0 : yypt+1] +//line yacc.y:193 + { + yyVAL.cols = make([]types.Column, 0, 0) + } + case 23: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:197 + { + yyVAL.cols = make([]types.Column, 0, 1) + yyVAL.cols = append(yyVAL.cols, yyDollar[1].col) + } + case 24: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:202 + { + yyVAL.cols = append(yyDollar[1].cols, yyDollar[3].col) + } + case 25: + yyDollar = yyS[yypt-4 : yypt+1] +//line yacc.y:208 + { + yyVAL.col = types.Column{Name: yyDollar[1].str, Type: yyDollar[2].coltype, Unique: yyDollar[3].flag, NotNull: yyDollar[4].flag} + } + case 26: + yyDollar = yyS[yypt-0 : yypt+1] +//line yacc.y:213 + { + yyVAL.keys = make([]types.Key, 0, 1) + } + case 27: + yyDollar = yyS[yypt-5 : yypt+1] +//line yacc.y:217 + { + yyVAL.keys = yyDollar[4].keys + } + case 28: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:223 + { + yyVAL.keys = make([]types.Key, 0, 1) + yyVAL.keys = append(yyVAL.keys, yyDollar[1].key) + } + case 29: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:228 + { + yyVAL.keys = append(yyDollar[1].keys, yyDollar[3].key) + } + case 30: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:234 + { + yyVAL.key = types.Key{ + Name: yyDollar[1].str, + // KeyOrder: $2 + } + } + case 31: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:288 + { + yyVAL.coltype = yyDollar[1].coltype + } + case 32: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:295 + { + yyVAL.coltype = types.ColumnType{TypeTag: types.Bool, Length: 1} + } + case 33: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:299 + { + yyVAL.coltype = types.ColumnType{TypeTag: types.Int64, Length: 8} + } + case 34: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:303 + { + yyVAL.coltype = types.ColumnType{TypeTag: types.Float64, Length: 8} + } + case 35: + yyDollar = yyS[yypt-4 : yypt+1] +//line yacc.y:308 + { + yyVAL.coltype = types.ColumnType{TypeTag: types.Bytes, Length: yyDollar[3].int} + } + case 36: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:312 + { + yyVAL.coltype = types.ColumnType{TypeTag: types.Date, Length: 5} + } + case 37: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:316 + { + yyVAL.coltype = types.ColumnType{TypeTag: types.Timestamp, Length: 8} + } + case 38: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:322 + { + yyVAL.int = yyDollar[1].int + } + case 39: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:326 + { + yyVAL.int = 255 + } + case 40: + yyDollar = yyS[yypt-0 : yypt+1] +//line yacc.y:348 + { + yyVAL.flag = types.False + } + case 41: + yyDollar = yyS[yypt-2 : yypt+1] +//line yacc.y:352 + { + yyVAL.flag = types.True + } + case 42: + yyDollar = yyS[yypt-9 : yypt+1] +//line yacc.y:358 + { + s := types.CreateIndexStatement{ + Unique: yyDollar[2].flag, + IndexName: yyDollar[4].str, + TableName: yyDollar[6].str, + Keys: yyDollar[8].keys, + // StoringClause: $10, + // Interleaves: $11, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 43: + yyDollar = yyS[yypt-0 : yypt+1] +//line yacc.y:372 + { + yyVAL.flag = types.False + } + case 44: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:376 + { + yyVAL.flag = types.True + } + case 45: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:399 + { + yyVAL.strs = make([]string, 0, 1) + yyVAL.strs = append(yyVAL.strs, yyDollar[1].str) + } + case 46: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:404 + { + yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) + } + case 47: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:431 + { + s := types.DropDatabaseStatement{ + DatabaseId: yyDollar[3].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 48: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:440 + { + s := types.DropTableStatement{ + TableName: yyDollar[3].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 49: + yyDollar = yyS[yypt-5 : yypt+1] +//line yacc.y:449 + { + s := types.DropIndexStatement{ + TableName: yyDollar[5].str, + IndexName: yyDollar[3].str, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 50: + yyDollar = yyS[yypt-7 : yypt+1] +//line yacc.y:459 + { + s := types.InsertStament{ + TableName: yyDollar[3].str, + ColumnNames: make([]string, 0, 0), + Values: yyDollar[6].valuetypelist, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 51: + yyDollar = yyS[yypt-10 : yypt+1] +//line yacc.y:468 + { + s := types.InsertStament{ + TableName: yyDollar[3].str, + ColumnNames: yyDollar[5].strs, + Values: yyDollar[9].valuetypelist, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 52: + yyDollar = yyS[yypt-5 : yypt+1] +//line yacc.y:478 + { + s := types.UpdateStament{ + TableName: yyDollar[2].str, + SetExpr: yyDollar[4].setexprlist, + Where: yyDollar[5].where, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 53: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:488 + { + yyVAL.setexprlist = make([]types.SetExpr, 0, 1) + yyVAL.setexprlist = append(yyVAL.setexprlist, yyDollar[1].setexpr) + } + case 54: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:493 + { + yyVAL.setexprlist = append(yyDollar[1].setexprlist, yyDollar[3].setexpr) + } + case 55: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:498 + { + yyVAL.setexpr = types.SetExpr{ + Left: yyDollar[1].str, + Right: yyDollar[3].valuetype, + } + } + case 56: + yyDollar = yyS[yypt-4 : yypt+1] +//line yacc.y:506 + { + s := types.DeleteStatement{ + TableName: yyDollar[3].str, + Where: yyDollar[4].where, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 57: + yyDollar = yyS[yypt-6 : yypt+1] +//line yacc.y:515 + { + s := types.SelectStatement{ + Fields: yyDollar[2].fieldsname, + TableNames: yyDollar[4].strs, + Where: yyDollar[5].where, + Limit: yyDollar[6].limit, + } + yylex.(*lexerWrapper).channelSend <- s + } + case 58: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:526 + { + yyVAL.fieldsname = types.FieldsName{ + SelectAll: true, + } + } + case 59: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:532 + { + yyVAL.fieldsname = types.FieldsName{ + SelectAll: false, + ColumnNames: yyDollar[1].strs, + } + } + case 60: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:541 + { + yyVAL.strs = make([]string, 0, 1) + yyVAL.strs = append(yyVAL.strs, yyDollar[1].str) + } + case 61: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:546 + { + yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) + } + case 62: + yyDollar = yyS[yypt-0 : yypt+1] +//line yacc.y:551 + { + yyVAL.where = nil + } + case 63: + yyDollar = yyS[yypt-2 : yypt+1] +//line yacc.y:555 + { + yyVAL.where = &types.Where{Expr: yyDollar[2].expr} + } + case 64: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:560 + { + yyVAL.expr = yyDollar[2].expr + } + case 65: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:564 + { + yyVAL.expr = &types.ComparisonExprLSRV{Left: yyDollar[1].str, Operator: yyDollar[2].compare, Right: yyDollar[3].valuetype} + } + case 66: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:568 + { + yyVAL.expr = &types.ComparisonExprLVRS{Left: yyDollar[1].valuetype, Operator: yyDollar[2].compare, Right: yyDollar[3].str} + } + case 67: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:572 + { + yyVAL.expr = &types.ComparisonExprLVRV{Left: yyDollar[1].valuetype, Operator: yyDollar[2].compare, Right: yyDollar[3].valuetype} + } + case 68: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:576 + { + yyVAL.expr = &types.ComparisonExprLSRS{Left: yyDollar[1].str, Operator: yyDollar[2].compare, Right: yyDollar[3].str} + } + case 69: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:580 + { + left := yyDollar[1].expr + right := yyDollar[3].expr + yyVAL.expr = &types.AndExpr{Left: left, Right: right, LeftNum: left.GetTargetColsNum(), RightNum: right.GetTargetColsNum()} + } + case 70: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:586 + { + left := yyDollar[1].expr + right := yyDollar[3].expr + yyVAL.expr = &types.OrExpr{Left: left, Right: right, LeftNum: left.GetTargetColsNum(), RightNum: right.GetTargetColsNum()} + } + case 71: + yyDollar = yyS[yypt-2 : yypt+1] +//line yacc.y:592 + { + left := yyDollar[2].expr + yyVAL.expr = &types.NotExpr{Expr: left, LeftNum: left.GetTargetColsNum()} + } + case 72: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:599 + { + yyVAL.valuetypelist = make([]Value.Value, 0, 1) + yyVAL.valuetypelist = append(yyVAL.valuetypelist, yyDollar[1].valuetype) + } + case 73: + yyDollar = yyS[yypt-3 : yypt+1] +//line yacc.y:604 + { + yyVAL.valuetypelist = append(yyDollar[1].valuetypelist, yyDollar[3].valuetype) + } + case 74: + yyDollar = yyS[yypt-0 : yypt+1] +//line yacc.y:609 + { + yyVAL.valuetype = Value.Bytes{} + } + case 75: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:613 + { + yyVAL.valuetype = Value.Bytes{Val: []byte(yyDollar[1].str)} + } + case 76: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:617 + { + yyVAL.valuetype = Value.Int{Val: yyDollar[1].i64} + } + case 77: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:621 + { + yyVAL.valuetype = Value.Float{Val: yyDollar[1].f64} + } + case 78: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:625 + { + yyVAL.valuetype = Value.Bool{Val: true} + } + case 79: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:629 + { + yyVAL.valuetype = Value.Bool{Val: false} + } + case 80: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:633 + { + yyVAL.valuetype = Value.Null{} + } + case 81: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:637 + { + yyVAL.compare = Value.Equal + } + case 82: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:638 + { + yyVAL.compare = Value.Less + } + case 83: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:639 + { + yyVAL.compare = Value.Great + } + case 84: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:640 + { + yyVAL.compare = Value.LessEqual + } + case 85: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:641 + { + yyVAL.compare = Value.GreatEqual + } + case 86: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:642 + { + yyVAL.compare = Value.NotEqual + } + case 87: + yyDollar = yyS[yypt-0 : yypt+1] +//line yacc.y:646 + { + yyVAL.limit = types.Limit{} + } + case 88: + yyDollar = yyS[yypt-2 : yypt+1] +//line yacc.y:650 + { + yyVAL.limit = types.Limit{Rowcount: yyDollar[2].int} + } + case 89: + yyDollar = yyS[yypt-4 : yypt+1] +//line yacc.y:654 + { + yyVAL.limit = types.Limit{Offset: yyDollar[2].int, Rowcount: yyDollar[4].int} + } + case 90: + yyDollar = yyS[yypt-4 : yypt+1] +//line yacc.y:658 + { + yyVAL.limit = types.Limit{Offset: yyDollar[2].int, Rowcount: yyDollar[4].int} + } + case 91: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:663 + { + v, _ := strconv.Atoi(yyDollar[1].str) + yyVAL.int = v + } + case 92: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:668 + { + v, _ := strconv.ParseInt(yyDollar[1].str, 16, 32) + yyVAL.int = int(v) + } + case 93: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:674 + { + v, _ := strconv.ParseInt(yyDollar[1].str, 10, 64) + yyVAL.i64 = v + } + case 94: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:679 + { + v, _ := strconv.ParseInt(yyDollar[1].str, 16, 64) + yyVAL.i64 = v + } + case 95: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:686 + { + v, _ := strconv.ParseFloat(yyDollar[1].str, 0) + yyVAL.f64 = v + } + case 96: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:693 + { + yyVAL.str = yyDollar[1].str + } + case 97: + yyDollar = yyS[yypt-1 : yypt+1] +//line yacc.y:697 + { + yyVAL.str = yyDollar[1].str + } + } + goto yystack /* stack new state and value */ +} diff --git a/src/Interpreter/parser/yacc.y b/src/Interpreter/parser/yacc.y new file mode 100644 index 0000000..7b434bc --- /dev/null +++ b/src/Interpreter/parser/yacc.y @@ -0,0 +1,699 @@ +%{ +package parser + +import ( + "strconv" + Value "miniSQL/src/value" + "miniSQL/src/types" +) +%} + +%union { + empty struct{} + flag bool + i64 int64 + int int + f64 float64 + str string + strs []string + col types.Column + cols []types.Column + coltype types.ColumnType + key types.Key + keys []types.Key +// keyorder types.KeyOrder +// clstr types.Cluster +// ondelete types.OnDelete +// stcls types.StoringClause +// intlr types.Interleave +// intlrs []types.Interleave + fieldsname types.FieldsName + LastToken int + expr types.Expr + where *types.Where + limit types.Limit + compare Value.CompareType + valuetype Value.Value + valuetypelist []Value.Value + setexpr types.SetExpr + setexprlist []types.SetExpr +} +%token IDENT IDENT_LEGAL +%token PRIMARY KEY ASC DESC +%token IN +%token INTERLEAVE +%token AND OR NOT NULL +%token ON CASCADE NO ACTION +%token MAX UNIQUE +%token ADD COLUMN SET +%token TRUE FALSE allow_commit_timestamp +%token '(' ',' ')' ';' '*' '.' +%left '=' '<' '>' LE GE NE +%token CREATE DROP EXECFILE +%token USE DATABASE TABLE INDEX STORING +%token SELECT WHERE FROM LIMIT OFFSET VALUES +%token INSERT INTO UPDATE DELETE +%token BOOL INT64 FLOAT64 STRING BYTES DATE TIMESTAMP + +%token database_id +%token table_name +%token column_name +%token index_name + +%type column_def +%type column_def_list +%type column_type scalar_type +%type length +%type int64_value +%type float64_value +%token decimal_value hex_value float_value string_value + +// %type key_order_opt +%type key_part +%type key_part_list +%type primary_key + +// %type cluster_opt +// %type cluster +// %type on_delete_opt + +%type not_null_opt +%type unique_opt +%type IDENT_ALL +%type column_name_list table_name_list +// %type storing_clause storing_clause_opt +// %type interleave_clause +// %type interleave_clause_list +%type sel_field_list +%type expr_opt +%type limit_opt +%type compare_type +%type Value +%type int_value +%type where_opt +%type set_opt +%type set_opt_list +%typevalue_list + +%start statements + + +%% + +statements: + statement + | statements statement + +statement: + create_database ';' + | use_database ';' + | create_table ';' + | create_index ';' + | drop_database ';' + | drop_table ';' + | drop_index ';' + | select_stmt ';' + | insert_stmt ';' + | update_stmt ';' + | delete_stmt ';' + | execfile_stmt ';' + + +execfile_stmt: + EXECFILE IDENT_ALL + { + s := types.ExecFileStatement{ + FileName: $2, + } + yylex.(*lexerWrapper).channelSend <- s + } + | EXECFILE IDENT_ALL '.' IDENT_ALL { + s := types.ExecFileStatement{ + FileName: $2+"."+$4, + } + yylex.(*lexerWrapper).channelSend <- s + } + | EXECFILE string_value { + s := types.ExecFileStatement{ + FileName: $2, + } + yylex.(*lexerWrapper).channelSend <- s + } + +create_database: + CREATE DATABASE database_id + { + s := types.CreateDatabaseStatement{ + DatabaseId: $3, + } + yylex.(*lexerWrapper).channelSend <- s + } +use_database: + USE DATABASE database_id + { + s:=types.UseDatabaseStatement{ + DatabaseId: $3, + } + yylex.(*lexerWrapper).channelSend <- s + } +create_table: + CREATE TABLE table_name '(' column_def_list ',' primary_key ')' + { + tmpmap:=make(map[string]types.Column) + for index,item:=range $5 { + item.ColumnPos=index + tmpmap[item.Name]=item + } + + s := types.CreateTableStatement{ + TableName: $3, + ColumnsMap: tmpmap , + PrimaryKeys: $7, + // Cluster: $9, + } + yylex.(*lexerWrapper).channelSend <- s + } + | CREATE TABLE table_name '(' column_def_list ')' + { + tmpmap:=make(map[string]types.Column) + for index,item:=range $5 { + item.ColumnPos=index + tmpmap[item.Name]=item + } + s := types.CreateTableStatement{ + TableName: $3, + ColumnsMap: tmpmap , + // Cluster: $7, + } + yylex.(*lexerWrapper).channelSend <- s + } + +column_def_list: + /* empty */ + { + $$ = make([]types.Column, 0, 0) + } + | column_def + { + $$ = make([]types.Column, 0, 1) + $$ = append($$, $1) + } + | column_def_list ',' column_def + { + $$ = append($1, $3) + } + +column_def: + IDENT_LEGAL column_type unique_opt not_null_opt + { + $$ = types.Column{Name: $1, Type: $2,Unique:$3,NotNull: $4} + } + +primary_key: + { + $$= make([]types.Key, 0, 1) + } + | PRIMARY KEY '(' key_part_list ')' + { + $$ = $4 + } + +key_part_list: + key_part + { + $$ = make([]types.Key, 0, 1) + $$ = append($$, $1) + } + | key_part_list ',' key_part + { + $$ = append($1, $3) + } + +key_part: + IDENT_LEGAL + { + $$ = types.Key{ + Name: $1, + // KeyOrder: $2 + } + } + +// key_order_opt: +// /* empty */ +// { +// $$ = types.Asc +// } +// | ASC +// { +// $$ = types.Asc +// } +// | DESC +// { +// $$ = types.Desc +// } + +// cluster_opt: +// /* empty */ +// { +// $$ = types.Cluster{} +// } +// | ',' cluster +// { +// $$ = $2 +// } + +// cluster: +// on_delete_opt +// { +// $$ = types.Cluster{OnDelete: $1} +// } + +// on_delete_opt: +// /* empty */ +// { +// // default +// $$ = types.NoAction +// } +// | ON DELETE CASCADE +// { +// $$ = types.Cascade +// } +// | ON DELETE NO ACTION +// { +// $$ = types.NoAction +// } + +column_type: + scalar_type + { + $$ = $1 + } + + +scalar_type: + BOOL + { + $$ = types.ColumnType{TypeTag: types.Bool, Length:1} + } + | INT64 + { + $$ = types.ColumnType{TypeTag: types.Int64, Length:8} + } + | FLOAT64 + { + $$ = types.ColumnType{TypeTag: types.Float64, Length:8} + } + + | BYTES '(' length ')' + { + $$ = types.ColumnType{TypeTag: types.Bytes, Length: $3} + } + | DATE + { + $$ = types.ColumnType{TypeTag: types.Date, Length:5} + } + | TIMESTAMP + { + $$ = types.ColumnType{TypeTag: types.Timestamp, Length:8} + } + +length: + int_value + { + $$ = $1 + } + | MAX + { + $$ = 255 + } + + + +//options_def: +// /* empty */ +// { +// $$ = "" +// } +// | OPTIONS '(' allow_commit_timestamp '=' TRUE ')' +// { +// $$ = $3 + "=" + $5 +// } +// | OPTIONS '(' allow_commit_timestamp '=' NULL ')' +// { +// $$ = $3 + "=" + $5 +// } + +not_null_opt: + /* empty */ + { + $$ = types.False + } + | NOT NULL + { + $$ = types.True + } + +create_index: + CREATE unique_opt INDEX index_name ON table_name '(' key_part_list ')' + { + s := types.CreateIndexStatement{ + Unique: $2, + IndexName: $4, + TableName: $6, + Keys: $8, + // StoringClause: $10, + // Interleaves: $11, + } + yylex.(*lexerWrapper).channelSend <- s + } + +unique_opt: + /* empty */ + { + $$ = types.False + } + | UNIQUE + { + $$ = types.True + } + + +// storing_clause_opt: +// /* empty */ +// { +// $$ = types.StoringClause{} +// } +// | storing_clause +// { +// $$ = $1 +// } + +// storing_clause: +// STORING '(' column_name_list ')' +// { +// $$ = types.StoringClause{ColumnNames: $3} +// } + +column_name_list: + IDENT_LEGAL + { + $$ = make([]string, 0, 1) + $$ = append($$, $1) + } + | column_name_list ',' IDENT_LEGAL + { + $$ = append($1, $3) + } + +// interleave_clause_list: +// /* empty */ +// { +// $$ = make([]types.Interleave, 0, 0) +// } +// | interleave_clause +// { +// $$ = make([]types.Interleave, 0, 1) +// $$ = append($$, $1) +// } +// | interleave_clause_list ',' interleave_clause +// { +// $$ = append($1, $3) +// } + +// interleave_clause: +// INTERLEAVE IN IDENT_ALL +// { +// $$ = types.Interleave{TableName: $3} +// } + + drop_database: + DROP DATABASE database_id + { + s := types.DropDatabaseStatement{ + DatabaseId: $3, + } + yylex.(*lexerWrapper).channelSend <- s + } + +drop_table: + DROP TABLE table_name + { + s := types.DropTableStatement{ + TableName: $3, + } + yylex.(*lexerWrapper).channelSend <- s + } + +drop_index: + DROP INDEX index_name ON table_name + { + s := types.DropIndexStatement{ + TableName: $5, + IndexName: $3, + } + yylex.(*lexerWrapper).channelSend <- s + } + +insert_stmt: + INSERT INTO table_name VALUES '(' value_list ')' + { + s:=types.InsertStament{ + TableName: $3, + ColumnNames: make([]string, 0, 0), + Values: $6, + } + yylex.(*lexerWrapper).channelSend <- s + } + | INSERT INTO table_name '(' column_name_list ')' VALUES '(' value_list ')' + { + s:=types.InsertStament{ + TableName: $3, + ColumnNames: $5, + Values: $9, + } + yylex.(*lexerWrapper).channelSend <- s + } +update_stmt: + UPDATE table_name SET set_opt_list where_opt + { + s:=types.UpdateStament{ + TableName: $2, + SetExpr: $4, + Where: $5, + } + yylex.(*lexerWrapper).channelSend <- s + } +set_opt_list: + set_opt + { + $$ = make([]types.SetExpr, 0, 1) + $$ = append($$, $1) + } + | set_opt_list ',' set_opt + { + $$ = append($1, $3) + } +set_opt: + IDENT_LEGAL '=' Value + { + $$=types.SetExpr{ + Left: $1, + Right: $3, + } + } +delete_stmt: + DELETE FROM IDENT_ALL where_opt + { + s:=types.DeleteStatement{ + TableName: $3, + Where: $4, + } + yylex.(*lexerWrapper).channelSend <- s + } +select_stmt: + SELECT sel_field_list FROM table_name_list where_opt limit_opt + { + s:=types.SelectStatement{ + Fields: $2, + TableNames: $4, + Where: $5, + Limit: $6, + } + yylex.(*lexerWrapper).channelSend <- s + } +sel_field_list: + '*' + { + $$=types.FieldsName{ + SelectAll:true, + } + } + | column_name_list + { + $$=types.FieldsName{ + SelectAll:false, + ColumnNames:$1, + } + } + +table_name_list: // TODO mulitplart where condition, now only one table can be select + IDENT_ALL //here we use table_name which is a string type ,not INDENT + { + $$ = make([]string, 0, 1) + $$ = append($$, $1) + } + | table_name_list ',' IDENT_ALL + { + $$ =append($1, $3) + } + +where_opt: + { + $$=nil + } + | WHERE expr_opt + { + $$= &types.Where{Expr:$2} + } +expr_opt: + '(' expr_opt ')' + { + $$=$2 + } + | IDENT_ALL compare_type Value + { + $$= &types.ComparisonExprLSRV{Left: $1,Operator:$2, Right:$3 } + } + | Value compare_type IDENT_ALL + { + $$= &types.ComparisonExprLVRS{Left: $1,Operator:$2, Right:$3 } + } + | Value compare_type Value + { + $$= &types.ComparisonExprLVRV{Left: $1,Operator:$2, Right:$3 } + } + | IDENT_ALL compare_type IDENT_ALL + { + $$= &types.ComparisonExprLSRS{Left: $1,Operator:$2, Right:$3 } + } + | expr_opt AND expr_opt + { + left:=$1 + right:=$3 + $$=&types.AndExpr{Left:left,Right:right,LeftNum:left.GetTargetColsNum(),RightNum:right.GetTargetColsNum(),} + } + | expr_opt OR expr_opt + { + left:=$1 + right:=$3 + $$=&types.OrExpr{Left:left,Right:right,LeftNum:left.GetTargetColsNum(),RightNum:right.GetTargetColsNum(),} + } + | NOT expr_opt + { + left:=$2 + $$=&types.NotExpr{Expr:left,LeftNum:left.GetTargetColsNum(),} + } + +value_list: + Value + { + $$ = make([]Value.Value, 0, 1) + $$ = append($$, $1) + } + | value_list ',' Value + { + $$ = append($1, $3) + } + +Value: + { + $$=Value.Bytes{} + } + | string_value + { + $$=Value.Bytes{Val:[]byte($1)} + } + | int64_value + { + $$=Value.Int{Val:$1} + } + | float64_value + { + $$=Value.Float{Val:$1} + } + | TRUE + { + $$=Value.Bool{Val:true} + } + | FALSE + { + $$=Value.Bool{Val:false} + } + | NULL + { + $$=Value.Null{} + } +compare_type: + '=' {$$= Value.Equal} + | '<' {$$ = Value.Less} + | '>' {$$ = Value.Great} + | LE { $$ = Value.LessEqual} + | GE { $$ = Value.GreatEqual} + | NE { $$ = Value.NotEqual} + + +limit_opt: + { + $$ =types.Limit{} + } + | LIMIT int_value + { + $$=types.Limit{Rowcount:$2} + } + | LIMIT int_value ',' int_value + { + $$=types.Limit{Offset:$2, Rowcount:$4} + } + | LIMIT int_value OFFSET int_value + { + $$=types.Limit{Offset:$2, Rowcount:$4} + } +int_value: + decimal_value + { + v, _ :=strconv.Atoi($1) + $$ = v + } + | hex_value + { + v, _ := strconv.ParseInt($1, 16, 32) + $$ = int(v) + } +int64_value: + decimal_value + { + v, _ := strconv.ParseInt($1, 10, 64) + $$ = v + } + | hex_value + { + v, _ := strconv.ParseInt($1, 16, 64) + $$ = v + } + +float64_value: + float_value + { + v, _ := strconv.ParseFloat($1, 0) + $$ = v + } + +IDENT_ALL: + IDENT + { + $$=$1 + } + | IDENT_LEGAL + { + $$=$1 + } \ No newline at end of file diff --git a/src/Interpreter/types/token.go b/src/Interpreter/types/token.go new file mode 100644 index 0000000..3d0510f --- /dev/null +++ b/src/Interpreter/types/token.go @@ -0,0 +1,62 @@ +package types + +// const IDENT = 57346 +// const IDENT_LEGAL = 57347 +// const PRIMARY = 57348 +// const KEY = 57349 +// const ASC = 57350 +// const DESC = 57351 +// const IN = 57352 +// const INTERLEAVE = 57353 +// const AND = 57354 +// const OR = 57355 +// const NOT = 57356 +// const NULL = 57357 +// const ON = 57358 +// const CASCADE = 57359 +// const NO = 57360 +// const ACTION = 57361 +// const MAX = 57362 +// const UNIQUE = 57363 +// const ADD = 57364 +// const COLUMN = 57365 +// const SET = 57366 +// const TRUE = 57367 +// const FALSE = 57368 +// const allow_commit_timestamp = 57369 +// const LE = 57370 +// const GE = 57371 +// const NE = 57372 +// const CREATE = 57373 +// const DROP = 57374 +// const EXECFILE = 57375 +// const USE = 57376 +// const DATABASE = 57377 +// const TABLE = 57378 +// const INDEX = 57379 +// const STORING = 57380 +// const SELECT = 57381 +// const WHERE = 57382 +// const FROM = 57383 +// const LIMIT = 57384 +// const OFFSET = 57385 +// const VALUES = 57386 +// const INSERT = 57387 +// const INTO = 57388 +// const UPDATE = 57389 +// const DELETE = 57390 +// const BOOL = 57391 +// const INT64 = 57392 +// const FLOAT64 = 57393 +// const STRING = 57394 +// const BYTES = 57395 +// const DATE = 57396 +// const TIMESTAMP = 57397 +// const database_id = 57398 +// const table_name = 57399 +// const column_name = 57400 +// const index_name = 57401 +// const decimal_value = 57402 +// const hex_value = 57403 +// const float_value = 57404 +// const string_value = 57405 diff --git a/src/Interpreter/types/type.go b/src/Interpreter/types/type.go new file mode 100644 index 0000000..58b31c3 --- /dev/null +++ b/src/Interpreter/types/type.go @@ -0,0 +1,524 @@ +package types + +import ( + "miniSQL/src/Interpreter/value" +) + +// NOTE aliases to refer from parser. +const ( + True = true + False = false +) + +// //OnDelete is used for on delete behave +// type OnDelete = int + +// const ( +// NoAction OnDelete = iota +// Cascade +// ) + +// //KeyOrder order for key +// type KeyOrder = int + +// const ( +// Asc KeyOrder = iota +// Desc +// ) + +//ScalarColumnTypeTag is the type +type ScalarColumnTypeTag = int + +const ( + Bool ScalarColumnTypeTag = iota + Int64 + Float64 + String + Bytes + Date + Timestamp +) + +type OperationType = int + +const ( + CreateDatabase OperationType = iota + UseDatabase + CreateTable + CreateIndex + DropTable + DropIndex + DropDatabase + Insert + Update + Delete + Select + ExecFile +) + +type DStatements interface { + GetOperationType() OperationType +} + +// DDStatements has parsed statements. +//type DDStatements struct { +// CreateDatabases []CreateDatabaseStatement +// CreateTables []CreateTableStatement +// CreateIndexes []CreateIndexStatement +// DropDatabses []DropDatabaseStatement +// DropTables []DropTableStatement +// DropIndexes []DropIndexStatement +//} + +// Column is a table column. +type Column struct { + Name string + Type ColumnType + Unique bool + NotNull bool + ColumnPos int //the created position when table is created, this value is fixed +} + +type ColumnType struct { + TypeTag ScalarColumnTypeTag + Length int + IsArray bool +} + +// Key is a table key. +type Key struct { + Name string + // KeyOrder KeyOrder +} + +// // Cluster is a Spanner table cluster. +// type Cluster struct { +// TableName string +// OnDelete OnDelete +// } + +// // StoringClause is a storing clause info. +// type StoringClause struct { +// ColumnNames []string +// } + +// // Interleave is a interlive. +// type Interleave struct { +// TableName string +// } + +// CreateDatabaseStatement is a 'CREATE DATABASE' statement info. +type CreateDatabaseStatement struct { + DatabaseId string +} + +func (c CreateDatabaseStatement) GetOperationType() OperationType { + return CreateDatabase +} + +// UseDatabaseStatement is a 'Use DATABASE' statement info. +type UseDatabaseStatement struct { + DatabaseId string +} + +func (c UseDatabaseStatement) GetOperationType() OperationType { + return UseDatabase +} + +// CreateTableStatement is a 'CREATE TABLE' statement info. +type CreateTableStatement struct { + TableName string + ColumnsMap map[string]Column + PrimaryKeys []Key + // Cluster Cluster +} + +func (c CreateTableStatement) GetOperationType() OperationType { + return CreateTable +} + +// CreateIndexStatement is a 'CREATE INDEX' statement info. +type CreateIndexStatement struct { + IndexName string + Unique bool + TableName string + Keys []Key + // StoringClause StoringClause + // Interleaves []Interleave +} + +func (c CreateIndexStatement) GetOperationType() OperationType { + return CreateIndex +} + +// DropDatabaseStatement is a 'DROP TABLE' statement info. +type DropDatabaseStatement struct { + DatabaseId string +} + +func (c DropDatabaseStatement) GetOperationType() OperationType { + return DropDatabase +} + +// DropTableStatement is a 'DROP TABLE' statement info. +type DropTableStatement struct { + TableName string +} + +func (c DropTableStatement) GetOperationType() OperationType { + return DropTable +} + +// DropIndexStatement is a 'DROP INDEX' statement info. +type DropIndexStatement struct { + TableName string + IndexName string +} + +func (c DropIndexStatement) GetOperationType() OperationType { + return DropIndex +} + +// SelectStatement is a 'SELECT' statement info. +type SelectStatement struct { + Fields FieldsName + TableNames []string + Where *Where //maybe is nil!!! + OrderBy []Order + Limit Limit //maybe is nil!!! +} + +func (s SelectStatement) GetOperationType() OperationType { + return Select +} + +type ExecFileStatement struct { + FileName string +} + +func (s ExecFileStatement) GetOperationType() OperationType { + return ExecFile +} + +type ( + //Where is the type for where func which maybe nil! + Where struct { + Expr Expr + } + // Where类型数据主要要实现的接口 + Expr interface { + // Evaluate(row []value.Value) (bool, error) + // GetTargetCols() []string + // Debug() + GetTargetColsNum() int + // //GetIndexExpr input a index column name, and find whether have a name same as index + // GetIndexExpr(string) (bool, *ComparisonExprLSRV) + } + // 以下就是各种Where类型的数据 + //ComparisonExprLSRV left string right value + ComparisonExprLSRV struct { + Left string + Operator value.CompareType + Right value.Value + } + ComparisonExprLVRS struct { + Left value.Value + Operator value.CompareType + Right string + } + ComparisonExprLVRV struct { + Left value.Value + Operator value.CompareType + Right value.Value + } + ComparisonExprLSRS struct { + Left string + Operator value.CompareType + Right string + } + AndExpr struct { + Left, Right Expr + LeftNum, RightNum int + } + OrExpr struct { + Left, Right Expr + LeftNum, RightNum int + } + NotExpr struct { + Expr Expr + LeftNum int + } + Limit struct { + Offset, Rowcount int + } + Order struct { + Col string + // Direction KeyOrder + } + FieldsName struct { + SelectAll bool + ColumnNames []string + } + SetExpr struct { + Left string + Right value.Value + } +) + +// func (e *ComparisonExprLSRV) Evaluate(row []value.Value) (bool, error) { +// val := row[0] +// if _, ok := val.(value.Null); ok { //left string's value is NULL +// if _, iok := e.Right.(value.Null); iok { //right is also NULL +// if e.Operator == value.Equal { +// return true, nil +// } +// return false, nil +// } else { +// if e.Operator == value.NotEqual { +// return true, nil +// } +// return false, nil +// } +// } +// if _, ok := e.Right.(value.Null); ok { //left not NULL +// if e.Operator == value.NotEqual { +// return true, nil +// } +// return false, nil +// } +// return val.SafeCompare(e.Right, e.Operator) +// } +// func (e *ComparisonExprLSRV) GetTargetCols() []string { +// return []string{e.Left} +// } +func (e *ComparisonExprLSRV) GetTargetColsNum() int { + return 1 +} + +// func (e *ComparisonExprLSRV) Debug() { +// fmt.Println(e.Left, e.Operator, e.Right.String()) +// } +// func (e *ComparisonExprLSRV) GetIndexExpr(indexName string) (bool, *ComparisonExprLSRV) { +// if e.Left == indexName && e.Operator != value.NotEqual { +// return true, &ComparisonExprLSRV{Left: e.Left, Operator: e.Operator, Right: e.Right} +// } +// return false, nil +// } + +// func (e *ComparisonExprLVRS) Evaluate(row []value.Value) (bool, error) { +// val := row[0] +// if _, ok := val.(value.Null); ok { +// if _, iok := e.Left.(value.Null); iok { +// if e.Operator == value.Equal { +// return true, nil +// } +// return false, nil +// } else { +// if e.Operator == value.NotEqual { +// return true, nil +// } +// return false, nil +// } +// } +// if _, ok := e.Left.(value.Null); ok { +// if e.Operator == value.NotEqual { +// return true, nil +// } +// return false, nil +// } +// return e.Left.SafeCompare(val, e.Operator) +// } +// func (e *ComparisonExprLVRS) GetTargetCols() []string { +// return []string{e.Right} +// } +func (e *ComparisonExprLVRS) GetTargetColsNum() int { + return 1 +} + +// func (e *ComparisonExprLVRS) Debug() { +// fmt.Println(e.Left.String(), e.Operator, e.Right) +// } +// func (e *ComparisonExprLVRS) GetIndexExpr(indexName string) (bool, *ComparisonExprLSRV) { +// if e.Right == indexName && e.Operator != value.NotEqual { +// return true, &ComparisonExprLSRV{Left: e.Right, Operator: e.Operator, Right: e.Left} +// } +// return false, nil +// } + +// func (e *ComparisonExprLVRV) Evaluate(row []value.Value) (bool, error) { +// return e.Left.SafeCompare(e.Right, e.Operator) +// } +// func (e *ComparisonExprLVRV) GetTargetCols() []string { +// return []string{} +// } +func (e *ComparisonExprLVRV) GetTargetColsNum() int { + return 0 +} + +// func (e *ComparisonExprLVRV) Debug() { +// fmt.Println(e.Left.String(), e.Operator, e.Right.String()) +// } +// func (e *ComparisonExprLVRV) GetIndexExpr(indexName string) (bool, *ComparisonExprLSRV) { +// return false, nil +// } + +// func (e *ComparisonExprLSRS) Evaluate(row []value.Value) (bool, error) { +// vall := row[0] +// valr := row[1] +// if _, ok := vall.(value.Null); ok { //left is NULL +// if _, iok := valr.(value.Null); iok { //right is also NULL +// if e.Operator == value.Equal { +// return true, nil +// } // +// return false, nil +// } else { +// if e.Operator == value.NotEqual { +// return true, nil +// } +// return false, nil +// } +// } +// if _, ok := valr.(value.Null); ok { +// if e.Operator == value.NotEqual { +// return true, nil +// } +// return false, nil +// } +// return vall.SafeCompare(valr, e.Operator) +// } +// func (e *ComparisonExprLSRS) GetTargetCols() []string { +// return []string{e.Left, e.Right} +// } +func (e *ComparisonExprLSRS) GetTargetColsNum() int { + return 2 +} + +// func (e *ComparisonExprLSRS) Debug() { +// fmt.Println(e.Left, e.Operator, e.Right) +// } +// func (e *ComparisonExprLSRS) GetIndexExpr(indexName string) (bool, *ComparisonExprLSRV) { +// return false, nil +// } + +// func (e *AndExpr) Evaluate(row []value.Value) (bool, error) { +// leftOk, err := e.Left.Evaluate(row[0:e.LeftNum]) +// if err != nil { +// return false, err +// } +// rightOk, err := e.Right.Evaluate(row[e.LeftNum : e.LeftNum+e.RightNum]) +// if err != nil { +// return false, err +// } +// if leftOk && rightOk { +// return true, nil +// } +// return false, nil +// } + +// func (e *AndExpr) GetTargetCols() []string { +// return append(e.Left.GetTargetCols(), e.Right.GetTargetCols()...) //maybe with duplicate +// } +func (e *AndExpr) GetTargetColsNum() int { + return e.LeftNum + e.RightNum +} + +// func (e *AndExpr) Debug() { +// e.Left.Debug() +// fmt.Println(" and ") +// e.Right.Debug() +// } +// func (e *AndExpr) GetIndexExpr(indexName string) (bool, *ComparisonExprLSRV) { +// b, c := e.Left.GetIndexExpr(indexName) +// if b == true { +// b1, c1 := e.Right.GetIndexExpr(indexName) +// if b1 == true && c1 != nil && c1.Operator == value.Equal { +// return true, c1 +// } +// return b, c +// } +// return e.Right.GetIndexExpr(indexName) +// } + +// func (e *OrExpr) Evaluate(row []value.Value) (bool, error) { +// leftOk, err := e.Left.Evaluate(row[0:e.LeftNum]) +// if err != nil { +// return false, err +// } +// if leftOk { +// return true, nil +// } +// rightOk, err := e.Right.Evaluate(row[e.LeftNum : e.LeftNum+e.RightNum]) +// if err != nil { +// return false, err +// } +// return rightOk, nil +// } +// func (e *OrExpr) GetTargetCols() []string { +// return append(e.Left.GetTargetCols(), e.Right.GetTargetCols()...) +// } +func (e *OrExpr) GetTargetColsNum() int { + return e.LeftNum + e.RightNum +} + +// func (e *OrExpr) Debug() { +// e.Left.Debug() +// fmt.Println(" or ") +// e.Right.Debug() + +// } + +// //GetIndexExpr 注意 如果是or表达式 直接返回false,因此没法走单索引 +// func (e *OrExpr) GetIndexExpr(indexName string) (bool, *ComparisonExprLSRV) { +// return false, nil +// } + +// func (e *NotExpr) Evaluate(row []value.Value) (bool, error) { +// ok, err := e.Expr.Evaluate(row) +// if err != nil { +// return false, err +// } +// return !ok, nil +// } +// func (e *NotExpr) GetTargetCols() []string { +// return e.Expr.GetTargetCols() +// } +func (e *NotExpr) GetTargetColsNum() int { + return e.LeftNum +} + +// func (e *NotExpr) Debug() { +// e.Expr.Debug() +// fmt.Println("not ") +// } +// func (e *NotExpr) GetIndexExpr(indexName string) (bool, *ComparisonExprLSRV) { +// return e.Expr.GetIndexExpr(indexName) +// } + +type InsertStament struct { + TableName string + ColumnNames []string + Values []value.Value +} + +func (c InsertStament) GetOperationType() OperationType { + return Insert +} + +type UpdateStament struct { + TableName string + SetExpr []SetExpr + Where *Where //maybe is nil!!! +} + +func (c UpdateStament) GetOperationType() OperationType { + return Update +} + +type DeleteStatement struct { + TableName string + Where *Where //maybe is nil!!! +} + +func (c DeleteStatement) GetOperationType() OperationType { + return Delete +} diff --git a/src/Interpreter/value/value.go b/src/Interpreter/value/value.go new file mode 100644 index 0000000..1e80cb4 --- /dev/null +++ b/src/Interpreter/value/value.go @@ -0,0 +1,496 @@ +package value + +import "fmt" + +//go:generate msgp + +//CompareType 用来标志比较类型 +type CompareType int + +const ( + Great CompareType = iota + GreatEqual + Less + LessEqual + Equal + NotEqual +) + +//ValueType 用来标志比较类型 +type ValueType = int + +const ( + BoolType ValueType = iota + IntType + FloatType + StringType + BytesType + DateType + TimestampType + NullType + AlienType +) + +//Row is a row for record +type Row struct { + Values []Value +} + +//Value is the most important type which record the true value +type Value interface { + String() string + // //Compare is unsafe compare, if you don't know the type is same, don't use it! + // Compare(Value, CompareType) (bool, error) + // // CompareWithoutType will return 0 if equal, -1 if less , 1 if greater + // CompareWithoutType(Value) (int, error) + // SafeCompare(Value, CompareType) (bool, error) + // //Convert2Bytes is convert value to bytes + // Convert2Bytes() ([]byte, error) + // Convert2IntType() ValueType +} +type Int struct { + Val int64 +} +type Float struct { + Val float64 +} +type Bytes struct { + Val []byte +} +type Bool struct { + Val bool +} +type Null struct { + length int +} +type Alien struct { + Val interface{} +} + +func (i Int) String() string { + return fmt.Sprint(i.Val) +} + +// //Compare1 仅用来测试 无实际意义 +// func (i Int) Compare1(v Int, op CompareType) (bool, error) { +// switch op { +// case Great: +// return i.Val > v.Val, nil +// case GreatEqual: +// return i.Val >= v.Val, nil +// case Less: +// return i.Val < v.Val, nil +// case LessEqual: +// return i.Val <= v.Val, nil +// case Equal: +// return i.Val == v.Val, nil +// case NotEqual: +// return i.Val != v.Val, nil +// } +// return false, fmt.Errorf("unknow operation type %d", op) +// } +// func (i Int) Compare(v Value, op CompareType) (bool, error) { +// switch v.(type) { +// case Int: +// switch op { +// case Great: +// return i.Val > v.(Int).Val, nil +// case GreatEqual: +// return i.Val >= v.(Int).Val, nil +// case Less: +// return i.Val < v.(Int).Val, nil +// case LessEqual: +// return i.Val <= v.(Int).Val, nil +// case Equal: +// return i.Val == v.(Int).Val, nil +// case NotEqual: +// return i.Val != v.(Int).Val, nil +// } +// case Float: +// switch op { +// case Great: +// return float64(i.Val) > v.(Float).Val, nil +// case GreatEqual: +// return float64(i.Val) >= v.(Float).Val, nil +// case Less: +// return float64(i.Val) < v.(Float).Val, nil +// case LessEqual: +// return float64(i.Val) <= v.(Float).Val, nil +// case Equal: +// return float64(i.Val) == v.(Float).Val, nil +// case NotEqual: +// return float64(i.Val) != v.(Float).Val, nil +// } +// } +// return false, nil +// } +// func (i Int) SafeCompare(v Value, op CompareType) (bool, error) { +// switch v.(type) { +// case Int: +// return i.Compare(v, op) +// case Float: +// var tmp_i = Float{Val: float64(i.Val)} +// return tmp_i.Compare(v, op) +// default: +// return false, nil +// } +// return false, nil +// } +// func (i Int) Convert2Bytes() ([]byte, error) { +// bytebuf := bytes.NewBuffer([]byte{}) +// binary.Write(bytebuf, binary.LittleEndian, i.Val) +// return bytebuf.Bytes(), nil +// } +// func (i Int) Convert2IntType() int { +// return IntType +// } +// func (i Int) CompareWithoutType(v Value) (int, error) { +// if i.Val < v.(Int).Val { +// return -1, nil +// } else if i.Val == v.(Int).Val { +// return 0, nil +// } +// return 1, nil +// } + +func (i Float) String() string { + return fmt.Sprint(i.Val) +} + +// func (i Float) Compare(v Value, op CompareType) (bool, error) { +// switch v.(type) { +// case Int: +// switch op { +// case Great: +// return i.Val > float64(v.(Int).Val), nil +// case GreatEqual: +// return i.Val >= float64(v.(Int).Val), nil +// case Less: +// return i.Val < float64(v.(Int).Val), nil +// case LessEqual: +// return i.Val <= float64(v.(Int).Val), nil +// case Equal: +// return i.Val == float64(v.(Int).Val), nil +// case NotEqual: +// return i.Val != float64(v.(Int).Val), nil +// } +// case Float: +// switch op { +// case Great: +// return i.Val > v.(Float).Val, nil +// case GreatEqual: +// return i.Val >= v.(Float).Val, nil +// case Less: +// return i.Val < v.(Float).Val, nil +// case LessEqual: +// return i.Val <= v.(Float).Val, nil +// case Equal: +// return i.Val == v.(Float).Val, nil +// case NotEqual: +// return i.Val != v.(Float).Val, nil +// } +// } + +// return false, fmt.Errorf("unknow operation type %d", op) +// } +// func (i Float) SafeCompare(v Value, op CompareType) (bool, error) { +// switch v.(type) { +// case Float: +// return i.Compare(v, op) +// case Int: +// var tmpV = Float{Val: float64(v.(Int).Val)} +// return i.Compare(tmpV, op) +// default: +// return false, nil +// } +// return false, nil +// } +// func (i Float) Convert2Bytes() ([]byte, error) { +// bytebuf := bytes.NewBuffer([]byte{}) +// binary.Write(bytebuf, binary.LittleEndian, i.Val) +// return bytebuf.Bytes(), nil +// } +// func (i Float) Convert2IntType() int { +// return FloatType +// } +// func (i Float) CompareWithoutType(v Value) (int, error) { +// if i.Val < v.(Float).Val { +// return -1, nil +// } else if i.Val == v.(Float).Val { +// return 0, nil +// } +// return 1, nil +// } + +func (i Bytes) String() string { + var ans []byte + for _, v := range i.Val { + if v == 0 { + break + } + ans = append(ans, v) + } + return string(ans) +} + +// func (i Bytes) Compare(v Value, op CompareType) (bool, error) { +// left := i.Val +// right := v.(Bytes).Val +// ib := bytes.IndexByte(left, 0) //去掉末尾的0 +// if ib != -1 { +// left = left[0:ib] +// } +// ib = bytes.IndexByte(right, 0) +// if ib != -1 { +// right = right[0:ib] +// } +// cp := bytes.Compare(left, right) +// switch op { +// case Great: +// return cp == 1, nil +// case GreatEqual: +// return cp == 0 || cp == 1, nil +// case Less: +// return cp == -1, nil +// case LessEqual: + +// return cp == 0 || cp == 1, nil +// case Equal: +// return cp == 0, nil +// case NotEqual: +// return cp != 0, nil +// } +// return false, fmt.Errorf("unknow operation type %d", op) +// } +// func (i Bytes) SafeCompare(v Value, op CompareType) (bool, error) { +// if _, ok := v.(Bytes); ok { +// return i.Compare(v, op) +// } +// return false, nil +// } +// func (i Bytes) Convert2Bytes() ([]byte, error) { +// return i.Val, nil +// } +// func (i Bytes) Convert2IntType() int { +// return BytesType +// } +// func (i Bytes) CompareWithoutType(v Value) (int, error) { +// return bytes.Compare(i.Val, v.(Bytes).Val), nil +// } + +func (i Bool) String() string { + return fmt.Sprint(i.Val) +} + +// func (i Bool) Compare(v Value, op CompareType) (bool, error) { +// switch op { +// case Great: +// return false, nil +// case GreatEqual: +// return false, nil +// case Less: +// return false, nil +// case LessEqual: +// return false, nil +// case Equal: +// return i.Val == v.(Bool).Val, nil +// case NotEqual: +// return i.Val != v.(Bool).Val, nil +// } +// return false, fmt.Errorf("unknow operation type %d", op) +// } +// func (i Bool) SafeCompare(v Value, op CompareType) (bool, error) { +// if _, ok := v.(Bool); ok { +// return i.Compare(v, op) +// } +// return false, nil +// } +// func (i Bool) Convert2Bytes() ([]byte, error) { +// if i.Val { +// return []byte{1}, nil +// } +// return []byte{0}, nil +// } +// func (i Bool) Convert2IntType() int { +// return BoolType +// } +// func (i Bool) CompareWithoutType(v Value) (int, error) { +// if i.Val == v.(Bool).Val { +// return 1, nil +// } +// return 0, nil +// } + +func (i Alien) String() string { + return fmt.Sprint(i.Val) +} + +// func (i Alien) Compare(v Value, op CompareType) (bool, error) { +// switch op { +// case Great: +// return false, nil +// case GreatEqual: +// return false, nil +// case Less: +// return false, nil +// case LessEqual: +// return false, nil +// case Equal: +// return false, nil +// case NotEqual: +// return false, nil +// } +// return false, fmt.Errorf("unknow operation type %d", op) +// } +// func (i Alien) SafeCompare(v Value, op CompareType) (bool, error) { +// if _, ok := v.(Alien); ok { +// return i.Compare(v, op) +// } +// return false, nil +// } +// func (i Alien) Convert2Bytes() ([]byte, error) { +// bytebuf := bytes.NewBuffer([]byte{}) +// binary.Write(bytebuf, binary.LittleEndian, i.Val) +// return bytebuf.Bytes(), nil +// } +// func (i Alien) Convert2IntType() int { +// return AlienType +// } +// func (i Alien) CompareWithoutType(v Value) (int, error) { + +// return -1, nil +// } + +func (i Null) String() string { + return "null" +} + +// func (i Null) Compare(v Value, op CompareType) (bool, error) { +// if op == Equal { +// return true, nil +// } +// return false, nil +// } +// func (i Null) SafeCompare(v Value, op CompareType) (bool, error) { +// if _, ok := v.(Null); ok { +// return i.Compare(v, op) +// } +// return false, nil +// } +// func (i Null) Convert2Bytes() ([]byte, error) { +// return make([]byte, i.length), nil +// } +// func (i Null) Convert2IntType() int { +// return NullType +// } +// func (i Null) CompareWithoutType(v Value) (int, error) { +// return -1, nil +// } + +// // NewFromParquetValue you can input a arbitrary type into it, and it will try it's best to convert it to Value +// func NewFromParquetValue(v interface{}) Value { +// switch v.(type) { +// case int: +// return Int{Val: int64(v.(int))} +// case float64: +// return Float{Val: v.(float64)} +// case []byte: +// return Bytes{Val: v.([]byte)} +// case int8: +// return Int{Val: int64(v.(int8))} +// case int16: +// return Int{Val: int64(v.(int16))} +// case int32: +// return Int{Val: int64(v.(int32))} +// case int64: +// return Int{Val: v.(int64)} +// case uint: +// return Int{Val: int64(v.(uint))} +// case uint8: +// return Int{Val: int64(v.(uint8))} +// case uint16: +// return Int{Val: int64(v.(uint16))} +// case uint32: +// return Int{Val: int64(v.(uint32))} +// case uint64: +// return Int{Val: int64(v.(uint64))} +// case float32: +// return Float{Val: float64(v.(float32))} + +// case bool: +// return Bool{Val: v.(bool)} + +// default: +// return Alien{Val: v} +// } +// } + +// //Byte2Value convert byte to Value ,length is used for char +// // IntType,FloatType,BoolType don't need a length, so you can use this function like Byte2Value([]bytes,IntType) +// // BytesType and NullType need a length to insure it's correct, so you must use this function like Byte2Value([]bytes,BytesType,10) +// func Byte2Value(mybytes []byte, vt ValueType, length ...int) (Value, error) { +// switch vt { +// case BoolType: +// if len(mybytes) < 1 { +// return nil, errors.New("mybytes length is less than 1") +// } +// if mybytes[0] == 1 { +// return Bool{Val: true}, nil +// } else if mybytes[0] == 0 { +// return Bool{Val: false}, nil +// } +// return nil, errors.New("this byte is not a bool byte") +// case IntType: +// if len(mybytes) < 8 { +// return nil, errors.New("mybytes length is less than 8") +// } +// var ret int64 +// buf := bytes.NewBuffer(mybytes[0:8]) +// binary.Read(buf, binary.LittleEndian, &ret) +// return Int{Val: ret}, nil +// case FloatType: +// if len(mybytes) < 8 { +// return nil, errors.New("mybytes length is less than 8") +// } +// var ret float64 +// buf := bytes.NewBuffer(mybytes[0:8]) +// binary.Read(buf, binary.LittleEndian, &ret) +// return Float{Val: ret}, nil +// case BytesType: +// if len(length) < 1 || length[0] <= 0 { +// return nil, errors.New("please input a length for bytes") +// } +// if len(mybytes) < length[0] { +// return nil, errors.New("bytes don't have enough length to convert to bytes") +// } +// return Bytes{Val: mybytes[0:length[0]]}, nil +// case NullType: +// if len(length) < 1 || length[0] <= 0 { +// return nil, errors.New("please input a length for bytes") +// } +// if len(mybytes) < length[0] { +// return nil, errors.New("bytes don't have enough length to convert to bytes") +// } +// return Null{length: length[0]}, nil +// } +// return nil, errors.New("The type is not supported.") +// } + +// //CompareWithType is function for compare +// func CompareWithType(i Value, v Value, op CompareType, vt ValueType) (bool, error) { +// switch vt { +// case BoolType: +// return i.(Bool).Compare(v, op) +// case IntType: +// return i.(Int).Compare(v, op) +// case FloatType: +// return i.(Float).Compare(v, op) +// case BytesType: +// return i.(Bytes).Compare(v, op) +// case NullType: +// return i.(Null).Compare(v, op) +// case AlienType: +// return i.(Alien).Compare(v, op) +// } +// return false, errors.New("The type is not supported.") +// }