Re: [DISCUSS] Refactoring tests

2021-11-16 Thread Vladimir Sitnikov
Jacques>This sounds like it will mean we will need to make calcite-core
test artifacts available

Test artifacts publication is yet another anti-pattern just like "base test
class".
This change has been discussed:
https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1

If you want to depend on a class from tests, consider moving it to /testkit
module:
https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit

Jacques>We should think about the rules around Kotlin

What happens in calcite-core/tests stays in calcite-core/tests :)

It is reasonable to assume that testkit module would have dependencies,
and testkit would provide API that is usable from Java and other JVM
languages.

In that regard, Kotlin dependency in testkit is not much different from
Quidem or commons-lang3.
Consumers might use Quidem if it fits just like they could use Kotlin if it
fits.

Vladimir


Re: [DISCUSS] Refactoring tests

2021-11-16 Thread Vladimir Sitnikov
Julian,

Thanks for taking time, and working on this.

"Fixture" is a too broad term, and I do not mean we should replace it
completely with AssertJ.

What I mean is that AssertJ allows creating *discoverable* assertions.
Hamcrest assertions are hard to create and hard to discover in IDE.

---

Re test code implementations, we junit5 extensions would likely be useful.
For instance


@ExtendWith(CalciteParserExtensions.class)
@WithLex(BACK_TICKS)
class MyParserTest {
   void invalidSqlFails(SqlParserFixture sql) { // <-- injected by extension
.

In other words, it does not mean fixture (whatever it means) must be 100%
junit5.
What I mean, junit5 extensions could simplify writting calcite tests by
making fixture confuguration declarative, and injecting the configured
object as test method argument.

Vladimir


Re: binding of boolean literals in SQL

2021-11-16 Thread Julian Hyde
It’s possible, and I would think desirable, to simplify

  “clean” = true

and for that matter

  “clean” is true

to

  “clean”

and based on your experiments it looks as if we do it already.  

Julian

> On Nov 16, 2021, at 18:06, Gavin Nicol  wrote:
> 
> I'm writing a FilterableTable implementation and so far all is well. When 
> handling more complex filters I've come across the need to pass in a boolean 
> flag via a filter clause, something like:
> 
> select "foo" from "bar" where "clean"=true and "id"='1234'
> 
> This results in a filter like: AND(CAST($2):BOOLEAN, =(CAST($0):VARCHAR, 
> '1234')), and I'm trying to figure out how to get to the actual value used 
> for the boolean. The operand in this case is a RexInputRef from which I can 
> get to the RelDataTypeField but I can't find the literal anywhere. Any 
> guidance here?


binding of boolean literals in SQL

2021-11-16 Thread Gavin Nicol
I'm writing a FilterableTable implementation and so far all is well. When 
handling more complex filters I've come across the need to pass in a boolean 
flag via a filter clause, something like:

 select "foo" from "bar" where "clean"=true and "id"='1234'

This results in a filter like: AND(CAST($2):BOOLEAN, =(CAST($0):VARCHAR, 
'1234')), and I'm trying to figure out how to get to the actual value used for 
the boolean. The operand in this case is a RexInputRef from which I can get to 
the RelDataTypeField but I can't find the literal anywhere. Any guidance here?


Re: [DISCUSS] Refactoring tests

2021-11-16 Thread Jacques Nadeau
I think it is a great idea to make the tests more accessible. A few
comments to consider in your work (no response expected):

   - I would vote to try to minimize the use of non-interface class
   inheritance , especially in downstream cases. For example, I would avoid a
   dominant path using base test subclasses in other projects. My experience
   on other similar projects is that using multi-level inheritance as a
   strategy makes things ultimately harder to compose.
   - This sounds like it will mean we will need to make calcite-core test
   artifacts available as part of distribution, something that doesn't happen
   currently
   .
   I was just trying to use SqlToRelTestBase.TesterImpl externally today and
   was disappointed to find out that maven doesn't hold the test
   classifier jars.
   - We should think about the rules around Kotlin, since it is used in the
   core test compilation cycle. Do projects need to depend on and/or adopt
   Kotlin to use these things?
   - I have zero opinion of AssertJ as relevant or a good idea.

My last thought is that I sometimes worry that we're quick to build bespoke
infrastructure within the project when there are good-enough primitives
that we could leverage that are more ecosystem idiomatic. A few examples
would be early json reading/writing, several relatively undocumented custom
plugins in the gradle build, ImmutableBeans, excessive use of unusual
reflection patterns, and use of Janino in non-performance-critical code
paths. I just hope we do our best to use ecosystem idiomatic solutions here
as much as makes sense. It improves approachability and helps when people
are struggling with problems (since usually there is more content out there
for people to figure things out on their own).

Again, super glad this work is getting done. Thanks for taking the
initiative Julian!



On Tue, Nov 16, 2021 at 2:27 PM Julian Hyde  wrote:

> I am working on https://issues.apache.org/jira/browse/CALCITE-4885,
> "Fluent test fixtures so that dependent projects can write parser,
> validator and rules tests".
>
> I wanted to give you all a heads up, because it's going to change
> quite a few lines of code.
>
> Here's the problem I'm trying to solve. Calcite defines APIs such as
> RelRule, SqlOperator, and we encourage people to implement them in
> their projects (not necessarily contribute them back). But experience
> has shown that if you want to write, say, a planner rule, you'd better
> write some tests for it. And to write tests, you need to sub-class
> RelOptRulesTest.
>
> So, 4885 is about making it easier to write those kinds of tests.
>
> But - spoiler alert - subclassing the test classes isn't the way to
> go. Your subclass will inherit all of the tests from the base class.
> If you keep mutable state ("fixtures") in your test class, then
> maintaining that state gets messy as more tests add more state. We
> have added abstractions such as "tester" [1] but it's still pretty
> complicated.
>
> I am refactoring the test along the following lines:
>
> Test classes (e.g. RelOptRulesTest) contain tests but have no state.
> They have a "fixture()" method that returns a fixture. Often there is
> also a "sql(String sql)" method that just does
> "fixture().withSql(sql)".
>
> A fixture class (renamed from the helper classes called "Sql" in
> various tests) has a lot of methods that allow you to test things. But
> the only state in the fixture is a tester and a config. That state is
> immutable; each time you set a property, you create a new fixture that
> wraps a new copy of the config.
>
> A test config class is immutable and has lots of data fields.
>
> If the test uses reference files, the config will contain a
> DiffRepository. Subclasses can use a different DiffRepository (mapping
> to a different .xml file) but still use the same fixture
> implementation.
>
> A tester implements the nuts and bolts (e.g. parsing SQL, converting
> SQL to RelNode, planning). It has no state; the methods accept lots of
> parameters, such as whether decorrelation is enabled, from the config.
> There's usually only one implementation of tester, but you can
> override for special reasons (e.g. an implementation of the parser
> tester that converts the AST back to SQL and tries to parse it a
> second time).
>
> With these changes, people will be able to create a test that
> instantiates a fixture, calls some methods to configure it, and then
> calls some methods to run their test. See FixtureTest and Fixtures
> [2]. They can do that in any class, not necessarily a subclass of an
> existing Calcite test.
>
> Our test framework is not covered by semantic versioning. People in
> dependent projects who depend on our test framework may have to fix up
> their tests when they upgrade. It shouldn't be too bad.
>
> In the bug Vladimir suggested that we take this opportunity to move
> from Hamcrest matchers to AssertJ. I 

[DISCUSS] Refactoring tests

2021-11-16 Thread Julian Hyde
I am working on https://issues.apache.org/jira/browse/CALCITE-4885,
"Fluent test fixtures so that dependent projects can write parser,
validator and rules tests".

I wanted to give you all a heads up, because it's going to change
quite a few lines of code.

Here's the problem I'm trying to solve. Calcite defines APIs such as
RelRule, SqlOperator, and we encourage people to implement them in
their projects (not necessarily contribute them back). But experience
has shown that if you want to write, say, a planner rule, you'd better
write some tests for it. And to write tests, you need to sub-class
RelOptRulesTest.

So, 4885 is about making it easier to write those kinds of tests.

But - spoiler alert - subclassing the test classes isn't the way to
go. Your subclass will inherit all of the tests from the base class.
If you keep mutable state ("fixtures") in your test class, then
maintaining that state gets messy as more tests add more state. We
have added abstractions such as "tester" [1] but it's still pretty
complicated.

I am refactoring the test along the following lines:

Test classes (e.g. RelOptRulesTest) contain tests but have no state.
They have a "fixture()" method that returns a fixture. Often there is
also a "sql(String sql)" method that just does
"fixture().withSql(sql)".

A fixture class (renamed from the helper classes called "Sql" in
various tests) has a lot of methods that allow you to test things. But
the only state in the fixture is a tester and a config. That state is
immutable; each time you set a property, you create a new fixture that
wraps a new copy of the config.

A test config class is immutable and has lots of data fields.

If the test uses reference files, the config will contain a
DiffRepository. Subclasses can use a different DiffRepository (mapping
to a different .xml file) but still use the same fixture
implementation.

A tester implements the nuts and bolts (e.g. parsing SQL, converting
SQL to RelNode, planning). It has no state; the methods accept lots of
parameters, such as whether decorrelation is enabled, from the config.
There's usually only one implementation of tester, but you can
override for special reasons (e.g. an implementation of the parser
tester that converts the AST back to SQL and tries to parse it a
second time).

With these changes, people will be able to create a test that
instantiates a fixture, calls some methods to configure it, and then
calls some methods to run their test. See FixtureTest and Fixtures
[2]. They can do that in any class, not necessarily a subclass of an
existing Calcite test.

Our test framework is not covered by semantic versioning. People in
dependent projects who depend on our test framework may have to fix up
their tests when they upgrade. It shouldn't be too bad.

In the bug Vladimir suggested that we take this opportunity to move
from Hamcrest matchers to AssertJ. I disagree. I'm not convinced that
AssertJ is so much better that moving to it is worth the disruption.
And in any case, this change is about figuring out the lifecycle (e.g.
how do I configure my test to add and remove rules from the planner,
when the planner doesn't exist until I'm half way through my test) and
I don't think AssertJ helps with that.

I am going to make fixtures, configs and testers top-level classes
(i.e. not inner classes). It makes them easier to extend.

I might make fixtures into interfaces whose methods all have defaults.
Then people can easily subclass fixtures; they could even inherit from
multiple fixtures.

Let me know if you have ideas or concerns. I recommend that people who
have written tricky tests (e.g. TopDownOptTest) track this
development.

Julian

[1] 
https://github.com/apache/calcite/blob/4b1e9ed1a513eae0c873a660b755bb4f27b39da9/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java#L568

[2] 
https://github.com/julianhyde/calcite/commit/0286f78b0db0e364f3225f004b32853de2685a39


Re: DISCUSS: merge calcite-avatica and calcite repositories

2021-11-16 Thread Jacques Nadeau
We've had 7 responses so far on the straw poll. For a reminder, results are
here:

https://docs.google.com/spreadsheets/d/1EXhrRkYp2owGAK2e3bBw1bEvNj5O3V22iTqndBAuyG8/edit?usp=sharing

My high level observations:

   - There isn't a lot of agreement on most questions :D.
   - 70% of people preferred to keep the repositories separate (5 out of 7).
   - All of the people who said they would be willing to
"Maintain/enhance/support
   the Avatica build/CI" also thought the repositories should stay separate.

Since maintenance is such a big part of the ongoing cost of projects and
the community average slightly prefers to keep things separate, I suggest
we stick with separate.

Additionally, I really appreciated Julian's comment on the survey, pasted
here "CI of Calcite master against Avatica master SHOULD pass but not MUST.
It is advisory only.". Based on this, I would suggest we do a small
modification around CI on Calcite whereby pre-commit tests do not include
running against Avatica main and instead we have a post-merge CI job that
monitors the status of connecting the two. This way people have "green"
tests for pre-merge even if the latest Avatica doesn't match.

I'd also suggest that if Calcite and Avatica are truly treated as
decoupled, this allows Calcite to be released not necessarily using the
latest Avatica release (treating it's upgrade policy just like any other
library Calcite uses).



On Fri, Nov 12, 2021 at 8:06 AM Vladimir Sitnikov <
sitnikov.vladi...@gmail.com> wrote:

> Josh>I am still upset from the porting of Avatica to Gradle
>
> Please migrate Avatica to whatever build system you like.
>
> I disagree with you a lot, however, I stop commenting as I do not see it
> might change your mind.
> I'm not touching Avatica anymore.
>
> me>I am going to delete/ignore the offending tests in Calcite in 24 hours
>
> Done. I commented out the test.
> I hope we no longer add tests to Caclite that verify low-level Avatica
> behaviour.
>
> Vladimir
>


Re: UNNEST in relational algebra

2021-11-16 Thread Spotify
Hi,
Sorry for being unclear. We have tried to generate SQL similar to the three
examples using the RelBuilder and the Uncollect expression. Something like
this.

relBuilder.scan("table");
final Holder correlVar = Holder.empty();
relBuilder.variable(correlVar);
relBuilder.values(new String[] {"dummy"}, "");
relBuilder.project(
relBuilder.alias(
relBuilder.dot(relBuilder.field(correlVar.get(), "history"),
"all_of_history"),
"unnest_all_of_history"));
relBuilder.uncollect(List.of("unnest_all_of_history"), false);
relBuilder.correlate(JoinRelType.INNER, correlVar.get().id);
RexNode userIdNode = relBuilder.alias(relBuilder.field("id"), "id");
RexNode isActive =
relBuilder.alias(
relBuilder.dot(relBuilder.field("unnest_all_of_history"),
"is_active"),
"is_active");
relBuilder.project(userIdNode, reportingRegion);
RelNode result = relBuilder.build();

We can generate SQL using the CalciteSqlDialect but we get an exception
when using the BigQuerySqlDialect. We wonder what the best way to work with
UNNEST in relational algebra using RelBuilder for BigQuery.

Thanks.



On Tue, Nov 16, 2021 at 2:49 PM Thomas Rebele 
wrote:

> Hello,
>
> I don't understand what you want to do here. There's an UNNEST operator in
> Calcite, see the comment at the bottom of this section:
> https://calcite.apache.org/docs/reference.html#collection-functions.
>
> Cordialement / Best Regards,
> *Thomas Rebele, PhD* | R Developer | Germany | www.tibco.com
>
>
> On Tue, Nov 16, 2021 at 2:30 PM Daniel (Spotify) Ståhl
>  wrote:
>
> > Hi
> > We are trying to generate relational algebra for SQL that uses UNNEST of
> > arrays in BigQuery. Here are three examples of SQL (in Big Query standard
> > query syntax) that we want to be able to handle and generate from
> > relational algebra. Any tips on how you would do that in Calcite?
> >
> > SELECT id,
> >   (SELECT h.is_active FROM UNNEST(history.all_of_history) h
> > WHERE start_date <= "2021-06-01" AND (end_date >= "2021-06-01" OR
> > end_date IS NULL))
> > FROM `table`;
> >
> > SELECT id, h.is_active
> > FROM `table`
> > CROSS JOIN UNNEST(history.all_of_history) h;
> >
> > SELECT id, count(h) as h
> > from `table`
> > CROSS JOIN UNNEST(history.all_of_history) h
> > GROUP BY id;
> >
> > The table "table" has two columns: "id" and "history". history is a
> record
> > and "history.all_of_history"
> > is a repeated record with three fields ("is_active", "start_date" and
> > "end_date").
> >
> > Thanks,
> > Daniel Ståhl
> >
>


Re: UNNEST in relational algebra

2021-11-16 Thread Thomas Rebele
Hello,

I don't understand what you want to do here. There's an UNNEST operator in
Calcite, see the comment at the bottom of this section:
https://calcite.apache.org/docs/reference.html#collection-functions.

Cordialement / Best Regards,
*Thomas Rebele, PhD* | R Developer | Germany | www.tibco.com


On Tue, Nov 16, 2021 at 2:30 PM Daniel (Spotify) Ståhl
 wrote:

> Hi
> We are trying to generate relational algebra for SQL that uses UNNEST of
> arrays in BigQuery. Here are three examples of SQL (in Big Query standard
> query syntax) that we want to be able to handle and generate from
> relational algebra. Any tips on how you would do that in Calcite?
>
> SELECT id,
>   (SELECT h.is_active FROM UNNEST(history.all_of_history) h
> WHERE start_date <= "2021-06-01" AND (end_date >= "2021-06-01" OR
> end_date IS NULL))
> FROM `table`;
>
> SELECT id, h.is_active
> FROM `table`
> CROSS JOIN UNNEST(history.all_of_history) h;
>
> SELECT id, count(h) as h
> from `table`
> CROSS JOIN UNNEST(history.all_of_history) h
> GROUP BY id;
>
> The table "table" has two columns: "id" and "history". history is a record
> and "history.all_of_history"
> is a repeated record with three fields ("is_active", "start_date" and
> "end_date").
>
> Thanks,
> Daniel Ståhl
>


UNNEST in relational algebra

2021-11-16 Thread Spotify
Hi
We are trying to generate relational algebra for SQL that uses UNNEST of
arrays in BigQuery. Here are three examples of SQL (in Big Query standard
query syntax) that we want to be able to handle and generate from
relational algebra. Any tips on how you would do that in Calcite?

SELECT id,
  (SELECT h.is_active FROM UNNEST(history.all_of_history) h
WHERE start_date <= "2021-06-01" AND (end_date >= "2021-06-01" OR
end_date IS NULL))
FROM `table`;

SELECT id, h.is_active
FROM `table`
CROSS JOIN UNNEST(history.all_of_history) h;

SELECT id, count(h) as h
from `table`
CROSS JOIN UNNEST(history.all_of_history) h
GROUP BY id;

The table "table" has two columns: "id" and "history". history is a record
and "history.all_of_history"
is a repeated record with three fields ("is_active", "start_date" and
"end_date").

Thanks,
Daniel Ståhl


[jira] [Created] (CALCITE-4889) Double join is created for NOT IN

2021-11-16 Thread Vladimir Sitnikov (Jira)
Vladimir Sitnikov created CALCITE-4889:
--

 Summary: Double join is created for NOT IN
 Key: CALCITE-4889
 URL: https://issues.apache.org/jira/browse/CALCITE-4889
 Project: Calcite
  Issue Type: Improvement
  Components: core
Affects Versions: 1.28.0
Reporter: Vladimir Sitnikov


The following queries yield several joins in the plan.
I think double joins are excessive here, especially for the first case where 
all the values are non-nullable.

{code}select * from "scott".emp where (empno, deptno) not in ((7369, 20), 
(7499, 30));{code}

{noformat}
select * from "scott".emp where empno not in (null, 7782);

EnumerableCalc(expr#0..12=[{inputs}], expr#13=[0:BIGINT], expr#14=[=($t8, 
$t13)], expr#15=[IS NULL($t12)], expr#16=[>=($t9, $t8)], expr#17=[AND($t15, 
$t16)], expr#18=[OR($t14, $t17)], proj#0..7=[{exprs}], $condition=[$t18])
  EnumerableMergeJoin(condition=[=($10, $11)], joinType=[left])
