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

Adds basic scalar and row-value subquery coercion #1258

Merged
merged 1 commit into from
Nov 2, 2023

Conversation

RCHowell
Copy link
Member

@RCHowell RCHowell commented Nov 2, 2023

Relevant Issues

Description

Adds basic scalar and row-value scalar subquery coercion. Note that this currently does not consider array expressions for row-value. A spot has been carved out, but is not required at the moment.

Other Information

  • Updated Unreleased Section in CHANGELOG: [YES/NO]
    No

  • Any backward-incompatible changes? [YES/NO]
    No

  • Any new external dependencies? [YES/NO]
    No

  • Do your changes comply with the Contributing Guidelines
    and Code Style Guidelines? [YES/NO]
    Yes

License Information

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link

github-actions bot commented Nov 2, 2023

Conformance comparison report

Base (262074f) 99a2551 +/-
% Passing 92.33% 92.33% 0.00%
✅ Passing 5372 5372 0
❌ Failing 446 446 0
🔶 Ignored 0 0 0
Total Tests 5818 5818 0

Number passing in both: 5372

Number failing in both: 446

Number passing in Base (262074f) but now fail: 0

Number failing in Base (262074f) but now pass: 0

Comment on lines +11 to +15
--#[subquery-02]
SELECT t.*, s.*
FROM T AS t
JOIN (SELECT * FROM S) AS s
ON t.x = s.a;
Copy link
Member

Choose a reason for hiding this comment

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

Great to see this pass.

Comment on lines +1 to +9
--#[subquery-00]
SELECT x
FROM T
WHERE x IN (SELECT a FROM S);

--#[subquery-01]
SELECT x
FROM T
WHERE x > (SELECT MAX(a) FROM S);
Copy link
Member

Choose a reason for hiding this comment

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

While this PR hasn't added full support for ROW coercion yet, would you also want to include tests where the subquery has more than 1 column?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, working on that now. Had some transpiler cases for this which are failing.

Comment on lines +94 to +100
private fun visitExprCoerce(node: Expr, ctx: Env, coercion: Rex.Op.Subquery.Coercion = Rex.Op.Subquery.Coercion.SCALAR): Rex {
val rex = super.visitExpr(node, ctx)
return when (rex.op is Rex.Op.Select) {
true -> rex(StaticType.ANY, rexOpSubquery(rex.op as Rex.Op.Select, coercion))
else -> rex
}
}
Copy link
Member

Choose a reason for hiding this comment

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

1:

Is there a reason why we don't make the default visitExpr have this logic? And whenever we encounter the limited cases (FROM, JOIN, etc), we invoke a function called visitExprNoCoercion.

2:

If there is a reason, do we need to pass coercion here?

An SELECT SFW subquery coerces into an array when it is the rhs (respectively, lhs) of a comparison operator whose other argument is an array.

The spec doesn't say array literal. Which means, we don't know whether to coerce the RHS into an array until we have typed.

3:

That being said, I'm not sure I'm a fan of the:

... operator whose other argument is an array.

To be SQL-compatible, I feel like we should syntactically support coercion to an array where the other argument is:

  1. an array constructor: ARRAY [ ... ]
  2. a row constructor: ROW ( ... ), ( ..., ... )
  3. a subquery: (SELECT ...)

Seems a bit weird to allow:

SELECT a
FROM t
LET [ t.a, t.b ] AS c
WHERE c < (SELECT d, e FROM g)

Comment on lines +720 to +741
// val n = coercion.columns.size
// val m = cons.fields.size
// if (n != m) {
// return rexErr("Cannot coercion subquery with $m attributes to a row-value-expression with $n attributes")
Copy link
Member

Choose a reason for hiding this comment

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

Depending on how we interpret the spec and whether coercion only pertains to array literals (it currently says arrays -- not literals), then we can potentially perform the cardinality check on the AST instead, which would be simpler.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree; I actually had this check in the RexConverter rather than the typer because I had access to the AST. I moved the to PlanTyper to perform type assertions on the constructor, but I'm beginning to think we may be limited to array expressions (not array literals).

Copy link
Member Author

@RCHowell RCHowell Nov 2, 2023

Choose a reason for hiding this comment

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

The cardinality check is just as easy for array expressions and literals, and we need the typing of the subquery for cases like

( 0, 0 ) = (SELECT * FROM points LIMIT 1); -- check if the first point is the origin

-- points : bag<<struct::closed{ x: int32, y: int32 }>>

Copy link
Member

@johnedquinn johnedquinn left a comment

Choose a reason for hiding this comment

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

In the interest of time, approving this. The only thing to eventually follow-up on is the unused coercion parameter. That is, unless we eventually type during the conversion 🤞

@RCHowell RCHowell merged commit 5946539 into partiql-planner Nov 2, 2023
6 of 8 checks passed
@RCHowell RCHowell deleted the planner-subquery branch November 2, 2023 22:11
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