Indeed, the "Default" precision of 3 seems to be hardwired in several places in Calcite for TIMESTAMPs and INTERVALs (and maybe for TIME intervals too).
I have filed a related issue about the JavaTypeFactory: https://issues.apache.org/jira/browse/CALCITE-6752 See a list of related issues in the discussion for this other issue I have filed. https://issues.apache.org/jira/browse/CALCITE-5919 Fixing these end-to-end may be difficult. Fixing the literals may be the easy part, but many other layers may need work, even if you get the literals to represent the values you want. As I discuss in the second issue, probably using BigDecimal is the right approach. When you say it "breaks many tests", are the tests wrong? Then they should break. Mihai ________________________________ From: Mark Lewis <mark.s.le...@outlook.com> Sent: Friday, February 28, 2025 9:40 AM To: dev@calcite.apache.org <dev@calcite.apache.org> Subject: Question about scale after parsing day/time intervals to RexLiteral Using Calcite to parse an SQL interval day seems to always result in a RexLiteral with a scale of 6, but with the value a millisecond representation of the interval. This is because SqlLiteral.getValueAs() always returns milliseconds, and the default fractional second precision is 6. The resulting RexLiteral scale confused me since the value of 6 suggested a microsecond representation. I tried to change this behaviour in several ways: 1. Change the default fractional second interval precision to 3. 2. Change SqlNodeToRexConverterImpl.convertLiteral() to scale the value passed to RexBuilder.makeIntervalLiteral() to microseconds in order to match the target scale returned by sqlIntervalQualifier.getFractionalSecondPrecision(rexBuilder.getTypeFactory().getTypeSystem()). 3. Change SqlNodeToRexConverterImpl.convertLiteral() so that it creates a new SqlIntervalQualifier that matches the one associated with the SqlLiteral but with a fractional second precision of 3 to indicate milliseconds. This has no effect because RexBuilder.makeIntervalLiteral() creates the RexLiteral's RelDataType by passing the interval qualifier to SqlTypeFactoryImpl.createSqlIntervalType(), and the canonize() call that happens there discards the fractional second precision — I guess by using an interned value with default fractional second precision. While some of these approaches did produce a RexLiteral that looked more as I expected, they all broke many Calcite tests. Is it expected that day/time intervals should always be represented in milliseconds but also report a scale of 6? If not, can you suggest the right approach to implement the correct behaviour? Thanks in advance for your help, Mark.