Skip to content

Commit 7e52c92

Browse files
committed
SqlServer: add support for DateConstruct/TimeConstruct
additionally, improved datetime/date/time construction for versions since v11 by using built-in functions
1 parent e26210e commit 7e52c92

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

Orm/Xtensive.Orm.SqlServer/Sql.Drivers.SqlServer/v09/Compiler.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,24 @@ public override void Visit(SqlFunctionCall node)
219219
arguments[1] - 1),
220220
arguments[2] - 1));
221221
return;
222+
#if NET6_0_OR_GREATER
223+
case SqlFunctionType.DateConstruct: {
224+
Visit(SqlDml.Cast(DateAddDay(DateAddMonth(DateAddYear(SqlDml.Literal(new DateOnly(2001, 1, 1)),
225+
arguments[0] - 2001),
226+
arguments[1] - 1),
227+
arguments[2] - 1), SqlType.Date));
228+
return;
229+
}
230+
case SqlFunctionType.TimeConstruct: {
231+
Visit(SqlDml.Cast(DateAddMillisecond(DateAddSecond(DateAddMinute(DateAddHour(SqlDml.Literal(new TimeOnly(0, 0, 0)),
232+
arguments[0]),
233+
arguments[1]),
234+
arguments[2]),
235+
arguments[3]), SqlType.Time));
236+
return;
237+
}
238+
239+
#endif
222240
case SqlFunctionType.DateTimeToStringIso:
223241
Visit(DateTimeToStringIso(arguments[0]));
224242
return;

Orm/Xtensive.Orm.SqlServer/Sql.Drivers.SqlServer/v11/Compiler.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,45 @@ protected override void VisitSelectLimitOffset(SqlSelect node)
4444
}
4545
}
4646

47+
public override void Visit(SqlFunctionCall node)
48+
{
49+
var arguments = node.Arguments;
50+
switch (node.FunctionType) {
51+
case SqlFunctionType.DateTimeConstruct:
52+
Visit(SqlDml.FunctionCall("DATETIME2FROMPARTS", arguments[0], arguments[1], arguments[2], 0, 0, 0, 0, 7));
53+
//Visit(DateAddDay(DateAddMonth(DateAddYear(SqlDml.Literal(new DateTime(2001, 1, 1)),
54+
// arguments[0] - 2001),
55+
// arguments[1] - 1),
56+
// arguments[2] - 1));
57+
return;
58+
#if NET6_0_OR_GREATER
59+
case SqlFunctionType.DateConstruct: {
60+
Visit(SqlDml.FunctionCall("DATEFROMPARTS", arguments[0], arguments[1], arguments[2]));
61+
62+
//Visit(SqlDml.Cast(DateAddDay(DateAddMonth(DateAddYear(SqlDml.Literal(new DateOnly(2001, 1, 1)),
63+
// arguments[0] - 2001),
64+
// arguments[1] - 1),
65+
// arguments[2] - 1), SqlType.Date));
66+
return;
67+
}
68+
case SqlFunctionType.TimeConstruct: {
69+
// argument[3] * 10000 operation is based on statement that millisaconds use 3 digits
70+
// default precision of time is 7, and if we use raw argument[3] value the result will be .0000xxx,
71+
// to prevent this and make fractions part valid .xxx0000 we multiply
72+
Visit(SqlDml.FunctionCall("TIMEFROMPARTS", arguments[0], arguments[1], arguments[2], arguments[3] * 10000, 7));
73+
//Visit(SqlDml.Cast(DateAddMillisecond(DateAddSecond(DateAddMinute(DateAddHour(SqlDml.Literal(new TimeOnly(0, 0, 0)),
74+
// arguments[0]),
75+
// arguments[1]),
76+
// arguments[2]),
77+
// arguments[3]), SqlType.Time));
78+
return;
79+
}
80+
#endif
81+
}
82+
83+
base.Visit(node);
84+
}
85+
4786
public Compiler(SqlDriver driver)
4887
: base(driver)
4988
{

0 commit comments

Comments
 (0)