EnumerableSort(sort0=[$10], dir0=[ASC])
  EnumerableCalc(expr#0..9=[{inputs}], proj#0..9=[{exprs}], EMPNO0=[$t0])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
  EnumerableTableScan(table=[[scott, EMP]])
  EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)])
EnumerableValues(tuples=[[{ null }, { 7782 }]])
EnumerableSort(sort0=[$0], dir0=[ASC])
  EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
EnumerableValues(tuples=[[{ null }, { 7782 }]])
{noformat}

{noformat}
select * from "scott".emp where (empno, deptno) not in ((1, 2), (3, null));

EnumerableCalc(expr#0..14=[{inputs}], expr#15=[0:BIGINT], expr#16=[=($t8, 
$t15)], expr#17=[IS NULL($t14)], expr#18=[>=($t9, $t8)], expr#19=[IS NOT 
NULL($t11)], expr#20=[AND($t17, $t18, $t19)], expr#21=[OR($t16, $t20)], 
proj#0..7=[{exprs}], $condition=[$t21])
  EnumerableMergeJoin(condition=[AND(=($10, $12), =($11, $13))], 
joinType=[left])
EnumerableSort(sort0=[$10], sort1=[$11], dir0=[ASC], dir1=[ASC])
  EnumerableCalc(expr#0..9=[{inputs}], proj#0..9=[{exprs}], EMPNO0=[$t0], 
DEPTNO0=[$t7])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
  EnumerableTableScan(table=[[scott, EMP]])
  EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0, 
