It’s not possible to do during front-end phases (validation or sql-to-rel) 
because you don’t yet know what the target dialect is. Not in general anyway; I 
know that Calcite is often run as a “translation layer”, where there is a 
single target dialect, but it’s not a clean architecture to make the front-end 
aware of that dialect.

So that leaves the option of doing some rel-to-rel rewrites in the back-end, 
when the target dialect is known, and while type information is still 
available. I don’t know whether RelToSqlConverter currently is able to run 
RelRules or a RelProgram, but it could.

To solve this problem, there would be a rule that matches Aggregate (or 
JdbcAggregate) and translates AggCall(MIN) to AggCall(BOOL_AND) if the target 
dialect is Postgres/Redshift and the argument has type BOOLEAN.

The nearest current analogs are:
 * AggregateExpandDistinctAggregatesRule can be enabled if the target dialect 
does not support COUNT(DISTINCT).
 * SqlDilect.emulateNullDirection does ’tree transformation’ — unlike most 
SqlDialect methods that just generate a string — but it operates on the AST 
(SqlNode). It suffers a little because it doesn’t know whether each of the 
columns are nullable.

Julian





> On Jan 23, 2024, at 1:04 PM, Tanner Clary <tannercl...@google.com.INVALID> 
> wrote:
> 
> Your first point is a good one.
> 
> For your second, validation doesn't need dialect knowledge with my
> suggestion. If the return type of MIN/MAX is inferred to be BOOLEAN, set
> the unparseOperator. This may or may not get used later, depending on
> dialect.
> 
> Tanner
> 
> On Tue, Jan 23, 2024 at 1:03 PM Mihai Budiu <mbu...@gmail.com> wrote:
> 
>> I think that unparse is supposed to work even if you haven't validated.
>> 
>> Also, validation does not really know about dialects.
>> 
>> Mihai
>> ________________________________
>> From: Tanner Clary <tannercl...@google.com.INVALID>
>> Sent: Tuesday, January 23, 2024 1:00 PM
>> To: dev@calcite.apache.org <dev@calcite.apache.org>
>> Subject: Re: Unparsing based on operand type
>> 
>> One idea I had was: during validation when the return type for a call is
>> derived, you could have a property in `SqlBasicCall` called something like
>> "unparseOperator". You could have some logic that determines the value of
>> this operator, and then set it accordingly. Later, during unparsing, you
>> can choose to utilize this "unparseOperator" if it is relevant (e.g. the
>> target dialect is Postgres or Redshift in this example.)
>> 
>> A downside of this is that you're no longer strictly validating, are there
>> other pitfalls?
>> 
>> Tanner
>> 
>> On Tue, Jan 23, 2024 at 12:52 PM Mihai Budiu <mbu...@gmail.com> wrote:
>> 
>>> My guess would be that this is not possible.
>>> At the SqlNode level there are no types.
>>> Even if there is some type information, it may be wrong or incomplete,
>>> since type inference has not been executed yet.
>>> 
>>> I am afraid that even going from RelNode to SqlNode to unparsing won't
>>> make this problem much simpler, although there you can at least count on
>>> the representation being properly typed.
>>> 
>>> Mihai
>>> ________________________________
>>> From: Tanner Clary <tannercl...@google.com.INVALID>
>>> Sent: Tuesday, January 23, 2024 12:32 PM
>>> To: dev@calcite.apache.org <dev@calcite.apache.org>
>>> Subject: Unparsing based on operand type
>>> 
>>> Hey Calcite Devs,
>>> 
>>> I'm working on CALCITE-6220
>>> <https://issues.apache.org/jira/browse/CALCITE-6220> and the summary is
>>> that we should unparse MIN/MAX differently for Postgres/Redshift
>> depending
>>> on its operand type (if the type is BOOLEAN, it should be rewritten as
>>> BOOL_AND/OR).
>>> 
>>> This problem seems simple enough, but I've been having trouble deriving
>> the
>>> operand type during unparsing, which has me wondering whether there's a
>>> better place for this translation to occur. My second thought was that
>> this
>>> could occur in StandardConvertletTable but this does not account for the
>>> case where the incoming dialect is NOT Redshift/Postgres (but the target
>>> dialect is.)
>>> 
>>> With that being said, my question is: where should this translation occur
>>> (a.k.a. where can I properly access the operand type in order to decide
>>> what the call should be unparsed as)?
>>> 
>>> Thanks as always,
>>> Tanner
>>> 
>> 

Reply via email to