Skip to content

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

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

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

Conversation

@mountaincrab

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.

Same change as #2825, raised from another fork.

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>
@mountaincrab
mountaincrab marked this pull request as ready for review October 20, 2026 09:01

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.

2 participants