Re: Rules to squash redundant join sides?

2023-03-30 Thread Julian Hyde
I agree with Stamatis that this would be a useful feature. The first step would 
be log a jira case with a clear description of the problem. Can you describe 
exactly what you mean by ‘mergeable’, ‘redundant' and ’squash’?

I can’t follow your example, Ian. Can you find a simpler example, or possibly 
express in SQL?

Decorrelation (and introducing a ‘value generator’ for all, or a superset of, 
the values of the correlating variable) is hard for general queries. I think it 
would be wrong to try too hard to produce a minimal query when decorrelating. 
Better to produce something that works, using a simple algorithm, and simplify 
it later.

Julian



> On Mar 30, 2023, at 10:29 AM, Ian Bertolacci 
>  wrote:
> 
> Stamatis,
> Thanks! I’ll take a look at this.
> Is it possible to avoid the creation of these kinds of joins correlated 
> subqueries? Or does that still have the same issue as general joins?
> 
> Thanks!
> -Ian
> 
> From: Stamatis Zampetakis 
> Date: Thursday, March 30, 2023 at 1:41 AM
> To: dev@calcite.apache.org 
> Subject: [External Sender] Re: Rules to squash redundant join sides?
> Hey Ian,
> 
> I think you are referring to the problem of query minimization and at
> the moment we don't have any such rules in Calcite but it would be a
> valuable contribution.
> Apart from the algorithm itself, it might be necessary to introduce
> some new metadata provider for PK-FK relationships otherwise dropping
> a join may remove duplicates and change the semantics of the plan.
> 
> You can find some previous discussion here [1].
> 
> Best,
> Stamatis
> 
> [1] 
> https://urldefense.com/v3/__https://lists.apache.org/thread/vsq59yhfj4glf7mgpf9n6j255myhs0so__;!!Iz9xO38YGHZK!7_nW_9SgSRGAzlQa7TmPcod2_Xhqk41iPbC7Wzi-IoMCPhnEG1ZYGnknVSxbgOx-CLhOl2WSB_2MMTXI1BMG$
> 
> On Thu, Mar 30, 2023 at 1:27 AM Ian Bertolacci
>  wrote:
>> 
>> Howdy,
>> Is there a collection of rules which squash a tree of binary joins if the 
>> same side of each join is mergeable?
>> 
>> For example:
>> ```
>> 201:LogicalProject(P4=[$70], P5=[$72])
>> └─ 199:LogicalJoin(condition=[=($0, $71)], joinType=[left])
>>   ├─ 190:LogicalProject(...)
>>   |  └─ 188:LogicalJoin(condition=[=($0, $70)], joinType=[left])
>>   | ├─ 164:QueryTableScan(table=[[Query, T123]])
>>   | └─ 186:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1)])
>>   |└─ 184:LogicalProject(C5633_586=[$85], C5633_170=[$12])
>>   |   └─ 182:LogicalFilter(condition=[IS_NOT_NULL($85)])
>>   |  └─ 165:QueryTableScan(table=[[QUERY, T893]])
>>   └─ 197:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1)])
>>  └─ 195:LogicalProject(C5633_586=[$85], C5633_203=[$45])
>> └─ 193:LogicalFilter(condition=[IS_NOT_NULL($85)])
>>└─ 172:QueryTableScan(table=[[QUERY, T893]])
>> ```
>> 
>> Can be simplified to one join as something like:
>> ```
>> 201:LogicalProject(P4=[$lhs+1)], P5=[$lhs+2])
>> └─ 188:LogicalJoin(condition=[=($0, $70)], joinType=[left])
>>   ├─ 164:QueryTableScan(table=[[Query, T123]])
>>   └─ 186:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1), 
>> EXPR$0=[ARRAY_AGG($2)])
>>  └─ 184:LogicalProject(C5633_586=[$85], C5633_170=[$12], C5633_203=[$45])
>> └─ 182:LogicalFilter(condition=[IS_NOT_NULL($85)])
>>└─ 165:QueryTableScan(table=[[QUERY, T893]])
>> ```
>> 
>> 
>> I spent some time trying applying various CoreRules, but didn’t immediately 
>> see anything I wanted.
>> I figure that there exists some set of existing rules which when applied 
>> together would accomplish what we want here.
>> 
>> The joins arise from correlated subqueries, but are also synthetically 
>> generated, so it is not as simple as asking the user to manually do a single 
>> join.
>> 
>> Thanks!
>> -Ian Bertolacci



