Skip to content

Only read date unit words as date units when they are function arguments - #2825

Draft
edeadington wants to merge 1 commit into
JSQLParser:masterfrom
edeadington:fix/date-unit-only-as-function-argument
Draft

edeadington wants to merge 1 commit into
JSQLParser:masterfrom
edeadington:fix/date-unit-only-as-function-argument

Conversation

@edeadington

@edeadington edeadington commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Since DateUnitExpression was added, an unquoted YEAR, MONTH, DAY, HOUR, MINUTE or SECOND is read as a date unit anywhere an expression can start, not only inside date functions. Columns with those names, which are common and not reserved in most databases, come back wrong:

SELECT year FROM t
-- a DateUnitExpression that prints as YEAR, not a Column

SELECT month.amount FROM sales month
-- RowGetExpression(DateUnitExpression(MONTH), amount), not Column(month.amount)

UPDATE t SET (a, year) = (1, 2)
-- ClassCastException from UpdateSet.getColumn(1)

DateUnitExpression also kept only the enum, so the original spelling was lost and day printed back as DAY.

This PR removes DateUnitExpression from PrimaryExpression, so these words parse as columns again, as they did before. A word is converted to a DateUnitExpression only after the function has been parsed and only when it is a whole, unquoted argument of the function, e.g. DATEADD(day, 1, d) or LAST_DAY(d, month). This follows the same approach as the existing ODBC TIMESTAMPADD interval normalisation. A word inside a larger argument expression, such as COALESCE(year + 1, 0), stays a column. DateUnitExpression now keeps the text it was parsed from, so day prints back as day.

The new tests cover the unit argument, a bare column, a qualified column, a word nested within an argument expression, a quoted argument and the UPDATE tuple.

An unquoted YEAR, MONTH, DAY, HOUR, MINUTE or SECOND was parsed as a
DateUnitExpression anywhere an expression could start, so a column with
one of those names lost its spelling and its qualifier, and broke
UPDATE ... SET (a, year) = ... with a ClassCastException. The word is now
parsed as a Column and converted to a DateUnitExpression only when it is
a whole argument of a function, which keeps its original spelling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@edeadington
edeadington marked this pull request as ready for review October 15, 2026 10:03
@edeadington
edeadington marked this pull request as draft October 15, 2026 10:54

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant