Re: 回复:cannot be cast to class org.apache.calcite.runtime.FlatLists$ComparableList error

2022-02-12 Thread Ruben Q L
Hello,

per ReflectiveSchema javadoc [1]:
"Implementation of {@link org.apache.calcite.schema.Schema} that exposes
the public fields and methods in a Java object."

[1]
https://github.com/apache/calcite/blob/812e3e98eae518cf85cd1b6b7f055fb96784a423/core/src/main/java/org/apache/calcite/adapter/java/ReflectiveSchema.java#L71


On Sat, Feb 12, 2022 at 1:54 AM xiaobo  wrote:

> Sorry for the HTML escape characters, I rewrite the problem as following:
>
>  SQL select count(a.PA01AI01) from p.PRH_PA01 as a
> failed with :
> Caused by: java.sql.SQLException: Error while executing SQL "select
> count(a.PA01AI01) from p.PRH_PA01 as a
> ": From line 1, column 16 to line 1, column 23: Column 'PA01AI01' not
> found in table 'a'
>
> to resolve the problem we must make the table fields of the target Java
> class as public, is this a rule for ReflectiveSchema?


Re: calcite multi-threading problem

2022-02-12 Thread xiaobo
we checked the janino release note page
http://janino-compiler.github.io/janino/changelog.html

Fixed issue #141: Unable to find org.codehaus.commons.compiler.properties in 
java 11: ICompilerFactories were loaded through the current thread's "context 
class loader", which is a bad choice in some environments. Thus, the methods 
"getDefaultCompilerFactory()", "getAllCompilerFactories()" and 
"getCompilerFactory(className)" were duplicated and augmented with a 
"classLoader" parameter. 

what does this mean?  the getDefaultCompilerFactory method with a classloader 
parameter was removed intentionally?
but it seems calcite still needs it , so what version of janino should we use 
for the latest calcite-core?





-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 12:01 PM
To: "dev"; 

Subject:  Re:calcite multi-threading problem



In our use case, the Java class which opens calcite connection is contained in 
a external Java jar file, which is loaded dynamicly through classloaders other 
than the default systemloader like this:


try {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { new URL("jar:file:" + path + "!/") },
getClass().getClassLoader());
Class clazz = Class.forName(classPath, true, loader);

we mention this because the error message shows a classloader parameter.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 11:56 AM
To: "dev"; 

Subject:  Re:   calcite multi-threading problem



And if we remove calcite from our project,  janino is not in "resolved 
depencies" library list of pom.xml,
So we think it not the janino conflic problem.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 9:49 AM
To: "dev"; 

Subject:  Re:  calcite multi-threading problem



can you share the solution for the problem, we are using the following 
libraries, and it seems janino 3.1.6  is only dependent by calcite-core.


  UTF-8
  UTF-8
  9
  9
  9
2.17.1
7.64.0.Final
   

org.apache.calcite
calcite-core
1.29.0


org.apache.calcite.avatica
avatica-core
1.20.0




org.drools
drools-core
${drools.version}


org.drools
drools-compiler
${drools.version}


org.drools
drools-decisiontables
${drools.version}



-- Original --
From:  "xiong duan";;
Send time: Saturday, Feb 12, 2022 8:43 AM
To: "dev"; 

Subject:  Re: calcite multi-threading problem



Yes, It is a dependency issue. I have met the same problem. +1 for Dmitry.

Dmitry Sysolyatin  于2022年2月11日周五 21:18写道:

> Actually, I had the same problem with spark. Spark 3.2.1 uses the old
> version of janino, calcite 1.29 uses the new version of janino and they are
> not compatible.
> If I downgrade janino version to version which spark uses I got an error
> not method found exception
> If I upgrade the janino version to the version which calcite uses I get the
> same error but with another method.
>
> As a result, I built a separate calcite jar package where I shaded janino
> dependency
>
>
>
> On Fri, Feb 11, 2022 at 2:39 PM stanilovsky evgeny <
> estanilovs...@gridgain.com> wrote:
>
> > for example on a current calcite branch:
> > grep janino gradle.properties
> > janino.version=3.1.6
> >
> >
> > > yes, we use drools in the same project,  and drools uses janino
> > > too, is there a version list of janino which calcite supports?
> > >
> > >
> > >
> > >
> > > ---Original---
> > > From: "Dmitry Sysolyatin" > > Date: Fri, Feb 11, 2022 18:30 PM
> > > To: "dev" > > Subject: Re: calcite multi-threading problem
> > >
> > >
> > > Hi!
> > >
> >
> It looks like a dependency issue, not like a multi-threading issue. Most
> > >
> >
> likely you have some dependency that use another version of janino but
> > > calcite requires another one
> > >
> > >
> >
> On Fri, Feb 11, 2022 at 12:18 PM xiaobo  > > wrote:
> > >
> > > > Hi,
> > > >
> > > >
> > >
> >
> > we open a calcite connection with ReflectiveSchema in one thread, and
> > >
> >
> > execute sqls in other  threads against the connection, but failed with
> > > > this error
> > > >
> > > >
> > > >
> > > >
> > > > com.google.common.util.concurrent.ExecutionError:
> > > > java.lang.NoSuchMethodError:
> > > >
> > >
> >
> > org.codehaus.commons.compiler.CompilerFactoryFactory.getDefaultCompilerFactory(Ljava/lang/ClassLoader;)
> > > >
> > > > Lorg/codehaus/commons/compiler/ICompilerFactory;
> > > >
> > > >
> > >
> >
> > do we miss anything regarding to multi-threading with calcite?
> >
>

Re: calcite multi-threading problem

2022-02-12 Thread xiaobo
but strange enough, the same code works in a single thread.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 8:02 PM
To: "dev"; 

Subject:  Re: calcite multi-threading problem



we checked the janino release note page
http://janino-compiler.github.io/janino/changelog.html

Fixed issue #141: Unable to find org.codehaus.commons.compiler.properties in 
java 11: ICompilerFactories were loaded through the current thread's "context 
class loader", which is a bad choice in some environments. Thus, the methods 
"getDefaultCompilerFactory()", "getAllCompilerFactories()" and 
"getCompilerFactory(className)" were duplicated and augmented with a 
"classLoader" parameter. 

what does this mean?  the getDefaultCompilerFactory method with a classloader 
parameter was removed intentionally?
but it seems calcite still needs it , so what version of janino should we use 
for the latest calcite-core?





-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 12:01 PM
To: "dev"; 

Subject:  Re:calcite multi-threading problem



In our use case, the Java class which opens calcite connection is contained in 
a external Java jar file, which is loaded dynamicly through classloaders other 
than the default systemloader like this:


try {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { new URL("jar:file:" + path + "!/") },
getClass().getClassLoader());
Class clazz = Class.forName(classPath, true, loader);

