Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update some analyzer rules and expression behavior to deal with tuples in a more principled way. #560

Merged
merged 5 commits into from
Sep 23, 2021

Conversation

reltuk
Copy link
Contributor

@reltuk reltuk commented Sep 21, 2021

Subquery expression nodes can now return tuples.

InSubquery expression nodes can work with tuples as expected.

An analyzer validation step now returns operand errors in more cases, expecting
almost all expressions to return one column, but special casing certain
operators and functions which support tuples.

Added some TODO tests for cases where our tuple comparisons are still not
behaving as we want them to. In particular, null safe vs. non-null safe
comparisons and type coercion of tuple subtypes in comparisons still need work.

…s in a more principled way.

Subquery expression nodes can now return tuples.

InSubquery expression nodes can work with tuples as expected.

An analyzer validation step now returns operand errors in more cases, expecting
almost all expressions to return one column, but special casing certain
operators and functions which support tuples.

Added some TODO tests for cases where our tuple comparisons are still not
behaving as we want them to. In particular, null safe vs. non-null safe
comparisons and type coercion of tuple subtypes in comparisons still need work.
@reltuk reltuk requested a review from zachmu September 21, 2021 23:23
@@ -531,22 +558,38 @@ func validateSubqueryColumns(ctx *sql.Context, a *Analyzer, n sql.Node, scope *S
return true
}

outerScopeRowLen := len(schemas(n.Children()))
plan.InspectExpressionsWithNode(s.Query, func(n sql.Node, e sql.Expression) bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This portion of the validation never actually worked, because the if condition down below as !valid and this block never touched valid.

Copy link
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a couple commens

Query: "SELECT 1 FROM DUAL WHERE (1, 2) in ((3, 4), (5, 6), (1, 2))",
Expected: []sql.Row{{1}},
},
// TODO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to BrokenQueries?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same below

Expected: []sql.Row{{1}},
},
{
Query: "SELECT 1 FROM DUAL WHERE (1, 2) in ((3, 4), (5, 6), (1, 2))",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing a false case for IN for tuple literals

Also should have a couple NOT IN cases

Expected: []sql.Row{{1}},
},
{
Query: "SELECT 1 FROM DUAL WHERE (null, null) <=> (select 1, 4 from dual where false)",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect <=> to work with nulls in tuples, e..g (null, null) <=> (select null, null)? Need a test if so, a BrokenQueries test if not

Expected: []sql.Row{{1}},
},
{
Query: "SELECT (((1,2),3)) = (((1,2),3)) from dual",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa, is this standard SQL? Tuples can nest?

func validateSubqueryColumns(ctx *sql.Context, a *Analyzer, n sql.Node, scope *Scope) (sql.Node, error) {
func validateOperands(ctx *sql.Context, a *Analyzer, n sql.Node, scope *Scope) (sql.Node, error) {
// Validate that the number of columns in an operand or a top level
// expression are as expected. The currently rules are:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current rules

if ok && len(s.Query.Schema()) != 1 {
valid = false
var err error
plan.Inspect(n, func(n sql.Node) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not plan.InspectExpressions?

@reltuk reltuk merged commit 67d872a into master Sep 23, 2021
@Hydrocharged Hydrocharged deleted the aaron/validate-operands branch December 8, 2021 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants