Skip to content

Commit

Permalink
Add DATEFROMPARTS function to SqlServer (#19400)
Browse files Browse the repository at this point in the history
Add DATEFROMPARTS function to SqlServer
  • Loading branch information
Marusyk authored and maumar committed Jan 8, 2020
1 parent 584855a commit 828d0de
Show file tree
Hide file tree
Showing 5 changed files with 476 additions and 46 deletions.
112 changes: 112 additions & 0 deletions src/EFCore.SqlServer/Extensions/SqlServerDbFunctionsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,5 +1007,117 @@ public static DateTime DateTimeFromParts(
int second,
int millisecond)
=> throw new InvalidOperationException(SqlServerStrings.FunctionOnClient(nameof(DateTimeFromParts)));

/// <summary>
/// Initializes a new instance of the <see cref="DateTime" /> structure to the specified year, month, day.
/// Corresponds to the SQL Server's DATEFROMPARTS(year, month, day).
/// </summary>
/// <param name="_">The DbFunctions instance.</param>
/// <param name="year">The year (1753 through 9999).</param>
/// <param name="month">The month (1 through 12).</param>
/// <param name="day">The day (1 through the number of days in month).</param>
/// <returns>New instance of the <see cref="DateTime" /> structure to the specified year, month, day.</returns>
public static DateTime DateFromParts(
[CanBeNull] this DbFunctions _,
int year,
int month,
int day)
=> throw new InvalidOperationException(SqlServerStrings.FunctionOnClient(nameof(DateFromParts)));

/// <summary>
/// Initializes a new instance of the <see cref="DateTime" /> structure to the specified year, month, day, hour, minute, second, fractions, and precision.
/// Corresponds to the SQL Server's DATETIME2FROMPARTS (year, month, day, hour, minute, seconds, fractions, precision).
/// </summary>
/// <param name="_">The DbFunctions instance.</param>
/// <param name="year">The year (1753 through 9999).</param>
/// <param name="month">The month (1 through 12).</param>
/// <param name="day">The day (1 through the number of days in month).</param>
/// <param name="hour">The hours (0 through 23).</param>
/// <param name="minute">The minutes (0 through 59).</param>
/// <param name="second">The seconds (0 through 59).</param>
/// <param name="fractions">The fractional seconds (0 through 9999999).</param>
/// <param name="precision">The precision of the datetime2 value (0 through 7).</param>
/// <returns>New instance of the <see cref="DateTime" /> structure to the specified year, month, day, hour, minute, second, fractions, and precision.</returns>
public static DateTime DateTime2FromParts(
[CanBeNull] this DbFunctions _,
int year,
int month,
int day,
int hour,
int minute,
int second,
int fractions,
int precision)
=> throw new InvalidOperationException(SqlServerStrings.FunctionOnClient(nameof(DateTime2FromParts)));

/// <summary>
/// Initializes a new instance of the <see cref="DateTimeOffset" /> structure to the specified year, month, day, hour, minute, second, fractions, hourOffset, minuteOffset and precision.
/// Corresponds to the SQL Server's DATETIMEOFFSETFROMPARTS (year, month, day, hour, minute, seconds, fractions, hour_offset, minute_offset, precision).
/// </summary>
/// <param name="_">The DbFunctions instance.</param>
/// <param name="year">The year (1753 through 9999).</param>
/// <param name="month">The month (1 through 12).</param>
/// <param name="day">The day (1 through the number of days in month).</param>
/// <param name="hour">The hours (0 through 23).</param>
/// <param name="minute">The minutes (0 through 59).</param>
/// <param name="second">The seconds (0 through 59).</param>
/// <param name="fractions">The fractional seconds (0 through 9999999).</param>
/// <param name="hourOffset">The hour portion of the time zone offset (-14 through +14).</param>
/// <param name="minuteOffset">The minute portion of the time zone offset (0 or 30).</param>
/// <param name="precision">The precision of the datetimeoffset value (0 through 7).</param>
/// <returns>New instance of the <see cref="DateTimeOffset" /> structure to the specified year, month, day, hour, minute, second, fractions, hourOffset, minuteOffset and precision.</returns>
public static DateTimeOffset DateTimeOffsetFromParts(
[CanBeNull] this DbFunctions _,
int year,
int month,
int day,
int hour,
int minute,
int second,
int fractions,
int hourOffset,
int minuteOffset,
int precision)
=> throw new InvalidOperationException(SqlServerStrings.FunctionOnClient(nameof(DateTimeOffsetFromParts)));

/// <summary>
/// Initializes a new instance of the <see cref="DateTime" /> structure to the specified year, month, day, hour and minute.
/// Corresponds to the SQL Server's SMALLDATETIMEFROMPARTS (year, month, day, hour, minute).
/// </summary>
/// <param name="_">The DbFunctions instance.</param>
/// <param name="year">The year (1753 through 9999).</param>
/// <param name="month">The month (1 through 12).</param>
/// <param name="day">The day (1 through the number of days in month).</param>
/// <param name="hour">The hours (0 through 23).</param>
/// <param name="minute">The minutes (0 through 59).</param>
/// <returns>New instance of the <see cref="DateTime" /> structure to the specified year, month, day, hour and minute.</returns>
public static DateTime SmallDateTimeFromParts(
[CanBeNull] this DbFunctions _,
int year,
int month,
int day,
int hour,
int minute)
=> throw new InvalidOperationException(SqlServerStrings.FunctionOnClient(nameof(SmallDateTimeFromParts)));

/// <summary>
/// Initializes a new instance of the <see cref="TimeSpan" /> structure to the specified hour, minute, second, fractions, and precision.
/// Corresponds to the SQL Server's TIMEFROMPARTS (hour, minute, seconds, fractions, precision).
/// </summary>
/// <param name="_">The DbFunctions instance.</param>
/// <param name="hour">The hours (0 through 23).</param>
/// <param name="minute">The minutes (0 through 59).</param>
/// <param name="second">The seconds (0 through 59).</param>
/// <param name="fractions">The fractional seconds (0 through 9999999).</param>
/// <param name="precision">The precision of the time value (0 through 7).</param>
/// <returns>New instance of the <see cref="TimeSpan" /> structure to the specified hour, minute, second, fractions, and precision.</returns>
public static TimeSpan TimeFromParts(
[CanBeNull] this DbFunctions _,
int hour,
int minute,
int second,
int fractions,
int precision)
=> throw new InvalidOperationException(SqlServerStrings.FunctionOnClient(nameof(TimeFromParts)));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Storage;

namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal
{
public class SqlServerFromPartsFunctionTranslator : IMethodCallTranslator
{
private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly IRelationalTypeMappingSource _typeMappingSource;

private static readonly MethodInfo _dateFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions)
.GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int) });