Re: What is difference between The UnifyRule and MaterializedViewRule?

2023-03-30 Thread LakeShen
Hi Chunwei,

Thank you very much for your answer.

Best,
LakeShen

Chunwei Lei  于2022年5月9日周一 14:22写道:

> Hi, LakeShen.
>
> You may find the answer in this doc[1].
>
> [1] https://calcite.apache.org/docs/materialized_views.html
>
>
> Best,
> Chunwei
>
>
> On Sat, May 7, 2022 at 9:17 AM LakeShen  wrote:
>
> > Hi community,
> >  I recently looked at the Calcite materialized view, there are two
> ways
> > to rewrite the sql query with MaterializedView : UnifyRule
> > and MaterializedViewRule.I have a question about the pros and cons of
> both
> > of them.Looking forward to your reply:)
> >
> > Best,
> > LakeShen
> >
>


Re: The question about the Apache Calcite 2.0's progress

2023-03-30 Thread LakeShen
Hi Stamatis,

Thank you very much for your answer,It really helped me.

Best,
LakeShen

Stamatis Zampetakis  于2023年3月30日周四 16:46写道:

> Hi LakeShen,
>
> The last discussion about this topic was back in 2021 [1].
>
> Apart from cleanup there is nothing major to be done as part of 2.0 so
> there is no big rush to get it out.
>
> Best,
> Stamatis
>
> [1] https://lists.apache.org/thread/p6svy4hps193g4knhsksv7psx0osgvq7
>
> On Wed, Mar 29, 2023 at 8:51 AM LakeShen 
> wrote:
> >
> > Hi community,
> >
> > Now I am reading the Calcite source code,and I find that there are a lot
> of
> > code comments  which are marked to be removed before 2.0.What is the
> status
> > of Apache Calcite 2.0?Where can I see Apache Calcite 2.0 progress?
> >
> > Best,
> > LakeShen.
>


[jira] [Created] (CALCITE-5626) Query with EXISTS function gives Table ... not found error

2023-03-30 Thread Roman Churganov (Jira)
Roman Churganov created CALCITE-5626:


 Summary: Query with EXISTS function gives Table ... not found error
 Key: CALCITE-5626
 URL: https://issues.apache.org/jira/browse/CALCITE-5626
 Project: Calcite
  Issue Type: Bug
  Components: core
Affects Versions: 1.30.0
Reporter: Roman Churganov


If query has some aggregate window function with a DISTINCT keyword and also 
WITHIN GROUP clause specified with ordering by some column other then grouped 
or grouping column, for example query like: 
{code:sql}
  SELECT C11, LISTAGG( DISTINCT C12) WITHIN GROUP ( ORDER BY C13 ) from FOO  
GROUP BY C11
{code}
will fail with exception:
{noformat}
java.lang.IllegalStateException: Unable to implement 
EnumerableAggregate(group=[{0}], EXPR$1=[LISTAGG($1) WITHIN GROUP ([2])]): 
rowcount = 1.0, cumulative cost = {112.125 rows, 102.0 cpu, 0.0 io}, id = 1800
  JdbcToEnumerableConverter: rowcount = 10.0, cumulative cost = {111.0 rows, 
102.0 cpu, 0.0 io}, id = 1798
JdbcAggregate(group=[{1, 2}]): rowcount = 10.0, cumulative cost = {110.0 
rows, 101.0 cpu, 0.0 io}, id = 1796
  JdbcTableScan(table=[[TESTSCHEMA, FOO]]): rowcount = 100.0, cumulative 
cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 1705


at 
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.implementRoot(EnumerableRelImplementor.java:114)
at 
org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:114)
at ru.roman.podd.test.UtilKt.runPlannerApiQuery(Util.kt:139)
at ru.roman.podd.test.UtilKt.runPlannerApiQuery$default(Util.kt:63)
at ru.roman.podd.test.JdbcSubQueryTest.should run 
LISTAGG(JdbcSubQueryTest.kt:144)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at 
org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at 
org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at 
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at 
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at 
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at 
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at 
org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at 
org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at 
org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at 
org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at 
org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at 
org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at 
org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at 
org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at 
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:205)
at 
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at 
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:201)
at 
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at 
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at 
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at 
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at 
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at 
org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at 
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at 

[jira] [Created] (CALCITE-5625) Expand SEARCH RexNode when converting toJson