$1)])
EnumerableValues(tuples=[[{ 1, 2 }, { 3, null }]])
EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC])
  EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], proj#0..2=[{exprs}])
EnumerableValues(tuples=[[{ 1, 2 }, { 3, null }]])
{noformat}



--
This message was sent by Atlassian Jira
(v8.20.1#820001)


Re: RelDecorrelator.java - Values Handler

2021-11-16 Thread Stamatis Zampetakis
Hi Mahendrakar,

I would say that Values should be handled more or less the same way that we
handle a TableScan so returning null seems like a bug.

However, to be sure it would help if you can come up with a concrete
query/plan that cannot be decorrelated due to this.
If that's the case please log a JIRA case with the steps to reproduce. You
can try to create a test case in SqlToRelConverterTest [1] or
RelOptRulesTest [2].

Best,
Stamatis

[1]
https://github.com/apache/calcite/blob/07e420bfc36e8f217f5c3459fdf6c1ede609cb80/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
[2]
https://github.com/apache/calcite/blob/07e420bfc36e8f217f5c3459fdf6c1ede609cb80/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java

On Thu, Nov 11, 2021 at 8:18 AM Mahendrakar Srinivasarao <
mahendrakar.srinivasa...@dremio.com> wrote:

> Hi Community,
>
> Hope you are doing well.
> I have a question about the handling of Values Rel.
>
> File: RelDecorrelator.java
>
> public Frame decorrelateRel(Values rel, boolean isCorVarDefined) {
>return null;
> }
>
> Why do we return null for Values Rel. Can you please let me know.
>
>
> While looking at the join/union handlers (in the same file), if one of
> the input frame is null, handler returns null.
>
> JOIN
>
> Input1 Input2
>
>
> In the above scenario, let's say input1 is decorrelated successfully
> but Input2 has Values Rel, in which case we return null as per the
> logic in Join (below).
>
> public Frame decorrelateRel(Join rel, boolean isCorVarDefined) {
>
> .
>
> .
>
> .
>
> final RelNode oldLeft = rel.getInput(0);
> final RelNode oldRight = rel.getInput(1);
>
> final Frame leftFrame = getInvoke(oldLeft, isCorVarDefined, rel);
> final Frame rightFrame = getInvoke(oldRight, isCorVarDefined, rel);
>
> if (leftFrame == null || rightFrame == null) {
>   // If any input has not been rewritten, do not rewrite this rel.
>   return null;
>
> .
>
> .
>
>
> .
> }
>
>
>
>
> Thanks,
> Mahendrakar.
>


Re: feature request / jdbc push-down / off-platform SQL rewrite

2021-11-16 Thread Stamatis Zampetakis
Hi Anthony,

I don't completely understand what point 1 and 2 concretely mean.

1) Calcite does a pretty good job pushing computations to the underlying
DBMS when that is possible.
JdbcAdapterTest [1] has a few examples where the whole query is pushed to
the database.
Can you give more details on what is missing or what you wanted to achieve?

2) Calcite has many components which can be used independently from one
another.
If you use Calcite as a library then you can use whichever component you
need and perform rewrites exactly as you want.
Would you like to propose a new API for some particular use-case?

Best,
Stamatis

[1]
https://github.com/apache/calcite/blob/07e420bfc36e8f217f5c3459fdf6c1ede609cb80/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java

On Fri, Nov 12, 2021 at 1:05 AM Anthony Krinsky 
wrote:

> Newbie question and perhaps feature request, apologies in advance if this
> is well trod.
>
> I've struggled to find a solution to these problems, which one would think
> are common:
>
> 1) Full fidelity push-down to a JDBC adapted, traditional RDBMS, when only
> that source is involved in a query.  Why not an optimization short-cut?
>
> 2) A plugin framework that would allow SQL rewrite outside of the
> framework.  For example, I might have a redaction, row-level security, or
> rewrite engine running on a separate application server.
>
>
> I fully appreciate that these ideas are contrary to the spirit of a
> cost-optimized, distributed and federated query middleware.  These
> limitations exist in Trino and Calcite derivatives.
>
> Thoughts?
>
> Thank you so much,
>
> Anthony
>