1010using Xtensive . Sql . Dml ;
1111using Xtensive . Sql . Model ;
1212using Xtensive . Core ;
13+ using System . Collections . Generic ;
1314
1415namespace Xtensive . Sql . Drivers . MySql . v5_0
1516{
@@ -182,10 +183,7 @@ public override void Visit(SqlFunctionCall node)
182183 Visit ( DateTimeAddYear ( arguments [ 0 ] , arguments [ 1 ] ) ) ;
183184 return ;
184185 case SqlFunctionType . DateTimeConstruct :
185- Visit ( DateTimeAddDay ( DateTimeAddMonth ( DateTimeAddYear ( SqlDml . Literal ( new DateTime ( 2001 , 1 , 1 ) ) ,
186- arguments [ 0 ] - 2001 ) ,
187- arguments [ 1 ] - 1 ) ,
188- arguments [ 2 ] - 1 ) ) ;
186+ ConstructDateTime ( arguments ) . AcceptVisitor ( this ) ;
189187 return ;
190188#if NET6_0_OR_GREATER
191189 case SqlFunctionType . DateAddYears:
@@ -198,10 +196,7 @@ public override void Visit(SqlFunctionCall node)
198196 Visit( DateAddDay ( arguments [ 0 ] , arguments [ 1 ] ) ) ;
199197 return ;
200198 case SqlFunctionType . DateConstruct:
201- Visit( DateAddDay ( DateAddMonth ( DateAddYear ( SqlDml . Literal ( new DateOnly ( 2001 , 1 , 1 ) ) ,
202- arguments [ 0 ] - 2001 ) ,
203- arguments[ 1 ] - 1 ) ,
204- arguments[ 2 ] - 1 ) ) ;
199+ ConstructDate( arguments ) . AcceptVisitor( this ) ;
205200 return ;
206201 case SqlFunctionType . TimeAddHours:
207202 Visit( SqlDml . FunctionCall ( "TIME" , SqlDml . FunctionCall (
@@ -220,11 +215,7 @@ public override void Visit(SqlFunctionCall node)
220215 SqlDml. Native ( "SECOND" ) ) ) ) ) ;
221216 return ;
222217 case SqlFunctionType . TimeConstruct:
223- Visit( SqlDml . FunctionCall ( "TIME" , TimeAddMillisecond ( TimeAddSecond ( TimeAddMinute ( TimeAddHour ( SqlDml . Literal ( new DateTime ( 2001 , 1 , 1 ) ) ,
224- arguments [ 0 ] ) ,
225- arguments [ 1 ] ) ,
226- arguments [ 2 ] ) ,
227- arguments [ 3 ] ) ) ) ;
218+ ConstructTime( arguments ) . AcceptVisitor( this ) ;
228219 return ;
229220 case SqlFunctionType . DateToString:
230221 Visit( DateToString ( arguments [ 0 ] ) ) ;
@@ -302,6 +293,17 @@ public override void Visit(SqlExtract node)
302293 base . Visit ( node ) ;
303294 }
304295
296+ protected virtual SqlExpression ConstructDateTime ( IReadOnlyList < SqlExpression > arguments )
297+ {
298+ return DateTimeAddDay (
299+ DateTimeAddMonth (
300+ DateTimeAddYear (
301+ SqlDml . Literal ( new DateTime ( 2001 , 1 , 1 ) ) ,
302+ arguments [ 0 ] - 2001 ) ,
303+ arguments [ 1 ] - 1 ) ,
304+ arguments [ 2 ] - 1 ) ;
305+ }
306+
305307 protected virtual SqlExpression DateTimeSubtractDateTime ( SqlExpression date1 , SqlExpression date2 )
306308 {
307309 return ( CastToDecimal ( DateDiffDay ( date1 , date2 ) , 18 , 0 ) * NanosecondsPerDay )
@@ -317,6 +319,48 @@ protected virtual SqlExpression DateTimeAddInterval(SqlExpression date, SqlExpre
317319 }
318320#if NET6_0_OR_GREATER
319321
322+ protected virtual SqlExpression ConstructDate ( IReadOnlyList < SqlExpression > arguments )
323+ {
324+ return DateAddDay (
325+ DateAddMonth (
326+ DateAddYear (
327+ SqlDml . Literal ( new DateOnly ( 2001 , 1 , 1 ) ) ,
328+ arguments [ 0 ] - 2001 ) ,
329+ arguments [ 1 ] - 1 ) ,
330+ arguments [ 2 ] - 1 ) ;
331+ }
332+
333+ protected virtual SqlExpression ConstructTime ( IReadOnlyList < SqlExpression > arguments )
334+ {
335+ SqlExpression hour , minute , second , millisecond ;
336+ if ( arguments . Count == 4 ) {
337+ hour = arguments [ 0 ] ;
338+ minute = arguments [ 1 ] ;
339+ second = arguments [ 2 ] ;
340+ millisecond = arguments [ 3 ] ;
341+ }
342+ else if ( arguments . Count == 1 ) {
343+ var ticks = arguments [ 0 ] ;
344+ hour = SqlDml . Cast ( ticks / 36000000000 , SqlType . Int32 ) ;
345+ minute = SqlDml . Cast ( ( ticks / 600000000 ) % 60 , SqlType . Int32 ) ;
346+ second = SqlDml . Cast ( ( ticks / 10000000 ) % 60 , SqlType . Int32 ) ;
347+ millisecond = 0 ; //SqlDml.Cast((ticks % 10000000) / 10, SqlType.Int32);
348+ }
349+ else {
350+ throw new InvalidOperationException ( "Unsupported count of parameters" ) ;
351+ }
352+
353+ return SqlDml . FunctionCall ( "TIME" ,
354+ TimeAddMillisecond (
355+ TimeAddSecond (
356+ TimeAddMinute (
357+ TimeAddHour (
358+ SqlDml . Literal ( new DateTime ( 2001 , 1 , 1 ) ) ,
359+ hour ) ,
360+ minute ) ,
361+ second ) ,
362+ millisecond ) ) ;
363+ }
320364 protected virtual SqlExpression TimeSubtractTime ( SqlExpression time1 , SqlExpression time2 ) =>
321365 SqlDml . Modulo (
322366 NanosecondsPerDay + CastToDecimal ( SqlDml . FunctionCall ( "TIME_TO_SEC" , time1 ) - SqlDml . FunctionCall ( "TIME_TO_SEC" , time2 ) , 18 , 0 ) * NanosecondsPerSecond ,
0 commit comments