Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,20 @@ internal static class CodeGenerationSupporter
internal const string DataRetention = "DATA_RETENTION";
internal const string DataSource = "DATA_SOURCE";
internal const string Date = "DATE";
internal const string DateAdd = "DATEADD";
internal const string DateBucket = "DATE_BUCKET";
internal const string DateCorrelationOptimization = "DATE_CORRELATION_OPTIMIZATION";
internal const string DateDiff = "DATEDIFF";
internal const string DateDiffBig = "DATEDIFF_BIG";
internal const string DateFirst = "DATEFIRST";
internal const string DateFormat = "DATEFORMAT";
internal const string DateFormat2 = "DATE_FORMAT";
internal const string DateName = "DATENAME";
internal const string DatePart = "DATEPART";
internal const string DateTime = "DATETIME";
internal const string DateTime2 = "DATETIME2";
internal const string DateTimeOffset = "DATETIMEOFFSET";
internal const string DateTrunc = "DATETRUNC";
internal const string Deterministic = "DETERMINISTIC";
internal const string DboOnly = "DBO_ONLY";
internal const string DbChaining = "DB_CHAINING";
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql100.g
Original file line number Diff line number Diff line change
Expand Up @@ -20874,6 +20874,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql110.g
Original file line number Diff line number Diff line change
Expand Up @@ -23849,6 +23849,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql120.g
Original file line number Diff line number Diff line change
Expand Up @@ -24598,6 +24598,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql130.g
Original file line number Diff line number Diff line change
Expand Up @@ -29420,6 +29420,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql140.g
Original file line number Diff line number Diff line change
Expand Up @@ -30237,6 +30237,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql150.g
Original file line number Diff line number Diff line change
Expand Up @@ -31390,6 +31390,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql160.g
Original file line number Diff line number Diff line change
Expand Up @@ -32215,6 +32215,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql170.g
Original file line number Diff line number Diff line change
Expand Up @@ -33343,6 +33343,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql180.g
Original file line number Diff line number Diff line change
Expand Up @@ -33343,6 +33343,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql80.g
Original file line number Diff line number Diff line change
Expand Up @@ -9103,6 +9103,9 @@ identifierBuiltInFunctionCallDefaultParams [FunctionCall vParent]
}
:
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
47 changes: 46 additions & 1 deletion SqlScriptDom/Parser/TSql/TSql80ParserBaseInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1979,6 +1979,51 @@ protected void PutIdentifiersIntoFunctionCall(FunctionCall functionCall, MultiPa
}
}

protected void NormalizeDatePartFunctionFirstParameter(FunctionCall functionCall)
{
if (functionCall == null ||
functionCall.FunctionName == null ||
String.IsNullOrEmpty(functionCall.FunctionName.Value) ||
functionCall.Parameters == null ||
functionCall.Parameters.Count == 0 ||
!IsDatePartFunction(functionCall.FunctionName.Value))
{
return;
}

ColumnReferenceExpression columnReference = functionCall.Parameters[0] as ColumnReferenceExpression;
if (columnReference == null ||
columnReference.MultiPartIdentifier == null ||
columnReference.MultiPartIdentifier.Count != 1)
{
return;
}

Identifier identifier = columnReference.MultiPartIdentifier[0];
IdentifierLiteral literal = FragmentFactory.CreateFragment<IdentifierLiteral>();
literal.Value = identifier.Value;
literal.QuoteType = identifier.QuoteType;
literal.UpdateTokenInfo(columnReference);
functionCall.Parameters[0] = literal;
}

private static bool IsDatePartFunction(string functionName)
{
switch (functionName.ToUpper(CultureInfo.InvariantCulture))
{
case CodeGenerationSupporter.DateAdd:
case CodeGenerationSupporter.DateBucket:
case CodeGenerationSupporter.DateDiff:
case CodeGenerationSupporter.DateDiffBig:
case CodeGenerationSupporter.DateName:
case CodeGenerationSupporter.DatePart:
case CodeGenerationSupporter.DateTrunc:
return true;
default:
return false;
}
}

protected void VerifyColumnDataType(ColumnDefinition column)
{
// If the scalarDataType is not parsed, the ColumnIdentifier has to be a timestamp.
Expand Down Expand Up @@ -2426,4 +2471,4 @@ protected static TSqlParseErrorException GetUnexpectedTokenErrorException(Identi

#endregion
}
}
}
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql90.g
Original file line number Diff line number Diff line change
Expand Up @@ -16550,6 +16550,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
3 changes: 3 additions & 0 deletions SqlScriptDom/Parser/TSql/TSqlFabricDW.g
Original file line number Diff line number Diff line change
Expand Up @@ -32381,6 +32381,9 @@ regularBuiltInFunctionCall [FunctionCall vParent]
:
(
expressionList[vParent, vParent.Parameters]
{
NormalizeDatePartFunctionFirstParameter(vParent);
}
|
vColumn=starColumnReferenceExpression
{
Expand Down
31 changes: 31 additions & 0 deletions Test/SqlDom/Only160SyntaxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,37 @@ public void TSql160Azure_SyntaxIn160ParserTest()
}
}

[TestMethod]
[Priority(0)]
[SqlStudioTestCategory(Category.UnitTest)]
public void DatePartFunctionParametersAreIdentifierLiteralsTest()
{
TSql160Parser parser = new TSql160Parser(true);

VerifyDatePartParameter(parser, "SELECT DATEDIFF(mm, ColA, ColB) FROM my_table;", "mm");
VerifyDatePartParameter(parser, "SELECT DATEADD(day, 1, ColA) FROM my_table;", "day");
VerifyDatePartParameter(parser, "SELECT DATEDIFF_BIG(second, ColA, ColB) FROM my_table;", "second");
VerifyDatePartParameter(parser, "SELECT DATENAME(month, ColA) FROM my_table;", "month");
VerifyDatePartParameter(parser, "SELECT DATEPART(wk, ColA) FROM my_table;", "wk");
VerifyDatePartParameter(parser, "SELECT DATE_BUCKET(WEEK, 10, ColA) FROM my_table;", "WEEK");
VerifyDatePartParameter(parser, "SELECT DATETRUNC(year, ColA) FROM my_table;", "year");
}

private static void VerifyDatePartParameter(TSqlParser parser, string sql, string expectedDatePart)
{
TSqlFragment fragment = parser.Parse(new System.IO.StringReader(sql), out System.Collections.Generic.IList<ParseError> errors);

Assert.AreEqual(0, errors.Count, sql);
TSqlScript script = (TSqlScript)fragment;
SelectStatement select = (SelectStatement)script.Batches[0].Statements[0];
QuerySpecification query = (QuerySpecification)select.QueryExpression;
SelectScalarExpression selectExpression = (SelectScalarExpression)query.SelectElements[0];
FunctionCall functionCall = (FunctionCall)selectExpression.Expression;

Assert.IsInstanceOfType(functionCall.Parameters[0], typeof(IdentifierLiteral), sql);
Assert.AreEqual(expectedDatePart, ((IdentifierLiteral)functionCall.Parameters[0]).Value, sql);
}

[TestMethod]
[Priority(0)]
[SqlStudioTestCategory(Category.UnitTest)]
Expand Down
Loading