[ 
https://issues.apache.org/jira/browse/CALCITE-7652?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Alexis Cubilla updated CALCITE-7652:
------------------------------------
    Description: 
 

PROBLEM

When RelToSqlConverter generates SQL for the SQL Server dialect 
(MssqlSqlDialect),
a CAST whose target type is TIMESTAMP is unparsed literally as TIMESTAMP(n).
In SQL Server, TIMESTAMP is a deprecated synonym for ROWVERSION — a binary,
auto-generated type — not a date/time type. As a result, the generated SQL is
rejected by the server.

This is commonly triggered by an implicit cast. For example, comparing a 
DATETIME
column (Calcite type TIMESTAMP(3)) against CURRENT_TIMESTAMP (Calcite type
TIMESTAMP(0)) makes Calcite insert a cast to align precision.

STEPS TO REPRODUCE

Generate SQL for the MSSQL dialect from a query such as:

    SELECT "fec" FROM "t" WHERE "fec" < CURRENT_TIMESTAMP     ("fec" is 
TIMESTAMP(3))

RelToSqlConverter with MssqlSqlDialect.DEFAULT produces:

    SELECT [fec] FROM [t] WHERE [fec] < CAST(CURRENT_TIMESTAMP AS TIMESTAMP(3))

Equivalently, MssqlSqlDialect.DEFAULT.getCastSpec(<TIMESTAMP(3)>) returns 
"TIMESTAMP(3)".

ACTUAL RESULT

SQL Server rejects the statement:

    CAST or CONVERT: invalid attributes specified for type 'timestamp'

EXPECTED RESULT

The dialect should emit a valid SQL Server date/time type. TIMESTAMP(n) should 
map
to DATETIME2(n) (SQL Server 2008+):

    SELECT [fec] FROM [t] WHERE [fec] < CAST(CURRENT_TIMESTAMP AS DATETIME2(3))

ROOT CAUSE

MssqlSqlDialect does not override getCastSpec(RelDataType) for 
SqlTypeName.TIMESTAMP,
so it falls back to the generic behaviour that emits the ANSI type name 
TIMESTAMP —
which is not a temporal type in SQL Server.

PROPOSED FIX

 Override MssqlSqlDialect.getCastSpec to map TIMESTAMP to DATETIME2 and 
TIMESTAMP WITH LOCAL TIME ZONE to DATETIMEOFFSET, both preserving 
fractional-seconds precision (0–7; without an argument SQL Server defaults to 
7). Add RelToSqlConverterTest cases asserting the generated SQL for both.

 

  was:
 

PROBLEM

When RelToSqlConverter generates SQL for the SQL Server dialect 
(MssqlSqlDialect),
a CAST whose target type is TIMESTAMP is unparsed literally as TIMESTAMP(n).
In SQL Server, TIMESTAMP is a deprecated synonym for ROWVERSION — a binary,
auto-generated type — not a date/time type. As a result, the generated SQL is
rejected by the server.

This is commonly triggered by an implicit cast. For example, comparing a 
DATETIME
column (Calcite type TIMESTAMP(3)) against CURRENT_TIMESTAMP (Calcite type
TIMESTAMP(0)) makes Calcite insert a cast to align precision.

STEPS TO REPRODUCE

Generate SQL for the MSSQL dialect from a query such as:

    SELECT "fec" FROM "t" WHERE "fec" < CURRENT_TIMESTAMP     ("fec" is 
TIMESTAMP(3))

RelToSqlConverter with MssqlSqlDialect.DEFAULT produces:

    SELECT [fec] FROM [t] WHERE [fec] < CAST(CURRENT_TIMESTAMP AS TIMESTAMP(3))

Equivalently, MssqlSqlDialect.DEFAULT.getCastSpec(<TIMESTAMP(3)>) returns 
"TIMESTAMP(3)".

ACTUAL RESULT

SQL Server rejects the statement:

    CAST or CONVERT: invalid attributes specified for type 'timestamp'

EXPECTED RESULT

The dialect should emit a valid SQL Server date/time type. TIMESTAMP(n) should 
map
to DATETIME2(n) (SQL Server 2008+):

    SELECT [fec] FROM [t] WHERE [fec] < CAST(CURRENT_TIMESTAMP AS DATETIME2(3))

ROOT CAUSE

MssqlSqlDialect does not override getCastSpec(RelDataType) for 
SqlTypeName.TIMESTAMP,
so it falls back to the generic behaviour that emits the ANSI type name 
TIMESTAMP —
which is not a temporal type in SQL Server.

PROPOSED FIX

Override MssqlSqlDialect.getCastSpec to map TIMESTAMP to DATETIME2 (preserving
precision), plus a RelToSqlConverterTest case asserting the generated SQL. The
TIMESTAMP WITH LOCAL TIME ZONE variant (which maps to datetimeoffset) can be
handled in the same place.

 


> MssqlSqlDialect unparses CAST to TIMESTAMP as "TIMESTAMP", which is invalid 
> in SQL Server (should be DATETIME2)
> ---------------------------------------------------------------------------------------------------------------
>
>                 Key: CALCITE-7652
>                 URL: https://issues.apache.org/jira/browse/CALCITE-7652
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.42.0
>            Reporter: Alexis Cubilla
>            Priority: Minor
>              Labels: pull-request-available
>
>  
> PROBLEM
> When RelToSqlConverter generates SQL for the SQL Server dialect 
> (MssqlSqlDialect),
> a CAST whose target type is TIMESTAMP is unparsed literally as TIMESTAMP(n).
> In SQL Server, TIMESTAMP is a deprecated synonym for ROWVERSION — a binary,
> auto-generated type — not a date/time type. As a result, the generated SQL is
> rejected by the server.
> This is commonly triggered by an implicit cast. For example, comparing a 
> DATETIME
> column (Calcite type TIMESTAMP(3)) against CURRENT_TIMESTAMP (Calcite type
> TIMESTAMP(0)) makes Calcite insert a cast to align precision.
> STEPS TO REPRODUCE
> Generate SQL for the MSSQL dialect from a query such as:
>     SELECT "fec" FROM "t" WHERE "fec" < CURRENT_TIMESTAMP     ("fec" is 
> TIMESTAMP(3))
> RelToSqlConverter with MssqlSqlDialect.DEFAULT produces:
>     SELECT [fec] FROM [t] WHERE [fec] < CAST(CURRENT_TIMESTAMP AS 
> TIMESTAMP(3))
> Equivalently, MssqlSqlDialect.DEFAULT.getCastSpec(<TIMESTAMP(3)>) returns 
> "TIMESTAMP(3)".
> ACTUAL RESULT
> SQL Server rejects the statement:
>     CAST or CONVERT: invalid attributes specified for type 'timestamp'
> EXPECTED RESULT
> The dialect should emit a valid SQL Server date/time type. TIMESTAMP(n) 
> should map
> to DATETIME2(n) (SQL Server 2008+):
>     SELECT [fec] FROM [t] WHERE [fec] < CAST(CURRENT_TIMESTAMP AS 
> DATETIME2(3))
> ROOT CAUSE
> MssqlSqlDialect does not override getCastSpec(RelDataType) for 
> SqlTypeName.TIMESTAMP,
> so it falls back to the generic behaviour that emits the ANSI type name 
> TIMESTAMP —
> which is not a temporal type in SQL Server.
> PROPOSED FIX
>  Override MssqlSqlDialect.getCastSpec to map TIMESTAMP to DATETIME2 and 
> TIMESTAMP WITH LOCAL TIME ZONE to DATETIMEOFFSET, both preserving 
> fractional-seconds precision (0–7; without an argument SQL Server defaults to 
> 7). Add RelToSqlConverterTest cases asserting the generated SQL for both.
>  



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

Reply via email to