pylegend 0.8.0__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. pylegend/_typing.py +6 -0
  2. pylegend/core/database/sql_to_string/db_extension.py +35 -6
  3. pylegend/core/language/pandas_api/__init__.py +13 -0
  4. pylegend/core/language/pandas_api/pandas_api_aggregate_specification.py +54 -0
  5. pylegend/core/language/pandas_api/pandas_api_custom_expressions.py +85 -0
  6. pylegend/core/language/pandas_api/pandas_api_series.py +174 -0
  7. pylegend/core/language/pandas_api/pandas_api_tds_row.py +74 -0
  8. pylegend/core/language/shared/operations/integer_operation_expressions.py +35 -0
  9. pylegend/core/language/shared/operations/nary_expression.py +104 -0
  10. pylegend/core/language/shared/operations/primitive_operation_expressions.py +30 -0
  11. pylegend/core/language/shared/operations/string_operation_expressions.py +624 -1
  12. pylegend/core/language/shared/primitives/integer.py +6 -0
  13. pylegend/core/language/shared/primitives/primitive.py +6 -0
  14. pylegend/core/language/shared/primitives/string.py +129 -1
  15. pylegend/core/sql/metamodel.py +3 -1
  16. pylegend/core/sql/metamodel_extension.py +18 -0
  17. pylegend/core/tds/pandas_api/frames/functions/aggregate_function.py +316 -0
  18. pylegend/core/tds/pandas_api/frames/functions/assign_function.py +20 -15
  19. pylegend/core/tds/pandas_api/frames/functions/drop.py +171 -0
  20. pylegend/core/tds/pandas_api/frames/functions/filter.py +193 -0
  21. pylegend/core/tds/pandas_api/frames/functions/filtering.py +85 -0
  22. pylegend/core/tds/pandas_api/frames/functions/sort_values_function.py +189 -0
  23. pylegend/core/tds/pandas_api/frames/functions/truncate_function.py +120 -0
  24. pylegend/core/tds/pandas_api/frames/pandas_api_applied_function_tds_frame.py +5 -1
  25. pylegend/core/tds/pandas_api/frames/pandas_api_base_tds_frame.py +204 -7
  26. pylegend/core/tds/pandas_api/frames/pandas_api_input_tds_frame.py +5 -3
  27. pylegend/core/tds/pandas_api/frames/pandas_api_tds_frame.py +90 -3
  28. {pylegend-0.8.0.dist-info → pylegend-0.9.0.dist-info}/METADATA +1 -1
  29. {pylegend-0.8.0.dist-info → pylegend-0.9.0.dist-info}/RECORD +33 -21
  30. {pylegend-0.8.0.dist-info → pylegend-0.9.0.dist-info}/WHEEL +0 -0
  31. {pylegend-0.8.0.dist-info → pylegend-0.9.0.dist-info}/licenses/LICENSE +0 -0
  32. {pylegend-0.8.0.dist-info → pylegend-0.9.0.dist-info}/licenses/LICENSE.spdx +0 -0
  33. {pylegend-0.8.0.dist-info → pylegend-0.9.0.dist-info}/licenses/NOTICE +0 -0
@@ -21,9 +21,12 @@ from pylegend.core.language.shared.expression import (
21
21
  PyLegendExpressionIntegerReturn,
22
22
  PyLegendExpressionFloatReturn,
23
23
  PyLegendExpressionBooleanReturn,
24
+ PyLegendExpressionDateTimeReturn,
24
25
  )
26
+ from pylegend.core.language.shared.expression import PyLegendExpression
25
27
  from pylegend.core.language.shared.operations.binary_expression import PyLegendBinaryExpression
26
28
  from pylegend.core.language.shared.operations.nullary_expression import PyLegendNullaryExpression
29
+ from pylegend.core.language.shared.operations.nary_expression import PyLegendNaryExpression
27
30
  from pylegend.core.language.shared.operations.unary_expression import PyLegendUnaryExpression
