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

A "let" expression #415

Open
gatesn opened this issue Jan 5, 2023 · 4 comments
Open

A "let" expression #415

gatesn opened this issue Jan 5, 2023 · 4 comments
Labels
enhancement New feature or request help wanted No one is currently implementing but it seems like a good idea

Comments

@gatesn
Copy link

gatesn commented Jan 5, 2023

I believe this has been brought up a couple of times before as part of #287 and somewhat in #320, but I thought it would be worth discussing explicitly.

The idea is whether it should be possible to reference common subexpressions. Either using an explicit "let" expression operator, e.g. let x = y + z; and(gt(a, x), lte(b, x)) or by pulling them to the plan-level as is done with the relation reference operator.

@julianhyde
Copy link

Calcite's RexProgram class is a bundle of project (and optionally filter) expressions. The expressions are topologically sorted so that common expressions are computed first. It might be a useful concept for substrait to borrow.

@westonpace
Copy link
Member

@julianhyde is RexProgram itself an expression?

@julianhyde
Copy link

is RexProgram itself an expression?

Not exactly. It is a collection of expressions and a filter. If you squint you could regard it as an expression that returns an optional tuple.

But I do think it solves the requirement for common subexpressions admirably.

An ordinary "let" expression, without the ability to return tuples, is going to struggle with cases like this (in Standard ML-like pseudocode), with multiple outputs based on the same common subexpressions:

   let
     val x = y + z
   in
     { b = a > x andalso b <= x, p = a + x, q = p + z }
   end

and this one, where output is conditional on an intermediate expression:

   let
     val x = y + z
   in
     if a > x andalso b <= x then
       emit { p = a + x,  q = p + z }
  end

@westonpace
Copy link
Member

westonpace commented Jan 10, 2023

@julianhyde If it isn't an expression then how do we use it? For example, a project is currently defined as:

message ProjectRel {
  RelCommon common = 1;
  Rel input = 2;
  repeated Expression expressions = 3;
  substrait.extensions.AdvancedExtension advanced_extension = 10;
}

Should we change field 3 to a repeated Program message?

@westonpace westonpace added enhancement New feature or request help wanted No one is currently implementing but it seems like a good idea labels Mar 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted No one is currently implementing but it seems like a good idea
Projects
None yet
Development

No branches or pull requests

3 participants