@@ -167,17 +167,32 @@ public override void Visit(SqlFunctionCall node)
167167 Visit ( CastToLong ( node . Arguments [ 0 ] ) ) ;
168168 return ;
169169 case SqlFunctionType . DateTimeAddMonths :
170- Visit ( DateAddMonth ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
170+ Visit ( DateTimeAddMonth ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
171171 return ;
172172 case SqlFunctionType . DateTimeAddYears :
173- Visit ( DateAddYear ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
173+ Visit ( DateTimeAddYear ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
174174 return ;
175175 case SqlFunctionType . DateTimeConstruct :
176- Visit ( DateAddDay ( DateAddMonth ( DateAddYear ( SqlDml . Literal ( new DateTime ( 2001 , 1 , 1 ) ) ,
176+ Visit ( DateTimeAddDay ( DateTimeAddMonth ( DateTimeAddYear ( SqlDml . Literal ( new DateTime ( 2001 , 1 , 1 ) ) ,
177177 node . Arguments [ 0 ] - 2001 ) ,
178178 node . Arguments [ 1 ] - 1 ) ,
179179 node . Arguments [ 2 ] - 1 ) ) ;
180180 return ;
181+ #if NET6_0_OR_GREATER //DO_DATEONLY
182+ case SqlFunctionType . DateConstruct:
183+ Visit( DateAddDay ( DateAddMonth ( DateAddYear ( SqlDml . Literal ( new DateOnly ( 2001 , 1 , 1 ) ) ,
184+ node . Arguments[ 0 ] - 2001 ) ,
185+ node. Arguments [ 1 ] - 1 ) ,
186+ node. Arguments [ 2 ] - 1 ) ) ;
187+ return ;
188+ case SqlFunctionType . TimeConstruct:
189+ Visit( SqlDml . FunctionCall ( "TIME" , TimeAddMillisecond ( TimeAddSecond ( TimeAddMinute ( TimeAddHour ( SqlDml . Literal ( new DateTime ( 2001 , 1 , 1 ) ) ,
190+ node . Arguments [ 0 ] ) ,
191+ node . Arguments [ 1 ] ) ,
192+ node . Arguments [ 2 ] ) ,
193+ node . Arguments [ 3 ] ) ) ) ;
194+ return ;
195+ #endif
181196 case SqlFunctionType . DateTimeToStringIso :
182197 Visit ( DateTimeToStringIso ( node . Arguments [ 0 ] ) ) ;
183198 return ;
@@ -186,6 +201,20 @@ public override void Visit(SqlFunctionCall node)
186201 base . Visit ( node ) ;
187202 }
188203
204+ #if NET6_0_OR_GREATER //DO_DATEONLY
205+ public override void Visit ( SqlPlaceholder node )
206+ {
207+ if ( node . Id is Xtensive . Orm . Providers . QueryParameterBinding qpb && qpb . TypeMapping . Type == typeof ( TimeOnly ) ) {
208+ _ = context . Output . Append ( "TIME(" ) ;
209+ base . Visit ( node ) ;
210+ _ = context . Output . Append ( ")" ) ;
211+ }
212+ else {
213+ base . Visit ( node ) ;
214+ }
215+ }
216+ #endif
217+
189218 /// <inheritdoc/>
190219 protected override void VisitSelectLimitOffset ( SqlSelect node )
191220 {
@@ -217,13 +246,13 @@ protected virtual SqlExpression DateTimeSubtractDateTime(SqlExpression date1, Sq
217246 {
218247 return ( CastToDecimal ( DateDiffDay ( date1 , date2 ) , 18 , 0 ) * NanosecondsPerDay )
219248 +
220- ( CastToDecimal ( DateDiffMicrosecond ( DateAddDay ( date2 , DateDiffDay ( date1 , date2 ) ) , date1 ) , 18 , 0 ) * NanosecondsPerMicrosecond ) ;
249+ ( CastToDecimal ( DateTimeDiffMicrosecond ( DateTimeAddDay ( date2 , DateDiffDay ( date1 , date2 ) ) , date1 ) , 18 , 0 ) * NanosecondsPerMicrosecond ) ;
221250 }
222251
223252 protected virtual SqlExpression DateTimeAddInterval ( SqlExpression date , SqlExpression interval )
224253 {
225- return DateAddMicrosecond (
226- DateAddDay ( date , ( ( interval - ( interval % NanosecondsPerDay ) ) + ( ( interval % NanosecondsPerDay ) > ( NanosecondsPerDay / 2 ) ? 0 : 1 ) ) / NanosecondsPerDay ) ,
254+ return DateTimeAddMicrosecond (
255+ DateTimeAddDay ( date , ( ( interval - ( interval % NanosecondsPerDay ) ) + ( ( interval % NanosecondsPerDay ) > ( NanosecondsPerDay / 2 ) ? 0 : 1 ) ) / NanosecondsPerDay ) ,
227256 ( interval / NanosecondsPerMillisecond * NanosecondsPerMicrosecond ) % ( MillisecondsPerDay * NanosecondsPerMicrosecond ) ) ;
228257 }
229258
@@ -237,20 +266,42 @@ private static SqlCast CastToDecimal(SqlExpression arg, short precision, short s
237266 private static SqlUserFunctionCall DateDiffDay ( SqlExpression date1 , SqlExpression date2 ) =>
238267 SqlDml . FunctionCall ( "DATEDIFF" , date1 , date2 ) ;
239268
240- private static SqlUserFunctionCall DateDiffMicrosecond ( SqlExpression date1 , SqlExpression date2 ) =>
241- SqlDml . FunctionCall ( "TIMESTAMPDIFF" , SqlDml . Native ( "MICROSECOND" ) , date1 , date2 ) ;
269+ private static SqlUserFunctionCall DateTimeDiffMicrosecond ( SqlExpression datetime1 , SqlExpression datetime2 ) =>
270+ SqlDml . FunctionCall ( "TIMESTAMPDIFF" , SqlDml . Native ( "MICROSECOND" ) , datetime1 , datetime2 ) ;
271+
272+ private static SqlUserFunctionCall DateTimeAddYear ( SqlExpression datetime , SqlExpression years ) =>
273+ SqlDml . FunctionCall ( "TIMESTAMPADD" , SqlDml . Native ( "YEAR" ) , years , datetime ) ;
274+
275+ private static SqlUserFunctionCall DateTimeAddMonth ( SqlExpression datetime , SqlExpression months ) =>
276+ SqlDml . FunctionCall ( "TIMESTAMPADD" , SqlDml . Native ( "MONTH" ) , months , datetime ) ;
277+
278+ private static SqlUserFunctionCall DateTimeAddDay ( SqlExpression datetime , SqlExpression days ) =>
279+ SqlDml . FunctionCall ( "TIMESTAMPADD" , SqlDml . Native ( "DAY" ) , days , datetime ) ;
242280
281+ private static SqlUserFunctionCall DateTimeAddMicrosecond ( SqlExpression datetime , SqlExpression microseconds ) =>
282+ SqlDml . FunctionCall ( "TIMESTAMPADD" , SqlDml . Native ( "MICROSECOND" ) , microseconds , datetime ) ;
283+
284+ #if NET6_0_OR_GREATER //DO_DATEONLY
243285 private static SqlUserFunctionCall DateAddYear ( SqlExpression date , SqlExpression years ) =>
244- SqlDml . FunctionCall ( "TIMESTAMPADD " , SqlDml . Native ( "YEAR " ) , years , date ) ;
286+ SqlDml . FunctionCall ( "DATE_ADD " , date , SqlDml . RawConcat ( SqlDml . Native ( "INTERVAL " ) , SqlDml . RawConcat ( years , SqlDml . Native ( "YEAR" ) ) ) ) ;
245287
246288 private static SqlUserFunctionCall DateAddMonth ( SqlExpression date , SqlExpression months ) =>
247- SqlDml . FunctionCall ( "TIMESTAMPADD" , SqlDml . Native ( "MONTH" ) , months , date ) ;
248-
289+ SqlDml . FunctionCall ( "DATE_ADD" , date , SqlDml . RawConcat ( SqlDml . Native ( "INTERVAL " ) , SqlDml . RawConcat ( months , SqlDml . Native ( "MONTH" ) ) ) ) ;
249290 private static SqlUserFunctionCall DateAddDay ( SqlExpression date , SqlExpression days ) =>
250- SqlDml . FunctionCall ( "TIMESTAMPADD" , SqlDml . Native ( "DAY" ) , days , date ) ;
291+ SqlDml . FunctionCall ( "DATE_ADD" , date , SqlDml . RawConcat ( SqlDml . Native ( "INTERVAL " ) , SqlDml . RawConcat ( days , SqlDml . Native ( "DAY" ) ) ) ) ;
292+
293+ private static SqlUserFunctionCall TimeAddHour ( SqlExpression time , SqlExpression hours ) =>
294+ SqlDml . FunctionCall ( "DATE_ADD" , time , SqlDml . RawConcat ( SqlDml . Native ( "INTERVAL " ) , SqlDml . RawConcat ( hours , SqlDml . Native ( "HOUR" ) ) ) ) ;
295+
296+ private static SqlUserFunctionCall TimeAddMinute ( SqlExpression time , SqlExpression minutes ) =>
297+ SqlDml . FunctionCall ( "DATE_ADD" , time , SqlDml . RawConcat ( SqlDml . Native ( "INTERVAL " ) , SqlDml . RawConcat ( minutes , SqlDml . Native ( "MINUTE" ) ) ) ) ;
298+
299+ private static SqlUserFunctionCall TimeAddSecond ( SqlExpression time , SqlExpression seconds ) =>
300+ SqlDml . FunctionCall ( "DATE_ADD" , time , SqlDml . RawConcat ( SqlDml . Native ( "INTERVAL " ) , SqlDml . RawConcat ( seconds , SqlDml . Native ( "SECOND" ) ) ) ) ;
251301
252- private static SqlUserFunctionCall DateAddMicrosecond ( SqlExpression date , SqlExpression microseconds ) =>
253- SqlDml . FunctionCall ( "TIMESTAMPADD" , SqlDml . Native ( "MICROSECOND" ) , microseconds , date ) ;
302+ private static SqlUserFunctionCall TimeAddMillisecond ( SqlExpression time , SqlExpression millisecond ) =>
303+ SqlDml . FunctionCall ( "DATE_ADD" , time , SqlDml . RawConcat ( SqlDml . Native ( "INTERVAL " ) , SqlDml . RawConcat ( millisecond * 1000 , SqlDml . Native ( "MICROSECOND" ) ) ) ) ;
304+ #endif
254305
255306 protected static SqlUserFunctionCall DateTimeToStringIso ( SqlExpression dateTime ) =>
256307 SqlDml . FunctionCall ( "DATE_FORMAT" , dateTime , "%Y-%m-%dT%T" ) ;
0 commit comments