func TestParserASTOutput(t *testing.T) { tests := []struct { input string output ast.Statement }{ {"SELECT * FROM test WHERE true", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: ast.NewLiteralBool(true), Limit: -1, }, }, {"SELECT * FROM :apool.test WHERE true", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Pool: "apool", Projection: ast.NewProperty("test")}, Where: ast.NewLiteralBool(true), Limit: -1, }, }, {"SELECT * FROM test ORDER BY foo", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: nil, OrderBy: []*ast.SortExpression{ ast.NewSortExpression(ast.NewProperty("foo"), true), }, Limit: -1, }, }, {"SELECT * FROM test LIMIT 10 OFFSET 3", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: nil, Limit: 10, Offset: 3, }, }, {"SELECT a FROM test", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpression(ast.NewProperty("a")), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: nil, Limit: -1, }, }, {"SELECT a FROM test t2", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpression(ast.NewProperty("a")), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test"), As: "t2"}, Where: nil, Limit: -1, }, }, {"SELECT 1+1*30 as steve", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"), }, Distinct: false, From: nil, Where: nil, Limit: -1, }, }, {"SELECT 1+1*30 steve", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"), }, Distinct: false, From: nil, Where: nil, Limit: -1, }, }, {"SELECT DISTINCT 1+1*30 as steve", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"), }, Distinct: true, From: nil, Where: nil, Limit: -1, }, }, {"CREATE INDEX abv_idx ON beer-sample(abv) USING VIEW", &ast.CreateIndexStatement{ Method: "view", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON beer-sample(abv) USING magic", &ast.CreateIndexStatement{ Method: "magic", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON beer-sample(abv)", &ast.CreateIndexStatement{ Method: "", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON :apool.beer-sample(abv) USING VIEW", &ast.CreateIndexStatement{ Method: "view", Pool: "apool", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON :apool.beer-sample(abv) USING magic", &ast.CreateIndexStatement{ Method: "magic", Pool: "apool", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON :apool.beer-sample(abv)", &ast.CreateIndexStatement{ Method: "", Pool: "apool", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"DROP INDEX beer-sample.abv", &ast.DropIndexStatement{ Bucket: "beer-sample", Name: "abv", }, }, {"DROP INDEX :apool.beer-sample.abv", &ast.DropIndexStatement{ Pool: "apool", Bucket: "beer-sample", Name: "abv", }, }, } n1qlParser := NewN1qlParser() for _, v := range tests { query, err := n1qlParser.Parse(v.input) if err != nil { t.Errorf("Valid Query Parse Failed: %v - %v", v, err) } if !reflect.DeepEqual(query, v.output) { t.Errorf("Expected %v, got %v", v.output, query) js, err := json.MarshalIndent(v.output, "", " ") if err == nil { t.Logf("Expected %v", string(js)) } js, err = json.MarshalIndent(query, "", " ") if err == nil { t.Logf("Got %v", string(js)) } } } }
func TestPlanJSON(t *testing.T) { tests := []struct { input *Plan }{ {&Plan{NewScan("pool", "bucket", "index", nil)}}, {&Plan{NewFetch(NewScan("pool", "bucket", "index", nil), "pool", "bucket", nil, "bucket")}}, {&Plan{NewFilter(NewFetch(NewScan("pool", "bucket", "index", nil), "pool", "bucket", nil, "bucket"), ast.NewLiteralBool(true))}}, {&Plan{NewFilter(NewFetch(NewScan("pool", "bucket", "index", nil), "pool", "bucket", nil, "bucket"), ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(1.0)))}}, } for _, x := range tests { _, err := json.MarshalIndent(x.input, "", " ") if err != nil { t.Errorf("error serializing json: %v", err) } // FIXME test doesn't actually assert anything } }