we mention this because the error message shows a classloader parameter.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 11:56 AM
To: "dev"; 

Subject:  Re:   calcite multi-threading problem



And if we remove calcite from our project,  janino is not in "resolved 
depencies" library list of pom.xml,
So we think it not the janino conflic problem.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 9:49 AM
To: "dev"; 

Subject:  Re:  calcite multi-threading problem



can you share the solution for the problem, we are using the following 
libraries, and it seems janino 3.1.6  is only dependent by calcite-core.


  UTF-8
  UTF-8
  9
  9
  9
2.17.1
7.64.0.Final
   

org.apache.calcite
calcite-core
1.29.0


org.apache.calcite.avatica
avatica-core
1.20.0




org.drools
drools-core
${drools.version}


org.drools
drools-compiler
${drools.version}


org.drools
drools-decisiontables
${drools.version}



-- Original --
From:  "xiong duan";;
Send time: Saturday, Feb 12, 2022 8:43 AM
To: "dev"; 

Subject:  Re: calcite multi-threading problem



Yes, It is a dependency issue. I have met the same problem. +1 for Dmitry.

Dmitry Sysolyatin  于2022年2月11日周五 21:18写道:

> Actually, I had the same problem with spark. Spark 3.2.1 uses the old
> version of janino, calcite 1.29 uses the new version of janino and they are
> not compatible.
> If I downgrade janino version to version which spark uses I got an error
> not method found exception
> If I upgrade the janino version to the version which calcite uses I get the
> same error but with another method.
>
> As a result, I built a separate calcite jar package where I shaded janino
> dependency
>
>
>
> On Fri, Feb 11, 2022 at 2:39 PM stanilovsky evgeny <
> estanilovs...@gridgain.com> wrote:
>
> > for example on a current calcite branch:
> > grep janino gradle.properties
> > janino.version=3.1.6
> >
> >
> > > yes, we use drools in the same project,  and drools uses janino
> > > too, is there a version list of janino which calcite supports?
> > >
> > >
> > >
> > >
> > > ---Original---
> > > From: "Dmitry Sysolyatin" > > Date: Fri, Feb 11, 2022 18:30 PM
> > > To: "dev" > > Subject: Re: calcite multi-threading problem
> > >
> > >
> > > Hi!
> > >
> >
> It looks like a dependency issue, not like a multi-threading issue. Most
> > >
> >
> likely you have some dependency that use another version of janino but
> > > calcite requires another one
> > >
> > >
> >
> On Fri, Feb 11, 2022 at 12:18 PM xiaobo  > > wrote:
> > >
> > > > Hi,
> > > >
> > > >
> > >
> >
> > we open a calcite connection with ReflectiveSchema in one thread, and
> > >
> >
> > execute sqls in other  threads against the connection, but failed with
> > > > this error
> > > >
> > > >
> > > >
> > > >
> > > > com.google.common.util.concurrent.ExecutionError:
> > > > java.lang.NoSuchMethodError:
> > > >
> > >
> >
> > org.codehaus.commons.compiler.CompilerFactoryFactory.getDefaultCompilerFactory(Ljava/lang/ClassLoader;)
> > > >
> > > > Lorg/codeh

Re: calcite multi-threading problem

2022-02-12 Thread xiaobo
3.1.4 of janino and commons-compiler works now.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 8:04 PM
To: "dev"; 

Subject:  Re:  calcite multi-threading problem



but strange enough, the same code works in a single thread.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 8:02 PM
To: "dev"; 

Subject:  Re: calcite multi-threading problem



we checked the janino release note page
http://janino-compiler.github.io/janino/changelog.html

Fixed issue #141: Unable to find org.codehaus.commons.compiler.properties in 
java 11: ICompilerFactories were loaded through the current thread's "context 
class loader", which is a bad choice in some environments. Thus, the methods 
"getDefaultCompilerFactory()", "getAllCompilerFactories()" and 
"getCompilerFactory(className)" were duplicated and augmented with a 
"classLoader" parameter. 

what does this mean?  the getDefaultCompilerFactory method with a classloader 
parameter was removed intentionally?
but it seems calcite still needs it , so what version of janino should we use 
for the latest calcite-core?





-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 12:01 PM
To: "dev"; 

Subject:  Re:calcite multi-threading problem



In our use case, the Java class which opens calcite connection is contained in 
a external Java jar file, which is loaded dynamicly through classloaders other 
than the default systemloader like this:


try {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { new URL("jar:file:" + path + "!/") },
getClass().getClassLoader());
Class clazz = Class.forName(classPath, true, loader);

we mention this because the error message shows a classloader parameter.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 11:56 AM
To: "dev"; 

Subject:  Re:   calcite multi-threading problem



And if we remove calcite from our project,  janino is not in "resolved 
depencies" library list of pom.xml,
So we think it not the janino conflic problem.




-- Original --
From:  "xiaobo ";;
Send time: Saturday, Feb 12, 2022 9:49 AM
To: "dev"; 

Subject:  Re:  calcite multi-threading problem



can you share the solution for the problem, we are using the following 
libraries, and it seems janino 3.1.6  is only dependent by calcite-core.


  UTF-8
  UTF-8
  9
  9
  9
2.17.1
7.64.0.Final
   

org.apache.calcite
calcite-core
1.29.0


org.apache.calcite.avatica
avatica-core
1.20.0




org.drools
drools-core
${drools.version}


org.drools
drools-compiler
${drools.version}


org.drools
drools-decisiontables
${drools.version}



-- Original --
From:  "xiong duan";;
Send time: Saturday, Feb 12, 2022 8:43 AM
To: "dev"; 

Subject:  Re: calcite multi-threading problem



Yes, It is a dependency issue. I have met the same problem. +1 for Dmitry.

Dmitry Sysolyatin  于2022年2月11日周五 21:18写道:

> Actually, I had the same problem with spark. Spark 3.2.1 uses the old
> version of janino, calcite 1.29 uses the new version of janino and they are
> not compatible.
> If I downgrade janino version to version which spark uses I got an error
> not method found exception
> If I upgrade the janino version to the version which calcite uses I get the
> same error but with another method.
>
> As a result, I built a separate calcite jar package where I shaded janino
> dependency
>
>
>
> On Fri, Feb 11, 2022 at 2:39 PM stanilovsky evgeny <
> estanilovs...@gridgain.com> wrote:
>
> > for example on a current calcite branch:
> > grep janino gradle.properties
> > janino.version=3.1.6
> >
> >
> > > yes, we use drools in the same project,  and drools uses janino
> > > too, is there a version list of janino which calcite supports?
> > >
> > >
> > >
> > >
> > > ---Original---
> > > From: "Dmitry Sysolyatin" > > Date: Fri, Feb 11, 2022 18:30 PM
> > > To: "dev" > > Subject: Re: calcite multi-threading problem
> > >
> > >
> > > Hi!
> > >
> >
> It looks like a dependency issue, not like a multi-threading issue. Most
> > >
> >
> likely you have some dependency that use another version of janino but
> > > calcite requires another one
> > >
> > >
> >
> On Fri, Feb 11, 2022 at 12:18 PM xiaobo  > > wrote:
> > >
> > > > Hi,
> > > >
> > > >
> > >
> >
> > we open a calcite connection with ReflectiveSchema in one thread, and
> > >
> >
> > execute sqls in other  threads against the connection, but failed with
> > > > this error
> > > >
> > > >
> > > >
> > > >
> > > > com.google.c