28
31
  from pylegend.core.language.shared.helpers import generate_pure_functional_call
29
32
  from pylegend.core.sql.metamodel import (
@@ -34,6 +37,9 @@ from pylegend.core.sql.metamodel import (
34
37
  ComparisonOperator,
35
38
  ComparisonExpression,
36
39
  StringLiteral,
40
+ FunctionCall,
41
+ QualifiedName,
42
+ IntegerLiteral
37
43
  )
38
44
  from pylegend.core.sql.metamodel_extension import (
39
45
  StringLengthExpression,
@@ -45,11 +51,11 @@ from pylegend.core.sql.metamodel_extension import (
45
51
  StringPosExpression,
46
52
  StringConcatExpression,
47
53
  ConstantExpression,
54
+ StringSubStringExpression
48
55
  )
49
56
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
50
57
  from pylegend.core.tds.tds_frame import FrameToPureConfig
51
58
 
52
-
53
59
  __all__: PyLegendSequence[str] = [
54
60
  "PyLegendStringLengthExpression",
55
61
  "PyLegendStringStartsWithExpression",
@@ -69,6 +75,24 @@ __all__: PyLegendSequence[str] = [
69
75
  "PyLegendStringGreaterThanExpression",
70
76
  "PyLegendStringGreaterThanEqualExpression",
71
77
  "PyLegendCurrentUserExpression",
78
+ "PyLegendStringParseBooleanExpression",
79
+ "PyLegendStringParseDateTimeExpression",
80
+ "PyLegendStringAsciiExpression",
81
+ "PyLegendStringDecodeBase64Expression",
82
+ "PyLegendStringEncodeBase64Expression",
83
+ "PyLegendStringReverseExpression",
84
+ "PyLegendStringToLowerFirstCharacterExpression",
85
+ "PyLegendStringToUpperFirstCharacterExpression",
86
+ "PyLegendStringLeftExpression",
87
+ "PyLegendStringRightExpression",
88
+ "PyLegendStringSubStringExpression",
89
+ "PyLegendStringReplaceExpression",
90
+ "PyLegendStringLpadExpression",
91
+ "PyLegendStringRpadExpression",
92
+ "PyLegendStringSplitPartExpression",
93
+ "PyLegendStringRepeatStringExpression",
94
+ "PyLegendStringFullMatchExpression",
95
+ "PyLegendStringMatchExpression"
72
96
  ]
73
97
 
74
98
 
@@ -393,6 +417,292 @@ class PyLegendStringParseFloatExpression(PyLegendUnaryExpression, PyLegendExpres
393
417
  )
394
418
 
395
419
 
420
+ class PyLegendStringParseBooleanExpression(PyLegendUnaryExpression, PyLegendExpressionBooleanReturn):
421
+
422
+ @staticmethod
423
+ def __to_sql_func(
424
+ expression: Expression,
425
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
426
+ config: FrameToSqlConfig
427
+ ) -> Expression:
428
+ return Cast(expression, ColumnType(name="BOOLEAN", parameters=[]))
429
+
430
+ @staticmethod
431
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
432
+ return generate_pure_functional_call("parseBoolean", [op_expr])
433
+
434
+ def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
435
+ PyLegendExpressionBooleanReturn.__init__(self)
436
+ PyLegendUnaryExpression.__init__(
437
+ self,
438
+ operand,
439
+ PyLegendStringParseBooleanExpression.__to_sql_func,
440
+ PyLegendStringParseBooleanExpression.__to_pure_func,
441
+ non_nullable=True,
442
+ operand_needs_to_be_non_nullable=True,
443
+ )
444
+
445
+
446
+ class PyLegendStringParseDateTimeExpression(PyLegendUnaryExpression, PyLegendExpressionDateTimeReturn):
447
+
448
+ @staticmethod
449
+ def __to_sql_func(
450
+ expression: Expression,
451
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
452
+ config: FrameToSqlConfig
453
+ ) -> Expression:
454
+ return Cast(expression, ColumnType(name="TIMESTAMP", parameters=[]))
455
+
456
+ @staticmethod
457
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
458
+ return generate_pure_functional_call("parseDate", [op_expr])
459
+
460
+ def __init__(self, operand: PyLegendExpressionStringReturn):
461
+ PyLegendExpressionDateTimeReturn.__init__(self)
462
+ PyLegendUnaryExpression.__init__(
463
+ self,
464
+ operand,
465
+ PyLegendStringParseDateTimeExpression.__to_sql_func,
466
+ PyLegendStringParseDateTimeExpression.__to_pure_func,
467
+ non_nullable=True,
468
+ operand_needs_to_be_non_nullable=True,
469
+ )
470
+
471
+
472
+ class PyLegendStringDecodeBase64Expression(PyLegendUnaryExpression, PyLegendExpressionStringReturn):
473
+
474
+ @staticmethod
475
+ def __to_sql_func(
476
+ expression: Expression,
477
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
478
+ config: FrameToSqlConfig
479
+ ) -> Expression:
480
+ return FunctionCall(
481
+ name=QualifiedName(parts=["CONVERT_FROM"]),
482
+ distinct=False,
483
+ arguments=[
484
+ FunctionCall(
485
+ name=QualifiedName(parts=["DECODE"]),
486
+ distinct=False,
487
+ arguments=[expression, StringLiteral("BASE64", quoted=False)],
488
+ filter_=None, window=None
489
+ ), StringLiteral("UTF8", quoted=False)
490
+ ],
491
+ filter_=None, window=None
492
+ )
493
+
494
+ @staticmethod
495
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
496
+ return generate_pure_functional_call("decodeBase64", [op_expr])
497
+
498
+ def __init__(self, operand: PyLegendExpressionStringReturn):
499
+ PyLegendExpressionStringReturn.__init__(self)
500
+ PyLegendUnaryExpression.__init__(
501
+ self,
502
+ operand,
503
+ PyLegendStringDecodeBase64Expression.__to_sql_func,
504
+ PyLegendStringDecodeBase64Expression.__to_pure_func,
505
+ non_nullable=True,
506
+ operand_needs_to_be_non_nullable=True,
507
+ )
508
+
509
+
510
+ class PyLegendStringEncodeBase64Expression(PyLegendUnaryExpression, PyLegendExpressionStringReturn):
511
+
512
+ @staticmethod
513
+ def __to_sql_func(
514
+ expression: Expression,
515
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
516
+ config: FrameToSqlConfig
517
+ ) -> Expression:
518
+ return FunctionCall(
519
+ name=QualifiedName(parts=["ENCODE"]),
520
+ distinct=False,
521
+ arguments=[
522
+ FunctionCall(
523
+ name=QualifiedName(parts=["CONVERT_TO"]),
524
+ distinct=False,
525
+ arguments=[expression, StringLiteral("UTF8", quoted=False)],
526
+ filter_=None, window=None
527
+ ), StringLiteral("BASE64", quoted=False)
528
+ ],
529
+ filter_=None, window=None
530
+ )
531
+
532
+ @staticmethod
533
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
534
+ return generate_pure_functional_call("encodeBase64", [op_expr])
535
+
536
+ def __init__(self, operand: PyLegendExpressionStringReturn):
537
+ PyLegendExpressionStringReturn.__init__(self)
538
+ PyLegendUnaryExpression.__init__(
539
+ self,
540
+ operand,
541
+ PyLegendStringEncodeBase64Expression.__to_sql_func,
542
+ PyLegendStringEncodeBase64Expression.__to_pure_func,
543
+ non_nullable=True,
544
+ operand_needs_to_be_non_nullable=True,
545
+ )
546
+
547
+
548
+ class PyLegendStringAsciiExpression(PyLegendUnaryExpression, PyLegendExpressionIntegerReturn):
549
+
550
+ @staticmethod
551
+ def __to_sql_func(
552
+ expression: Expression,
553
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
554
+ config: FrameToSqlConfig
555
+ ) -> Expression:
556
+ return FunctionCall(
557
+ name=QualifiedName(parts=["ASCII"]),
558
+ distinct=False,
559
+ arguments=[expression],
560
+ filter_=None, window=None
561
+ )
562
+
563
+ @staticmethod
564
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
565
+ return generate_pure_functional_call("ascii", [op_expr])
566
+
567
+ def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
568
+ PyLegendExpressionIntegerReturn.__init__(self)
569
+ PyLegendUnaryExpression.__init__(
570
+ self,
571
+ operand,
572
+ PyLegendStringAsciiExpression.__to_sql_func,
573
+ PyLegendStringAsciiExpression.__to_pure_func,
574
+ non_nullable=True,
575
+ operand_needs_to_be_non_nullable=True,
576
+ )
577
+
578
+
579
+ class PyLegendStringReverseExpression(PyLegendUnaryExpression, PyLegendExpressionStringReturn):
580
+
581
+ @staticmethod
582
+ def __to_sql_func(
583
+ expression: Expression,
584
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
585
+ config: FrameToSqlConfig
586
+ ) -> Expression:
587
+ return FunctionCall(
588
+ name=QualifiedName(parts=["REVERSE"]),
589
+ distinct=False,
590
+ arguments=[expression],
591
+ filter_=None, window=None
592
+ )
593
+
594
+ @staticmethod
595
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
596
+ return generate_pure_functional_call("reverseString", [op_expr])
597
+
598
+ def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
599
+ PyLegendExpressionStringReturn.__init__(self)
600
+ PyLegendUnaryExpression.__init__(
601
+ self,
602
+ operand,
603
+ PyLegendStringReverseExpression.__to_sql_func,
604
+ PyLegendStringReverseExpression.__to_pure_func,
605
+ non_nullable=True,
606
+ operand_needs_to_be_non_nullable=True,
607
+ )
608
+
609
+
610
+ class PyLegendStringToLowerFirstCharacterExpression(PyLegendUnaryExpression, PyLegendExpressionStringReturn):
611
+
612
+ @staticmethod
613
+ def __to_sql_func(
614
+ expression: Expression,
615
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
616
+ config: FrameToSqlConfig
617
+ ) -> Expression:
618
+ return FunctionCall(
619
+ name=QualifiedName(parts=["CONCAT"]),
620
+ distinct=False,
621
+ arguments=[
622
+ FunctionCall(
623
+ name=QualifiedName(parts=["LOWER"]),
624
+ distinct=False,
625
+ arguments=[FunctionCall(
626
+ name=QualifiedName(parts=["LEFT"]),
627
+ distinct=False,
628
+ arguments=[expression, IntegerLiteral(1)],
629
+ filter_=None, window=None
630
+ )],
631
+ filter_=None, window=None
632
+ ),
633
+ FunctionCall(
634
+ name=QualifiedName(parts=["SUBSTR"]),
635
+ distinct=False,
636
+ arguments=[expression, IntegerLiteral(2)],
637
+ filter_=None, window=None
638
+ )],
639
+ filter_=None, window=None
640
+ )
641
+
642
+ @staticmethod
643
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
644
+ return generate_pure_functional_call("toLowerFirstCharacter", [op_expr])
645
+
646
+ def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
647
+ PyLegendExpressionStringReturn.__init__(self)
648
+ PyLegendUnaryExpression.__init__(
649
+ self,
650
+ operand,
651
+ PyLegendStringToLowerFirstCharacterExpression.__to_sql_func,
652
+ PyLegendStringToLowerFirstCharacterExpression.__to_pure_func,
653
+ non_nullable=True,
654
+ operand_needs_to_be_non_nullable=True,
655
+ )
656
+
657
+
658
+ class PyLegendStringToUpperFirstCharacterExpression(PyLegendUnaryExpression, PyLegendExpressionStringReturn):
659
+
660
+ @staticmethod
661
+ def __to_sql_func(
662
+ expression: Expression,
663
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
664
+ config: FrameToSqlConfig
665
+ ) -> Expression:
666
+ return FunctionCall(
667
+ name=QualifiedName(parts=["CONCAT"]),
668
+ distinct=False,
669
+ arguments=[
670
+ FunctionCall(
671
+ name=QualifiedName(parts=["UPPER"]),
672
+ distinct=False,
673
+ arguments=[FunctionCall(
674
+ name=QualifiedName(parts=["LEFT"]),
675
+ distinct=False,
676
+ arguments=[expression, IntegerLiteral(1)],
677
+ filter_=None, window=None
678
+ )],
679
+ filter_=None, window=None
680
+ ),
681
+ FunctionCall(
682
+ name=QualifiedName(parts=["SUBSTR"]),
683
+ distinct=False,
684
+ arguments=[expression, IntegerLiteral(2)],
685
+ filter_=None, window=None
686
+ )],
687
+ filter_=None, window=None
688
+ )
689
+
690
+ @staticmethod
691
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
692
+ return generate_pure_functional_call("toUpperFirstCharacter", [op_expr])
693
+
694
+ def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
695
+ PyLegendExpressionStringReturn.__init__(self)
696
+ PyLegendUnaryExpression.__init__(
697
+ self,
698
+ operand,
699
+ PyLegendStringToUpperFirstCharacterExpression.__to_sql_func,
700
+ PyLegendStringToUpperFirstCharacterExpression.__to_pure_func,
701
+ non_nullable=True,
702
+ operand_needs_to_be_non_nullable=True,
703
+ )
704
+
705
+
396
706
  class PyLegendStringConcatExpression(PyLegendBinaryExpression, PyLegendExpressionStringReturn):
397
707
 
398
708
  @staticmethod
@@ -422,6 +732,98 @@ class PyLegendStringConcatExpression(PyLegendBinaryExpression, PyLegendExpressio
422
732
  )
423
733
 
424
734
 
735
+ class PyLegendStringFullMatchExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
736
+
737
+ @staticmethod
738
+ def __to_sql_func(
739
+ expression1: Expression,
740
+ expression2: Expression,
741
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
742
+ config: FrameToSqlConfig
743
+ ) -> Expression:
744
+ return ComparisonExpression(expression1, expression2, ComparisonOperator.LIKE)
745
+
746
+ @staticmethod
747
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
748
+ return generate_pure_functional_call("matches", [op1_expr, op2_expr])
749
+
750
+ def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
751
+ PyLegendExpressionBooleanReturn.__init__(self)
752
+ PyLegendBinaryExpression.__init__(
753
+ self,
754
+ operand1,
755
+ operand2,
756
+ PyLegendStringFullMatchExpression.__to_sql_func,
757
+ PyLegendStringFullMatchExpression.__to_pure_func,
758
+ non_nullable=True,
759
+ first_operand_needs_to_be_non_nullable=True,
760
+ second_operand_needs_to_be_non_nullable=True
761
+ )
762
+
763
+
764
+ class PyLegendStringMatchExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
765
+
766
+ @staticmethod
767
+ def __to_sql_func(
768
+ expression1: Expression,
769
+ expression2: Expression,
770
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
771
+ config: FrameToSqlConfig
772
+ ) -> Expression:
773
+ return ComparisonExpression(expression1, expression2, ComparisonOperator.REGEX_MATCH) # pragma: no cover
774
+
775
+ @staticmethod
776
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
777
+ return generate_pure_functional_call("regexpLike", [op1_expr, op2_expr]) # pragma: no cover
778
+
779
+ def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
780
+ PyLegendExpressionBooleanReturn.__init__(self) # pragma: no cover
781
+ PyLegendBinaryExpression.__init__(
782
+ self,
783
+ operand1,
784
+ operand2,
785
+ PyLegendStringMatchExpression.__to_sql_func,
786
+ PyLegendStringMatchExpression.__to_pure_func,
787
+ non_nullable=True,
788
+ first_operand_needs_to_be_non_nullable=True,
789
+ second_operand_needs_to_be_non_nullable=True
790
+ ) # pragma: no cover
791
+
792
+
793
+ class PyLegendStringRepeatStringExpression(PyLegendBinaryExpression, PyLegendExpressionStringReturn):
794
+
795
+ @staticmethod
796
+ def __to_sql_func(
797
+ expression1: Expression,
798
+ expression2: Expression,
799
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
800
+ config: FrameToSqlConfig
801
+ ) -> Expression:
802
+ return FunctionCall(
803
+ name=QualifiedName(parts=["REPEAT"]),
804
+ distinct=False,
805
+ arguments=[expression1, expression2],
806
+ filter_=None, window=None
807
+ )
808
+
809
+ @staticmethod
810
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
811
+ return generate_pure_functional_call("repeatString", [op1_expr, op2_expr])
812
+
813
+ def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
814
+ PyLegendExpressionStringReturn.__init__(self)
815
+ PyLegendBinaryExpression.__init__(
816
+ self,
817
+ operand1,
818
+ operand2,
819
+ PyLegendStringRepeatStringExpression.__to_sql_func,
820
+ PyLegendStringRepeatStringExpression.__to_pure_func,
821
+ non_nullable=True,
822
+ first_operand_needs_to_be_non_nullable=True,
823
+ second_operand_needs_to_be_non_nullable=True
824
+ )
825
+
826
+
425
827
  class PyLegendStringLessThanExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
426
828
 
427
829
  @staticmethod
@@ -526,6 +928,227 @@ class PyLegendStringGreaterThanEqualExpression(PyLegendBinaryExpression, PyLegen
526
928
  )
527
929
 
528
930
 
931
+ class PyLegendStringLeftExpression(PyLegendBinaryExpression, PyLegendExpressionStringReturn):
932
+
933
+ @staticmethod
934
+ def __to_sql_func(
935
+ expression1: Expression,
936
+ expression2: Expression,
937
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
938
+ config: FrameToSqlConfig
939
+ ) -> Expression:
940
+ return FunctionCall(
941
+ name=QualifiedName(parts=["LEFT"]),
942
+ distinct=False,
943
+ arguments=[expression1, expression2],
944
+ filter_=None, window=None
945
+ )
946
+
947
+ @staticmethod
948
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
949
+ return generate_pure_functional_call("left", [op1_expr, op2_expr])
950
+
951
+ def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
952
+ PyLegendExpressionStringReturn.__init__(self)
953
+ PyLegendBinaryExpression.__init__(
954
+ self,
955
+ operand1,
956
+ operand2,
957
+ PyLegendStringLeftExpression.__to_sql_func,
958
+ PyLegendStringLeftExpression.__to_pure_func,
959
+ non_nullable=True,
960
+ first_operand_needs_to_be_non_nullable=True,
961
+ second_operand_needs_to_be_non_nullable=True
962
+ )
963
+
964
+
965
+ class PyLegendStringRightExpression(PyLegendBinaryExpression, PyLegendExpressionStringReturn):
966
+
967
+ @staticmethod
968
+ def __to_sql_func(
969
+ expression1: Expression,
970
+ expression2: Expression,
971
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
972
+ config: FrameToSqlConfig
973
+ ) -> Expression:
974
+ return FunctionCall(
975
+ name=QualifiedName(parts=["RIGHT"]),
976
+ distinct=False,
977
+ arguments=[expression1, expression2],
978
+ filter_=None, window=None
979
+ )
980
+
981
+ @staticmethod
982
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
983
+ return generate_pure_functional_call("right", [op1_expr, op2_expr])
984
+
985
+ def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
986
+ PyLegendExpressionStringReturn.__init__(self)
987
+ PyLegendBinaryExpression.__init__(
988
+ self,
989
+ operand1,
990
+ operand2,
991
+ PyLegendStringRightExpression.__to_sql_func,
992
+ PyLegendStringRightExpression.__to_pure_func,
993
+ non_nullable=True,
994
+ first_operand_needs_to_be_non_nullable=True,
995
+ second_operand_needs_to_be_non_nullable=True
996
+ )
997
+
998
+
999
+ class PyLegendStringSubStringExpression(PyLegendNaryExpression, PyLegendExpressionStringReturn):
1000
+
1001
+ @staticmethod
1002
+ def __to_sql_func(
1003
+ expressions: list[Expression],
1004
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
1005
+ config: FrameToSqlConfig
1006
+ ) -> Expression:
1007
+ if len(expressions) > 2:
1008
+ return StringSubStringExpression(expressions[0], expressions[1], expressions[2])
1009
+ else:
1010
+ return StringSubStringExpression(expressions[0], expressions[1])
1011
+
1012
+ @staticmethod
1013
+ def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
1014
+ return generate_pure_functional_call("substring", op_expr)
1015
+
1016
+ def __init__(self, operands: list[PyLegendExpression]) -> None:
1017
+ PyLegendExpressionStringReturn.__init__(self)
1018
+ PyLegendNaryExpression.__init__(
1019
+ self,
1020
+ operands,
1021
+ PyLegendStringSubStringExpression.__to_sql_func,
1022
+ PyLegendStringSubStringExpression.__to_pure_func,
1023
+ non_nullable=False,
1024
+ operands_non_nullable_flags=[True, True, False]
1025
+ )
1026
+
1027
+
1028
+ class PyLegendStringReplaceExpression(PyLegendNaryExpression, PyLegendExpressionStringReturn):
1029
+
1030
+ @staticmethod
1031
+ def __to_sql_func(
1032
+ expressions: list[Expression],
1033
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
1034
+ config: FrameToSqlConfig
1035
+ ) -> Expression:
1036
+ return FunctionCall(
1037
+ name=QualifiedName(parts=["REPLACE"]),
1038
+ distinct=False,
1039
+ arguments=expressions,
1040
+ filter_=None, window=None
1041
+ )
1042
+
1043
+ @staticmethod
1044
+ def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
1045
+ return generate_pure_functional_call("replace", op_expr)
1046
+
1047
+ def __init__(self, operands: list[PyLegendExpression]) -> None:
1048
+ PyLegendExpressionStringReturn.__init__(self)
1049
+ PyLegendNaryExpression.__init__(
1050
+ self,
1051
+ operands,
1052
+ PyLegendStringReplaceExpression.__to_sql_func,
1053
+ PyLegendStringReplaceExpression.__to_pure_func,
1054
+ non_nullable=True,
1055
+ operands_non_nullable_flags=[True, True, True]
1056
+ )
1057
+
1058
+
1059
+ class PyLegendStringLpadExpression(PyLegendNaryExpression, PyLegendExpressionStringReturn):
1060
+
1061
+ @staticmethod
1062
+ def __to_sql_func(
1063
+ expressions: list[Expression],
1064
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
1065
+ config: FrameToSqlConfig
1066
+ ) -> Expression:
1067
+ return FunctionCall(
1068
+ name=QualifiedName(parts=["LPAD"]),
1069
+ distinct=False,
1070
+ arguments=expressions,
1071
+ filter_=None, window=None
1072
+ )
1073
+
1074
+ @staticmethod
1075
+ def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
1076
+ return generate_pure_functional_call("lpad", op_expr)
1077
+
1078
+ def __init__(self, operands: list[PyLegendExpression]) -> None:
1079
+ PyLegendExpressionStringReturn.__init__(self)
1080
+ PyLegendNaryExpression.__init__(
1081
+ self,
1082
+ operands,
1083
+ PyLegendStringLpadExpression.__to_sql_func,
1084
+ PyLegendStringLpadExpression.__to_pure_func,
1085
+ non_nullable=True,
1086
+ operands_non_nullable_flags=[True, True, True]
1087
+ )
1088
+
1089
+
1090
+ class PyLegendStringRpadExpression(PyLegendNaryExpression, PyLegendExpressionStringReturn):
1091
+
1092
+ @staticmethod
1093
+ def __to_sql_func(
1094
+ expressions: list[Expression],
1095
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
1096
+ config: FrameToSqlConfig
1097
+ ) -> Expression:
1098
+ return FunctionCall(
1099
+ name=QualifiedName(parts=["RPAD"]),
1100
+ distinct=False,
1101
+ arguments=expressions,
1102
+ filter_=None, window=None
1103
+ )
1104
+
1105
+ @staticmethod
1106
+ def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
1107
+ return generate_pure_functional_call("rpad", op_expr)
1108
+
1109
+ def __init__(self, operands: list[PyLegendExpression]) -> None:
1110
+ PyLegendExpressionStringReturn.__init__(self)
1111
+ PyLegendNaryExpression.__init__(
1112
+ self,
1113
+ operands,
1114
+ PyLegendStringRpadExpression.__to_sql_func,
1115
+ PyLegendStringRpadExpression.__to_pure_func,
1116
+ non_nullable=True,
1117
+ operands_non_nullable_flags=[True, True, True]
1118
+ )
1119
+
1120
+
1121
+ class PyLegendStringSplitPartExpression(PyLegendNaryExpression, PyLegendExpressionStringReturn):
1122
+
1123
+ @staticmethod
1124
+ def __to_sql_func(
1125
+ expressions: list[Expression],
1126
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
1127
+ config: FrameToSqlConfig
1128
+ ) -> Expression:
1129
+ return FunctionCall(
1130
+ name=QualifiedName(parts=["SPLIT_PART"]),
1131
+ distinct=False,
1132
+ arguments=expressions,
1133
+ filter_=None, window=None
1134
+ )
1135
+
1136
+ @staticmethod
1137
+ def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
1138
+ return generate_pure_functional_call("splitPart", op_expr)
1139
+
1140
+ def __init__(self, operands: list[PyLegendExpression]) -> None:
1141
+ PyLegendExpressionStringReturn.__init__(self)
1142
+ PyLegendNaryExpression.__init__(
1143
+ self,
1144
+ operands,
1145
+ PyLegendStringSplitPartExpression.__to_sql_func,
1146
+ PyLegendStringSplitPartExpression.__to_pure_func,
1147
+ non_nullable=True,
1148
+ operands_non_nullable_flags=[True, True, True]
1149
+ )
1150
+
1151
+
529
1152
  class PyLegendCurrentUserExpression(PyLegendNullaryExpression, PyLegendExpressionStringReturn):
530
1153
 
531
1154
  @staticmethod
@@ -33,9 +33,11 @@ from pylegend.core.language.shared.operations.integer_operation_expressions impo
33
33
  PyLegendIntegerSubtractExpression,
34
34
  PyLegendIntegerMultiplyExpression,
35
35
  PyLegendIntegerModuloExpression,
36
+ PyLegendIntegerCharExpression
36
37
  )
37
38
  if TYPE_CHECKING:
38
39
  from pylegend.core.language.shared.primitives import PyLegendFloat
40
+ from pylegend.core.language.shared.primitives.string import PyLegendString
39
41
 
40
42
  __all__: PyLegendSequence[str] = [
41
43
  "PyLegendInteger"
@@ -52,6 +54,10 @@ class PyLegendInteger(PyLegendNumber):
52
54
  self.__value_copy = value
53
55
  super().__init__(value)
54
56
 
57
+ def char(self) -> "PyLegendString":
58
+ from pylegend.core.language.shared.primitives.string import PyLegendString
59
+ return PyLegendString(PyLegendIntegerCharExpression(self.__value_copy))
60
+
55
61
  def to_sql_expression(
56
62
  self,
57
63
  frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],