2023-03-30 Thread Oliver Lee (Jira)
Oliver Lee created CALCITE-5625:
---

 Summary: Expand SEARCH RexNode when converting toJson 
 Key: CALCITE-5625
 URL: https://issues.apache.org/jira/browse/CALCITE-5625
 Project: Calcite
  Issue Type: Sub-task
Reporter: Oliver Lee


Because the Sarg class is not able to be serialized/deserialized to/from JSON, 
we would like to expand the SEARCH RexNode as a workaround. 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Created] (CALCITE-5624) Cannot parse array udf for Spark Dialect

2023-03-30 Thread Jira
Guillaume Massé created CALCITE-5624:


 Summary: Cannot parse array udf for Spark Dialect
 Key: CALCITE-5624
 URL: https://issues.apache.org/jira/browse/CALCITE-5624
 Project: Calcite
  Issue Type: Bug
  Components: core
Affects Versions: 1.34.0
Reporter: Guillaume Massé


AtomicRowExpression should not have ArrayConstructor for Apache spark. Arrays 
are constructed by a udf 
(https://spark.apache.org/docs/latest/api/sql/index.html#array).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


Re: Re: Rules to squash redundant join sides?

2023-03-30 Thread Ian Bertolacci
Stamatis,
Thanks! I’ll take a look at this.
Is it possible to avoid the creation of these kinds of joins correlated 
subqueries? Or does that still have the same issue as general joins?

Thanks!
-Ian

From: Stamatis Zampetakis 
Date: Thursday, March 30, 2023 at 1:41 AM
To: dev@calcite.apache.org 
Subject: [External Sender] Re: Rules to squash redundant join sides?
Hey Ian,

I think you are referring to the problem of query minimization and at
the moment we don't have any such rules in Calcite but it would be a
valuable contribution.
Apart from the algorithm itself, it might be necessary to introduce
some new metadata provider for PK-FK relationships otherwise dropping
a join may remove duplicates and change the semantics of the plan.

You can find some previous discussion here [1].

Best,
Stamatis

[1] 
https://urldefense.com/v3/__https://lists.apache.org/thread/vsq59yhfj4glf7mgpf9n6j255myhs0so__;!!Iz9xO38YGHZK!7_nW_9SgSRGAzlQa7TmPcod2_Xhqk41iPbC7Wzi-IoMCPhnEG1ZYGnknVSxbgOx-CLhOl2WSB_2MMTXI1BMG$

On Thu, Mar 30, 2023 at 1:27 AM Ian Bertolacci
 wrote:
>
> Howdy,
> Is there a collection of rules which squash a tree of binary joins if the 
> same side of each join is mergeable?
>
> For example:
> ```
> 201:LogicalProject(P4=[$70], P5=[$72])
> └─ 199:LogicalJoin(condition=[=($0, $71)], joinType=[left])
>├─ 190:LogicalProject(...)
>|  └─ 188:LogicalJoin(condition=[=($0, $70)], joinType=[left])
>| ├─ 164:QueryTableScan(table=[[Query, T123]])
>| └─ 186:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1)])
>|└─ 184:LogicalProject(C5633_586=[$85], C5633_170=[$12])
>|   └─ 182:LogicalFilter(condition=[IS_NOT_NULL($85)])
>|  └─ 165:QueryTableScan(table=[[QUERY, T893]])
>└─ 197:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1)])
>   └─ 195:LogicalProject(C5633_586=[$85], C5633_203=[$45])
>  └─ 193:LogicalFilter(condition=[IS_NOT_NULL($85)])
> └─ 172:QueryTableScan(table=[[QUERY, T893]])
> ```
>
> Can be simplified to one join as something like:
> ```
> 201:LogicalProject(P4=[$lhs+1)], P5=[$lhs+2])
> └─ 188:LogicalJoin(condition=[=($0, $70)], joinType=[left])
>├─ 164:QueryTableScan(table=[[Query, T123]])
>└─ 186:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1), 
> EXPR$0=[ARRAY_AGG($2)])
>   └─ 184:LogicalProject(C5633_586=[$85], C5633_170=[$12], C5633_203=[$45])
>  └─ 182:LogicalFilter(condition=[IS_NOT_NULL($85)])
> └─ 165:QueryTableScan(table=[[QUERY, T893]])
> ```
>
>
> I spent some time trying applying various CoreRules, but didn’t immediately 
> see anything I wanted.
> I figure that there exists some set of existing rules which when applied 
> together would accomplish what we want here.
>
> The joins arise from correlated subqueries, but are also synthetically 
> generated, so it is not as simple as asking the user to manually do a single 
> join.
>
> Thanks!
> -Ian Bertolacci


[jira] [Created] (CALCITE-5623) assert

2023-03-30 Thread Ran Tao (Jira)
Ran Tao created CALCITE-5623:


 Summary: assert
 Key: CALCITE-5623
 URL: https://issues.apache.org/jira/browse/CALCITE-5623
 Project: Calcite
  Issue Type: Bug
Reporter: Ran Tao
Assignee: Ran Tao






--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Created] (CALCITE-5622) Cast is lost from Plan to Postgres Statement