Re: can we set a default schema for calcite connection to avoid writing schema names in sql

2022-02-12 Thread Gavin Ray
Hey Xiabo,

You can do this, however it is easiest to do from the "FrameworkConfig"
object, like this:

import org.apache.calcite.tools.FrameworkConfig
// Need to set case-sensitive to false, or else it tries to
// look up capitalized table names and fails
//
// IE: "EMPS" instead of "emps"
val frameworkConfig: FrameworkConfig = Frameworks.newConfigBuilder()
.defaultSchema(connection.rootSchema)
.parserConfig(SqlParser.config().withCaseSensitive(false))
.build()

Hope this helps =)

On Fri, Feb 11, 2022 at 9:09 PM xiaobo  wrote:

> sorry for the html escape characters,
> we tried the following and it does not work
>
> Class.forName("org.apache.calcite.jdbc.Driver");
> Properties info = new Properties();
> info.setProperty("lex", "JAVA");
> info.setProperty(InternalProperty.CASE_SENSITIVE.name(),
> "false");
> info.setProperty("defaultSchema", "hr");
> Connection connection =
> DriverManager.getConnection("jdbc:calcite:", info);
> CalciteConnection conn =
> connection.unwrap(CalciteConnection.class);
> SchemaPlus rootSchema = conn.getRootSchema();
> Schema schema = new ReflectiveSchema(target);
> rootSchema.add(schemaName, schema);
> return conn;
>
>
>
>
> -- Original --
> From:  "xiaobo ";;
> Send time: Friday, Feb 11, 2022 11:20 PM
> To: "dev";
>
> Subject:  can we set a default schema for calcite connection to avoid
> writing schema names in sql
>
>
>
> we have tried the following and it does not work
>
>
> Class.forName("org.apache.calcite.jdbc.Driver");
>         Properties info =
> new Properties();
>        
> info.setProperty("lex", "JAVA");
>        
> info.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(),
> "false");
>        
> info.setProperty("defaultSchema", "hr");
>         try {
>        
>     Connection connection =
>        
>        
> DriverManager.getConnection("jdbc:calcite:", info);
>        
>     CalciteConnection conn =
>        
>        
> connection.unwrap(CalciteConnection.class);
>        
>     SchemaPlus rootSchema = conn.getRootSchema();
>     


Re: Why are nested aggregations illegal? Best alternatives?

2022-02-12 Thread Gavin Ray
Apologies for the delay in replying

This makes things clear and seems obvious now that you point it out.
Thank you, Justin and Julian =)

Let me ask another question (if I may) that I am struggling to phrase
easily.

So with GraphQL, you might have a query like:
- "Get houses"
- "For each house get the user that lives in the house
- "And for each user get their list of todos"

