3313 lines
83 KiB
Go
3313 lines
83 KiB
Go
// Copyright © 2016 Abcum Ltd
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package sql
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
)
|
|
|
|
type tester struct {
|
|
skip bool
|
|
sql string
|
|
err string
|
|
str string
|
|
res Statement
|
|
}
|
|
|
|
func testerr(err error) string {
|
|
if err != nil {
|
|
return err.Error()
|
|
}
|
|
return ""
|
|
}
|
|
|
|
type Selfer interface{}
|
|
|
|
func testsql(t *testing.T, test tester) {
|
|
|
|
if test.skip {
|
|
Convey(" ❗️ "+test.sql, t, nil)
|
|
return
|
|
}
|
|
|
|
s, e := Parse(test.sql)
|
|
|
|
Convey(test.sql, t, func() {
|
|
|
|
if test.err != "" {
|
|
Convey(testerr(e), func() {
|
|
So(testerr(e), ShouldResemble, test.err)
|
|
})
|
|
}
|
|
|
|
if test.err == "" {
|
|
So(e, ShouldBeNil)
|
|
So(s, ShouldResemble, test.res)
|
|
if test.str != "" {
|
|
So(fmt.Sprint(test.res.(*Query).Statements[0]), ShouldEqual, test.str)
|
|
} else {
|
|
So(fmt.Sprint(test.res.(*Query).Statements[0]), ShouldEqual, test.sql)
|
|
}
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
func TestMain(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `USE`,
|
|
err: "Found `` but expected `NAMESPACE, DATABASE, NS, DB`",
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE`,
|
|
err: "Found `` but expected `IDENT, STRING, NUMBER, DOUBLE, DATE, TIME`",
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE ''`,
|
|
err: "Found `` but expected `namespace name`",
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE name`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
NS: "name",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE 1`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
NS: "1",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE 1.3000`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
NS: "1.3000",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE 123.123.123.123`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
NS: "123.123.123.123",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE {"some":"thing"}`,
|
|
err: "Found `{\"some\":\"thing\"}` but expected `IDENT, STRING, NUMBER, DOUBLE, DATE, TIME`",
|
|
},
|
|
{
|
|
sql: `USE NAMESPACE name something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `USE DATABASE`,
|
|
err: "Found `` but expected `IDENT, STRING, NUMBER, DOUBLE, DATE, TIME`",
|
|
},
|
|
{
|
|
sql: `USE DATABASE ''`,
|
|
err: "Found `` but expected `database name`",
|
|
},
|
|
{
|
|
sql: `USE DATABASE name`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
DB: "name",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE DATABASE 1`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
DB: "1",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE DATABASE 1.3000`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
DB: "1.3000",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE DATABASE 123.123.123.123`,
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
DB: "123.123.123.123",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `USE DATABASE {}`,
|
|
err: "Found `{}` but expected `IDENT, STRING, NUMBER, DOUBLE, DATE, TIME`",
|
|
},
|
|
{
|
|
sql: `USE DATABASE name something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: "USE NS `*` DB `*`",
|
|
str: "USE NAMESPACE `*` DATABASE `*`",
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
NS: "*",
|
|
DB: "*",
|
|
}}},
|
|
},
|
|
{
|
|
sql: "USE NAMESPACE `*` DATABASE `*`",
|
|
res: &Query{Statements: []Statement{&UseStatement{
|
|
NS: "*",
|
|
DB: "*",
|
|
}}},
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_IDs(t *testing.T) {
|
|
|
|
Convey("All IDs should parse correctly", t, func() {
|
|
So(ParseThing("test:tester"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: string("tester"),
|
|
})
|
|
So(ParseThing("test:123456"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: float64(123456),
|
|
})
|
|
So(ParseThing("test:abcdef"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: string("abcdef"),
|
|
})
|
|
So(ParseThing("test:a1b2c3"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: string("a1b2c3"),
|
|
})
|
|
So(ParseThing("test:1a2b3c"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: string("1a2b3c"),
|
|
})
|
|
So(ParseThing("test:4m9sms"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: string("4m9sms"),
|
|
})
|
|
So(ParseThing("test:4m98m85ms"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: string("4m98m85ms"),
|
|
})
|
|
So(ParseThing("test:00s5w36sm"), ShouldResemble, &Thing{
|
|
TB: "test",
|
|
ID: string("00s5w36sm"),
|
|
})
|
|
})
|
|
|
|
}
|
|
|
|
|
|
// Ensure the parser can parse a multi-statement query.
|
|
func Test_Parse_General(t *testing.T) {
|
|
|
|
s := `SELECT a FROM b`
|
|
q, err := Parse(s)
|
|
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
} else if len(q.Statements) != 1 {
|
|
t.Fatalf("unexpected statement count: %d", len(q.Statements))
|
|
}
|
|
|
|
}
|
|
|
|
// Ensure the parser can parse a multi-statement query.
|
|
func Test_Parse_General_Single(t *testing.T) {
|
|
|
|
s := `SELECT a FROM b`
|
|
q, err := Parse(s)
|
|
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
} else if len(q.Statements) != 1 {
|
|
t.Fatalf("unexpected statement count: %d", len(q.Statements))
|
|
}
|
|
|
|
}
|
|
|
|
// Ensure the parser can parse a multi-statement query.
|
|
func Test_Parse_General_Multi(t *testing.T) {
|
|
|
|
s := `SELECT a FROM b; SELECT c FROM d`
|
|
q, err := Parse(s)
|
|
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
} else if len(q.Statements) != 2 {
|
|
t.Fatalf("unexpected statement count: %d", len(q.Statements))
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Malformed(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: ``,
|
|
err: "Your SQL query is empty",
|
|
},
|
|
{
|
|
sql: "SELECT ` FROM person",
|
|
err: "Found ` FROM person` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT ' FROM person`,
|
|
err: "Found ` FROM person` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT " FROM person`,
|
|
err: "Found ` FROM person` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT "\" FROM person`,
|
|
err: "Found `\" FROM person` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `!`,
|
|
err: "Found `!` but expected `USE, INFO, BEGIN, CANCEL, COMMIT, IF, LET, RETURN, LIVE, KILL, SELECT, CREATE, UPDATE, DELETE, RELATE, INSERT, UPSERT, DEFINE, REMOVE, OPTION`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Info(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `INFO`,
|
|
err: "Found `` but expected `FOR`",
|
|
},
|
|
{
|
|
sql: `INFO FOR`,
|
|
err: "Found `` but expected `ALL, NAMESPACE, DATABASE, SCOPE, TABLE, NS, DB`",
|
|
},
|
|
{
|
|
sql: `INFO FOR ALL`,
|
|
res: &Query{Statements: []Statement{&InfoStatement{
|
|
Kind: ALL,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INFO FOR NAMESPACE`,
|
|
res: &Query{Statements: []Statement{&InfoStatement{
|
|
Kind: NAMESPACE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INFO FOR NS`,
|
|
str: `INFO FOR NAMESPACE`,
|
|
res: &Query{Statements: []Statement{&InfoStatement{
|
|
Kind: NS,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INFO FOR DATABASE`,
|
|
res: &Query{Statements: []Statement{&InfoStatement{
|
|
Kind: DATABASE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INFO FOR DB`,
|
|
str: `INFO FOR DATABASE`,
|
|
res: &Query{Statements: []Statement{&InfoStatement{
|
|
Kind: DB,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INFO FOR SCOPE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `INFO FOR SCOPE test`,
|
|
res: &Query{Statements: []Statement{&InfoStatement{
|
|
Kind: SCOPE,
|
|
What: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INFO FOR TABLE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `INFO FOR TABLE test`,
|
|
res: &Query{Statements: []Statement{&InfoStatement{
|
|
Kind: TABLE,
|
|
What: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INFO FOR TABLE test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Let(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `LET`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `LET name`,
|
|
err: "Found `` but expected `=`",
|
|
},
|
|
{
|
|
sql: `LET name =`,
|
|
err: "Found `=` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `LET name = true`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: true,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = false`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: false,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = "test"`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: &Value{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = 1`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: float64(1),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = 1.0`,
|
|
str: `LET name = 1`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: float64(1),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = 1.1`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: float64(1.1),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = thing:test`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: &Thing{TB: "thing", ID: "test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = thing:test`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: &Thing{TB: "thing", ID: "test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = @thing:test`,
|
|
str: `LET name = thing:test`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: &Thing{TB: "thing", ID: "test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = {"key": "val"}`,
|
|
str: `LET name = {"key":"val"}`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: map[string]interface{}{"key": "val"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = ["key", "val"]`,
|
|
str: `LET name = ["key","val"]`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: []interface{}{"key", "val"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = $test`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: false,
|
|
Name: &Ident{"name"},
|
|
What: &Param{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = (CREATE person)`,
|
|
res: &Query{Statements: []Statement{&LetStatement{
|
|
RW: true,
|
|
Name: &Ident{"name"},
|
|
What: &SubExpression{Expr: &CreateStatement{
|
|
What: Exprs{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LET name = "test" something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Return(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `RETURN`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `RETURN true`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{true},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN true`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{true},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN false`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{false},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN "test"`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{&Value{"test"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN 1`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{float64(1)},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN 1.0`,
|
|
str: `RETURN 1`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{float64(1)},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN 1.1`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{float64(1.1)},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN @thing:test`,
|
|
str: `RETURN thing:test`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{&Thing{TB: "thing", ID: "test"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN {"key": "val"}`,
|
|
str: `RETURN {"key":"val"}`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{map[string]interface{}{"key": "val"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN ["key", "val"]`,
|
|
str: `RETURN ["key","val"]`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{[]interface{}{"key", "val"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN $test`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: false,
|
|
What: Exprs{&Param{"test"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN (CREATE person)`,
|
|
res: &Query{Statements: []Statement{&ReturnStatement{
|
|
RW: true,
|
|
What: Exprs{&SubExpression{Expr: &CreateStatement{
|
|
What: Exprs{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RETURN $test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Select(t *testing.T) {
|
|
|
|
date, _ := time.Parse("2006-01-02", "1987-06-22")
|
|
nano, _ := time.Parse(time.RFC3339, "1987-06-22T08:30:30.511Z")
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `SELECT`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT FROM`,
|
|
err: "Found `FROM` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT *`,
|
|
err: "Found `` but expected `FROM`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM per!son`,
|
|
err: "Found `!` but expected `;`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM @`,
|
|
err: "Found `@` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM @person`,
|
|
err: "Found `@person` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM @person:`,
|
|
err: "Found `@person:` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM @person WHERE`,
|
|
err: "Found `@person` but expected `expression`",
|
|
},
|
|
{
|
|
sql: "SELECT * FROM 111",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{float64(111)},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT * FROM `111`",
|
|
str: "SELECT * FROM 111",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"111"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT * FROM `2006-01-02`",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"2006-01-02"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT * FROM `2006-01-02T15:04:05+07:00`",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"2006-01-02T15:04:05+07:00"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT * FROM `2006-01-02T15:04:05.999999999+07:00`",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"2006-01-02T15:04:05.999999999+07:00"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person, tweet`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}, &Ident{"tweet"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:1a`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: "1a"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨1a⟩`,
|
|
str: `SELECT * FROM person:1a`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: "1a"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:123456`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: float64(123456)}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨123456⟩`,
|
|
str: `SELECT * FROM person:123456`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: float64(123456)}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:123.456`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: float64(123.456)}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨123.456⟩`,
|
|
str: `SELECT * FROM person:123.456`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: float64(123.456)}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:123.456.789.012`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: "123.456.789.012"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨123.456.789.012⟩`,
|
|
str: `SELECT * FROM person:123.456.789.012`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: "123.456.789.012"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨1987-06-22⟩`,
|
|
str: `SELECT * FROM person:⟨1987-06-22T00:00:00Z⟩`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: date}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨1987-06-22T08:30:30.511Z⟩`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: nano}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨A250C5A3-948F-4657-88AD-FF5F27B5B24E⟩`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: "A250C5A3-948F-4657-88AD-FF5F27B5B24E"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨8250C5A3-948F-4657-88AD-FF5F27B5B24E⟩`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: "8250C5A3-948F-4657-88AD-FF5F27B5B24E"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person:⟨Tobie Morgan Hitchcock⟩`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "person", ID: "Tobie Morgan Hitchcock"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM ⟨email addresses⟩:⟨tobie@abcum.com⟩`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "email addresses", ID: "tobie@abcum.com"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM ⟨email addresses⟩:⟨tobie+spam@abcum.com⟩`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Thing{TB: "email addresses", ID: "tobie+spam@abcum.com"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT *, temp AS test FROM person`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{
|
|
{Expr: &All{}, Field: "*"},
|
|
{Expr: &Ident{"temp"}, Field: "test", Alias: "test"},
|
|
},
|
|
What: []Expr{&Ident{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT `email addresses` AS emails FROM person",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{
|
|
{Expr: &Ident{"email addresses"}, Field: "emails", Alias: "emails"},
|
|
},
|
|
What: []Expr{&Ident{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT emails AS `email addresses` FROM person",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{
|
|
{Expr: &Ident{"emails"}, Field: "email addresses", Alias: "email addresses"},
|
|
},
|
|
What: []Expr{&Ident{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM (CREATE person)`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: true,
|
|
Expr: []*Field{
|
|
{Expr: &All{}, Field: "*"},
|
|
},
|
|
What: Exprs{&SubExpression{Expr: &CreateStatement{
|
|
What: Exprs{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT * FROM person WHERE id = \"\x0A\"",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"id"}, Op: EQ, RHS: &Value{"\n"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT * FROM person WHERE id = \"\x0D\"",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"id"}, Op: EQ, RHS: &Value{"\r"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: "SELECT * FROM person WHERE id = \"\b\n\r\t\"",
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"id"}, Op: EQ, RHS: &Value{"\b\n\r\t"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE id`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &Ident{"id"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE id = `,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE id = 1`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"id"}, Op: EQ, RHS: float64(1)},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old = EMPTY`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: EQ, RHS: &Empty{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old != EMPTY`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: NEQ, RHS: &Empty{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old = MISSING`,
|
|
str: `SELECT * FROM person WHERE old = VOID`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: EQ, RHS: &Void{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old != MISSING`,
|
|
str: `SELECT * FROM person WHERE old != VOID`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: NEQ, RHS: &Void{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old IS EMPTY`,
|
|
str: `SELECT * FROM person WHERE old = EMPTY`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: EQ, RHS: &Empty{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old IS NOT EMPTY`,
|
|
str: `SELECT * FROM person WHERE old != EMPTY`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: NEQ, RHS: &Empty{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old IS MISSING`,
|
|
str: `SELECT * FROM person WHERE old = VOID`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: EQ, RHS: &Void{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old IS NOT MISSING`,
|
|
str: `SELECT * FROM person WHERE old != VOID`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: NEQ, RHS: &Void{}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old = true`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: EQ, RHS: true},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE old = false`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"old"}, Op: EQ, RHS: false},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE id != NULL AND id > 13.9 AND id < 31 AND id >= 15 AND id <= 29.9`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &Ident{"id"},
|
|
Op: NEQ,
|
|
RHS: &Null{},
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &Ident{"id"},
|
|
Op: GT,
|
|
RHS: float64(13.9),
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &Ident{"id"},
|
|
Op: LT,
|
|
RHS: float64(31),
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &Ident{"id"},
|
|
Op: GTE,
|
|
RHS: float64(15),
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &Ident{"id"},
|
|
Op: LTE,
|
|
RHS: float64(29.9),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE 2 * 3 + 4 = 10`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: float64(2),
|
|
Op: MUL,
|
|
RHS: &BinaryExpression{
|
|
LHS: float64(3),
|
|
Op: ADD,
|
|
RHS: float64(4),
|
|
},
|
|
},
|
|
Op: EQ,
|
|
RHS: float64(10),
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE 2 + 3 * 4 = 14`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: float64(2),
|
|
Op: ADD,
|
|
RHS: &BinaryExpression{
|
|
LHS: float64(3),
|
|
Op: MUL,
|
|
RHS: float64(4),
|
|
},
|
|
},
|
|
Op: EQ,
|
|
RHS: float64(14),
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE 2 * 3 + 3 * 4 = 18`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: float64(2),
|
|
Op: MUL,
|
|
RHS: &BinaryExpression{
|
|
LHS: float64(3),
|
|
Op: ADD,
|
|
RHS: &BinaryExpression{
|
|
LHS: float64(3),
|
|
Op: MUL,
|
|
RHS: float64(4),
|
|
},
|
|
},
|
|
},
|
|
Op: EQ,
|
|
RHS: float64(18),
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE 2 + 3 + 3 * 4 = 17`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: float64(2),
|
|
Op: ADD,
|
|
RHS: &BinaryExpression{
|
|
LHS: float64(3),
|
|
Op: ADD,
|
|
RHS: &BinaryExpression{
|
|
LHS: float64(3),
|
|
Op: MUL,
|
|
RHS: float64(4),
|
|
},
|
|
},
|
|
},
|
|
Op: EQ,
|
|
RHS: float64(17),
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE (2 + 3 + 3) * 4 = 32`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &SubExpression{
|
|
Expr: &BinaryExpression{
|
|
LHS: float64(2),
|
|
Op: ADD,
|
|
RHS: &BinaryExpression{
|
|
LHS: float64(3),
|
|
Op: ADD,
|
|
RHS: float64(3),
|
|
},
|
|
},
|
|
},
|
|
Op: MUL,
|
|
RHS: float64(4),
|
|
},
|
|
Op: EQ,
|
|
RHS: float64(32),
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE test IN ["London","Paris"]`,
|
|
str: `SELECT * FROM person WHERE test ∈ ["London","Paris"]`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"test"}, Op: INS, RHS: []interface{}{"London", "Paris"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE test IS IN ["London","Paris"]`,
|
|
str: `SELECT * FROM person WHERE test ∈ ["London","Paris"]`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"test"}, Op: INS, RHS: []interface{}{"London", "Paris"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE test IS NOT IN ["London","Paris"]`,
|
|
str: `SELECT * FROM person WHERE test ∉ ["London","Paris"]`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"test"}, Op: NIS, RHS: []interface{}{"London", "Paris"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE ["London","Paris"] CONTAINS test`,
|
|
str: `SELECT * FROM person WHERE ["London","Paris"] ∋ test`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: []interface{}{"London", "Paris"}, Op: SIN, RHS: &Ident{"test"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE ["London","Paris"] CONTAINS NOT test`,
|
|
str: `SELECT * FROM person WHERE ["London","Paris"] ∌ test`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: []interface{}{"London", "Paris"}, Op: SNI, RHS: &Ident{"test"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE test = {`,
|
|
err: "Found `{` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE test = {"name":"London"}`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"test"}, Op: EQ, RHS: map[string]interface{}{"name": "London"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person WHERE test = {"name":{"f":"first","l":"last"}}`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{LHS: &Ident{"test"}, Op: EQ, RHS: map[string]interface{}{"name": map[string]interface{}{"f": "first", "l": "last"}}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person TIMEOUT 1s`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Timeout: 1 * time.Second,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `SELECT * FROM person TIMEOUT null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
}
|
|
|
|
/*bday1, _ := time.Parse("2006-01-02", "1987-06-22")
|
|
bday2, _ := time.Parse(time.RFC3339, "1987-06-22T08:00:00Z")
|
|
bday3, _ := time.Parse(time.RFC3339, "1987-06-22T08:30:00.193943735Z")
|
|
bday4, _ := time.Parse(time.RFC3339, "2016-03-14T11:19:31.193943735Z")
|
|
|
|
tests = append(tests, tester{
|
|
sql: `SELECT * FROM person WHERE bday >= "1987-06-22" AND bday >= "1987-06-22T08:00:00Z" AND bday >= "1987-06-22T08:30:00.193943735Z" AND bday <= "2016-03-14T11:19:31.193943735Z"`,
|
|
res: &Query{Statements: []Statement{&SelectStatement{
|
|
RW: true,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &Ident{"bday"},
|
|
Op: GTE,
|
|
RHS: bday1,
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &Ident{"bday"},
|
|
Op: GTE,
|
|
RHS: bday2,
|
|
},
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &Ident{"bday"},
|
|
Op: GTE,
|
|
RHS: bday3,
|
|
},
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &Ident{"bday"},
|
|
Op: LTE,
|
|
RHS: bday4,
|
|
},
|
|
},
|
|
}}},
|
|
})*/
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Create(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `CREATE`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `CREATE person`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person SET 123`,
|
|
err: "Found `123` but expected `field name`",
|
|
},
|
|
{
|
|
sql: `CREATE person SET firstname`,
|
|
err: "Found `` but expected `=, +=, -=`",
|
|
},
|
|
{
|
|
sql: `CREATE person SET firstname = VOID`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &DataExpression{Data: []*ItemExpression{{LHS: &Ident{"firstname"}, Op: EQ, RHS: &Void{}}}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person SET firstname = EMPTY`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &DataExpression{Data: []*ItemExpression{{LHS: &Ident{"firstname"}, Op: EQ, RHS: &Empty{}}}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person SET firstname = "Tobie" something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `CREATE person SET firstname = "Tobie"`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &DataExpression{Data: []*ItemExpression{{LHS: &Ident{"firstname"}, Op: EQ, RHS: &Value{"Tobie"}}}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person MERGE something`,
|
|
err: "Found `something` but expected `json`",
|
|
},
|
|
{
|
|
sql: `CREATE person MERGE {"firstname"::"Tobie"}`,
|
|
err: "Found `{\"firstname\"::\"Tobie\"}` but expected `json`",
|
|
},
|
|
{
|
|
sql: `CREATE person MERGE {"firstname":"Tobie"} something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `CREATE person MERGE {"firstname":"Tobie"}`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &MergeExpression{Data: map[string]interface{}{"firstname": "Tobie"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person CONTENT {"test":"{{{"}`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &ContentExpression{Data: map[string]interface{}{"test": "{{{"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person CONTENT something`,
|
|
err: "Found `something` but expected `json`",
|
|
},
|
|
{
|
|
sql: `CREATE person CONTENT {"firstname"::"Tobie"}`,
|
|
err: "Found `{\"firstname\"::\"Tobie\"}` but expected `json`",
|
|
},
|
|
{
|
|
sql: `CREATE person CONTENT {"firstname":"Tobie"} something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `CREATE person CONTENT {"firstname":"Tobie"}`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &ContentExpression{Data: map[string]interface{}{"firstname": "Tobie"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person RETURN`,
|
|
err: "Found `` but expected `NONE, BEFORE, AFTER`",
|
|
},
|
|
{
|
|
sql: `CREATE person RETURN NONE`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: NONE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person RETURN BEFORE`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: BEFORE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person RETURN AFTER`,
|
|
str: `CREATE person`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person TIMEOUT 1s`,
|
|
res: &Query{Statements: []Statement{&CreateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
Timeout: 1 * time.Second,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `CREATE person TIMEOUT null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
{
|
|
sql: `CREATE person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Update(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `UPDATE`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `UPDATE person`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person SET 123`,
|
|
err: "Found `123` but expected `field name`",
|
|
},
|
|
{
|
|
sql: `UPDATE person SET firstname`,
|
|
err: "Found `` but expected `=, +=, -=`",
|
|
},
|
|
{
|
|
sql: `UPDATE person SET firstname = VOID`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &DataExpression{Data: []*ItemExpression{{LHS: &Ident{"firstname"}, Op: EQ, RHS: &Void{}}}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person SET firstname = EMPTY`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &DataExpression{Data: []*ItemExpression{{LHS: &Ident{"firstname"}, Op: EQ, RHS: &Empty{}}}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person SET firstname = "Tobie" something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `UPDATE person SET firstname = "Tobie"`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &DataExpression{Data: []*ItemExpression{{LHS: &Ident{"firstname"}, Op: EQ, RHS: &Value{"Tobie"}}}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person DIFF something`,
|
|
err: "Found `something` but expected `json`",
|
|
},
|
|
{
|
|
sql: `UPDATE person DIFF {} something`,
|
|
err: "Found `{}` but expected `json`",
|
|
},
|
|
{
|
|
sql: `UPDATE person DIFF [] something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `UPDATE person DIFF []`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &DiffExpression{Data: []interface{}{}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person MERGE something`,
|
|
err: "Found `something` but expected `json`",
|
|
},
|
|
{
|
|
sql: `UPDATE person MERGE {"firstname"::"Tobie"}`,
|
|
err: "Found `{\"firstname\"::\"Tobie\"}` but expected `json`",
|
|
},
|
|
{
|
|
sql: `UPDATE person MERGE {"firstname":"Tobie"} something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `UPDATE person MERGE {"firstname":"Tobie"}`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &MergeExpression{Data: map[string]interface{}{"firstname": "Tobie"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person CONTENT something`,
|
|
err: "Found `something` but expected `json`",
|
|
},
|
|
{
|
|
sql: `UPDATE person CONTENT {"firstname"::"Tobie"}`,
|
|
err: "Found `{\"firstname\"::\"Tobie\"}` but expected `json`",
|
|
},
|
|
{
|
|
sql: `UPDATE person CONTENT {"firstname":"Tobie"} something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `UPDATE person CONTENT {"firstname":"Tobie"}`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &ContentExpression{Data: map[string]interface{}{"firstname": "Tobie"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person CONTENT {"test":"{{{"}`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Data: &ContentExpression{Data: map[string]interface{}{"test": "{{{"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person RETURN`,
|
|
err: "Found `` but expected `NONE, BEFORE, AFTER`",
|
|
},
|
|
{
|
|
sql: `UPDATE person RETURN NONE`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: NONE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person RETURN BEFORE`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: BEFORE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person RETURN AFTER`,
|
|
str: `UPDATE person`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person TIMEOUT 1s`,
|
|
res: &Query{Statements: []Statement{&UpdateStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
Timeout: 1 * time.Second,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPDATE person TIMEOUT null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
{
|
|
sql: `UPDATE person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Delete(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `DELETE`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DELETE FROM`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DELETE person`,
|
|
res: &Query{Statements: []Statement{&DeleteStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: NONE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DELETE person RETURN`,
|
|
err: "Found `` but expected `NONE, BEFORE, AFTER`",
|
|
},
|
|
{
|
|
sql: `DELETE person RETURN NONE`,
|
|
str: `DELETE person`,
|
|
res: &Query{Statements: []Statement{&DeleteStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: NONE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DELETE person RETURN BEFORE`,
|
|
res: &Query{Statements: []Statement{&DeleteStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: BEFORE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DELETE person RETURN AFTER`,
|
|
res: &Query{Statements: []Statement{&DeleteStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DELETE person TIMEOUT 1s`,
|
|
res: &Query{Statements: []Statement{&DeleteStatement{
|
|
What: []Expr{&Ident{"person"}},
|
|
Echo: NONE,
|
|
Timeout: 1 * time.Second,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DELETE person TIMEOUT null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
{
|
|
sql: `DELETE person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Relate(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `RELATE`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `RELATE person`,
|
|
err: "Found `` but expected `->, <-`",
|
|
},
|
|
{
|
|
sql: `RELATE person ->`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase`,
|
|
err: "Found `` but expected `->`",
|
|
},
|
|
{
|
|
sql: `RELATE item <- purchase`,
|
|
err: "Found `` but expected `<-`",
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> `,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `RELATE item <- purchase <- `,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE item <- purchase <- person`,
|
|
str: `RELATE person -> purchase -> item`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item UNIQUE`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Uniq: true,
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE item <- purchase <- person UNIQUE`,
|
|
str: `RELATE person -> purchase -> item UNIQUE`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Uniq: true,
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item SET 123`,
|
|
err: "Found `123` but expected `field name`",
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item SET firstname`,
|
|
err: "Found `` but expected `=, +=, -=`",
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item SET public = true`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Data: &DataExpression{Data: []*ItemExpression{{LHS: &Ident{"public"}, Op: EQ, RHS: true}}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item RETURN`,
|
|
err: "Found `` but expected `NONE, BEFORE, AFTER`",
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item RETURN NONE`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Echo: NONE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item RETURN BEFORE`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Echo: BEFORE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item RETURN AFTER`,
|
|
str: `RELATE person -> purchase -> item`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item TIMEOUT 1s`,
|
|
res: &Query{Statements: []Statement{&RelateStatement{
|
|
Type: &Table{"purchase"},
|
|
From: []Expr{&Ident{"person"}},
|
|
With: []Expr{&Ident{"item"}},
|
|
Echo: AFTER,
|
|
Timeout: 1 * time.Second,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item TIMEOUT null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
{
|
|
sql: `RELATE person -> purchase -> item something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Insert(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `INSERT`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"]`,
|
|
err: "Found `` but expected `INTO`",
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person`,
|
|
res: &Query{Statements: []Statement{&InsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person RETURN`,
|
|
err: "Found `` but expected `NONE, BEFORE, AFTER`",
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person RETURN NONE`,
|
|
res: &Query{Statements: []Statement{&InsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: NONE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person RETURN BEFORE`,
|
|
res: &Query{Statements: []Statement{&InsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: BEFORE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person RETURN AFTER`,
|
|
str: `INSERT ["one","two","tre"] INTO person`,
|
|
res: &Query{Statements: []Statement{&InsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person TIMEOUT 1s`,
|
|
res: &Query{Statements: []Statement{&InsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: AFTER,
|
|
Timeout: 1 * time.Second,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person TIMEOUT null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
{
|
|
sql: `INSERT ["one","two","tre"] INTO person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Upsert(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `UPSERT`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"]`,
|
|
err: "Found `` but expected `INTO`",
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person`,
|
|
res: &Query{Statements: []Statement{&UpsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person RETURN`,
|
|
err: "Found `` but expected `NONE, BEFORE, AFTER`",
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person RETURN NONE`,
|
|
res: &Query{Statements: []Statement{&UpsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: NONE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person RETURN BEFORE`,
|
|
res: &Query{Statements: []Statement{&UpsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: BEFORE,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person RETURN AFTER`,
|
|
str: `UPSERT ["one","two","tre"] INTO person`,
|
|
res: &Query{Statements: []Statement{&UpsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: AFTER,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person TIMEOUT 1s`,
|
|
res: &Query{Statements: []Statement{&UpsertStatement{
|
|
Data: []interface{}{"one", "two", "tre"},
|
|
Into: &Table{"person"},
|
|
Echo: AFTER,
|
|
Timeout: 1 * time.Second,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person TIMEOUT null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
{
|
|
sql: `UPSERT ["one","two","tre"] INTO person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Live(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `LIVE`,
|
|
err: "Found `` but expected `SELECT`",
|
|
},
|
|
{
|
|
sql: `LIVE SELECT`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `LIVE SELECT *`,
|
|
err: "Found `` but expected `FROM`",
|
|
},
|
|
{
|
|
sql: `LIVE SELECT * FROM`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `LIVE SELECT * FROM person`,
|
|
res: &Query{Statements: []Statement{&LiveStatement{
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: Exprs{&Ident{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LIVE SELECT * FROM person WHERE`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `LIVE SELECT * FROM person WHERE public = true`,
|
|
res: &Query{Statements: []Statement{&LiveStatement{
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: Exprs{&Ident{"person"}},
|
|
Cond: &BinaryExpression{
|
|
LHS: &Ident{"public"},
|
|
Op: EQ,
|
|
RHS: true,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `LIVE SELECT * FROM person WHERE public = true something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Kill(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `KILL`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `KILL identifier`,
|
|
res: &Query{Statements: []Statement{&KillStatement{
|
|
What: Exprs{&Ident{"identifier"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `KILL "identifier"`,
|
|
res: &Query{Statements: []Statement{&KillStatement{
|
|
What: Exprs{&Value{"identifier"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `KILL "identifier" something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Define(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `DEFINE`,
|
|
err: "Found `` but expected `NAMESPACE, DATABASE, LOGIN, TOKEN, SCOPE, TABLE, EVENT, FIELD, INDEX`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE NAMESPACE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE NAMESPACE 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE NAMESPACE 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE NAMESPACE test`,
|
|
res: &Query{Statements: []Statement{&DefineNamespaceStatement{
|
|
Name: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE NAMESPACE test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE DATABASE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE DATABASE 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE DATABASE 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE DATABASE test`,
|
|
res: &Query{Statements: []Statement{&DefineDatabaseStatement{
|
|
Name: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE DATABASE test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE LOGIN`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test ON`,
|
|
err: "Found `` but expected `NAMESPACE, DATABASE`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test ON something`,
|
|
err: "Found `something` but expected `NAMESPACE, DATABASE`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test ON NAMESPACE`,
|
|
err: "Found `` but expected `PASSWORD, PASSHASH`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test ON NAMESPACE PASSWORD`,
|
|
err: "Found `` but expected `string`",
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test ON NAMESPACE PASSWORD "123456"`,
|
|
str: `DEFINE LOGIN test ON NAMESPACE PASSHASH "123456"`,
|
|
res: &Query{Statements: []Statement{&DefineLoginStatement{
|
|
Kind: NAMESPACE,
|
|
User: &Ident{"test"},
|
|
Pass: []byte("123456"),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test ON DATABASE PASSWORD "123456"`,
|
|
str: `DEFINE LOGIN test ON DATABASE PASSHASH "123456"`,
|
|
res: &Query{Statements: []Statement{&DefineLoginStatement{
|
|
Kind: DATABASE,
|
|
User: &Ident{"test"},
|
|
Pass: []byte("123456"),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE LOGIN test ON NAMESPACE PASSWORD "123456" something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE TOKEN`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON`,
|
|
err: "Found `` but expected `NAMESPACE, DATABASE, SCOPE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON something`,
|
|
err: "Found `something` but expected `NAMESPACE, DATABASE, SCOPE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON NAMESPACE`,
|
|
err: "Found `` but expected `TYPE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON NAMESPACE TYPE 100`,
|
|
err: "Found `100` but expected `ES256, ES384, ES512, HS256, HS384, HS512, PS256, PS384, PS512, RS256, RS384, RS512`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON NAMESPACE TYPE XX512`,
|
|
err: "Found `XX512` but expected `ES256, ES384, ES512, HS256, HS384, HS512, PS256, PS384, PS512, RS256, RS384, RS512`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON NAMESPACE TYPE HS512`,
|
|
err: "Found `` but expected `VALUE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON NAMESPACE TYPE HS512`,
|
|
err: "Found `` but expected `VALUE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON NAMESPACE TYPE HS512 VALUE`,
|
|
err: "Found `` but expected `string`",
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON NAMESPACE TYPE HS512 VALUE "secret"`,
|
|
str: `DEFINE TOKEN test ON NAMESPACE TYPE HS512 VALUE "secret"`,
|
|
res: &Query{Statements: []Statement{&DefineTokenStatement{
|
|
Kind: NAMESPACE,
|
|
Name: &Ident{"test"},
|
|
What: &Ident{""},
|
|
Type: "HS512",
|
|
Code: []byte("secret"),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON DATABASE TYPE HS512 VALUE "secret"`,
|
|
str: `DEFINE TOKEN test ON DATABASE TYPE HS512 VALUE "secret"`,
|
|
res: &Query{Statements: []Statement{&DefineTokenStatement{
|
|
Kind: DATABASE,
|
|
Name: &Ident{"test"},
|
|
What: &Ident{""},
|
|
Type: "HS512",
|
|
Code: []byte("secret"),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON SCOPE test TYPE HS512 VALUE "secret"`,
|
|
str: `DEFINE TOKEN test ON SCOPE test TYPE HS512 VALUE "secret"`,
|
|
res: &Query{Statements: []Statement{&DefineTokenStatement{
|
|
Kind: SCOPE,
|
|
Name: &Ident{"test"},
|
|
What: &Ident{"test"},
|
|
Type: "HS512",
|
|
Code: []byte("secret"),
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TOKEN test ON SCOPE test TYPE HS512 VALUE "secret" something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE SCOPE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SESSION null`,
|
|
err: "Found `null` but expected `duration`",
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SESSION 1h`,
|
|
str: `DEFINE SCOPE test SESSION 1h0m0s`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
Time: 1 * time.Hour,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SESSION 1d`,
|
|
str: `DEFINE SCOPE test SESSION 24h0m0s`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
Time: 24 * time.Hour,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SESSION 1w`,
|
|
str: `DEFINE SCOPE test SESSION 168h0m0s`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
Time: 168 * time.Hour,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SIGNUP AS NONE`,
|
|
err: "Found `NONE` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SIGNUP AS (CREATE person)`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
Signup: &SubExpression{
|
|
Expr: &CreateStatement{
|
|
What: Exprs{&Ident{"person"}},
|
|
Echo: AFTER,
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SIGNIN AS NONE`,
|
|
err: "Found `NONE` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SIGNIN AS (SELECT * FROM person)`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
Signin: &SubExpression{
|
|
Expr: &SelectStatement{
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"person"}},
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test CONNECT AS NONE`,
|
|
err: "Found `NONE` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test CONNECT AS (SELECT * FROM $id)`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
Connect: &SubExpression{
|
|
Expr: &SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Param{"id"}},
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test SIGNUP AS (CREATE tester) SIGNIN AS (SELECT * FROM tester) CONNECT AS (SELECT * FROM $id)`,
|
|
res: &Query{Statements: []Statement{&DefineScopeStatement{
|
|
Name: &Ident{"test"},
|
|
Signup: &SubExpression{
|
|
Expr: &CreateStatement{
|
|
What: []Expr{&Ident{"tester"}},
|
|
Echo: AFTER,
|
|
},
|
|
},
|
|
Signin: &SubExpression{
|
|
Expr: &SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Ident{"tester"}},
|
|
},
|
|
},
|
|
Connect: &SubExpression{
|
|
Expr: &SelectStatement{
|
|
RW: false,
|
|
Expr: []*Field{{Expr: &All{}, Field: "*"}},
|
|
What: []Expr{&Param{"id"}},
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE SCOPE test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE TABLE`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE 111`,
|
|
err: "Found `111` but expected `table`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE 111.111`,
|
|
err: "Found `111.111` but expected `table`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person DROP`,
|
|
str: `DEFINE TABLE person DROP`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Drop: true,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person SCHEMALESS`,
|
|
str: `DEFINE TABLE person`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Full: false,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person SCHEMAFULL`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Full: true,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS SOME`,
|
|
err: "Found `SOME` but expected `FOR, NONE, FULL, WHERE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS NONE`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: false,
|
|
Create: false,
|
|
Update: false,
|
|
Delete: false,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS FULL`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: true,
|
|
Create: true,
|
|
Update: true,
|
|
Delete: true,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS WHERE public = true`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Create: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Update: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Delete: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS FOR select FULL FOR insert, upsert NONE`,
|
|
err: "Found `insert` but expected `SELECT, CREATE, UPDATE, DELETE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS FOR select FULL FOR create, update, delete SOME`,
|
|
err: "Found `SOME` but expected `FULL, NONE, WHERE`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS FOR select FULL FOR create, update, delete NONE`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: true,
|
|
Create: false,
|
|
Update: false,
|
|
Delete: false,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person PERMISSIONS FOR select, create, update WHERE public = true FOR delete NONE`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Create: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Update: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Delete: false,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person AS SELECT nationality, math.midhinge(age) AS mid FROM users GROUP BY nationality`,
|
|
err: "Found 'mid' but field is not an aggregate function, and is not present in GROUP expression",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person AS SELECT nationality, count(*) AS total FROM users WHERE public = true GROUP BY nationality`,
|
|
res: &Query{Statements: []Statement{&DefineTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
Lock: true,
|
|
Expr: Fields{
|
|
&Field{
|
|
Expr: &Ident{"nationality"},
|
|
Field: "nationality",
|
|
},
|
|
&Field{
|
|
Expr: &FuncExpression{
|
|
Name: "count",
|
|
Args: Exprs{&All{}},
|
|
Aggr: true,
|
|
},
|
|
Field: "total",
|
|
Alias: "total",
|
|
},
|
|
},
|
|
From: Tables{
|
|
&Table{TB: "users"},
|
|
},
|
|
Cond: &BinaryExpression{
|
|
LHS: &Ident{"public"},
|
|
Op: EQ,
|
|
RHS: true,
|
|
},
|
|
Group: Groups{
|
|
&Group{
|
|
Expr: &Ident{"nationality"},
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person SCHEMALESS something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `DEFINE TABLE person SCHEMAFULL something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE EVENT`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON person`,
|
|
err: "Found `` but expected `WHEN`",
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON person WHEN`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON person WHEN $before.price < $after.price`,
|
|
err: "Found `` but expected `THEN`",
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON person WHEN $before.price < $after.price THEN`,
|
|
err: "Found `` but expected `(`",
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON person WHEN $before.price < $after.price THEN (UPDATE $this SET increased = true)`,
|
|
res: &Query{Statements: []Statement{&DefineEventStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
When: &BinaryExpression{
|
|
LHS: &Param{"before.price"},
|
|
Op: LT,
|
|
RHS: &Param{"after.price"},
|
|
},
|
|
Then: &MultExpression{
|
|
Expr: []Expr{
|
|
&UpdateStatement{
|
|
What: Exprs{&Param{"this"}},
|
|
Data: &DataExpression{[]*ItemExpression{
|
|
{
|
|
LHS: &Ident{"increased"},
|
|
Op: EQ,
|
|
RHS: true,
|
|
},
|
|
}},
|
|
Echo: AFTER,
|
|
},
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON person WHEN $before.price < $after.price THEN (UPDATE $this SET increased = true; UPDATE $this SET finished = true)`,
|
|
res: &Query{Statements: []Statement{&DefineEventStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
When: &BinaryExpression{
|
|
LHS: &Param{"before.price"},
|
|
Op: LT,
|
|
RHS: &Param{"after.price"},
|
|
},
|
|
Then: &MultExpression{
|
|
Expr: []Expr{
|
|
&UpdateStatement{
|
|
What: Exprs{&Param{"this"}},
|
|
Data: &DataExpression{[]*ItemExpression{
|
|
{
|
|
LHS: &Ident{"increased"},
|
|
Op: EQ,
|
|
RHS: true,
|
|
},
|
|
}},
|
|
Echo: AFTER,
|
|
},
|
|
&UpdateStatement{
|
|
What: Exprs{&Param{"this"}},
|
|
Data: &DataExpression{[]*ItemExpression{
|
|
{
|
|
LHS: &Ident{"finished"},
|
|
Op: EQ,
|
|
RHS: true,
|
|
},
|
|
}},
|
|
Echo: AFTER,
|
|
},
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE EVENT temp ON person WHEN $before.price < $after.price THEN (UPDATE $this SET increased = true) something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE FIELD`,
|
|
err: "Found `` but expected `name, or expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE`,
|
|
err: "Found `` but expected `array, boolean, circle, datetime, number, object, point, polygon, record, string`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE something`,
|
|
err: "Found `something` but expected `array, boolean, circle, datetime, number, object, point, polygon, record, string`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE array`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Type: "array",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE object`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Type: "object",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE string`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Type: "string",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE number`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Type: "number",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE record`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Type: "record",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person TYPE record (item)`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Type: "record",
|
|
Kind: "item",
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person VALUE`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person VALUE string.uppercase($value)`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Value: &FuncExpression{Name: "string.uppercase", Args: Exprs{&Param{"value"}}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person ASSERT`,
|
|
err: "Found `` but expected `expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person ASSERT $value > 0 AND $value < 100`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Assert: &BinaryExpression{
|
|
LHS: &BinaryExpression{
|
|
LHS: &Param{"value"},
|
|
Op: GT,
|
|
RHS: 0.0,
|
|
},
|
|
Op: AND,
|
|
RHS: &BinaryExpression{
|
|
LHS: &Param{"value"},
|
|
Op: LT,
|
|
RHS: 100.0,
|
|
},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS SOME`,
|
|
err: "Found `SOME` but expected `FOR, NONE, FULL, WHERE`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS NONE`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: false,
|
|
Create: false,
|
|
Update: false,
|
|
Delete: false,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS FULL`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: true,
|
|
Create: true,
|
|
Update: true,
|
|
Delete: true,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS WHERE public = true`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Create: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Update: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Delete: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS FOR select FULL FOR insert, upsert NONE`,
|
|
err: "Found `insert` but expected `SELECT, CREATE, UPDATE, DELETE`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS FOR select FULL FOR create, update, delete SOME`,
|
|
err: "Found `SOME` but expected `FULL, NONE, WHERE`",
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS FOR select FULL FOR create, update, delete NONE`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: true,
|
|
Create: false,
|
|
Update: false,
|
|
Delete: false,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person PERMISSIONS FOR select, create, update WHERE public = true FOR delete NONE`,
|
|
res: &Query{Statements: []Statement{&DefineFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Perms: &PermExpression{
|
|
Select: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Create: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Update: &BinaryExpression{LHS: &Ident{"public"}, Op: EQ, RHS: true},
|
|
Delete: false,
|
|
},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE FIELD temp ON person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `DEFINE INDEX`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp ON`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp ON person`,
|
|
err: "Found `` but expected `COLUMNS`",
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp ON person COLUMNS`,
|
|
err: "Found `` but expected `name, or expression`",
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp ON person COLUMNS firstname, lastname`,
|
|
res: &Query{Statements: []Statement{&DefineIndexStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Cols: Idents{&Ident{"firstname"}, &Ident{"lastname"}},
|
|
Uniq: false,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp ON person COLUMNS firstname, lastname UNIQUE`,
|
|
res: &Query{Statements: []Statement{&DefineIndexStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
Cols: Idents{&Ident{"firstname"}, &Ident{"lastname"}},
|
|
Uniq: true,
|
|
}}},
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp ON person COLUMNS firstname, lastname something UNIQUE`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `DEFINE INDEX temp ON person COLUMNS firstname, lastname UNIQUE something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Remove(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `REMOVE`,
|
|
err: "Found `` but expected `NAMESPACE, DATABASE, LOGIN, TOKEN, SCOPE, TABLE, EVENT, FIELD, INDEX`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE NAMESPACE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE NAMESPACE 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE NAMESPACE 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE NAMESPACE test`,
|
|
res: &Query{Statements: []Statement{&RemoveNamespaceStatement{
|
|
Name: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE NAMESPACE test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE DATABASE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE DATABASE 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE DATABASE 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE DATABASE test`,
|
|
res: &Query{Statements: []Statement{&RemoveDatabaseStatement{
|
|
Name: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE DATABASE test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE LOGIN`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN test`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN test ON`,
|
|
err: "Found `` but expected `NAMESPACE, DATABASE`",
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN test ON something`,
|
|
err: "Found `something` but expected `NAMESPACE, DATABASE`",
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN test ON NAMESPACE`,
|
|
res: &Query{Statements: []Statement{&RemoveLoginStatement{
|
|
Kind: NAMESPACE,
|
|
User: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN test ON DATABASE`,
|
|
res: &Query{Statements: []Statement{&RemoveLoginStatement{
|
|
Kind: DATABASE,
|
|
User: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE LOGIN test ON DATABASE something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE TOKEN`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test ON`,
|
|
err: "Found `` but expected `NAMESPACE, DATABASE, SCOPE`",
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test ON something`,
|
|
err: "Found `something` but expected `NAMESPACE, DATABASE, SCOPE`",
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test ON NAMESPACE`,
|
|
res: &Query{Statements: []Statement{&RemoveTokenStatement{
|
|
Kind: NAMESPACE,
|
|
Name: &Ident{"test"},
|
|
What: &Ident{""},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test ON DATABASE`,
|
|
res: &Query{Statements: []Statement{&RemoveTokenStatement{
|
|
Kind: DATABASE,
|
|
Name: &Ident{"test"},
|
|
What: &Ident{""},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test ON SCOPE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test ON SCOPE test`,
|
|
res: &Query{Statements: []Statement{&RemoveTokenStatement{
|
|
Kind: SCOPE,
|
|
Name: &Ident{"test"},
|
|
What: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE TOKEN test ON DATABASE something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE SCOPE`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE SCOPE 111`,
|
|
err: "Found `111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE SCOPE 111.111`,
|
|
err: "Found `111.111` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE SCOPE test`,
|
|
res: &Query{Statements: []Statement{&RemoveScopeStatement{
|
|
Name: &Ident{"test"},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE SCOPE test something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE TABLE`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `REMOVE TABLE 111`,
|
|
err: "Found `111` but expected `table`",
|
|
},
|
|
{
|
|
sql: `REMOVE TABLE 111.111`,
|
|
err: "Found `111.111` but expected `table`",
|
|
},
|
|
{
|
|
sql: `REMOVE TABLE person`,
|
|
res: &Query{Statements: []Statement{&RemoveTableStatement{
|
|
What: Tables{&Table{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE TABLE person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE EVENT`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE EVENT temp`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `REMOVE EVENT temp ON`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `REMOVE EVENT temp ON person`,
|
|
res: &Query{Statements: []Statement{&RemoveEventStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE EVENT temp ON person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE FIELD`,
|
|
err: "Found `` but expected `name, or expression`",
|
|
},
|
|
{
|
|
sql: `REMOVE FIELD temp`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `REMOVE FIELD temp ON`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `REMOVE FIELD temp ON person`,
|
|
res: &Query{Statements: []Statement{&RemoveFieldStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE FIELD temp ON person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
// ----------------------------------------------------------------------
|
|
{
|
|
sql: `REMOVE INDEX`,
|
|
err: "Found `` but expected `name`",
|
|
},
|
|
{
|
|
sql: `REMOVE INDEX temp`,
|
|
err: "Found `` but expected `ON`",
|
|
},
|
|
{
|
|
sql: `REMOVE INDEX temp ON`,
|
|
err: "Found `` but expected `table`",
|
|
},
|
|
{
|
|
sql: `REMOVE INDEX temp ON person`,
|
|
res: &Query{Statements: []Statement{&RemoveIndexStatement{
|
|
Name: &Ident{"temp"},
|
|
What: Tables{&Table{"person"}},
|
|
}}},
|
|
},
|
|
{
|
|
sql: `REMOVE INDEX temp ON person something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Begin(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `BEGIN`,
|
|
str: `BEGIN TRANSACTION`,
|
|
res: &Query{Statements: []Statement{&BeginStatement{}}},
|
|
},
|
|
{
|
|
sql: `BEGIN something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `BEGIN TRANSACTION`,
|
|
res: &Query{Statements: []Statement{&BeginStatement{}}},
|
|
},
|
|
{
|
|
sql: `BEGIN TRANSACTION something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Cancel(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `CANCEL`,
|
|
str: `CANCEL TRANSACTION`,
|
|
res: &Query{Statements: []Statement{&CancelStatement{}}},
|
|
},
|
|
{
|
|
sql: `CANCEL something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `CANCEL TRANSACTION`,
|
|
res: &Query{Statements: []Statement{&CancelStatement{}}},
|
|
},
|
|
{
|
|
sql: `CANCEL TRANSACTION something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Parse_Queries_Commit(t *testing.T) {
|
|
|
|
var tests = []tester{
|
|
{
|
|
sql: `COMMIT`,
|
|
str: `COMMIT TRANSACTION`,
|
|
res: &Query{Statements: []Statement{&CommitStatement{}}},
|
|
},
|
|
{
|
|
sql: `COMMIT something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
{
|
|
sql: `COMMIT TRANSACTION`,
|
|
res: &Query{Statements: []Statement{&CommitStatement{}}},
|
|
},
|
|
{
|
|
sql: `COMMIT TRANSACTION something`,
|
|
err: "Found `something` but expected `;`",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
testsql(t, test)
|
|
}
|
|
|
|
}
|