@@ -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" ;
0 commit comments