11// Copyright (C) 2003-2010 Xtensive LLC.
2- // All rights reserved .
3- // For conditions of distribution and use, see license .
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.02.14
66
@@ -130,7 +130,7 @@ public static SqlExpression MathSignFloat(
130130 private static SqlExpression Min ( SqlExpression left , SqlExpression right )
131131 {
132132 var result = SqlDml . Case ( ) ;
133- result . Add ( left < right , left ) ;
133+ _ = result . Add ( left < right , left ) ;
134134 result . Else = right ;
135135 return result ;
136136 }
@@ -230,7 +230,7 @@ public static SqlExpression MathMinDecimal(
230230 private static SqlExpression Max ( SqlExpression left , SqlExpression right )
231231 {
232232 var result = SqlDml . Case ( ) ;
233- result . Add ( left > right , left ) ;
233+ _ = result . Add ( left > right , left ) ;
234234 result . Else = right ;
235235 return result ;
236236 }
@@ -373,7 +373,7 @@ public static SqlExpression MathCeilingDouble(
373373 public static SqlExpression MathCeilingDecimal (
374374 [ Type ( typeof ( decimal ) ) ] SqlExpression d )
375375 {
376- return SqlDml . Ceiling ( d ) ;
376+ return TryCastToDecimalPS ( SqlDml . Ceiling ( d ) , 28 , 0 ) ;
377377 }
378378
379379 [ Compiler ( typeof ( Math ) , "Cos" , TargetKind . Static | TargetKind . Method ) ]
@@ -408,7 +408,7 @@ public static SqlExpression MathFloorDouble(
408408 public static SqlExpression MathFloorDecimal (
409409 [ Type ( typeof ( decimal ) ) ] SqlExpression d )
410410 {
411- return SqlDml . Floor ( d ) ;
411+ return TryCastToDecimalPS ( SqlDml . Floor ( d ) , 28 , 0 ) ;
412412 }
413413
414414 [ Compiler ( typeof ( Math ) , "Log" , TargetKind . Static | TargetKind . Method ) ]
@@ -560,28 +560,58 @@ public static SqlExpression MathTruncateDouble(
560560 public static SqlExpression MathTruncateDecimal (
561561 [ Type ( typeof ( decimal ) ) ] SqlExpression d )
562562 {
563- return SqlDml . Truncate ( d ) ;
563+ return TryCastToDecimalPS ( SqlDml . Truncate ( d ) , 28 , 0 ) ;
564564 }
565565
566566 #region Round helpers
567567
568568 private static SqlExpression GenericRound ( SqlExpression value , SqlExpression digits , bool isDecimal , SqlExpression mode )
569569 {
570- if ( mode . NodeType != SqlNodeType . Container )
570+ if ( mode . NodeType != SqlNodeType . Container ) {
571571 throw new NotSupportedException ( ) ;
572+ }
573+
572574 var container = ( SqlContainer ) mode ;
573- if ( ! ( container . Value is MidpointRounding ) )
575+ if ( ! ( container . Value is MidpointRounding midpointRounding ) ) {
576+ throw new NotSupportedException ( ) ;
577+ }
578+ if ( ! isDecimal ) {
579+ return SqlDml . Round ( value , digits , TypeCode . Double , midpointRounding ) ;
580+ }
581+ if ( digits == null ) {
582+ return TryCastToDecimalPS ( SqlDml . Round ( value , digits , TypeCode . Decimal , midpointRounding ) , 28 , 0 ) ;
583+ }
584+ if ( ! ( digits is SqlLiteral < int > scale ) ) {
574585 throw new NotSupportedException ( ) ;
575- return SqlDml . Round ( value , digits ,
576- isDecimal ? TypeCode . Decimal : TypeCode . Double ,
577- ( MidpointRounding ) container . Value ) ;
586+ }
587+ return TryCastToDecimalPS ( SqlDml . Round ( value , digits , TypeCode . Decimal , midpointRounding ) , 28 , Convert . ToInt16 ( scale . Value ) ) ;
578588 }
579589
580590 private static SqlExpression BankersRound ( SqlExpression value , SqlExpression digits , bool isDecimal )
581591 {
582- return SqlDml . Round ( value , digits , isDecimal ? TypeCode . Decimal : TypeCode . Double , MidpointRounding . ToEven ) ;
592+ if ( ! isDecimal ) {
593+ return SqlDml . Round ( value , digits , TypeCode . Double , MidpointRounding . ToEven ) ;
594+ }
595+ if ( digits == null ) {
596+ return TryCastToDecimalPS ( SqlDml . Round ( value , digits , TypeCode . Decimal , MidpointRounding . ToEven ) , 28 , 0 ) ;
597+ }
598+ if ( ! ( digits is SqlLiteral < int > scale ) ) {
599+ throw new NotSupportedException ( ) ;
600+ }
601+ return TryCastToDecimalPS ( SqlDml . Round ( value , digits , TypeCode . Decimal , MidpointRounding . ToEven ) , 28 , Convert . ToInt16 ( scale . Value ) ) ;
583602 }
584603
585604 #endregion
605+
606+ private static SqlExpression TryCastToDecimalPS ( SqlExpression value , short precision , short scale )
607+ {
608+ var context = ExpressionTranslationContext . Current ;
609+ var provider = context . ProviderInfo . ProviderName ;
610+ if ( provider . Equals ( WellKnown . Provider . PostgreSql , StringComparison . Ordinal ) ) {
611+ // to fit result into .Net decimal since Npgsql client libarary does not provide a way to make in on reading
612+ return SqlDml . Cast ( value , SqlType . Decimal , precision , scale ) ;
613+ }
614+ return value ;
615+ }
586616 }
587617}
0 commit comments