The result has to come back such that it's a single object for each row
==
{
  houses: [{
address: "123 Main Street",
users: [{
  name: "Joe",
  todos: [{
description: "Take out trash"
  }]
}]
}

>From a SQL perspective, the logical equivalent would be something like:
==
SELECT
house.address,
(somehow nest users + double-nest todos under user)
FROM
house
JOIN
user ON user.house_id = house.id
todos ON todos.user_id = user.id
WHERE
house.id = 1

I'm not familiar enough with SQL to have figured out a way to make this
kind of
query using operators that are supported across most of the DB's Calcite has
adapters for.

Currently what I have done instead, on a tip from Gopalakrishna Holla from
LinkedIn Coral team who has built GraphQL-on-Calcite, was to break up the
query
into individual parts and then do the join in-memory:

SELECT ... FROM users;
SELECT ... FROM todos WHERE todos.user_id IN (ResultSet from prev response);

However, the way I am doing this seems like it's probably very inefficient.
Because I do a series of nested loops to add the key to each object in the
parent ResultSet row:

https://github.com/GavinRay97/GraphQLCalcite/blob/648e0ac4f6810a3c360d13a03e6597c33406de4b/src/main/kotlin/TableDataFetcher.kt#L135-L153

Is there some better way of doing this?
I would be eternally grateful for any advice.


On Thu, Feb 10, 2022 at 3:27 PM Julian Hyde  wrote:

> Yes, if you want to do multiple layers of aggregation, use CTEs (WITH) or
> nested sub-queries. For example, the following is I believe valid standard
> SQL, and actually computes something useful:
>
>   WITH q1 AS
>(SELECT deptno, job, AVG(sal) AS avg_sal
> FROM emp
> GROUP BY deptno, job)
>   WITH q2 AS
>(SELECT deptno, AVG(avg_sal) AS avg_avg_sal
> FROM q1
> GROUP BY deptno)
>   SELECT AVG(avg_avg_sal)
>   FROM q2
>   GROUP BY ()
>
> (You can omit the “GROUP BY ()” line, but I think it makes things clearer.)
>
> Julian
>
>
>
> > On Feb 10, 2022, at 12:17 PM, Justin Swanhart 
> wrote:
> >
> > I wish you could unsend emails :)  Answering my own question, no, because
> > that would return three rows with the average :D
> >
> > On Thu, Feb 10, 2022 at 3:16 PM Justin Swanhart 
> wrote:
> >
> >> Just out of curiosity, is the second level aggregation using AVG in a
> >> window context?  It the frame is the whole table and it aggregates over
> it?
> >>
> >> On Thu, Feb 10, 2022 at 3:12 PM Justin Swanhart 
> >> wrote:
> >>
> >>> That is really neat about Oracle.
> >>>
> >>> The alternative in general is to use a subquery:
> >>> SELECT avg(avg(sal)) FROM emp GROUP BY deptno;
> >>> becomes
> >>> select avg(the_avg)
> >>> from (select avg(sal) from emp group b deptno) an_alias;
> >>>
> >>> or
> >>>
> >>> with the_cte as (select avg(sal) x from emp group by deptno)
> >>> select avg(x) from the_cte;
> >>>
> >>> On Thu, Feb 10, 2022 at 3:03 PM Julian Hyde 
> >>> wrote:
> >>>
>  Some databases, e.g. Oracle, allow TWO levels of nesting:
> 
>  SELECT avg(sal) FROM emp GROUP BY deptno;
> 
>  AVG(SAL)
>  
>  1,566.67
>  2,175.00
>  2,916.65
> 
>  SELECT avg(avg(sal)) FROM emp GROUP BY deptno;
> 
>  AVG(SUM(SAL))
>  =
> 9,675
> 
>  The first level aggregates by department (returning 3 records), and
> the
>  second level computes the grand total (returning 1 record). But that
> is an
>  exceptional case.
> 
>  Generally, any expression in the SELECT or HAVING clause of an
> aggregate
>  query is either ‘before’ or ‘after’ aggregation. Consider
> 
>   SELECT t.x + 1 AS a, 2 + SUM(t.y + 3) AS b
>   FROM t
>   GROUP BY t.x
> 
>  The expressions “t.y” and “t.y + 3” occur before aggregation; “t.x”,
>  “t.x + 1”, “SUM(t.y + 3)” and “2 + SUM(t.y + 3)” occur after
> aggregation.
>  SQL semantics rely heavily on this stratification. Allowing an extra
> level
>  of aggregation would mess it all up.
> 
>  Julian
> 
> 
> 
> > On Feb 10, 2022, at 9:45 AM, Justin Swanhart 
>  wrote:
> >
> > This is a SQL limitation.
> >
> > mysql> select sum(1);
> > ++
> > | sum(1) |
> > ++
> > |  1 |
> > ++
> > 1 row in set (0.00 sec)
> >
> > mysql> select sum(sum(1));
> > ERROR  (HY000): Invalid use of group function
> >
> > On Thu, Feb 10, 2022 at 12:39 PM Gavin Ray 
>  wrote:
> >
> >> Went to test this query out and found that it can't be

Re: Why are nested aggregations illegal? Best alternatives?

2022-02-12 Thread Julian Hyde
Correlated ARRAY sub-query?

> On Feb 12, 2022, at 10:40 AM, Gavin Ray  wrote:
> 
> Apologies for the delay in replying
> 
> This makes things clear and seems obvious now that you point it out.
> Thank you, Justin and Julian =)
> 
> Let me ask another question (if I may) that I am struggling to phrase
> easily.
> 
> So with GraphQL, you might have a query like:
> - "Get houses"
> - "For each house get the user that lives in the house
> - "And for each user get their list of todos"
> 
> The result has to come back such that it's a single object for each row
> ==
> {
>  houses: [{
>address: "123 Main Street",
>users: [{
>  name: "Joe",
>  todos: [{
>description: "Take out trash"
>  }]
>}]
> }
> 
> From a SQL perspective, the logical equivalent would be something like:
> ==
> SELECT
>house.address,
>(somehow nest users + double-nest todos under user)
> FROM
>house
> JOIN
>user ON user.house_id = house.id
>todos ON todos.user_id = user.id
> WHERE
>house.id = 1
> 
> I'm not familiar enough with SQL to have figured out a way to make this
> kind of
> query using operators that are supported across most of the DB's Calcite has
> adapters for.
> 
> Currently what I have done instead, on a tip from Gopalakrishna Holla from
> LinkedIn Coral team who has built GraphQL-on-Calcite, was to break up the
> query
> into individual parts and then do the join in-memory:
> 
> SELECT ... FROM users;
> SELECT ... FROM todos WHERE todos.user_id IN (ResultSet from prev response);
> 
> However, the way I am doing this seems like it's probably very inefficient.
> Because I do a series of nested loops to add the key to each object in the
> parent ResultSet row:
> 
> https://github.com/GavinRay97/GraphQLCalcite/blob/648e0ac4f6810a3c360d13a03e6597c33406de4b/src/main/kotlin/TableDataFetcher.kt#L135-L153
> 
> Is there some better way of doing this?
> I would be eternally grateful for any advice.
> 
> 
> On Thu, Feb 10, 2022 at 3:27 PM Julian Hyde  wrote:
> 
>> Yes, if you want to do multiple layers of aggregation, use CTEs (WITH) or
>> nested sub-queries. For example, the following is I believe valid standard
>> SQL, and actually computes something useful:
>> 
>>  WITH q1 AS
>>   (SELECT deptno, job, AVG(sal) AS avg_sal
>>FROM emp
>>GROUP BY deptno, job)
>>  WITH q2 AS
>>   (SELECT deptno, AVG(avg_sal) AS avg_avg_sal
>>FROM q1
>>GROUP BY deptno)
>>  SELECT AVG(avg_avg_sal)
>>  FROM q2
>>  GROUP BY ()
>> 
>> (You can omit the “GROUP BY ()” line, but I think it makes things clearer.)
>> 
>> Julian
>> 
>> 
>> 
>>> On Feb 10, 2022, at 12:17 PM, Justin Swanhart 
>> wrote:
>>> 
>>> I wish you could unsend emails :)  Answering my own question, no, because
>>> that would return three rows with the average :D
>>> 
>>> On Thu, Feb 10, 2022 at 3:16 PM Justin Swanhart 
>> wrote:
>>> 
 Just out of curiosity, is the second level aggregation using AVG in a
 window context?  It the frame is the whole table and it aggregates over
>> it?
 
 On Thu, Feb 10, 2022 at 3:12 PM Justin Swanhart 
 wrote:
 
> That is really neat about Oracle.
> 
> The alternative in general is to use a subquery:
> SELECT avg(avg(sal)) FROM emp GROUP BY deptno;
> becomes
> select avg(the_avg)
> from (select avg(sal) from emp group b deptno) an_alias;
> 
> or
> 
> with the_cte as (select avg(sal) x from emp group by deptno)
> select avg(x) from the_cte;
> 
> On Thu, Feb 10, 2022 at 3:03 PM Julian Hyde 
> wrote:
> 
>> Some databases, e.g. Oracle, allow TWO levels of nesting:
>> 
>> SELECT avg(sal) FROM emp GROUP BY deptno;
>> 
>> AVG(SAL)
>> 
>> 1,566.67
>> 2,175.00
>> 2,916.65
>> 
>> SELECT avg(avg(sal)) FROM emp GROUP BY deptno;
>> 
>> AVG(SUM(SAL))
>> =
>>   9,675
>> 
>> The first level aggregates by department (returning 3 records), and
>> the
>> second level computes the grand total (returning 1 record). But that
>> is an
>> exceptional case.
>> 
>> Generally, any expression in the SELECT or HAVING clause of an
>> aggregate
>> query is either ‘before’ or ‘after’ aggregation. Consider
>> 
>> SELECT t.x + 1 AS a, 2 + SUM(t.y + 3) AS b
>> FROM t
>> GROUP BY t.x
>> 
>> The expressions “t.y” and “t.y + 3” occur before aggregation; “t.x”,
>> “t.x + 1”, “SUM(t.y + 3)” and “2 + SUM(t.y + 3)” occur after
>> aggregation.
>> SQL semantics rely heavily on this stratification. Allowing an extra
>> level
>> of aggregation would mess it all up.
>> 
>> Julian
>> 
>> 
>> 
>>> On Feb 10, 2022, at 9:45 AM, Justin Swanhart 
>> wrote:
>>> 
>>> This is a SQL limitation.
>>> 
>>> mysql> select sum(1);
>>> ++
>>> | sum(1) |
>>> ++
>>> |  1 |
>>> ++
>>> 1 row in set (0.00 sec)
>>

Re: Why are nested aggregations illegal? Best alternatives?

2022-02-12 Thread Gavin Ray
Forgive my ignorance/lack of experience

I am somewhat familiar with the ARRAY() function, but not sure I know the
term "correlated"
Searching the Calcite codebase for uses of "correlated" + "query", I found:

https://github.com/apache/calcite/blob/1d4f1b394bfdba03c5538017e12ab2431b137ca9/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java#L1603-L1612

  @Test void testCorrelatedSubQueryInJoin() {
final String sql = "select *\n"
+ "from emp as e\n"
+ "join dept as d using (deptno)\n"
+ "where d.name = (\n"
+ "  select max(name)\n"
+ "  from dept as d2\n"
+ "  where d2.deptno = d.deptno)";
sql(sql).withExpand(false).ok();
  }

But I also see this, which says it is "uncorrelated" but seems very similar?

  @Test void testInUncorrelatedSubQuery() {
final String sql = "select empno from emp where deptno in"
+ " (select deptno from dept)";
sql(sql).ok();
  }

I wouldn't blame you for not answering such a basic question -- but what
exactly does "correlation" mean here?

Thanks, as usual Julian


On Sat, Feb 12, 2022 at 3:08 PM Julian Hyde  wrote:

> Correlated ARRAY sub-query?
>
> > On Feb 12, 2022, at 10:40 AM, Gavin Ray  wrote:
> >
> > Apologies for the delay in replying
> >
> > This makes things clear and seems obvious now that you point it out.
> > Thank you, Justin and Julian =)
> >
> > Let me ask another question (if I may) that I am struggling to phrase
> > easily.
> >
> > So with GraphQL, you might have a query like:
> > - "Get houses"
> > - "For each house get the user that lives in the house
> > - "And for each user get their list of todos"
> >
> > The result has to come back such that it's a single object for each row
> > ==
> > {
> >  houses: [{
> >address: "123 Main Street",
> >users: [{
> >  name: "Joe",
> >  todos: [{
> >description: "Take out trash"
> >  }]
> >}]
> > }
> >
> > From a SQL perspective, the logical equivalent would be something like:
> > ==
> > SELECT
> >house.address,
> >(somehow nest users + double-nest todos under user)
> > FROM
> >house
> > JOIN
> >user ON user.house_id = house.id
> >todos ON todos.user_id = user.id
> > WHERE
> >house.id = 1
> >
> > I'm not familiar enough with SQL to have figured out a way to make this
> > kind of
> > query using operators that are supported across most of the DB's Calcite
> has
> > adapters for.
> >
> > Currently what I have done instead, on a tip from Gopalakrishna Holla
> from
> > LinkedIn Coral team who has built GraphQL-on-Calcite, was to break up the
> > query
> > into individual parts and then do the join in-memory:
> >
> > SELECT ... FROM users;
> > SELECT ... FROM todos WHERE todos.user_id IN (ResultSet from prev
> response);
> >
> > However, the way I am doing this seems like it's probably very
> inefficient.
> > Because I do a series of nested loops to add the key to each object in
> the
> > parent ResultSet row:
> >
> >
> https://github.com/GavinRay97/GraphQLCalcite/blob/648e0ac4f6810a3c360d13a03e6597c33406de4b/src/main/kotlin/TableDataFetcher.kt#L135-L153
> >
> > Is there some better way of doing this?
> > I would be eternally grateful for any advice.
> >
> >
> > On Thu, Feb 10, 2022 at 3:27 PM Julian Hyde 
> wrote:
> >
> >> Yes, if you want to do multiple layers of aggregation, use CTEs (WITH)
> or
> >> nested sub-queries. For example, the following is I believe valid
> standard
> >> SQL, and actually computes something useful:
> >>
> >>  WITH q1 AS
> >>   (SELECT deptno, job, AVG(sal) AS avg_sal
> >>FROM emp
> >>GROUP BY deptno, job)
> >>  WITH q2 AS
> >>   (SELECT deptno, AVG(avg_sal) AS avg_avg_sal
> >>FROM q1
> >>GROUP BY deptno)
> >>  SELECT AVG(avg_avg_sal)
> >>  FROM q2
> >>  GROUP BY ()
> >>
> >> (You can omit the “GROUP BY ()” line, but I think it makes things
> clearer.)
> >>
> >> Julian
> >>
> >>
> >>
> >>> On Feb 10, 2022, at 12:17 PM, Justin Swanhart 
> >> wrote:
> >>>
> >>> I wish you could unsend emails :)  Answering my own question, no,
> because
> >>> that would return three rows with the average :D
> >>>
> >>> On Thu, Feb 10, 2022 at 3:16 PM Justin Swanhart 
> >> wrote:
> >>>
>  Just out of curiosity, is the second level aggregation using AVG in a
>  window context?  It the frame is the whole table and it aggregates
> over
> >> it?
> 
>  On Thu, Feb 10, 2022 at 3:12 PM Justin Swanhart 
>  wrote:
> 
> > That is really neat about Oracle.
> >
> > The alternative in general is to use a subquery:
> > SELECT avg(avg(sal)) FROM emp GROUP BY deptno;
> > becomes
> > select avg(the_avg)
> > from (select avg(sal) from emp group b deptno) an_alias;
> >
> > or
> >
> > with the_cte as (select avg(sal) x from emp group by deptno)
> > select avg(x) from the_cte;
> >
> > On Thu, Feb 10, 2022 at 3:03 PM Julian Hyde 
> > wrote:
> >
> >> Some databases, e.g. O

Re: Why are nested aggregations illegal? Best alternatives?

2022-02-12 Thread Gavin Ray
Nevermind, this is a standard term not something Calcite-specific it seems!

https://en.wikipedia.org/wiki/Correlated_subquery

On Sat, Feb 12, 2022 at 3:46 PM Gavin Ray  wrote:

> Forgive my ignorance/lack of experience
>
> I am somewhat familiar with the ARRAY() function, but not sure I know the
> term "correlated"
> Searching the Calcite codebase for uses of "correlated" + "query", I found:
>
>
> https://github.com/apache/calcite/blob/1d4f1b394bfdba03c5538017e12ab2431b137ca9/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java#L1603-L1612
>
>   @Test void testCorrelatedSubQueryInJoin() {
> final String sql = "select *\n"
> + "from emp as e\n"
> + "join dept as d using (deptno)\n"
> + "where d.name = (\n"
> + "  select max(name)\n"
> + "  from dept as d2\n"
> + "  where d2.deptno = d.deptno)";
> sql(sql).withExpand(false).ok();
>   }
>
> But I also see this, which says it is "uncorrelated" but seems very
> similar?
>
>   @Test void testInUncorrelatedSubQuery() {
> final String sql = "select empno from emp where deptno in"
> + " (select deptno from dept)";
> sql(sql).ok();
>   }
>
> I wouldn't blame you for not answering such a basic question -- but what
> exactly does "correlation" mean here?
>
> Thanks, as usual Julian
>
>
> On Sat, Feb 12, 2022 at 3:08 PM Julian Hyde 
> wrote:
>
>> Correlated ARRAY sub-query?
>>
>> > On Feb 12, 2022, at 10:40 AM, Gavin Ray  wrote:
>> >
>> > Apologies for the delay in replying
>> >
>> > This makes things clear and seems obvious now that you point it out.
>> > Thank you, Justin and Julian =)
>> >
>> > Let me ask another question (if I may) that I am struggling to phrase
>> > easily.
>> >
>> > So with GraphQL, you might have a query like:
>> > - "Get houses"
>> > - "For each house get the user that lives in the house
>> > - "And for each user get their list of todos"
>> >
>> > The result has to come back such that it's a single object for each row
>> > ==
>> > {
>> >  houses: [{
>> >address: "123 Main Street",
>> >users: [{
>> >  name: "Joe",
>> >  todos: [{
>> >description: "Take out trash"
>> >  }]
>> >}]
>> > }
>> >
>> > From a SQL perspective, the logical equivalent would be something like:
>> > ==
>> > SELECT
>> >house.address,
>> >(somehow nest users + double-nest todos under user)
>> > FROM
>> >house
>> > JOIN
>> >user ON user.house_id = house.id
>> >todos ON todos.user_id = user.id
>> > WHERE
>> >house.id = 1
>> >
>> > I'm not familiar enough with SQL to have figured out a way to make this
>> > kind of
>> > query using operators that are supported across most of the DB's
>> Calcite has
>> > adapters for.
>> >
>> > Currently what I have done instead, on a tip from Gopalakrishna Holla
>> from
>> > LinkedIn Coral team who has built GraphQL-on-Calcite, was to break up
>> the
>> > query
>> > into individual parts and then do the join in-memory:
>> >
>> > SELECT ... FROM users;
>> > SELECT ... FROM todos WHERE todos.user_id IN (ResultSet from prev
>> response);
>> >
>> > However, the way I am doing this seems like it's probably very
>> inefficient.
>> > Because I do a series of nested loops to add the key to each object in
>> the
>> > parent ResultSet row:
>> >
>> >
>> https://github.com/GavinRay97/GraphQLCalcite/blob/648e0ac4f6810a3c360d13a03e6597c33406de4b/src/main/kotlin/TableDataFetcher.kt#L135-L153
>> >
>> > Is there some better way of doing this?
>> > I would be eternally grateful for any advice.
>> >
>> >
>> > On Thu, Feb 10, 2022 at 3:27 PM Julian Hyde 
>> wrote:
>> >
>> >> Yes, if you want to do multiple layers of aggregation, use CTEs (WITH)
>> or
>> >> nested sub-queries. For example, the following is I believe valid
>> standard
>> >> SQL, and actually computes something useful:
>> >>
>> >>  WITH q1 AS
>> >>   (SELECT deptno, job, AVG(sal) AS avg_sal
>> >>FROM emp
>> >>GROUP BY deptno, job)
>> >>  WITH q2 AS
>> >>   (SELECT deptno, AVG(avg_sal) AS avg_avg_sal
>> >>FROM q1
>> >>GROUP BY deptno)
>> >>  SELECT AVG(avg_avg_sal)
>> >>  FROM q2
>> >>  GROUP BY ()
>> >>
>> >> (You can omit the “GROUP BY ()” line, but I think it makes things
>> clearer.)
>> >>
>> >> Julian
>> >>
>> >>
>> >>
>> >>> On Feb 10, 2022, at 12:17 PM, Justin Swanhart 
>> >> wrote:
>> >>>
>> >>> I wish you could unsend emails :)  Answering my own question, no,
>> because
>> >>> that would return three rows with the average :D
>> >>>
>> >>> On Thu, Feb 10, 2022 at 3:16 PM Justin Swanhart 
>> >> wrote:
>> >>>
>>  Just out of curiosity, is the second level aggregation using AVG in a
>>  window context?  It the frame is the whole table and it aggregates
>> over
>> >> it?
>> 
>>  On Thu, Feb 10, 2022 at 3:12 PM Justin Swanhart > >
>>  wrote:
>> 
>> > That is really neat about Oracle.
>> >
>> > The alternative in general is to use a subquery:
>> > SELECT avg(avg(sal)) FROM emp 

Re: can we set a default schema for calcite connection to avoid writing schema names in sql

2022-02-12 Thread xiaobo
Hi Gavin,
Thanks for your help, 

the defaultSchema(SchemaPlus defaultSchema) method need a SchemaPlus which only 
can be get after a connection is opened, but we want to set a target subschema 
such as RelfectiveShcema to be the default one, and we guess the default schema 
setting operation should be done before the connection is opened.



-- Original --
From:  "Gavin Ray";;
Send time: Sunday, Feb 13, 2022 1:43 AM
To: "dev"; 

Subject:  Re: can we set a default schema for calcite connection to avoid 
writing schema names in sql



Hey Xiabo,

You can do this, however it is easiest to do from the "FrameworkConfig"
object, like this:

import org.apache.calcite.tools.FrameworkConfig
// Need to set case-sensitive to false, or else it tries to
// look up capitalized table names and fails
//
// IE: "EMPS" instead of "emps"
val frameworkConfig: FrameworkConfig = Frameworks.newConfigBuilder()
 .defaultSchema(connection.rootSchema)
 .parserConfig(SqlParser.config().withCaseSensitive(false))
 .build()

Hope this helps =)

