Skip to content

Commit

Permalink
support EXISTS subquery (#978)
Browse files Browse the repository at this point in the history
  • Loading branch information
jycor authored Nov 19, 2024
1 parent c1ac30d commit 35a449e
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 7 deletions.
2 changes: 1 addition & 1 deletion server/ast/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ func nodeExpr(ctx *Context, node tree.Expr) (vitess.Expr, error) {
Expression: unknownLiteral,
}, nil
case *tree.Subquery:
return nodeSubquery(ctx, node)
return nodeSubqueryOrExists(ctx, node)
case *tree.Tuple:
if len(node.Labels) > 0 {
return nil, fmt.Errorf("tuple labels are not yet supported")
Expand Down
19 changes: 14 additions & 5 deletions server/ast/subquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
package ast

import (
"fmt"

vitess "github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
Expand All @@ -28,9 +26,6 @@ func nodeSubquery(ctx *Context, node *tree.Subquery) (*vitess.Subquery, error) {
if node == nil {
return nil, nil
}
if node.Exists {
return nil, fmt.Errorf("EXISTS is not yet supported")
}
selectStmt, err := nodeSelectStatement(ctx, node.Select)
if err != nil {
return nil, err
Expand All @@ -51,3 +46,17 @@ func nodeSubqueryToTableExpr(ctx *Context, node *tree.Subquery) (vitess.TableExp
As: vitess.NewTableIdent(utils.GenerateUniqueAlias()),
}, nil
}

// nodeSubqueryOrExists handles *tree.Subquery nodes that may be an EXISTS subquery, returning a vitess.Expr.
func nodeSubqueryOrExists(ctx *Context, node *tree.Subquery) (vitess.Expr, error) {
subquery, err := nodeSubquery(ctx, node)
if err != nil {
return nil, err
}
if !node.Exists {
return subquery, nil
}
return &vitess.ExistsExpr{
Subquery: subquery,
}, nil
}
2 changes: 1 addition & 1 deletion testing/go/regression/tool/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ ListenerLoop:
}
}
for _, failQuery := range options.FailQueries {
if message.String == failQuery {
if strings.Contains(message.String, failQuery) {
tracker.Failed++
tracker.AddFailure(ReplayTrackerItem{
Query: message.String,
Expand Down
1 change: 1 addition & 0 deletions testing/go/regression/tool/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,5 @@ WHERE pg_class.oid=indexrelid
AND indrelid=pg_class_2.oid
AND pg_class_2.relname = 'clstr_tst'
AND indisclustered;`,
`SELECT 1 FROM pg_catalog.pg_constraint WHERE conrelid = i.indrelid AND conindid = i.indexrelid`,
}
46 changes: 46 additions & 0 deletions testing/go/subqueries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,49 @@ ORDER BY 1;`,
},
})
}

func TestExistSubquery(t *testing.T) {
RunScripts(t, []ScriptTest{
{
Name: "basic case",
SetUpScript: []string{
`CREATE TABLE test (id INT PRIMARY KEY);`,
`INSERT INTO test VALUES (1), (3), (2);`,
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT * FROM test WHERE EXISTS (SELECT 123);`,
Expected: []sql.Row{
{1},
{2},
{3},
},
},
{
Query: `SELECT * FROM test WHERE NOT EXISTS (SELECT 123);`,
Expected: []sql.Row{},
},
{
Query: `SELECT 123 WHERE EXISTS (SELECT * FROM test);`,
Expected: []sql.Row{
{123},
},
},
{
Query: `SELECT 123 WHERE EXISTS (SELECT * FROM test WHERE id > 10);`,
Expected: []sql.Row{},
},
{
Query: `SELECT 123 WHERE NOT EXISTS (SELECT * FROM test);`,
Expected: []sql.Row{},
},
{
Query: `SELECT 123 WHERE NOT EXISTS (SELECT * FROM test WHERE id > 10);`,
Expected: []sql.Row{
{123},
},
},
},
},
})
}

0 comments on commit 35a449e

Please sign in to comment.