2023-03-30 Thread Corvin Kuebler (Jira)
Corvin Kuebler created CALCITE-5622:
---

 Summary: Cast is lost from Plan to Postgres Statement
 Key: CALCITE-5622
 URL: https://issues.apache.org/jira/browse/CALCITE-5622
 Project: Calcite
  Issue Type: Bug
  Components: jdbc-adapter
Affects Versions: 1.34.0
Reporter: Corvin Kuebler


Hey,

I found an issue with translation from plan to postgres sql statement.

Adding the following Test to `JdbcAdapterTests.java` exposes the bug:


{code:java}
@Test void testDateCastPlan() {
final String sql = "SELECT CAST(T1.\"brand_name\" AS DATE)\n"
+ "FROM \"foodmart\".\"product\" AS T1\n"
+ "WHERE CAST(T1.\"brand_name\" AS DATE) = CAST('2023-03-27' AS DATE)";
CalciteAssert.model(FoodmartSchema.FOODMART_MODEL)
.query(sql)
.explainContains("PLAN=JdbcToEnumerableConverter\n" +
" JdbcProject(EXPR$0=[CAST($2):DATE])\n" +
" JdbcFilter(condition=[=(CAST($2):DATE, 2023-03-27)])\n" +
" JdbcTableScan(table=[[foodmart, product]])\n\n")
.runs()
.enable(CalciteAssert.DB == DatabaseInstance.POSTGRESQL)
.planHasSql("SELECT CAST(\"brand_name\" AS DATE)\n" +
"FROM \"foodmart\".\"product\"\n" +
"CAST(\"brand_name\" AS DATE)= DATE '2023-03-27'");
}{code}
 
The plan contains the cast of the column to DATE type. The resulting SQL 
Statement however does not contain the cast. 
The test fails in run, as the column I'm trying to cast does not contain date 
values but the sql that is being sent to postgres is already wrong.
 
I'd be happy if you could take a look at it.
 
Best regards,
Corvin
 
 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


Re: CI requiring approval for external contributors

2023-03-30 Thread Stamatis Zampetakis
It's true that I've never seen a fake PR so far in the ASF repos but
at the same time I am not following every single PR.
I can understand the approval for first time contributors but keeping
the approval for everyone seems a bit too much.

Best,
Stamatis

On Wed, Mar 29, 2023 at 5:04 AM 王鹏  wrote:
>
> +1 for this. I think it's very friendly to create PR for contributors.
>
> Dan Zou  于2023年3月29日周三 10:13写道:
>
> > +1 for this, it is something out of my expectation when I created my first
> > PR in calcite and informed that approval is required.
> >
> > Best,
> > Dan Zou
> >
> >
> >
> >
> >
> > > 2023年3月28日 21:37,Benchao Li  写道:
> > >
> > > I'm +1 for changing it back.
> > >
> > > I was also thinking about starting a discussion about this before, but I
> > > didn't know how to achieve it. Thanks Julian for sharing this with us.
> > >
> > > Julian Hyde  于2023年3月28日周二 20:57写道:
> > >
> > >> (Forwarding from the Druid list for discussion.)
> > >>
> > >> Julian
> > >>
> > >> Begin forwarded message:
> > >>
> > >>> From: Gian Merlino 
> > >>> Date: March 28, 2023 at 1:24:42 AM CDT
> > >>> To: d...@druid.apache.org
> > >>> Subject: CI requiring approval for external contributors
> > >>> Reply-To: d...@druid.apache.org
> > >>>
> > >>> Recently, ASF GitHub repos had their defaults for GitHub Actions
> > >> changed to
> > >>> "always require approval for external contributors". In Slack, Karan
> > >>> pointed out that Airflow has recently submitted a ticket to have that
> > >>> changed back: https://issues.apache.org/jira/browse/INFRA-24200. IMO,
> > we
> > >>> should do the same. I don't think we have a problem with fake PRs, but
> > we
> > >>> can always improve our responsiveness to contributors from outside the
> > >>> project! Every little bit helps, including running CI automatically.
> > >>>
> > >>> If others have opinions on this, let me know. I'd like to raise our own
> > >>> ticket to change our default.
> > >>>
> > >>> Gian
> > >>
> > >
> > >
> > > --
> > >
> > > Best,
> > > Benchao Li
> >
> >


