`DAY` used as argument for `DATEADD()` is interpreted as `ColumnReferenceExpression`
Script
USE MyDB
GO
SELECT Id,
DATEADD(DAY, 1, GETDATE())
FROM Table1
GO
SELECT DATEADD(DAY, 1, GETDATE())
The 2nd query does not select from a table, but also then, DAY is of type ColumnReferenceExpression.
AST of the above-mentioned script
+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Type | Region | Contents |
+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TSqlScript | (1,1) - (10,1) | USE MyDB\r\nGO\r\n\r\nSELECT Id,\r\n DATEADD(DAY, 1, GETDATE())\r\nFROM Table1\r\n\r\nGO\r\nSELECT DATEADD(DAY, 1, GETDATE())\r\n |
| TSqlBatch | (1,1) - (1,9) | USE MyDB |
| UseStatement | (1,1) - (1,9) | USE MyDB |
| Identifier | (1,5) - (1,9) | MyDB |
| TSqlBatch | (4,1) - (6,19) | SELECT Id,\r\n DATEADD(DAY, 1, GETDATE())\r\nFROM Table1 |
| SelectStatement | (4,1) - (6,19) | SELECT Id,\r\n DATEADD(DAY, 1, GETDATE())\r\nFROM Table1 |
| QuerySpecification | (4,1) - (6,19) | SELECT Id,\r\n DATEADD(DAY, 1, GETDATE())\r\nFROM Table1 |
| SelectScalarExpression | (4,13) - (4,15) | Id |
| ColumnReferenceExpression | (4,13) - (4,15) | Id |
| MultiPartIdentifier | (4,13) - (4,15) | Id |
| Identifier | (4,13) - (4,15) | Id |
| SelectScalarExpression | (5,13) - (5,39) | DATEADD(DAY, 1, GETDATE()) |
| FunctionCall | (5,13) - (5,39) | DATEADD(DAY, 1, GETDATE()) |
| Identifier | (5,13) - (5,20) | DATEADD |
| ColumnReferenceExpression | (5,21) - (5,24) | DAY |
| MultiPartIdentifier | (5,21) - (5,24) | DAY |
| Identifier | (5,21) - (5,24) | DAY |
| IntegerLiteral | (5,26) - (5,27) | 1 |
| FunctionCall | (5,29) - (5,38) | GETDATE() |
| Identifier | (5,29) - (5,36) | GETDATE |
| FromClause | (6,1) - (6,19) | FROM Table1 |
| NamedTableReference | (6,13) - (6,19) | Table1 |
| SchemaObjectName | (6,13) - (6,19) | Table1 |
| Identifier | (6,13) - (6,19) | Table1 |
| TSqlBatch | (9,1) - (9,39) | SELECT DATEADD(DAY, 1, GETDATE()) |
| SelectStatement | (9,1) - (9,39) | SELECT DATEADD(DAY, 1, GETDATE()) |
| QuerySpecification | (9,1) - (9,39) | SELECT DATEADD(DAY, 1, GETDATE()) |
| SelectScalarExpression | (9,13) - (9,39) | DATEADD(DAY, 1, GETDATE()) |
| FunctionCall | (9,13) - (9,39) | DATEADD(DAY, 1, GETDATE()) |
| Identifier | (9,13) - (9,20) | DATEADD |
| ColumnReferenceExpression | (9,21) - (9,24) | DAY |
| MultiPartIdentifier | (9,21) - (9,24) | DAY |
| Identifier | (9,21) - (9,24) | DAY |
| IntegerLiteral | (9,26) - (9,27) | 1 |
| FunctionCall | (9,29) - (9,38) | GETDATE() |
| Identifier | (9,29) - (9,36) | GETDATE |
+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
Tokens of the above-mentioned script
+-------+------------------+-----------------+----------------+
| Index | Type | Region | Contents |
+-------+------------------+-----------------+----------------+
| 0 | Use | (1,1) - (1,4) | USE |
| 1 | WhiteSpace | (1,4) - (1,5) | ¦ ¦ |
| 2 | Identifier | (1,5) - (1,9) | MyDB |
| 3 | WhiteSpace | (1,9) - (2,1) | \r\n |
| 4 | Go | (2,1) - (2,3) | GO |
| 5 | WhiteSpace | (2,3) - (3,1) | \r\n |
| 6 | WhiteSpace | (3,1) - (4,1) | \r\n |
| 7 | Select | (4,1) - (4,7) | SELECT |
| 8 | WhiteSpace | (4,7) - (4,13) | ¦ ¦ |
| 9 | Identifier | (4,13) - (4,15) | Id |
| 10 | Comma | (4,15) - (4,16) | , |
| 11 | WhiteSpace | (4,16) - (5,1) | \r\n |
| 12 | WhiteSpace | (5,1) - (5,13) | ¦ ¦ |
| 13 | Identifier | (5,13) - (5,20) | DATEADD |
| 14 | LeftParenthesis | (5,20) - (5,21) | ( |
| 15 | Identifier | (5,21) - (5,24) | DAY |
| 16 | Comma | (5,24) - (5,25) | , |
| 17 | WhiteSpace | (5,25) - (5,26) | ¦ ¦ |
| 18 | Integer | (5,26) - (5,27) | 1 |
| 19 | Comma | (5,27) - (5,28) | , |
| 20 | WhiteSpace | (5,28) - (5,29) | ¦ ¦ |
| 21 | Identifier | (5,29) - (5,36) | GETDATE |
| 22 | LeftParenthesis | (5,36) - (5,37) | ( |
| 23 | RightParenthesis | (5,37) - (5,38) | ) |
| 24 | RightParenthesis | (5,38) - (5,39) | ) |
| 25 | WhiteSpace | (5,39) - (6,1) | \r\n |
| 26 | From | (6,1) - (6,5) | FROM |
| 27 | WhiteSpace | (6,5) - (6,13) | ¦ ¦ |
| 28 | Identifier | (6,13) - (6,19) | Table1 |
| 29 | WhiteSpace | (6,19) - (7,1) | \r\n |
| 30 | WhiteSpace | (7,1) - (8,1) | \r\n |
| 31 | Go | (8,1) - (8,3) | GO |
| 32 | WhiteSpace | (8,3) - (9,1) | \r\n |
| 33 | Select | (9,1) - (9,7) | SELECT |
| 34 | WhiteSpace | (9,7) - (9,13) | ¦ ¦ |
| 35 | Identifier | (9,13) - (9,20) | DATEADD |
| 36 | LeftParenthesis | (9,20) - (9,21) | ( |
| 37 | Identifier | (9,21) - (9,24) | DAY |
| 38 | Comma | (9,24) - (9,25) | , |
| 39 | WhiteSpace | (9,25) - (9,26) | ¦ ¦ |
| 40 | Integer | (9,26) - (9,27) | 1 |
| 41 | Comma | (9,27) - (9,28) | , |
| 42 | WhiteSpace | (9,28) - (9,29) | ¦ ¦ |
| 43 | Identifier | (9,29) - (9,36) | GETDATE |
| 44 | LeftParenthesis | (9,36) - (9,37) | ( |
| 45 | RightParenthesis | (9,37) - (9,38) | ) |
| 46 | RightParenthesis | (9,38) - (9,39) | ) |
| 47 | WhiteSpace | (9,39) - (10,1) | \r\n |
| 48 | EndOfFile | (10,1) - (10,1) | ¦¦ |
+-------+------------------+-----------------+----------------+
It seems that the same issue also exists for DATENAME, DATEDIFF, and DATEPART. The first argument to the function, an interval, is being treated as a column reference expression.
Queries
SELECT DATEDIFF(year, '2017/08/25', '2011/08/25')
SELECT DATENAME(year, '2017/08/25')
SELECT DATEPART(year, '2017/08/25')
Incorrect AST
SelectStatement [SELECT DATEDIFF(year, '2017/08/25', '2011/08/25')] QuerySpecification [SELECT DATEDIFF(year, '2017/08/25', '2011/08/25')] SelectScalarExpression [DATEDIFF(year, '2017/08/25', '2011/08/25')] FunctionCall [DATEDIFF(year, '2017/08/25', '2011/08/25')] Identifier [DATEDIFF] ColumnReferenceExpression [year] MultiPartIdentifier [year] Identifier [year] StringLiteral ['2017/08/25'] StringLiteral ['2011/08/25']
The produced ASTs for DATENAME and DATEPART are incorrect in the same way
👍
looks similar to #98