Alexis Cubilla created CALCITE-7652:
---------------------------------------

             Summary: 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


 

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.

 



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

Reply via email to