Re: The question about the Apache Calcite 2.0's progress

2023-03-30 Thread Stamatis Zampetakis
Hi LakeShen,

The last discussion about this topic was back in 2021 [1].

Apart from cleanup there is nothing major to be done as part of 2.0 so
there is no big rush to get it out.

Best,
Stamatis

[1] https://lists.apache.org/thread/p6svy4hps193g4knhsksv7psx0osgvq7

On Wed, Mar 29, 2023 at 8:51 AM LakeShen  wrote:
>
> Hi community,
>
> Now I am reading the Calcite source code,and I find that there are a lot of
> code comments  which are marked to be removed before 2.0.What is the status
> of Apache Calcite 2.0?Where can I see Apache Calcite 2.0 progress?
>
> Best,
> LakeShen.


Re: Rules to squash redundant join sides?

2023-03-30 Thread Stamatis Zampetakis
Hey Ian,

I think you are referring to the problem of query minimization and at
the moment we don't have any such rules in Calcite but it would be a
valuable contribution.
Apart from the algorithm itself, it might be necessary to introduce
some new metadata provider for PK-FK relationships otherwise dropping
a join may remove duplicates and change the semantics of the plan.

You can find some previous discussion here [1].

Best,
Stamatis

[1] https://lists.apache.org/thread/vsq59yhfj4glf7mgpf9n6j255myhs0so

On Thu, Mar 30, 2023 at 1:27 AM Ian Bertolacci
 wrote:
>
> Howdy,
> Is there a collection of rules which squash a tree of binary joins if the 
> same side of each join is mergeable?
>
> For example:
> ```
> 201:LogicalProject(P4=[$70], P5=[$72])
> └─ 199:LogicalJoin(condition=[=($0, $71)], joinType=[left])
>├─ 190:LogicalProject(...)
>|  └─ 188:LogicalJoin(condition=[=($0, $70)], joinType=[left])
>| ├─ 164:QueryTableScan(table=[[Query, T123]])
>| └─ 186:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1)])
>|└─ 184:LogicalProject(C5633_586=[$85], C5633_170=[$12])
>|   └─ 182:LogicalFilter(condition=[IS_NOT_NULL($85)])
>|  └─ 165:QueryTableScan(table=[[QUERY, T893]])
>└─ 197:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1)])
>   └─ 195:LogicalProject(C5633_586=[$85], C5633_203=[$45])
>  └─ 193:LogicalFilter(condition=[IS_NOT_NULL($85)])
> └─ 172:QueryTableScan(table=[[QUERY, T893]])
> ```
>
> Can be simplified to one join as something like:
> ```
> 201:LogicalProject(P4=[$lhs+1)], P5=[$lhs+2])
> └─ 188:LogicalJoin(condition=[=($0, $70)], joinType=[left])
>├─ 164:QueryTableScan(table=[[Query, T123]])
>└─ 186:LogicalAggregate(group=[{0}], EXPR$0=[ARRAY_AGG($1), 
> EXPR$0=[ARRAY_AGG($2)])
>   └─ 184:LogicalProject(C5633_586=[$85], C5633_170=[$12], C5633_203=[$45])
>  └─ 182:LogicalFilter(condition=[IS_NOT_NULL($85)])
> └─ 165:QueryTableScan(table=[[QUERY, T893]])
> ```
>
>
> I spent some time trying applying various CoreRules, but didn’t immediately 
> see anything I wanted.
> I figure that there exists some set of existing rules which when applied 
> together would accomplish what we want here.
>
> The joins arise from correlated subqueries, but are also synthetically 
> generated, so it is not as simple as asking the user to manually do a single 
> join.
>
> Thanks!
> -Ian Bertolacci