Skip to content

Commit 6c59d90

Browse files
committed
TimeOnly.Ticks support
1 parent 4f7cdf9 commit 6c59d90

8 files changed

Lines changed: 178 additions & 60 deletions

File tree

Orm/Xtensive.Orm.Firebird/Sql.Drivers.Firebird/v2_5/Compiler.cs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@ namespace Xtensive.Sql.Drivers.Firebird.v2_5
1616
{
1717
internal class Compiler : SqlCompiler
1818
{
19-
protected static readonly long NanosecondsPerDay = TimeSpan.FromDays(1).Ticks * 100;
20-
protected static readonly long NanosecondsPerSecond = 1000000000;
21-
protected static readonly long NanosecondsPerMillisecond = 1000000;
22-
protected static readonly long MillisecondsPerDay = (long) TimeSpan.FromDays(1).TotalMilliseconds;
23-
protected static readonly long MillisecondsPerSecond = 1000L;
19+
protected const long NanosecondsPerDay = 86400000000000;
20+
protected const long NanosecondsPerHour = 3600000000000;
21+
protected const long NanosecondsPerMinute = 60000000000;
22+
protected const long NanosecondsPerSecond = 1000000000;
23+
protected const long NanosecondsPerMillisecond = 1000000;
24+
protected const long MillisecondsPerDay = 86400000;
25+
protected const long MillisecondsPerSecond = 1000L;
26+
27+
//protected static readonly long NanosecondsPerDay = TimeSpan.FromDays(1).Ticks * 100;
28+
//protected static readonly long NanosecondsPerSecond = 1000000000;
29+
//protected static readonly long NanosecondsPerMillisecond = 1000000;
30+
//protected static readonly long MillisecondsPerDay = (long) TimeSpan.FromDays(1).TotalMilliseconds;
31+
//protected static readonly long MillisecondsPerSecond = 1000L;
2432
private bool case_SqlDateTimePart_DayOfYear;
2533
private bool case_SqlDateTimePart_Second;
2634

@@ -253,6 +261,9 @@ public override void Visit(SqlFunctionCall node)
253261
case SqlFunctionType.TimeConstruct:
254262
ConstructTime(arguments).AcceptVisitor(this);
255263
return;
264+
case SqlFunctionType.TimeToNanoseconds:
265+
TimeToNanoseconds(arguments[0]).AcceptVisitor(this);
266+
return;
256267
case SqlFunctionType.DateToString:
257268
Visit(DateToString(arguments[0]));
258269
return;
@@ -336,6 +347,16 @@ protected virtual SqlExpression ConstructTime(IReadOnlyList<SqlExpression> argum
336347
throw new InvalidOperationException("Unsupported count of parameters");
337348
}
338349
}
350+
351+
protected virtual SqlExpression TimeToNanoseconds(SqlExpression time)
352+
{
353+
var nPerHour = SqlDml.Extract(SqlTimePart.Hour, time) * NanosecondsPerHour;
354+
var nPerMinute = SqlDml.Extract(SqlTimePart.Minute, time) * NanosecondsPerMinute;
355+
var nPerSecond = SqlDml.Extract(SqlTimePart.Second, time) * NanosecondsPerSecond;
356+
var nPerMillisecond = SqlDml.Extract(SqlTimePart.Millisecond, time) * NanosecondsPerMillisecond;
357+
358+
return nPerHour + nPerMinute + nPerSecond + nPerMillisecond;
359+
}
339360
#endif
340361

341362
#region Static helpers

Orm/Xtensive.Orm.MySql/Sql.Drivers.MySql/v5_0/Compiler.cs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@ namespace Xtensive.Sql.Drivers.MySql.v5_0
1616
{
1717
internal class Compiler : SqlCompiler
1818
{
19-
protected static readonly long NanosecondsPerDay = TimeSpan.FromDays(1).Ticks * 100;
20-
protected static readonly long NanosecondsPerSecond = 1000000000;
21-
protected static readonly long NanosecondsPerMillisecond = 1000000;
22-
protected static readonly long NanosecondsPerMicrosecond = 1000;
23-
protected static readonly long MillisecondsPerDay = (long) TimeSpan.FromDays(1).TotalMilliseconds;
24-
protected static readonly long MillisecondsPerSecond = 1000L;
19+
protected const long NanosecondsPerDay = 86400000000000;
20+
protected const long NanosecondsPerHour = 3600000000000;
21+
protected const long NanosecondsPerMinute = 60000000000;
22+
protected const long NanosecondsPerSecond = 1000000000;
23+
protected const long NanosecondsPerMillisecond = 1000000;
24+
protected const long NanosecondsPerMicrosecond = 1000;
25+
protected const long MillisecondsPerDay = 86400000;
26+
27+
//protected static readonly long NanosecondsPerDay = TimeSpan.FromDays(1).Ticks * 100;
28+
//protected static readonly long NanosecondsPerSecond = 1000000000;
29+
//protected static readonly long NanosecondsPerMillisecond = 1000000;
30+
//protected static readonly long NanosecondsPerMicrosecond = 1000;
31+
//protected static readonly long MillisecondsPerDay = (long) TimeSpan.FromDays(1).TotalMilliseconds;
32+
//protected static readonly long MillisecondsPerSecond = 1000L;
2533

2634
/// <inheritdoc/>
2735
public override void Visit(SqlSelect node)
@@ -217,6 +225,9 @@ public override void Visit(SqlFunctionCall node)
217225
case SqlFunctionType.TimeConstruct:
218226
ConstructTime(arguments).AcceptVisitor(this);
219227
return;
228+
case SqlFunctionType.TimeToNanoseconds:
229+
TimeToNanoseconds(arguments[0]).AcceptVisitor(this);
230+
return;
220231
case SqlFunctionType.DateToString:
221232
Visit(DateToString(arguments[0]));
222233
return;
@@ -361,6 +372,17 @@ protected virtual SqlExpression ConstructTime(IReadOnlyList<SqlExpression> argum
361372
second),
362373
millisecond));
363374
}
375+
376+
protected virtual SqlExpression TimeToNanoseconds(SqlExpression time)
377+
{
378+
var nPerHour = SqlDml.Extract(SqlTimePart.Hour, time) * NanosecondsPerHour;
379+
var nPerMinute = SqlDml.Extract(SqlTimePart.Minute, time) * NanosecondsPerMinute;
380+
var nPerSecond = SqlDml.Extract(SqlTimePart.Second, time) * NanosecondsPerSecond;
381+
var nPerMillisecond = SqlDml.Extract(SqlTimePart.Millisecond, time) * NanosecondsPerMillisecond;
382+
383+
return nPerHour + nPerMinute + nPerSecond + nPerMillisecond;
384+
}
385+
364386
protected virtual SqlExpression TimeSubtractTime(SqlExpression time1, SqlExpression time2) =>
365387
SqlDml.Modulo(
366388
NanosecondsPerDay + CastToDecimal(SqlDml.FunctionCall("TIME_TO_SEC", time1) - SqlDml.FunctionCall("TIME_TO_SEC", time2), 18, 0) * NanosecondsPerSecond,

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

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,120 +44,130 @@ internal class Compiler : SqlCompiler
4444
protected const string ToDSIntervalFunctionName = "TO_DSINTERVAL";
4545
protected const string TimeFormat = "HH24:MI:SS.FF7";
4646

47+
protected const long NanosecondsPerHour = 3600000000000;
48+
protected const long NanosecondsPerMinute = 60000000000;
49+
protected const long NanosecondsPerSecond = 1000000000;
50+
protected const long NanosecondsPerMillisecond = 1000000;
51+
4752
private static readonly SqlExpression SundayNumber = SqlDml.Native(
4853
"TO_NUMBER(TO_CHAR(TIMESTAMP '2009-07-26 00:00:00.000', 'D'))");
4954
private static readonly SqlNative RefTimestamp = SqlDml.Native("timestamp '2009-01-01 00:00:00.0000000'");
5055

5156
public override void Visit(SqlFunctionCall node)
5257
{
58+
var arguments = node.Arguments;
59+
5360
switch (node.FunctionType) {
5461
case SqlFunctionType.PadLeft:
5562
case SqlFunctionType.PadRight:
5663
SqlHelper.GenericPad(node).AcceptVisitor(this);
5764
return;
5865
case SqlFunctionType.DateTimeOffsetAddYears:
5966
case SqlFunctionType.DateTimeAddYears:
60-
DateTimeAddYMInterval(node.Arguments[0], node.Arguments[1], YearIntervalPart).AcceptVisitor(this);
67+
DateTimeAddYMInterval(arguments[0], arguments[1], YearIntervalPart).AcceptVisitor(this);
6168
return;
6269
case SqlFunctionType.DateTimeOffsetAddMonths:
6370
case SqlFunctionType.DateTimeAddMonths:
64-
DateTimeAddYMInterval(node.Arguments[0], node.Arguments[1], MonthIntervalPart).AcceptVisitor(this);
71+
DateTimeAddYMInterval(arguments[0], arguments[1], MonthIntervalPart).AcceptVisitor(this);
6572
return;
6673
case SqlFunctionType.IntervalConstruct:
67-
IntervalConstruct(node.Arguments[0]).AcceptVisitor(this);
74+
IntervalConstruct(arguments[0]).AcceptVisitor(this);
6875
return;
6976
case SqlFunctionType.DateTimeConstruct:
70-
DateTimeConstruct(node.Arguments[0], node.Arguments[1], node.Arguments[2]).AcceptVisitor(this);
77+
DateTimeConstruct(arguments[0], arguments[1], arguments[2]).AcceptVisitor(this);
7178
return;
7279
#if NET6_0_OR_GREATER
7380
case SqlFunctionType.DateConstruct:
74-
DateConstruct(node.Arguments[0], node.Arguments[1], node.Arguments[2]).AcceptVisitor(this);
81+
DateConstruct(arguments[0], arguments[1], arguments[2]).AcceptVisitor(this);
7582
return;
7683
case SqlFunctionType.TimeConstruct:
77-
TimeConstruct(node.Arguments).AcceptVisitor(this);
84+
TimeConstruct(arguments).AcceptVisitor(this);
85+
return;
86+
case SqlFunctionType.TimeToNanoseconds:
87+
TimeToNanoseconds(arguments[0]).AcceptVisitor(this);
7888
return;
7989
case SqlFunctionType.DateAddYears:
80-
DateTimeAddYMInterval(node.Arguments[0], node.Arguments[1], YearIntervalPart).AcceptVisitor(this);
90+
DateTimeAddYMInterval(arguments[0], arguments[1], YearIntervalPart).AcceptVisitor(this);
8191
return;
8292
case SqlFunctionType.DateAddMonths:
83-
DateTimeAddYMInterval(node.Arguments[0], node.Arguments[1], MonthIntervalPart).AcceptVisitor(this);
93+
DateTimeAddYMInterval(arguments[0], arguments[1], MonthIntervalPart).AcceptVisitor(this);
8494
return;
8595
case SqlFunctionType.DateAddDays:
86-
DateTimeAddDSInterval(node.Arguments[0], node.Arguments[1], DayIntervalPart).AcceptVisitor(this);
96+
DateTimeAddDSInterval(arguments[0], arguments[1], DayIntervalPart).AcceptVisitor(this);
8797
return;
8898
case SqlFunctionType.TimeAddHours:
89-
TimeAddHourOrMinute(node.Arguments[0], node.Arguments[1], true).AcceptVisitor(this);
99+
TimeAddHourOrMinute(arguments[0], arguments[1], true).AcceptVisitor(this);
90100
return;
91101
case SqlFunctionType.TimeAddMinutes:
92-
TimeAddHourOrMinute(node.Arguments[0], node.Arguments[1], false).AcceptVisitor(this);
102+
TimeAddHourOrMinute(arguments[0], arguments[1], false).AcceptVisitor(this);
93103
return;
94104
case SqlFunctionType.DateToString:
95-
DateToString(node.Arguments[0]).AcceptVisitor(this);
105+
DateToString(arguments[0]).AcceptVisitor(this);
96106
return;
97107
case SqlFunctionType.TimeToString:
98-
TimeToString(node.Arguments[0]).AcceptVisitor(this);
108+
TimeToString(arguments[0]).AcceptVisitor(this);
99109
return;
100110
#endif
101111
case SqlFunctionType.IntervalAbs:
102-
SqlHelper.IntervalAbs(node.Arguments[0]).AcceptVisitor(this);
112+
SqlHelper.IntervalAbs(arguments[0]).AcceptVisitor(this);
103113
return;
104114
case SqlFunctionType.IntervalToMilliseconds:
105-
SqlHelper.IntervalToMilliseconds(node.Arguments[0]).AcceptVisitor(this);
115+
SqlHelper.IntervalToMilliseconds(arguments[0]).AcceptVisitor(this);
106116
return;
107117
case SqlFunctionType.IntervalToNanoseconds:
108-
SqlHelper.IntervalToNanoseconds(node.Arguments[0]).AcceptVisitor(this);
118+
SqlHelper.IntervalToNanoseconds(arguments[0]).AcceptVisitor(this);
109119
return;
110120
case SqlFunctionType.Position:
111-
Position(node.Arguments[0], node.Arguments[1]).AcceptVisitor(this);
121+
Position(arguments[0], arguments[1]).AcceptVisitor(this);
112122
return;
113123
case SqlFunctionType.CharLength:
114-
SqlDml.Coalesce(SqlDml.FunctionCall("LENGTH", node.Arguments[0]), 0).AcceptVisitor(this);
124+
SqlDml.Coalesce(SqlDml.FunctionCall("LENGTH", arguments[0]), 0).AcceptVisitor(this);
115125
return;
116126
case SqlFunctionType.DateTimeToStringIso:
117-
DateTimeToStringIso(node.Arguments[0]).AcceptVisitor(this);
127+
DateTimeToStringIso(arguments[0]).AcceptVisitor(this);
118128
return;
119129
case SqlFunctionType.DateTimeOffsetConstruct:
120-
DateTimeOffsetConstruct(node.Arguments[0], node.Arguments[1]).AcceptVisitor(this);
130+
DateTimeOffsetConstruct(arguments[0], arguments[1]).AcceptVisitor(this);
121131
return;
122132
case SqlFunctionType.DateTimeOffsetTimeOfDay:
123-
DateTimeOffsetTimeOfDay(node.Arguments[0]).AcceptVisitor(this);
133+
DateTimeOffsetTimeOfDay(arguments[0]).AcceptVisitor(this);
124134
return;
125135
case SqlFunctionType.DateTimeOffsetToLocalTime:
126-
DateTimeOffsetToLocalTime(node.Arguments[0]).AcceptVisitor(this);
136+
DateTimeOffsetToLocalTime(arguments[0]).AcceptVisitor(this);
127137
return;
128138
case SqlFunctionType.DateTimeToDateTimeOffset:
129-
DateTimeToDateTimeOffset(node.Arguments[0]).AcceptVisitor(this);
139+
DateTimeToDateTimeOffset(arguments[0]).AcceptVisitor(this);
130140
return;
131141
case SqlFunctionType.DateTimeOffsetToDateTime:
132-
DateTimeOffsetToDateTime(node.Arguments[0]).AcceptVisitor(this);
142+
DateTimeOffsetToDateTime(arguments[0]).AcceptVisitor(this);
133143
return;
134144
case SqlFunctionType.DateTimeOffsetToUtcTime:
135-
DateTimeOffsetToUtcTime(node.Arguments[0]).AcceptVisitor(this);
145+
DateTimeOffsetToUtcTime(arguments[0]).AcceptVisitor(this);
136146
return;
137147
#if NET6_0_OR_GREATER
138148
case SqlFunctionType.DateTimeToDate:
139-
DateTimeToDate(node.Arguments[0]).AcceptVisitor(this);
149+
DateTimeToDate(arguments[0]).AcceptVisitor(this);
140150
return;
141151
case SqlFunctionType.DateToDateTime:
142-
DateToDateTime(node.Arguments[0]).AcceptVisitor(this);
152+
DateToDateTime(arguments[0]).AcceptVisitor(this);
143153
return;
144154
case SqlFunctionType.DateTimeToTime:
145-
DateTimeToTime(node.Arguments[0]).AcceptVisitor(this);
155+
DateTimeToTime(arguments[0]).AcceptVisitor(this);
146156
return;
147157
case SqlFunctionType.TimeToDateTime:
148-
TimeToDateTime(node.Arguments[0]).AcceptVisitor(this);
158+
TimeToDateTime(arguments[0]).AcceptVisitor(this);
149159
return;
150160
case SqlFunctionType.DateTimeOffsetToDate:
151-
DateTimeOffsetToDate(node.Arguments[0]).AcceptVisitor(this);
161+
DateTimeOffsetToDate(arguments[0]).AcceptVisitor(this);
152162
return;
153163
case SqlFunctionType.DateTimeOffsetToTime:
154-
DateTimeOffsetToTime(node.Arguments[0]).AcceptVisitor(this);
164+
DateTimeOffsetToTime(arguments[0]).AcceptVisitor(this);
155165
return;
156166
case SqlFunctionType.DateToDateTimeOffset:
157-
DateToDateTimeOffset(node.Arguments[0]).AcceptVisitor(this);
167+
DateToDateTimeOffset(arguments[0]).AcceptVisitor(this);
158168
return;
159169
case SqlFunctionType.TimeToDateTimeOffset:
160-
TimeToDateTimeOffset(node.Arguments[0]).AcceptVisitor(this);
170+
TimeToDateTimeOffset(arguments[0]).AcceptVisitor(this);
161171
return;
162172
#endif
163173
default:
@@ -401,6 +411,16 @@ private static SqlExpression TimeConstruct(IReadOnlyList<SqlExpression> argument
401411
}
402412
}
403413

414+
private static SqlExpression TimeToNanoseconds(SqlExpression time)
415+
{
416+
var nPerHour = SqlDml.Extract(SqlTimePart.Hour, time) * NanosecondsPerHour;
417+
var nPerMinute = SqlDml.Extract(SqlTimePart.Minute, time) * NanosecondsPerMinute;
418+
var nPerSecond = SqlDml.Extract(SqlTimePart.Second, time) * NanosecondsPerSecond;
419+
var nPerMillisecond = SqlDml.Extract(SqlTimePart.Millisecond, time) * NanosecondsPerMillisecond;
420+
421+
return nPerHour + nPerMinute + nPerSecond + nPerMillisecond;
422+
}
423+
404424
private static SqlExpression TimeAddHourOrMinute(SqlExpression time, SqlExpression hourOrMinute, bool isHour)
405425
{
406426
var intervalLiteral = isHour ? "INTERVAL '1' HOUR" : "INTERVAL '1' MINUTE";

Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/Compiler.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ internal class Compiler : SqlCompiler
2020
private const string TimeFormat = "HH24:MI:SS.US0";
2121
#endif
2222

23+
private const long NanosecondsPerHour = 3600000000000;
24+
private const long NanosecondsPerMinute = 60000000000;
25+
private const long NanosecondsPerSecond = 1000000000;
26+
private const long NanosecondsPerMillisecond = 1000000;
27+
2328
private static readonly Type SqlPlaceholderType = typeof(SqlPlaceholder);
2429

2530
private static readonly SqlNative OneYearInterval = SqlDml.Native("interval '1 year'");
@@ -135,6 +140,9 @@ public override void Visit(SqlFunctionCall node)
135140
case SqlFunctionType.TimeConstruct:
136141
ConstructTime(node.Arguments).AcceptVisitor(this);
137142
return;
143+
case SqlFunctionType.TimeToNanoseconds:
144+
TimeToNanoseconds(node.Arguments[0]).AcceptVisitor(this);
145+
return;
138146
#endif
139147
case SqlFunctionType.DateTimeTruncate:
140148
(SqlDml.FunctionCall("date_trunc", "day", node.Arguments[0])).AcceptVisitor(this);
@@ -422,8 +430,17 @@ protected virtual SqlExpression ConstructTime(IReadOnlyList<SqlExpression> argum
422430
}
423431
else {
424432
throw new InvalidOperationException("Unsupported count of parameters");
425-
}
426-
433+
}
434+
}
435+
436+
protected virtual SqlExpression TimeToNanoseconds(SqlExpression time)
437+
{
438+
var nPerHour = SqlDml.Extract(SqlTimePart.Hour, time) * NanosecondsPerHour;
439+
var nPerMinute = SqlDml.Extract(SqlTimePart.Minute, time) * NanosecondsPerMinute;
440+
var nPerSecond = SqlDml.Extract(SqlTimePart.Second, time) * NanosecondsPerSecond;
441+
var nPerMillisecond = SqlDml.Extract(SqlTimePart.Millisecond, time) * NanosecondsPerMillisecond;
442+
443+
return nPerHour + nPerMinute + nPerSecond + nPerMillisecond;
427444
}
428445
#endif
429446

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

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ internal class Compiler : SqlCompiler
3030
protected const string WeekdayPart = "WEEKDAY";
3131
#endregion
3232

33-
protected static readonly long NanosecondsPerDay = TimeSpan.FromDays(1).Ticks*100;
34-
protected static readonly long NanosecondsPerSecond = 1000000000;
35-
protected static readonly long NanosecondsPerMillisecond = 1000000;
36-
protected static readonly long MillisecondsPerDay = (long) TimeSpan.FromDays(1).TotalMilliseconds;
37-
protected static readonly long MillisecondsPerSecond = 1000L;
33+
protected const long NanosecondsPerDay = 86400000000000;
34+
protected const long NanosecondsPerHour = 3600000000000;
35+
protected const long NanosecondsPerMinute = 60000000000;
36+
protected const long NanosecondsPerSecond = 1000000000;
37+
protected const long NanosecondsPerMillisecond = 1000000;
38+
protected const long MillisecondsPerDay = 86400000;
39+
protected const long MillisecondsPerSecond = 1000L;
40+
3841
protected static readonly SqlExpression DateFirst = SqlDml.Native("@@DATEFIRST");
3942

4043
/// <inheritdoc/>
@@ -229,6 +232,9 @@ public override void Visit(SqlFunctionCall node)
229232
case SqlFunctionType.TimeConstruct:
230233
ConstructTime(arguments).AcceptVisitor(this);
231234
return;
235+
case SqlFunctionType.TimeToNanoseconds:
236+
TimeToNanoseconds(arguments[0]).AcceptVisitor(this);
237+
return;
232238
case SqlFunctionType.DateToString:
233239
Visit(DateToString(arguments[0]));
234240
return;
@@ -542,6 +548,21 @@ protected virtual SqlExpression ConstructTime(IReadOnlyList<SqlExpression> argum
542548
SqlType.Time);
543549
}
544550

551+
/// <summary>
552+
/// Creates expression that represents conversion of time value to nanoseconds.
553+
/// </summary>
554+
/// <param name="time">Time value to convert.</param>
555+
/// <returns>Result expression.</returns>
556+
protected virtual SqlExpression TimeToNanoseconds(SqlExpression time)
557+
{
558+
var nPerHour = SqlDml.Extract(SqlTimePart.Hour, time) * NanosecondsPerHour;
559+
var nPerMinute = SqlDml.Extract(SqlTimePart.Minute, time) * NanosecondsPerMinute;
560+
var nPerSecond = SqlDml.Extract(SqlTimePart.Second, time) * NanosecondsPerSecond;
561+
var n = SqlDml.Extract(SqlTimePart.Nanosecond, time);
562+
563+
return nPerHour + nPerMinute + nPerSecond + n;
564+
}
565+
545566
/// <summary>
546567
/// Creates expression that represents addition <paramref name="interval"/> to the given <paramref name="time"/>.
547568
/// </summary>

0 commit comments

Comments
 (0)