1- // Copyright (C) 2003-2010 Xtensive LLC.
2- // All rights reserved .
3- // For conditions of distribution and use, see license .
1+ // Copyright (C) 2009-2021 Xtensive LLC.
2+ // This code is distributed under MIT license terms .
3+ // See the License.txt file in the project root for more information .
44// Created by: Denis Krjuchkov
55// Created: 2009.07.07
66
@@ -11,20 +11,20 @@ namespace Xtensive.Sql.Drivers.SqlServer.v10
1111{
1212 internal class Compiler : v09 . Compiler
1313 {
14- protected static SqlUserFunctionCall DateAddNanosecond ( SqlExpression date , SqlExpression nanoseconds )
15- {
16- return SqlDml . FunctionCall ( "DATEADD" , SqlDml . Native ( "NS" ) , nanoseconds , date ) ;
17- }
14+ protected const string UtcTimeZone = "+00:00" ;
15+ protected const string SqlDateTypeName = "date" ;
16+ protected const string SqlDateTime2TypeName = "datetime2" ;
1817
19- protected static SqlUserFunctionCall DateDiffNanosecond ( SqlExpression date1 , SqlExpression date2 )
20- {
21- return SqlDml . FunctionCall ( "DATEDIFF" , SqlDml . Native ( "NS" ) , date1 , date2 ) ;
22- }
18+ protected static SqlUserFunctionCall DateAddNanosecond ( SqlExpression date , SqlExpression nanoseconds ) =>
19+ SqlDml . FunctionCall ( "DATEADD" , SqlDml . Native ( "NS" ) , nanoseconds , date ) ;
2320
24- protected override SqlExpression DateTimeTruncate ( SqlExpression date )
25- {
26- return SqlDml . Cast ( SqlDml . Cast ( date , new SqlValueType ( "Date" ) ) , new SqlValueType ( "DateTime2" ) ) ;
27- }
21+ protected static SqlUserFunctionCall DateDiffNanosecond ( SqlExpression date1 , SqlExpression date2 ) =>
22+ SqlDml . FunctionCall ( "DATEDIFF" , SqlDml . Native ( "NS" ) , date1 , date2 ) ;
23+
24+ protected override SqlExpression DateTimeTruncate ( SqlExpression date ) =>
25+ SqlDml . Cast (
26+ SqlDml . Cast ( date , new SqlValueType ( SqlDateTypeName ) ) ,
27+ new SqlValueType ( SqlDateTime2TypeName ) ) ;
2828
2929 protected override SqlExpression DateTimeSubtractDateTime ( SqlExpression date1 , SqlExpression date2 )
3030 {
@@ -52,32 +52,31 @@ protected override SqlExpression DateTimeAddInterval(SqlExpression date, SqlExpr
5252
5353 public override void Visit ( SqlExtract node )
5454 {
55- if ( node . DateTimeOffsetPart == SqlDateTimeOffsetPart . DayOfWeek ) {
56- Visit ( ( DatePartWeekDay ( node . Operand ) + DateFirst + 6 ) % 7 ) ;
57- return ;
58- }
5955 switch ( node . DateTimeOffsetPart ) {
60- case SqlDateTimeOffsetPart . TimeZoneHour :
61- Visit ( DateTimeOffsetTimeZoneInMinutes ( node . Operand ) / 60 ) ;
62- return ;
63- case SqlDateTimeOffsetPart . TimeZoneMinute :
64- Visit ( DateTimeOffsetTimeZoneInMinutes ( node . Operand ) % 60 ) ;
65- return ;
66- case SqlDateTimeOffsetPart . Date :
67- DateTimeOffsetTruncate ( node . Operand ) . AcceptVisitor ( this ) ;
68- return ;
69- case SqlDateTimeOffsetPart . DateTime :
70- DateTimeOffsetTruncateOffset ( node . Operand ) . AcceptVisitor ( this ) ;
71- return ;
72- case SqlDateTimeOffsetPart . LocalDateTime :
73- DateTimeOffsetToLocalDateTime ( node . Operand ) . AcceptVisitor ( this ) ;
74- return ;
75- case SqlDateTimeOffsetPart . UtcDateTime :
76- SqlDml . Cast ( Switchoffset ( node . Operand , "+00:00" ) , SqlType . DateTime ) . AcceptVisitor ( this ) ;
77- return ;
78- case SqlDateTimeOffsetPart . Offset :
79- DateTimeOffsetPartOffset ( node . Operand ) . AcceptVisitor ( this ) ;
80- return ;
56+ case SqlDateTimeOffsetPart . DayOfWeek :
57+ Visit ( ( DatePartWeekDay ( node . Operand ) + DateFirst + 6 ) % 7 ) ;
58+ return ;
59+ case SqlDateTimeOffsetPart . TimeZoneHour :
60+ Visit ( DateTimeOffsetTimeZoneInMinutes ( node . Operand ) / 60 ) ;
61+ return ;
62+ case SqlDateTimeOffsetPart . TimeZoneMinute :
63+ Visit ( DateTimeOffsetTimeZoneInMinutes ( node . Operand ) % 60 ) ;
64+ return ;
65+ case SqlDateTimeOffsetPart . Date :
66+ DateTimeOffsetTruncate ( node . Operand ) . AcceptVisitor ( this ) ;
67+ return ;
68+ case SqlDateTimeOffsetPart . DateTime :
69+ DateTimeOffsetTruncateOffset ( node . Operand ) . AcceptVisitor ( this ) ;
70+ return ;
71+ case SqlDateTimeOffsetPart . LocalDateTime :
72+ DateTimeOffsetToLocalDateTime ( node . Operand ) . AcceptVisitor ( this ) ;
73+ return ;
74+ case SqlDateTimeOffsetPart . UtcDateTime :
75+ SqlDml . Cast ( Switchoffset ( node . Operand , UtcTimeZone ) , SqlType . DateTime ) . AcceptVisitor ( this ) ;
76+ return ;
77+ case SqlDateTimeOffsetPart . Offset :
78+ DateTimeOffsetPartOffset ( node . Operand ) . AcceptVisitor ( this ) ;
79+ return ;
8180 }
8281 base . Visit ( node ) ;
8382 }
@@ -86,27 +85,27 @@ public override void Visit(SqlExtract node)
8685 public override void Visit ( SqlFunctionCall node )
8786 {
8887 switch ( node . FunctionType ) {
89- case SqlFunctionType . DateTimeOffsetAddMonths :
90- Visit ( DateAddMonth ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
91- return ;
92- case SqlFunctionType . DateTimeOffsetAddYears :
93- Visit ( DateAddYear ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
94- return ;
95- case SqlFunctionType . DateTimeOffsetTimeOfDay :
96- DateTimeOffsetTimeOfDay ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
97- return ;
98- case SqlFunctionType . DateTimeOffsetConstruct :
99- Visit ( ToDateTimeOffset ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
100- return ;
101- case SqlFunctionType . DateTimeOffsetToLocalTime :
102- DateTimeOffsetToLocalTime ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
103- return ;
104- case SqlFunctionType . DateTimeOffsetToUtcTime :
105- DateTimeOffsetToUtcTime ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
106- return ;
107- case SqlFunctionType . DateTimeToDateTimeOffset :
108- DateTimeToDateTimeOffset ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
109- return ;
88+ case SqlFunctionType . DateTimeOffsetAddMonths :
89+ Visit ( DateAddMonth ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
90+ return ;
91+ case SqlFunctionType . DateTimeOffsetAddYears :
92+ Visit ( DateAddYear ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
93+ return ;
94+ case SqlFunctionType . DateTimeOffsetTimeOfDay :
95+ DateTimeOffsetTimeOfDay ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
96+ return ;
97+ case SqlFunctionType . DateTimeOffsetConstruct :
98+ Visit ( ToDateTimeOffset ( node . Arguments [ 0 ] , node . Arguments [ 1 ] ) ) ;
99+ return ;
100+ case SqlFunctionType . DateTimeOffsetToLocalTime :
101+ DateTimeOffsetToLocalTime ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
102+ return ;
103+ case SqlFunctionType . DateTimeOffsetToUtcTime :
104+ DateTimeOffsetToUtcTime ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
105+ return ;
106+ case SqlFunctionType . DateTimeToDateTimeOffset :
107+ DateTimeToDateTimeOffset ( node . Arguments [ 0 ] ) . AcceptVisitor ( this ) ;
108+ return ;
110109 }
111110
112111 base . Visit ( node ) ;
@@ -115,93 +114,64 @@ public override void Visit(SqlFunctionCall node)
115114 public override void Visit ( SqlBinary node )
116115 {
117116 switch ( node . NodeType ) {
118- case SqlNodeType . DateTimeOffsetPlusInterval :
119- DateTimeAddInterval ( node . Left , node . Right ) . AcceptVisitor ( this ) ;
120- return ;
121- case SqlNodeType . DateTimeOffsetMinusDateTimeOffset :
122- DateTimeOffsetSubtractDateTimeOffset ( node . Left , node . Right ) . AcceptVisitor ( this ) ;
123- return ;
124- case SqlNodeType . DateTimeOffsetMinusInterval :
125- DateTimeAddInterval ( node . Left , - node . Right ) . AcceptVisitor ( this ) ;
126- return ;
117+ case SqlNodeType . DateTimeOffsetPlusInterval :
118+ DateTimeAddInterval ( node . Left , node . Right ) . AcceptVisitor ( this ) ;
119+ return ;
120+ case SqlNodeType . DateTimeOffsetMinusDateTimeOffset :
121+ DateTimeOffsetSubtractDateTimeOffset ( node . Left , node . Right ) . AcceptVisitor ( this ) ;
122+ return ;
123+ case SqlNodeType . DateTimeOffsetMinusInterval :
124+ DateTimeAddInterval ( node . Left , - node . Right ) . AcceptVisitor ( this ) ;
125+ return ;
127126 }
128127 base . Visit ( node ) ;
129128 }
130129
131130 #region Static helpers
132131
133- private static SqlExpression DateTimeOffsetTruncate ( SqlExpression dateTimeOffset )
134- {
135- return SqlDml . Cast (
136- DateAddMillisecond (
137- DateAddSecond (
138- DateAddMinute (
139- DateAddHour ( dateTimeOffset ,
140- - SqlDml . Extract ( SqlDateTimeOffsetPart . Hour , dateTimeOffset ) ) ,
141- - SqlDml . Extract ( SqlDateTimeOffsetPart . Minute , dateTimeOffset ) ) ,
142- - SqlDml . Extract ( SqlDateTimeOffsetPart . Second , dateTimeOffset ) ) ,
143- - SqlDml . Extract ( SqlDateTimeOffsetPart . Millisecond , dateTimeOffset ) ) ,
144- SqlType . DateTime ) ;
145- }
132+ private static SqlExpression DateTimeOffsetTruncate ( SqlExpression dateTimeOffset ) =>
133+ SqlDml . Cast (
134+ SqlDml . Cast ( dateTimeOffset , new SqlValueType ( SqlDateTypeName ) ) ,
135+ new SqlValueType ( SqlDateTime2TypeName ) ) ;
146136
147- private static SqlExpression DateTimeOffsetTruncateOffset ( SqlExpression dateTimeOffset )
148- {
149- return SqlDml . Cast ( dateTimeOffset , SqlType . DateTime ) ;
150- }
137+ private static SqlExpression DateTimeOffsetTruncateOffset ( SqlExpression dateTimeOffset ) =>
138+ SqlDml . Cast ( dateTimeOffset , SqlType . DateTime ) ;
151139
152- private static SqlExpression DateTimeOffsetPartOffset ( SqlExpression dateTimeOffset )
153- {
154- return SqlDml . DateTimeOffsetMinusDateTimeOffset (
140+ private static SqlExpression DateTimeOffsetPartOffset ( SqlExpression dateTimeOffset ) =>
141+ SqlDml . DateTimeOffsetMinusDateTimeOffset (
155142 DateTimeOffsetTruncateOffset ( dateTimeOffset ) ,
156- Switchoffset ( dateTimeOffset , "+00:00" ) ) ;
157- }
143+ Switchoffset ( dateTimeOffset , UtcTimeZone ) ) ;
158144
159- private static SqlExpression DateTimeOffsetTimeOfDay ( SqlExpression dateTimeOffset )
160- {
161- return SqlDml . Extract ( SqlDateTimeOffsetPart . Hour , dateTimeOffset ) * ( 60 * 60 * NanosecondsPerSecond )
162- + SqlDml . Extract ( SqlDateTimeOffsetPart . Minute , dateTimeOffset ) * ( 60 * NanosecondsPerSecond )
163- + SqlDml . Extract ( SqlDateTimeOffsetPart . Second , dateTimeOffset ) * NanosecondsPerSecond
164- + SqlDml . Extract ( SqlDateTimeOffsetPart . Millisecond , dateTimeOffset ) * NanosecondsPerMillisecond ;
165- }
145+ private static SqlExpression DateTimeOffsetTimeOfDay ( SqlExpression dateTimeOffset ) =>
146+ DateDiffMillisecond (
147+ SqlDml . Native ( "'00:00:00.0000000'" ) ,
148+ SqlDml . Cast ( dateTimeOffset , new SqlValueType ( "time" ) ) )
149+ * NanosecondsPerMillisecond ;
166150
167- private static SqlExpression DateTimeOffsetToLocalDateTime ( SqlExpression dateTimeOffset )
168- {
169- return SqlDml . Cast (
170- SqlDml . DateTimePlusInterval (
171- Switchoffset ( dateTimeOffset , "+00:00" ) ,
172- SqlDml . DateTimeMinusDateTime ( SqlDml . Native ( "getdate()" ) , SqlDml . Native ( "getutcdate()" ) ) ) ,
173- SqlType . DateTime ) ;
174- }
151+ private static SqlExpression DateTimeOffsetToLocalDateTime ( SqlExpression dateTimeOffset ) =>
152+ SqlDml . Cast ( DateTimeOffsetToLocalTime ( dateTimeOffset ) , SqlType . DateTime ) ;
175153
176- private static SqlUserFunctionCall ToDateTimeOffset ( SqlExpression dateTime , SqlExpression offsetInMinutes )
177- {
178- return SqlDml . FunctionCall ( "TODATETIMEOFFSET" , dateTime , offsetInMinutes ) ;
179- }
154+ private static SqlUserFunctionCall ToDateTimeOffset ( SqlExpression dateTime , SqlExpression offsetInMinutes ) =>
155+ SqlDml . FunctionCall ( "TODATETIMEOFFSET" , dateTime , offsetInMinutes ) ;
180156
181- private static SqlExpression Switchoffset ( SqlExpression dateTimeOffset , SqlExpression offset )
182- {
183- return SqlDml . FunctionCall ( "SWITCHOFFSET" , dateTimeOffset , offset ) ;
184- }
157+ private static SqlExpression Switchoffset ( SqlExpression dateTimeOffset , SqlExpression offset ) =>
158+ SqlDml . FunctionCall ( "SWITCHOFFSET" , dateTimeOffset , offset ) ;
185159
186- private static SqlUserFunctionCall DateTimeOffsetTimeZoneInMinutes ( SqlExpression date )
187- {
188- return SqlDml . FunctionCall ( "DATEPART" , SqlDml . Native ( "TZoffset" ) , date ) ;
189- }
160+ private static SqlUserFunctionCall DateTimeOffsetTimeZoneInMinutes ( SqlExpression date ) =>
161+ SqlDml . FunctionCall ( "DATEPART" , SqlDml . Native ( "TZoffset" ) , date ) ;
190162
191- private static SqlExpression DateTimeOffsetToLocalTime ( SqlExpression dateTimeOffset )
192- {
193- return Switchoffset ( dateTimeOffset , DateTimeOffsetTimeZoneInMinutes ( SqlDml . Native ( "SYSDATETIMEOFFSET()" ) ) ) ;
194- }
163+ private static SqlExpression DateTimeOffsetToLocalTime ( SqlExpression dateTimeOffset ) =>
164+ Switchoffset ( dateTimeOffset , DateTimeOffsetTimeZoneInMinutes ( SqlDml . Native ( "SYSDATETIMEOFFSET()" ) ) ) ;
195165
196- private static SqlExpression DateTimeOffsetToUtcTime ( SqlExpression dateTimeOffset )
197- {
198- return Switchoffset ( dateTimeOffset , "+00:00" ) ;
199- }
166+ private static SqlExpression DateTimeOffsetToUtcTime ( SqlExpression dateTimeOffset ) =>
167+ Switchoffset ( dateTimeOffset , UtcTimeZone ) ;
200168
201- private static SqlExpression DateTimeToDateTimeOffset ( SqlExpression dateTime )
202- {
203- return SqlDml . FunctionCall ( "TODATETIMEOFFSET" , dateTime , SqlDml . FunctionCall ( "DATEPART" , SqlDml . Native ( "TZoffset" ) , SqlDml . Native ( "SYSDATETIMEOFFSET()" ) ) ) ;
204- }
169+ private static SqlExpression DateTimeToDateTimeOffset ( SqlExpression dateTime ) =>
170+ SqlDml . FunctionCall ( "TODATETIMEOFFSET" ,
171+ dateTime ,
172+ SqlDml . FunctionCall ( "DATEPART" ,
173+ SqlDml . Native ( "TZoffset" ) ,
174+ SqlDml . Native ( "SYSDATETIMEOFFSET()" ) ) ) ;
205175
206176 #endregion
207177
0 commit comments