On Fri, Feb 11, 2022 at 9:09 PM xiaobo  wrote:

> sorry for the html escape characters,
> we tried the following and it does not work
>
> Class.forName("org.apache.calcite.jdbc.Driver");
> Properties info = new Properties();
> info.setProperty("lex", "JAVA");
> info.setProperty(InternalProperty.CASE_SENSITIVE.name(),
> "false");
> info.setProperty("defaultSchema", "hr");
> Connection connection =
> DriverManager.getConnection("jdbc:calcite:", info);
> CalciteConnection conn =
> connection.unwrap(CalciteConnection.class);
> SchemaPlus rootSchema = conn.getRootSchema();
> Schema schema = new ReflectiveSchema(target);
> rootSchema.add(schemaName, schema);
> return conn;
>
>
>
>
> -- Original --
> From:  "xiaobo ";;
> Send time: Friday, Feb 11, 2022 11:20 PM
> To: "dev";
>
> Subject:  can we set a default schema for calcite connection to avoid
> writing schema names in sql
>
>
>
> we have tried the following and it does not work
>
>
> Class.forName("org.apache.calcite.jdbc.Driver");
>         Properties info =
> new Properties();
>        
> info.setProperty("lex", "JAVA");
>        
> info.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(),
> "false");
>        
> info.setProperty("defaultSchema", "hr");
>         try {
>        
>     Connection connection =
>        
>        
> DriverManager.getConnection("jdbc:calcite:", info);
>        
>     CalciteConnection conn =
>        
>        
> connection.unwrap(CalciteConnection.class);
>        
>     SchemaPlus rootSchema = conn.getRootSchema();
>     

Re: can we set a default schema for calcite connection to avoid writing schema names in sql

2022-02-12 Thread Gavin Ray
You can create an empty root schema, add a ReflectiveSchema, and then set
this as the default schema:

val rootSchema: SchemaPlus = Frameworks.createRootSchema(true)
val hrReflectiveSchema = ReflectiveSchema(HrSchema())
rootSchema.add("hr", hrReflectiveSchema)

Frameworks.newConfigBuilder()
.defaultSchema(rootSchema.getSubSchema("hr"))

On Sat, Feb 12, 2022 at 9:14 PM xiaobo  wrote:

> Hi Gavin,
> Thanks for your help,
>
> the defaultSchema(SchemaPlus defaultSchema) method need a SchemaPlus which
> only can be get after a connection is opened, but we want to set a target
> subschema such as RelfectiveShcema to be the default one, and we guess the
> default schema setting operation should be done before the connection is
> opened.
>
>
>
> -- Original --
> From:  "Gavin Ray";;
> Send time: Sunday, Feb 13, 2022 1:43 AM
> To: "dev";
>
> Subject:  Re: can we set a default schema for calcite connection to avoid
> writing schema names in sql
>
>
>
> Hey Xiabo,
>
> You can do this, however it is easiest to do from the "FrameworkConfig"
> object, like this:
>
> import org.apache.calcite.tools.FrameworkConfig
> // Need to set case-sensitive to false, or else it tries to
> // look up capitalized table names and fails
> //
> // IE: "EMPS" instead of "emps"
> val frameworkConfig: FrameworkConfig = Frameworks.newConfigBuilder()
>  .defaultSchema(connection.rootSchema)
>  .parserConfig(SqlParser.config().withCaseSensitive(false))
>  .build()
>
> Hope this helps =)
>
> On Fri, Feb 11, 2022 at 9:09 PM xiaobo 
> wrote:
>
> > sorry for the html escape characters,
> > we tried the following and it does not work
> >
> > Class.forName("org.apache.calcite.jdbc.Driver");
> > Properties info = new Properties();
> > info.setProperty("lex", "JAVA");
> > info.setProperty(InternalProperty.CASE_SENSITIVE.name(),
> > "false");
> > info.setProperty("defaultSchema", "hr");
> > Connection connection =
> > DriverManager.getConnection("jdbc:calcite:", info);
> > CalciteConnection conn =
> > connection.unwrap(CalciteConnection.class);
> > SchemaPlus rootSchema = conn.getRootSchema();
> > Schema schema = new ReflectiveSchema(target);
> > rootSchema.add(schemaName, schema);
> > return conn;
> >
> >
> >
> >
> > -- Original --
> > From:  "xiaobo ";;
> > Send time: Friday, Feb 11, 2022 11:20 PM
> > To: "dev";
> >
> > Subject:  can we set a default schema for calcite connection to avoid
> > writing schema names in sql
> >
> >
> >
> > we have tried the following and it does not work
> >
> >
> > Class.forName("org.apache.calcite.jdbc.Driver");
> >         Properties info
> =
> > new Properties();
> >        
> > info.setProperty("lex", "JAVA");
> >        
> > info.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(),
> > "false");
> >        
> > info.setProperty("defaultSchema", "hr");
> >         try {
> >        
> >     Connection connection =
> >        
> >        
> > DriverManager.getConnection("jdbc:calcite:", info);
> >        
> >     CalciteConnection conn =
> >        
> >        
> > connection.unwrap(CalciteConnection.class);
> >        
> >     SchemaPlus rootSchema = conn.getRootSchema();
> >     


Re: Why are nested aggregations illegal? Best alternatives?

2022-02-12 Thread Gavin Ray
After ~5 hours, I think I may have made some progress =)

