@@ -151,10 +151,11 @@ public override void Visit(SqlFunctionCall node)
151
151
var arguments = node . Arguments ;
152
152
switch ( node . FunctionType ) {
153
153
case SqlFunctionType . CharLength :
154
- ( SqlDml . FunctionCall ( "LENGTH" , arguments ) / 2 ) . AcceptVisitor ( this ) ;
154
+ SqlDml . FunctionCall ( "LENGTH" , arguments ) . AcceptVisitor ( this ) ;
155
155
return ;
156
156
case SqlFunctionType . PadLeft :
157
157
case SqlFunctionType . PadRight :
158
+ Visit ( EmulateLpadOrRpad ( arguments , node . FunctionType is SqlFunctionType . PadLeft ) ) ;
158
159
return ;
159
160
case SqlFunctionType . Concat :
160
161
var nod = arguments [ 0 ] ;
@@ -631,6 +632,42 @@ private static SqlDateTimePart ConvertDateTimeOffsetPartToDateTimePart(SqlDateTi
631
632
} ;
632
633
}
633
634
635
+ private static SqlCase EmulateLpadOrRpad ( IReadOnlyList < SqlExpression > arguments , bool isLpad )
636
+ {
637
+ var operand = arguments [ 0 ] ;
638
+ var charcount = arguments [ 1 ] ;
639
+ if ( charcount is not SqlLiteral < int > intWidth ) {
640
+ // Since we emulate function with contatination, we need to know total width
641
+ // to calculate prefix
642
+ throw SqlHelper . NotSupported ( "PadLeft/PadRight with expressions as total width." ) ;
643
+ }
644
+ var totalWidth = intWidth . Value ;
645
+
646
+ var padChar = arguments switch {
647
+ _ when arguments . Count == 3 && arguments [ 2 ] is SqlLiteral < char > charLiteral => charLiteral . Value ,
648
+ _ when arguments . Count == 2 => ' ' ,
649
+ _ => throw new NotSupportedException ( )
650
+ } ;
651
+
652
+ var paddingString = SqlDml . Literal ( new string ( Enumerable . Repeat ( padChar , intWidth . Value ) . ToArray ( ) ) ) ;
653
+
654
+ var padExpression = isLpad
655
+ ? SqlDml . Substring (
656
+ SqlDml . Concat ( paddingString , operand ) ,
657
+ SqlDml . Literal ( - totalWidth - 1 ) , // handles '+1' operation in translation of substring function call
658
+ SqlDml . Literal ( totalWidth ) )
659
+ : SqlDml . Substring (
660
+ SqlDml . Concat ( operand , paddingString ) ,
661
+ SqlDml . Literal ( 0 ) , // handles '+1' operation in translation of substring function call
662
+ SqlDml . Literal ( totalWidth ) ) ;
663
+
664
+ var @case = SqlDml . Case ( ) ;
665
+ _ = @case . Add ( SqlDml . CharLength ( operand ) >= charcount , operand ) ;
666
+ @case . Else = padExpression ;
667
+ return @case ;
668
+ }
669
+
670
+
634
671
// Constructors
635
672
636
673
/// <param name="driver">The driver.</param>
0 commit comments