diff --git a/driver/driver_test.go b/driver/driver_test.go index d1e1484..a5d0567 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -1170,6 +1170,64 @@ func TestInsertByteArrayODBC(t *testing.T) { } } +func TestInsertBoolTrueODBC(t *testing.T) { + + db, err := sql.Open("ramsql", "TestInsertBoolODBC") + if err != nil { + t.Fatalf("sql.Open : Error : %s\n", err) + } + + _, err = db.Exec(`CREATE TABLE test_bool (sequence_number BIGSERIAL PRIMARY KEY, is_ready boolean, created_at TIMESTAMP)`) + if err != nil { + t.Fatalf("sql.Exec: Error: %s\n", err) + } + + want := true + _, err = db.Exec("INSERT INTO test_bool (is_ready) values (?)", want) + if err != nil { + t.Fatalf("sql.Exec: Error: %s\n", err) + } + + var got bool + err = db.QueryRow("SELECT is_ready FROM test_bool limit 1").Scan(&got) + if err != nil { + t.Fatalf("sql.Select: Error: %s\n", err) + } + + if !reflect.DeepEqual(want, got) { + t.Fatalf("Expected JSON to be '%v', got '%v'", want, got) + } +} + +func TestInsertBoolFalseODBC(t *testing.T) { + + db, err := sql.Open("ramsql", "TestInsertBoolODBC") + if err != nil { + t.Fatalf("sql.Open : Error : %s\n", err) + } + + _, err = db.Exec(`CREATE TABLE test_bool (sequence_number BIGSERIAL PRIMARY KEY, is_ready boolean, created_at TIMESTAMP)`) + if err != nil { + t.Fatalf("sql.Exec: Error: %s\n", err) + } + + want := false + _, err = db.Exec("INSERT INTO test_bool (is_ready) values (?)", want) + if err != nil { + t.Fatalf("sql.Exec: Error: %s\n", err) + } + + var got bool + err = db.QueryRow("SELECT is_ready FROM test_bool limit 1").Scan(&got) + if err != nil { + t.Fatalf("sql.Select: Error: %s\n", err) + } + + if !reflect.DeepEqual(want, got) { + t.Fatalf("Expected JSON to be '%v', got '%v'", want, got) + } +} + func TestSchema(t *testing.T) { db, err := sql.Open("ramsql", "TestSchema") diff --git a/engine/parser/lexer.go b/engine/parser/lexer.go index 4665923..ca4fc55 100644 --- a/engine/parser/lexer.go +++ b/engine/parser/lexer.go @@ -196,7 +196,7 @@ func (l *lexer) lex(instruction []byte) ([]Token, error) { matchers = append(matchers, l.genericStringMatcher("for", ForToken)) matchers = append(matchers, l.genericStringMatcher("default", DefaultToken)) matchers = append(matchers, l.genericStringMatcher("localtimestamp", LocalTimestampToken)) - matchers = append(matchers, l.genericStringMatcher("false", LocalTimestampToken)) + matchers = append(matchers, l.isCreateStatement(l.genericStringMatcher("false", FalseToken))) matchers = append(matchers, l.genericStringMatcher("unique", UniqueToken)) matchers = append(matchers, l.genericStringMatcher("now()", NowToken)) matchers = append(matchers, l.genericStringMatcher("offset", OffsetToken)) @@ -212,6 +212,7 @@ func (l *lexer) lex(instruction []byte) ([]Token, error) { matchers = append(matchers, l.MatchDateToken) matchers = append(matchers, l.MatchNumberToken) matchers = append(matchers, l.MatchStringToken) + matchers = append(matchers, l.MatchBooleanToken) var r bool for l.pos < l.instructionLen { @@ -237,6 +238,23 @@ func (l *lexer) lex(instruction []byte) ([]Token, error) { return l.tokens, nil } +func (l *lexer) isCreateStatement(matcher Matcher) Matcher { + return func() bool { + isCreateStmt := false + for _, token := range l.tokens { + if token.Token == CreateToken { + isCreateStmt = true + } + } + + if !isCreateStmt { + return false + } + + return matcher() + } +} + func (l *lexer) MatchArgTokenODBC() bool { i := l.pos @@ -430,6 +448,44 @@ func (l *lexer) MatchNumberToken() bool { return false } +func (l *lexer) MatchBooleanToken() bool { + + // check if it is an update or insert statment; make sure it is not a create statement + canContinue := false + for _, token := range l.tokens { + if token.Token == CreateToken { + return false + } + if token.Token == UpdateToken || token.Token == InsertToken { + canContinue = true + } + } + + if !canContinue { + return false + } + + i := l.pos + for i < l.instructionLen && + (unicode.IsLetter(rune(l.instruction[i])) || + l.instruction[i] == '_' || + l.instruction[i] == '@') { + i++ + } + + if i != l.pos { + t := Token{ + Token: StringToken, + Lexeme: string(l.instruction[l.pos:i]), + } + l.tokens = append(l.tokens, t) + l.pos = i + return true + } + + return false +} + // 2015-09-10 14:03:09.444695269 +0200 CEST); func (l *lexer) MatchDateToken() bool {