private static readonly MethodInfo _dateTimeFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions)
.GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTimeFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });

private static readonly MethodInfo _dateTime2FromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions)
.GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTime2FromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });

private static readonly MethodInfo _dateTimeOffsetFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions)
.GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTimeOffsetFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });

private static readonly MethodInfo _smallDateTimeFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions)
.GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.SmallDateTimeFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });

private static readonly MethodInfo _timeFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions)
.GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.TimeFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });

public SqlServerFromPartsFunctionTranslator(
[NotNull] ISqlExpressionFactory sqlExpressionFactory,
[NotNull] IRelationalTypeMappingSource typeMappingSource)
{
_sqlExpressionFactory = sqlExpressionFactory;
_typeMappingSource = typeMappingSource;
}

public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList<SqlExpression> arguments)
{
if (_dateFromPartsMethodInfo.Equals(method))
{
return _sqlExpressionFactory.Function(
"DATEFROMPARTS",
arguments.Skip(1),
_dateFromPartsMethodInfo.ReturnType,
_typeMappingSource.FindMapping(typeof(DateTime), "date"));
}

if (_dateTimeFromPartsMethodInfo.Equals(method))
{
return _sqlExpressionFactory.Function(
"DATETIMEFROMPARTS",
arguments.Skip(1),
_dateTimeFromPartsMethodInfo.ReturnType,
_typeMappingSource.FindMapping(typeof(DateTime), "datetime"));
}

if (_dateTime2FromPartsMethodInfo.Equals(method))
{
return _sqlExpressionFactory.Function(
"DATETIME2FROMPARTS",
arguments.Skip(1),
_dateTime2FromPartsMethodInfo.ReturnType,
_typeMappingSource.FindMapping(typeof(DateTime), "datetime2"));
}

if (_dateTimeOffsetFromPartsMethodInfo.Equals(method))
{
return _sqlExpressionFactory.Function(
"DATETIMEOFFSETFROMPARTS",
arguments.Skip(1),
_dateTimeOffsetFromPartsMethodInfo.ReturnType,
_typeMappingSource.FindMapping(typeof(DateTimeOffset), "datetimeoffset"));
}

if (_smallDateTimeFromPartsMethodInfo.Equals(method))
{
return _sqlExpressionFactory.Function(
"SMALLDATETIMEFROMPARTS",
arguments.Skip(1),
_smallDateTimeFromPartsMethodInfo.ReturnType,
_typeMappingSource.FindMapping(typeof(DateTime), "smalldatetime"));
}

if (_timeFromPartsMethodInfo.Equals(method))
{
return _sqlExpressionFactory.Function(
"TIMEFROMPARTS",
arguments.Skip(1),
_timeFromPartsMethodInfo.ReturnType,
_typeMappingSource.FindMapping(typeof(TimeSpan), "time"));
}

return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ public SqlServerMethodCallTranslatorProvider([NotNull] RelationalMethodCallTrans
new SqlServerByteArrayMethodTranslator(sqlExpressionFactory),
new SqlServerConvertTranslator(sqlExpressionFactory),
new SqlServerDateDiffFunctionsTranslator(sqlExpressionFactory),
new SqlServerDateTimeFromPartsFunctionTranslator(sqlExpressionFactory, typeMappingSource),
new SqlServerDateTimeMethodTranslator(sqlExpressionFactory),
new SqlServerFromPartsFunctionTranslator(sqlExpressionFactory, typeMappingSource),
new SqlServerFullTextSearchFunctionsTranslator(sqlExpressionFactory),
new SqlServerIsDateFunctionTranslator(sqlExpressionFactory),
new SqlServerMathTranslator(sqlExpressionFactory),
new SqlServerNewGuidTranslator(sqlExpressionFactory),
new SqlServerObjectToStringTranslator(sqlExpressionFactory),
new SqlServerStringMethodTranslator(sqlExpressionFactory)
new SqlServerStringMethodTranslator(sqlExpressionFactory),
});
}
}
Expand Down
Loading

0 comments on commit 828d0de

Please sign in to comment.