I have this, which currently works. The problem is that the nested columns
don't have names on them.
Since I need to return a nested "Map", I have to figure out
how to convert this query into a form that gives column names.

But this is still great progress I think!

SELECT
"todos".*,
ARRAY(
SELECT
"users".*,
ARRAY(
SELECT
"todos".*
FROM
"todos"
) AS "todos"
FROM
"users"
) AS "users"
FROM
"todos"
WHERE
"user_id" IN (
SELECT
"user_id"
FROM
"users"
WHERE
"house_id" IN (
SELECT
"id"
FROM
"houses"
)
);


++-++--+
| id | user_id |  description   |
|
++-++--+
| 1  | 1   | Take out the trash | [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
| 2  | 1   | Watch my favorite show | [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
| 3  | 1   | Charge my phone| [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
| 4  | 2   | Cook dinner| [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
| 5  | 2   | Read a book| [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
| 6  | 2   | Organize office| [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
| 7  | 3   | Walk the dog   | [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
| 8  | 3   | Feed the cat   | [{1, John, 1, [{1, 1, Take out
the trash}, {2, 1, Watch my favorite show}, { |
++-++--+

On Sat, Feb 12, 2022 at 4:13 PM Gavin Ray  wrote:

> Nevermind, this is a standard term not something Calcite-specific it seems!
>
> https://en.wikipedia.org/wiki/Correlated_subquery
>
> On Sat, Feb 12, 2022 at 3:46 PM Gavin Ray  wrote:
>
>> Forgive my ignorance/lack of experience
>>
>> I am somewhat familiar with the ARRAY() function, but not sure I know the
>> term "correlated"
>> Searching the Calcite codebase for uses of "correlated" + "query", I
>> found:
>>
>>
>> https://github.com/apache/calcite/blob/1d4f1b394bfdba03c5538017e12ab2431b137ca9/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java#L1603-L1612
>>
>>   @Test void testCorrelatedSubQueryInJoin() {
>> final String sql = "select *\n"
>> + "from emp as e\n"
>> + "join dept as d using (deptno)\n"
>> + "where d.name = (\n"
>> + "  select max(name)\n"
>> + "  from dept as d2\n"
>> + "  where d2.deptno = d.deptno)";
>> sql(sql).withExpand(false).ok();
>>   }
>>
>> But I also see this, which says it is "uncorrelated" but seems very
>> similar?
>>
>>   @Test void testInUncorrelatedSubQuery() {
>> final String sql = "select empno from emp where deptno in"
>> + " (select deptno from dept)";
>> sql(sql).ok();
>>   }
>>
>> I wouldn't blame you for not answering such a basic question -- but what
>> exactly does "correlation" mean here?
>>
>> Thanks, as usual Julian
>>
>>
>> On Sat, Feb 12, 2022 at 3:08 PM Julian Hyde 
>> wrote:
>>
>>> Correlated ARRAY sub-query?
>>>
>>> > On Feb 12, 2022, at 10:40 AM, Gavin Ray  wrote:
>>> >
>>> > Apologies for the delay in replying
>>> >
>>> > This makes things clear and seems obvious now that you point it out.
>>> > Thank you, Justin and Julian =)
>>> >
>>> > Let me ask another question (if I may) that I am struggling to phrase
>>> > easily.
>>> >
>>> > So with GraphQL, you might have a query like:
>>> > - "Get houses"
>>> > - "For each house get the user that lives in the house
>>> > - "And for each user get their list of todos"
>>> >
>>> > The result has to come back such that it's a single object for each row
>>> > ==
>>> > {
>>> >  houses: [{
>>> >address: "123 Main Street",
>>> >users: [{
>>> >  name: "Joe",
>>> >  todos: [{
>>> >description: "Take out trash"
>>> >  }]
>>> >}]
>>> > }
>>> >
>>> > From a SQL perspective, the logical equivalent would be something like:
>>> > ==
>>> > SELECT
>>> >house.address,
>>> >(somehow nest users + double-nest todos under user)
>>> > FROM
>>> >house
>>> > JOIN
>>> >user ON user.house_id = house.id
>>> >todos ON todos.user_id = user.id
>>> > WHERE
>>> >house.id = 1
>>> >

Re: Why are nested aggregations illegal? Best alternatives?

2022-02-12 Thread Gavin Ray
Ah wait nevermind, got excited and spoke too soon. Looking at it more
closely, that data isn't correct.
At least it's in somewhat the right shape, ha!

On Sat, Feb 12, 2022 at 9:57 PM Gavin Ray  wrote:

> After ~5 hours, I think I may have made some progress =)
>
> I have this, which currently works. The problem is that the nested columns
> don't have names on them.
> Since I need to return a nested "Map", I have to figure
> out how to convert this query into a form that gives column names.
>
> But this is still great progress I think!
>
> SELECT
> "todos".*,
> ARRAY(
> SELECT
> "users".*,
> ARRAY(
> SELECT
> "todos".*
> FROM
> "todos"
> ) AS "todos"
> FROM
> "users"
> ) AS "users"
> FROM
> "todos"
> WHERE
> "user_id" IN (
> SELECT
> "user_id"
> FROM
> "users"
> WHERE
> "house_id" IN (
> SELECT
> "id"
> FROM
> "houses"
> )
> );
>
>
>
> ++-++--+
> | id | user_id |  description   |
> |
>
> ++-++--+
> | 1  | 1   | Take out the trash | [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
> | 2  | 1   | Watch my favorite show | [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
> | 3  | 1   | Charge my phone| [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
> | 4  | 2   | Cook dinner| [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
> | 5  | 2   | Read a book| [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
> | 6  | 2   | Organize office| [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
> | 7  | 3   | Walk the dog   | [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
> | 8  | 3   | Feed the cat   | [{1, John, 1, [{1, 1, Take out
> the trash}, {2, 1, Watch my favorite show}, { |
>
> ++-++--+
>
> On Sat, Feb 12, 2022 at 4:13 PM Gavin Ray  wrote:
>
>> Nevermind, this is a standard term not something Calcite-specific it
>> seems!
>>
>> https://en.wikipedia.org/wiki/Correlated_subquery
>>
>> On Sat, Feb 12, 2022 at 3:46 PM Gavin Ray  wrote:
>>
>>> Forgive my ignorance/lack of experience
>>>
>>> I am somewhat familiar with the ARRAY() function, but not sure I know
>>> the term "correlated"
>>> Searching the Calcite codebase for uses of "correlated" + "query", I
>>> found:
>>>
>>>
>>> https://github.com/apache/calcite/blob/1d4f1b394bfdba03c5538017e12ab2431b137ca9/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java#L1603-L1612
>>>
>>>   @Test void testCorrelatedSubQueryInJoin() {
>>> final String sql = "select *\n"
>>> + "from emp as e\n"
>>> + "join dept as d using (deptno)\n"
>>> + "where d.name = (\n"
>>> + "  select max(name)\n"
>>> + "  from dept as d2\n"
>>> + "  where d2.deptno = d.deptno)";
>>> sql(sql).withExpand(false).ok();
>>>   }
>>>
>>> But I also see this, which says it is "uncorrelated" but seems very
>>> similar?
>>>
>>>   @Test void testInUncorrelatedSubQuery() {
>>> final String sql = "select empno from emp where deptno in"
>>> + " (select deptno from dept)";
>>> sql(sql).ok();
>>>   }
>>>
>>> I wouldn't blame you for not answering such a basic question -- but what
>>> exactly does "correlation" mean here?
>>>
>>> Thanks, as usual Julian
>>>
>>>
>>> On Sat, Feb 12, 2022 at 3:08 PM Julian Hyde 
>>> wrote:
>>>
 Correlated ARRAY sub-query?

 > On Feb 12, 2022, at 10:40 AM, Gavin Ray 
 wrote:
 >
 > Apologies for the delay in replying
 >
 > This makes things clear and seems obvious now that you point it out.
 > Thank you, Justin and Julian =)
 >
 > Let me ask another question (if I may) that I am struggling to phrase
 > easily.
 >
 > So with GraphQL, you might have a query like:
 > - "Get houses"
 > - "For each house get the user that lives in the house
 > - "And for each user get their list of todos"
 >
 > The result has to come back such that it's a single object for each
 row
 > ==
 > {
 >  houses: [{
 >address: "123 Main Street",
 >users: [{
 >  name: "Joe",
 >  todos: [{
 >description