pylegend 0.11.0__py3-none-any.whl → 0.13.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.
- pylegend/core/database/sql_to_string/db_extension.py +244 -6
- pylegend/core/language/legendql_api/legendql_api_custom_expressions.py +190 -5
- pylegend/core/language/pandas_api/pandas_api_series.py +3 -0
- pylegend/core/language/shared/expression.py +5 -0
- pylegend/core/language/shared/literal_expressions.py +22 -1
- pylegend/core/language/shared/operations/boolean_operation_expressions.py +144 -0
- pylegend/core/language/shared/operations/date_operation_expressions.py +91 -0
- pylegend/core/language/shared/operations/integer_operation_expressions.py +183 -1
- pylegend/core/language/shared/operations/string_operation_expressions.py +31 -1
- pylegend/core/language/shared/primitives/boolean.py +40 -0
- pylegend/core/language/shared/primitives/date.py +39 -0
- pylegend/core/language/shared/primitives/datetime.py +18 -0
- pylegend/core/language/shared/primitives/integer.py +54 -1
- pylegend/core/language/shared/primitives/strictdate.py +25 -1
- pylegend/core/language/shared/primitives/string.py +16 -2
- pylegend/core/sql/metamodel.py +54 -2
- pylegend/core/sql/metamodel_extension.py +77 -1
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_distinct_function.py +53 -7
- pylegend/core/tds/legendql_api/frames/legendql_api_base_tds_frame.py +146 -4
- pylegend/core/tds/legendql_api/frames/legendql_api_tds_frame.py +33 -2
- pylegend/core/tds/pandas_api/frames/functions/assign_function.py +65 -23
- pylegend/core/tds/pandas_api/frames/functions/drop.py +3 -3
- pylegend/core/tds/pandas_api/frames/functions/dropna.py +167 -0
- pylegend/core/tds/pandas_api/frames/functions/fillna.py +162 -0
- pylegend/core/tds/pandas_api/frames/functions/filter.py +10 -5
- pylegend/core/tds/pandas_api/frames/functions/iloc.py +99 -0
- pylegend/core/tds/pandas_api/frames/functions/loc.py +136 -0
- pylegend/core/tds/pandas_api/frames/functions/truncate_function.py +151 -120
- pylegend/core/tds/pandas_api/frames/pandas_api_applied_function_tds_frame.py +7 -3
- pylegend/core/tds/pandas_api/frames/pandas_api_base_tds_frame.py +340 -34
- pylegend/core/tds/pandas_api/frames/pandas_api_tds_frame.py +90 -9
- pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_function_input_frame.py +9 -4
- pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_service_input_frame.py +12 -5
- pylegend/extensions/tds/pandas_api/frames/pandas_api_table_spec_input_frame.py +12 -4
- {pylegend-0.11.0.dist-info → pylegend-0.13.0.dist-info}/METADATA +1 -1
- {pylegend-0.11.0.dist-info → pylegend-0.13.0.dist-info}/RECORD +40 -36
- {pylegend-0.11.0.dist-info → pylegend-0.13.0.dist-info}/WHEEL +1 -1
- {pylegend-0.11.0.dist-info → pylegend-0.13.0.dist-info}/licenses/LICENSE +0 -0
- {pylegend-0.11.0.dist-info → pylegend-0.13.0.dist-info}/licenses/LICENSE.spdx +0 -0
- {pylegend-0.11.0.dist-info → pylegend-0.13.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -28,6 +28,8 @@ from pylegend.core.sql.metamodel import (
|
|
|
28
28
|
LogicalBinaryExpression,
|
|
29
29
|
LogicalBinaryType,
|
|
30
30
|
NotExpression,
|
|
31
|
+
ComparisonExpression,
|
|
32
|
+
ComparisonOperator,
|
|
31
33
|
)
|
|
32
34
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
33
35
|
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
@@ -37,6 +39,11 @@ __all__: PyLegendSequence[str] = [
|
|
|
37
39
|
"PyLegendBooleanOrExpression",
|
|
38
40
|
"PyLegendBooleanAndExpression",
|
|
39
41
|
"PyLegendBooleanNotExpression",
|
|
42
|
+
"PyLegendBooleanLessThanExpression",
|
|
43
|
+
"PyLegendBooleanLessThanEqualExpression",
|
|
44
|
+
"PyLegendBooleanGreaterThanExpression",
|
|
45
|
+
"PyLegendBooleanGreaterThanEqualExpression",
|
|
46
|
+
"PyLegendBooleanXorExpression"
|
|
40
47
|
]
|
|
41
48
|
|
|
42
49
|
|
|
@@ -98,6 +105,143 @@ class PyLegendBooleanAndExpression(PyLegendBinaryExpression, PyLegendExpressionB
|
|
|
98
105
|
)
|
|
99
106
|
|
|
100
107
|
|
|
108
|
+
class PyLegendBooleanLessThanExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
109
|
+
|
|
110
|
+
@staticmethod
|
|
111
|
+
def __to_sql_func(
|
|
112
|
+
expression1: Expression,
|
|
113
|
+
expression2: Expression,
|
|
114
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
115
|
+
config: FrameToSqlConfig
|
|
116
|
+
) -> Expression:
|
|
117
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.LESS_THAN)
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
121
|
+
return f"({op1_expr} < {op2_expr})"
|
|
122
|
+
|
|
123
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
124
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
125
|
+
PyLegendBinaryExpression.__init__(
|
|
126
|
+
self,
|
|
127
|
+
operand1,
|
|
128
|
+
operand2,
|
|
129
|
+
PyLegendBooleanLessThanExpression.__to_sql_func,
|
|
130
|
+
PyLegendBooleanLessThanExpression.__to_pure_func,
|
|
131
|
+
non_nullable=True
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class PyLegendBooleanLessThanEqualExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
def __to_sql_func(
|
|
139
|
+
expression1: Expression,
|
|
140
|
+
expression2: Expression,
|
|
141
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
142
|
+
config: FrameToSqlConfig
|
|
143
|
+
) -> Expression:
|
|
144
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.LESS_THAN_OR_EQUAL)
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
148
|
+
return f"({op1_expr} <= {op2_expr})"
|
|
149
|
+
|
|
150
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
151
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
152
|
+
PyLegendBinaryExpression.__init__(
|
|
153
|
+
self,
|
|
154
|
+
operand1,
|
|
155
|
+
operand2,
|
|
156
|
+
PyLegendBooleanLessThanEqualExpression.__to_sql_func,
|
|
157
|
+
PyLegendBooleanLessThanEqualExpression.__to_pure_func,
|
|
158
|
+
non_nullable=True
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class PyLegendBooleanGreaterThanExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
163
|
+
|
|
164
|
+
@staticmethod
|
|
165
|
+
def __to_sql_func(
|
|
166
|
+
expression1: Expression,
|
|
167
|
+
expression2: Expression,
|
|
168
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
169
|
+
config: FrameToSqlConfig
|
|
170
|
+
) -> Expression:
|
|
171
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.GREATER_THAN)
|
|
172
|
+
|
|
173
|
+
@staticmethod
|
|
174
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
175
|
+
return f"({op1_expr} > {op2_expr})"
|
|
176
|
+
|
|
177
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
178
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
179
|
+
PyLegendBinaryExpression.__init__(
|
|
180
|
+
self,
|
|
181
|
+
operand1,
|
|
182
|
+
operand2,
|
|
183
|
+
PyLegendBooleanGreaterThanExpression.__to_sql_func,
|
|
184
|
+
PyLegendBooleanGreaterThanExpression.__to_pure_func,
|
|
185
|
+
non_nullable=True
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class PyLegendBooleanGreaterThanEqualExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
190
|
+
|
|
191
|
+
@staticmethod
|
|
192
|
+
def __to_sql_func(
|
|
193
|
+
expression1: Expression,
|
|
194
|
+
expression2: Expression,
|
|
195
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
196
|
+
config: FrameToSqlConfig
|
|
197
|
+
) -> Expression:
|
|
198
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.GREATER_THAN_OR_EQUAL)
|
|
199
|
+
|
|
200
|
+
@staticmethod
|
|
201
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
202
|
+
return f"({op1_expr} >= {op2_expr})"
|
|
203
|
+
|
|
204
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
205
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
206
|
+
PyLegendBinaryExpression.__init__(
|
|
207
|
+
self,
|
|
208
|
+
operand1,
|
|
209
|
+
operand2,
|
|
210
|
+
PyLegendBooleanGreaterThanEqualExpression.__to_sql_func,
|
|
211
|
+
PyLegendBooleanGreaterThanEqualExpression.__to_pure_func,
|
|
212
|
+
non_nullable=True
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class PyLegendBooleanXorExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
217
|
+
|
|
218
|
+
@staticmethod
|
|
219
|
+
def __to_sql_func(
|
|
220
|
+
expression1: Expression,
|
|
221
|
+
expression2: Expression,
|
|
222
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
223
|
+
config: FrameToSqlConfig
|
|
224
|
+
) -> Expression:
|
|
225
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.NOT_EQUAL)
|
|
226
|
+
|
|
227
|
+
@staticmethod
|
|
228
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
229
|
+
return generate_pure_functional_call("xor", [op1_expr, op2_expr])
|
|
230
|
+
|
|
231
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
232
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
233
|
+
PyLegendBinaryExpression.__init__(
|
|
234
|
+
self,
|
|
235
|
+
operand1,
|
|
236
|
+
operand2,
|
|
237
|
+
PyLegendBooleanXorExpression.__to_sql_func,
|
|
238
|
+
PyLegendBooleanXorExpression.__to_pure_func,
|
|
239
|
+
non_nullable=True,
|
|
240
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
241
|
+
second_operand_needs_to_be_non_nullable=True
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
|
|
101
245
|
class PyLegendBooleanNotExpression(PyLegendUnaryExpression, PyLegendExpressionBooleanReturn):
|
|
102
246
|
|
|
103
247
|
@staticmethod
|
|
@@ -22,8 +22,10 @@ from pylegend.core.language.shared.expression import (
|
|
|
22
22
|
PyLegendExpressionStrictDateReturn,
|
|
23
23
|
PyLegendExpressionIntegerReturn,
|
|
24
24
|
PyLegendExpressionBooleanReturn,
|
|
25
|
+
PyLegendExpression
|
|
25
26
|
)
|
|
26
27
|
from pylegend.core.language.shared.operations.binary_expression import PyLegendBinaryExpression
|
|
28
|
+
from pylegend.core.language.shared.operations.nary_expression import PyLegendNaryExpression
|
|
27
29
|
from pylegend.core.language.shared.operations.nullary_expression import PyLegendNullaryExpression
|
|
28
30
|
from pylegend.core.language.shared.operations.unary_expression import PyLegendUnaryExpression
|
|
29
31
|
from pylegend.core.language.shared.helpers import generate_pure_functional_call
|
|
@@ -61,6 +63,10 @@ from pylegend.core.sql.metamodel_extension import (
|
|
|
61
63
|
MinuteExpression,
|
|
62
64
|
SecondExpression,
|
|
63
65
|
EpochExpression,
|
|
66
|
+
DateAdjustExpression,
|
|
67
|
+
DateDiffExpression,
|
|
68
|
+
DateTimeBucketExpression,
|
|
69
|
+
DateType,
|
|
64
70
|
)
|
|
65
71
|
|
|
66
72
|
|
|
@@ -91,6 +97,9 @@ __all__: PyLegendSequence[str] = [
|
|
|
91
97
|
"PyLegendDateLessThanEqualExpression",
|
|
92
98
|
"PyLegendDateGreaterThanExpression",
|
|
93
99
|
"PyLegendDateGreaterThanEqualExpression",
|
|
100
|
+
"PyLegendDateAdjustExpression",
|
|
101
|
+
"PyLegendDateDiffExpression",
|
|
102
|
+
"PyLegendDateTimeBucketExpression",
|
|
94
103
|
]
|
|
95
104
|
|
|
96
105
|
|
|
@@ -780,3 +789,85 @@ class PyLegendDateGreaterThanEqualExpression(PyLegendBinaryExpression, PyLegendE
|
|
|
780
789
|
|
|
781
790
|
def is_non_nullable(self) -> bool:
|
|
782
791
|
return True
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
class PyLegendDateAdjustExpression(PyLegendNaryExpression, PyLegendExpressionDateReturn):
|
|
795
|
+
|
|
796
|
+
@staticmethod
|
|
797
|
+
def __to_sql_func(
|
|
798
|
+
expressions: list[Expression],
|
|
799
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
800
|
+
config: FrameToSqlConfig
|
|
801
|
+
) -> Expression:
|
|
802
|
+
return DateAdjustExpression(expressions[0], expressions[1], expressions[2]) # type:ignore
|
|
803
|
+
|
|
804
|
+
@staticmethod
|
|
805
|
+
def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
|
|
806
|
+
return generate_pure_functional_call("adjust", [op_expr[0], op_expr[1], f"DurationUnit.{op_expr[2]}"])
|
|
807
|
+
|
|
808
|
+
def __init__(self, operands: list[PyLegendExpression]) -> None:
|
|
809
|
+
PyLegendExpressionDateReturn.__init__(self)
|
|
810
|
+
PyLegendNaryExpression.__init__(
|
|
811
|
+
self,
|
|
812
|
+
operands,
|
|
813
|
+
PyLegendDateAdjustExpression.__to_sql_func,
|
|
814
|
+
PyLegendDateAdjustExpression.__to_pure_func,
|
|
815
|
+
non_nullable=True,
|
|
816
|
+
operands_non_nullable_flags=[True, True, True]
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
class PyLegendDateDiffExpression(PyLegendNaryExpression, PyLegendExpressionIntegerReturn):
|
|
821
|
+
|
|
822
|
+
@staticmethod
|
|
823
|
+
def __to_sql_func(
|
|
824
|
+
expressions: list[Expression],
|
|
825
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
826
|
+
config: FrameToSqlConfig
|
|
827
|
+
) -> Expression:
|
|
828
|
+
return DateDiffExpression(expressions[0], expressions[1], expressions[2]) # type: ignore
|
|
829
|
+
|
|
830
|
+
@staticmethod
|
|
831
|
+
def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
|
|
832
|
+
return generate_pure_functional_call("dateDiff", [op_expr[0], op_expr[1], f"DurationUnit.{op_expr[2]}"])
|
|
833
|
+
|
|
834
|
+
def __init__(self, operands: list[PyLegendExpression]) -> None:
|
|
835
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
836
|
+
PyLegendNaryExpression.__init__(
|
|
837
|
+
self,
|
|
838
|
+
operands,
|
|
839
|
+
PyLegendDateDiffExpression.__to_sql_func,
|
|
840
|
+
PyLegendDateDiffExpression.__to_pure_func,
|
|
841
|
+
non_nullable=True,
|
|
842
|
+
operands_non_nullable_flags=[True, True, True]
|
|
843
|
+
)
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
class PyLegendDateTimeBucketExpression(PyLegendNaryExpression, PyLegendExpressionDateReturn):
|
|
847
|
+
|
|
848
|
+
@staticmethod
|
|
849
|
+
def __to_sql_func(
|
|
850
|
+
expressions: list[Expression],
|
|
851
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
852
|
+
config: FrameToSqlConfig
|
|
853
|
+
) -> Expression:
|
|
854
|
+
return DateTimeBucketExpression(
|
|
855
|
+
expressions[0],
|
|
856
|
+
expressions[1],
|
|
857
|
+
expressions[2], # type: ignore
|
|
858
|
+
DateType.DateTime if expressions[3].value == "DATETIME" else DateType.StrictDate) # type: ignore
|
|
859
|
+
|
|
860
|
+
@staticmethod
|
|
861
|
+
def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
|
|
862
|
+
return generate_pure_functional_call("timeBucket", [op_expr[0], op_expr[1], f"DurationUnit.{op_expr[2]}"])
|
|
863
|
+
|
|
864
|
+
def __init__(self, operands: list[PyLegendExpression]) -> None:
|
|
865
|
+
PyLegendExpressionDateReturn.__init__(self)
|
|
866
|
+
PyLegendNaryExpression.__init__(
|
|
867
|
+
self,
|
|
868
|
+
operands,
|
|
869
|
+
PyLegendDateTimeBucketExpression.__to_sql_func,
|
|
870
|
+
PyLegendDateTimeBucketExpression.__to_pure_func,
|
|
871
|
+
non_nullable=True,
|
|
872
|
+
operands_non_nullable_flags=[True, True, True]
|
|
873
|
+
)
|
|
@@ -30,10 +30,15 @@ from pylegend.core.sql.metamodel import (
|
|
|
30
30
|
ArithmeticExpression,
|
|
31
31
|
NegativeExpression,
|
|
32
32
|
FunctionCall,
|
|
33
|
-
QualifiedName
|
|
33
|
+
QualifiedName,
|
|
34
|
+
BitwiseBinaryExpression,
|
|
35
|
+
BitwiseBinaryOperator,
|
|
36
|
+
BitwiseShiftExpression,
|
|
37
|
+
BitwiseShiftDirection
|
|
34
38
|
)
|
|
35
39
|
from pylegend.core.sql.metamodel_extension import (
|
|
36
40
|
AbsoluteExpression,
|
|
41
|
+
BitwiseNotExpression,
|
|
37
42
|
)
|
|
38
43
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
39
44
|
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
@@ -47,6 +52,12 @@ __all__: PyLegendSequence[str] = [
|
|
|
47
52
|
"PyLegendIntegerMultiplyExpression",
|
|
48
53
|
"PyLegendIntegerModuloExpression",
|
|
49
54
|
"PyLegendIntegerCharExpression",
|
|
55
|
+
"PyLegendIntegerBitAndExpression",
|
|
56
|
+
"PyLegendIntegerBitOrExpression",
|
|
57
|
+
"PyLegendIntegerBitXorExpression",
|
|
58
|
+
"PyLegendIntegerBitShiftLeftExpression",
|
|
59
|
+
"PyLegendIntegerBitShiftRightExpression",
|
|
60
|
+
"PyLegendIntegerBitNotExpression"
|
|
50
61
|
]
|
|
51
62
|
|
|
52
63
|
|
|
@@ -253,3 +264,174 @@ class PyLegendIntegerCharExpression(PyLegendUnaryExpression, PyLegendExpressionS
|
|
|
253
264
|
non_nullable=True,
|
|
254
265
|
operand_needs_to_be_non_nullable=True,
|
|
255
266
|
)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class PyLegendIntegerBitAndExpression(PyLegendBinaryExpression, PyLegendExpressionIntegerReturn):
|
|
270
|
+
|
|
271
|
+
@staticmethod
|
|
272
|
+
def __to_sql_func(
|
|
273
|
+
expression1: Expression,
|
|
274
|
+
expression2: Expression,
|
|
275
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
276
|
+
config: FrameToSqlConfig
|
|
277
|
+
) -> Expression:
|
|
278
|
+
return BitwiseBinaryExpression(expression1, expression2, BitwiseBinaryOperator.AND)
|
|
279
|
+
|
|
280
|
+
@staticmethod
|
|
281
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
282
|
+
return generate_pure_functional_call("bitAnd", [op1_expr, op2_expr])
|
|
283
|
+
|
|
284
|
+
def __init__(self, operand1: PyLegendExpressionIntegerReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
|
|
285
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
286
|
+
PyLegendBinaryExpression.__init__(
|
|
287
|
+
self,
|
|
288
|
+
operand1,
|
|
289
|
+
operand2,
|
|
290
|
+
PyLegendIntegerBitAndExpression.__to_sql_func,
|
|
291
|
+
PyLegendIntegerBitAndExpression.__to_pure_func,
|
|
292
|
+
non_nullable=True,
|
|
293
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
294
|
+
second_operand_needs_to_be_non_nullable=True
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class PyLegendIntegerBitOrExpression(PyLegendBinaryExpression, PyLegendExpressionIntegerReturn):
|
|
299
|
+
|
|
300
|
+
@staticmethod
|
|
301
|
+
def __to_sql_func(
|
|
302
|
+
expression1: Expression,
|
|
303
|
+
expression2: Expression,
|
|
304
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
305
|
+
config: FrameToSqlConfig
|
|
306
|
+
) -> Expression:
|
|
307
|
+
return BitwiseBinaryExpression(expression1, expression2, BitwiseBinaryOperator.OR)
|
|
308
|
+
|
|
309
|
+
@staticmethod
|
|
310
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
311
|
+
return generate_pure_functional_call("bitOr", [op1_expr, op2_expr])
|
|
312
|
+
|
|
313
|
+
def __init__(self, operand1: PyLegendExpressionIntegerReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
|
|
314
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
315
|
+
PyLegendBinaryExpression.__init__(
|
|
316
|
+
self,
|
|
317
|
+
operand1,
|
|
318
|
+
operand2,
|
|
319
|
+
PyLegendIntegerBitOrExpression.__to_sql_func,
|
|
320
|
+
PyLegendIntegerBitOrExpression.__to_pure_func,
|
|
321
|
+
non_nullable=True,
|
|
322
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
323
|
+
second_operand_needs_to_be_non_nullable=True
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
class PyLegendIntegerBitXorExpression(PyLegendBinaryExpression, PyLegendExpressionIntegerReturn):
|
|
328
|
+
|
|
329
|
+
@staticmethod
|
|
330
|
+
def __to_sql_func(
|
|
331
|
+
expression1: Expression,
|
|
332
|
+
expression2: Expression,
|
|
333
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
334
|
+
config: FrameToSqlConfig
|
|
335
|
+
) -> Expression:
|
|
336
|
+
return BitwiseBinaryExpression(expression1, expression2, BitwiseBinaryOperator.XOR)
|
|
337
|
+
|
|
338
|
+
@staticmethod
|
|
339
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
340
|
+
return generate_pure_functional_call("bitXor", [op1_expr, op2_expr])
|
|
341
|
+
|
|
342
|
+
def __init__(self, operand1: PyLegendExpressionIntegerReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
|
|
343
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
344
|
+
PyLegendBinaryExpression.__init__(
|
|
345
|
+
self,
|
|
346
|
+
operand1,
|
|
347
|
+
operand2,
|
|
348
|
+
PyLegendIntegerBitXorExpression.__to_sql_func,
|
|
349
|
+
PyLegendIntegerBitXorExpression.__to_pure_func,
|
|
350
|
+
non_nullable=True,
|
|
351
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
352
|
+
second_operand_needs_to_be_non_nullable=True
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
class PyLegendIntegerBitShiftLeftExpression(PyLegendBinaryExpression, PyLegendExpressionIntegerReturn):
|
|
357
|
+
|
|
358
|
+
@staticmethod
|
|
359
|
+
def __to_sql_func(
|
|
360
|
+
expression1: Expression,
|
|
361
|
+
expression2: Expression,
|
|
362
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
363
|
+
config: FrameToSqlConfig
|
|
364
|
+
) -> Expression:
|
|
365
|
+
return BitwiseShiftExpression(expression1, expression2, BitwiseShiftDirection.LEFT)
|
|
366
|
+
|
|
367
|
+
@staticmethod
|
|
368
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
369
|
+
return generate_pure_functional_call("bitShiftLeft", [op1_expr, op2_expr])
|
|
370
|
+
|
|
371
|
+
def __init__(self, operand1: PyLegendExpressionIntegerReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
|
|
372
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
373
|
+
PyLegendBinaryExpression.__init__(
|
|
374
|
+
self,
|
|
375
|
+
operand1,
|
|
376
|
+
operand2,
|
|
377
|
+
PyLegendIntegerBitShiftLeftExpression.__to_sql_func,
|
|
378
|
+
PyLegendIntegerBitShiftLeftExpression.__to_pure_func,
|
|
379
|
+
non_nullable=True,
|
|
380
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
381
|
+
second_operand_needs_to_be_non_nullable=True
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
class PyLegendIntegerBitShiftRightExpression(PyLegendBinaryExpression, PyLegendExpressionIntegerReturn):
|
|
386
|
+
|
|
387
|
+
@staticmethod
|
|
388
|
+
def __to_sql_func(
|
|
389
|
+
expression1: Expression,
|
|
390
|
+
expression2: Expression,
|
|
391
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
392
|
+
config: FrameToSqlConfig
|
|
393
|
+
) -> Expression:
|
|
394
|
+
return BitwiseShiftExpression(expression1, expression2, BitwiseShiftDirection.RIGHT)
|
|
395
|
+
|
|
396
|
+
@staticmethod
|
|
397
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
398
|
+
return generate_pure_functional_call("bitShiftRight", [op1_expr, op2_expr])
|
|
399
|
+
|
|
400
|
+
def __init__(self, operand1: PyLegendExpressionIntegerReturn, operand2: PyLegendExpressionIntegerReturn) -> None:
|
|
401
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
402
|
+
PyLegendBinaryExpression.__init__(
|
|
403
|
+
self,
|
|
404
|
+
operand1,
|
|
405
|
+
operand2,
|
|
406
|
+
PyLegendIntegerBitShiftRightExpression.__to_sql_func,
|
|
407
|
+
PyLegendIntegerBitShiftRightExpression.__to_pure_func,
|
|
408
|
+
non_nullable=True,
|
|
409
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
410
|
+
second_operand_needs_to_be_non_nullable=True
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
class PyLegendIntegerBitNotExpression(PyLegendUnaryExpression, PyLegendExpressionIntegerReturn):
|
|
415
|
+
|
|
416
|
+
@staticmethod
|
|
417
|
+
def __to_sql_func(
|
|
418
|
+
expression: Expression,
|
|
419
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
420
|
+
config: FrameToSqlConfig
|
|
421
|
+
) -> Expression:
|
|
422
|
+
return BitwiseNotExpression(expression)
|
|
423
|
+
|
|
424
|
+
@staticmethod
|
|
425
|
+
def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
|
|
426
|
+
return generate_pure_functional_call("bitNot", [op_expr])
|
|
427
|
+
|
|
428
|
+
def __init__(self, operand: PyLegendExpressionIntegerReturn) -> None:
|
|
429
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
430
|
+
PyLegendUnaryExpression.__init__(
|
|
431
|
+
self,
|
|
432
|
+
operand,
|
|
433
|
+
PyLegendIntegerBitNotExpression.__to_sql_func,
|
|
434
|
+
PyLegendIntegerBitNotExpression.__to_pure_func,
|
|
435
|
+
non_nullable=True,
|
|
436
|
+
operand_needs_to_be_non_nullable=True,
|
|
437
|
+
)
|
|
@@ -92,7 +92,8 @@ __all__: PyLegendSequence[str] = [
|
|
|
92
92
|
"PyLegendStringSplitPartExpression",
|
|
93
93
|
"PyLegendStringRepeatStringExpression",
|
|
94
94
|
"PyLegendStringFullMatchExpression",
|
|
95
|
-
"PyLegendStringMatchExpression"
|
|
95
|
+
"PyLegendStringMatchExpression",
|
|
96
|
+
"PyLegendStringCoalesceExpression"
|
|
96
97
|
]
|
|
97
98
|
|
|
98
99
|
|
|
@@ -1149,6 +1150,35 @@ class PyLegendStringSplitPartExpression(PyLegendNaryExpression, PyLegendExpressi
|
|
|
1149
1150
|
)
|
|
1150
1151
|
|
|
1151
1152
|
|
|
1153
|
+
class PyLegendStringCoalesceExpression(PyLegendNaryExpression, PyLegendExpressionStringReturn):
|
|
1154
|
+
|
|
1155
|
+
@staticmethod
|
|
1156
|
+
def __to_sql_func(
|
|
1157
|
+
expressions: list[Expression],
|
|
1158
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
1159
|
+
config: FrameToSqlConfig
|
|
1160
|
+
) -> Expression:
|
|
1161
|
+
return FunctionCall(
|
|
1162
|
+
name=QualifiedName(parts=["COALESCE"]),
|
|
1163
|
+
distinct=False,
|
|
1164
|
+
arguments=expressions,
|
|
1165
|
+
filter_=None, window=None
|
|
1166
|
+
)
|
|
1167
|
+
|
|
1168
|
+
@staticmethod
|
|
1169
|
+
def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
|
|
1170
|
+
return generate_pure_functional_call("meta::pure::functions::flow::coalesce", op_expr)
|
|
1171
|
+
|
|
1172
|
+
def __init__(self, operands: list[PyLegendExpression]) -> None:
|
|
1173
|
+
PyLegendExpressionStringReturn.__init__(self)
|
|
1174
|
+
PyLegendNaryExpression.__init__(
|
|
1175
|
+
self,
|
|
1176
|
+
operands,
|
|
1177
|
+
PyLegendStringCoalesceExpression.__to_sql_func,
|
|
1178
|
+
PyLegendStringCoalesceExpression.__to_pure_func
|
|
1179
|
+
)
|
|
1180
|
+
|
|
1181
|
+
|
|
1152
1182
|
class PyLegendCurrentUserExpression(PyLegendNullaryExpression, PyLegendExpressionStringReturn):
|
|
1153
1183
|
|
|
1154
1184
|
@staticmethod
|
|
@@ -24,6 +24,11 @@ from pylegend.core.language.shared.operations.boolean_operation_expressions impo
|
|
|
24
24
|
PyLegendBooleanOrExpression,
|
|
25
25
|
PyLegendBooleanAndExpression,
|
|
26
26
|
PyLegendBooleanNotExpression,
|
|
27
|
+
PyLegendBooleanLessThanExpression,
|
|
28
|
+
PyLegendBooleanLessThanEqualExpression,
|
|
29
|
+
PyLegendBooleanGreaterThanExpression,
|
|
30
|
+
PyLegendBooleanGreaterThanEqualExpression,
|
|
31
|
+
PyLegendBooleanXorExpression,
|
|
27
32
|
)
|
|
28
33
|
from pylegend.core.sql.metamodel import (
|
|
29
34
|
Expression,
|
|
@@ -83,6 +88,41 @@ class PyLegendBoolean(PyLegendPrimitive):
|
|
|
83
88
|
def __invert__(self) -> "PyLegendBoolean":
|
|
84
89
|
return PyLegendBoolean(PyLegendBooleanNotExpression(self.__value))
|
|
85
90
|
|
|
91
|
+
def __lt__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
|
|
92
|
+
return self._create_binary_expression(other, PyLegendBooleanLessThanExpression, "less than (<)")
|
|
93
|
+
|
|
94
|
+
def __le__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
|
|
95
|
+
return self._create_binary_expression(other, PyLegendBooleanLessThanEqualExpression, "less than equal (<=)")
|
|
96
|
+
|
|
97
|
+
def __gt__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
|
|
98
|
+
return self._create_binary_expression(other, PyLegendBooleanGreaterThanExpression, "greater than (>)")
|
|
99
|
+
|
|
100
|
+
def __ge__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
|
|
101
|
+
return self._create_binary_expression(
|
|
102
|
+
other,
|
|
103
|
+
PyLegendBooleanGreaterThanEqualExpression,
|
|
104
|
+
"greater than equal (>=)")
|
|
105
|
+
|
|
106
|
+
def __xor__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
|
|
107
|
+
return self._create_binary_expression(other, PyLegendBooleanXorExpression, "xor (^)")
|
|
108
|
+
|
|
109
|
+
def __rxor__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
|
|
110
|
+
return self._create_binary_expression(other, PyLegendBooleanXorExpression, "xor (^)", reverse=True)
|
|
111
|
+
|
|
112
|
+
def _create_binary_expression(
|
|
113
|
+
self,
|
|
114
|
+
other: PyLegendUnion[bool, "PyLegendBoolean"],
|
|
115
|
+
expression_class: type,
|
|
116
|
+
operation_name: str,
|
|
117
|
+
reverse: bool = False
|
|
118
|
+
) -> "PyLegendBoolean":
|
|
119
|
+
PyLegendBoolean.__validate__param_to_be_bool(other, f"Boolean {operation_name} parameter")
|
|
120
|
+
other_op = PyLegendBooleanLiteralExpression(other) if isinstance(other, bool) else other.__value
|
|
121
|
+
|
|
122
|
+
if reverse:
|
|
123
|
+
return PyLegendBoolean(expression_class(other_op, self.__value))
|
|
124
|
+
return PyLegendBoolean(expression_class(self.__value, other_op))
|
|
125
|
+
|
|
86
126
|
@staticmethod
|
|
87
127
|
def __validate__param_to_be_bool(param: PyLegendUnion[bool, "PyLegendBoolean"], desc: str) -> None:
|
|
88
128
|
if not isinstance(param, (bool, PyLegendBoolean)):
|
|
@@ -28,6 +28,8 @@ from pylegend.core.language.shared.expression import (
|
|
|
28
28
|
from pylegend.core.language.shared.literal_expressions import (
|
|
29
29
|
PyLegendDateTimeLiteralExpression,
|
|
30
30
|
PyLegendStrictDateLiteralExpression,
|
|
31
|
+
PyLegendIntegerLiteralExpression,
|
|
32
|
+
PyLegendStringLiteralExpression,
|
|
31
33
|
)
|
|
32
34
|
from pylegend.core.language.shared.operations.date_operation_expressions import (
|
|
33
35
|
PyLegendFirstDayOfYearExpression,
|
|
@@ -54,6 +56,8 @@ from pylegend.core.language.shared.operations.date_operation_expressions import
|
|
|
54
56
|
PyLegendDateLessThanEqualExpression,
|
|
55
57
|
PyLegendDateGreaterThanExpression,
|
|
56
58
|
PyLegendDateGreaterThanEqualExpression,
|
|
59
|
+
PyLegendDateAdjustExpression,
|
|
60
|
+
PyLegendDateDiffExpression,
|
|
57
61
|
)
|
|
58
62
|
from pylegend.core.sql.metamodel import (
|
|
59
63
|
Expression,
|
|
@@ -158,6 +162,23 @@ class PyLegendDate(PyLegendPrimitive):
|
|
|
158
162
|
from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
|
|
159
163
|
return PyLegendStrictDate(PyLegendDatePartExpression(self.__value))
|
|
160
164
|
|
|
165
|
+
def timedelta(self, number: PyLegendUnion[int, "PyLegendInteger"], duration_unit: str) -> "PyLegendDate":
|
|
166
|
+
self.validate_param_to_be_int_or_int_expr(number, "timedelta number parameter")
|
|
167
|
+
number_op = PyLegendIntegerLiteralExpression(number) if isinstance(number, int) else number.value()
|
|
168
|
+
self.validate_duration_unit_param(duration_unit)
|
|
169
|
+
duration_unit_op = PyLegendStringLiteralExpression(duration_unit.upper())
|
|
170
|
+
return PyLegendDate(PyLegendDateAdjustExpression([self.__value, number_op, duration_unit_op]))
|
|
171
|
+
|
|
172
|
+
def diff(
|
|
173
|
+
self,
|
|
174
|
+
other: PyLegendUnion[date, datetime, "PyLegendStrictDate", "PyLegendDateTime", "PyLegendDate"],
|
|
175
|
+
duration_unit: str) -> "PyLegendInteger":
|
|
176
|
+
self.validate_param_to_be_date(other, "Diff parameter")
|
|
177
|
+
other_op = PyLegendDate.__convert_to_date_expr(other)
|
|
178
|
+
self.validate_duration_unit_param(duration_unit)
|
|
179
|
+
duration_unit_op = PyLegendStringLiteralExpression(duration_unit.upper())
|
|
180
|
+
return PyLegendInteger(PyLegendDateDiffExpression([self.__value, other_op, duration_unit_op]))
|
|
181
|
+
|
|
161
182
|
def __lt__(
|
|
162
183
|
self,
|
|
163
184
|
other: PyLegendUnion[date, datetime, "PyLegendStrictDate", "PyLegendDateTime", "PyLegendDate"]
|
|
@@ -211,3 +232,21 @@ class PyLegendDate(PyLegendPrimitive):
|
|
|
211
232
|
raise TypeError(desc + " should be a datetime.date/datetime.datetime or a Date expression"
|
|
212
233
|
" (PyLegendDateTime/PyLegendStrictDate/PyLegendDate)."
|
|
213
234
|
" Got value " + str(param) + " of type: " + str(type(param)))
|
|
235
|
+
|
|
236
|
+
@staticmethod
|
|
237
|
+
def validate_duration_unit_param(duration_unit: str) -> None:
|
|
238
|
+
if duration_unit.lower() not in ('years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds',
|
|
239
|
+
'milliseconds', 'microseconds', 'nanoseconds'):
|
|
240
|
+
raise ValueError(
|
|
241
|
+
f"Unknown duration unit - {duration_unit}. Supported values are - YEARS, MONTHS, WEEKS, DAYS, HOURS,"
|
|
242
|
+
" MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
@staticmethod
|
|
246
|
+
def validate_param_to_be_int_or_int_expr(
|
|
247
|
+
param: PyLegendUnion[int, "PyLegendInteger"],
|
|
248
|
+
desc: str
|
|
249
|
+
) -> None:
|
|
250
|
+
if not isinstance(param, (int, PyLegendInteger)):
|
|
251
|
+
raise TypeError(desc + " should be a int or an integer expression (PyLegendInteger)."
|
|
252
|
+
" Got value " + str(param) + " of type: " + str(type(param)))
|
|
@@ -18,12 +18,16 @@ from pylegend._typing import (
|
|
|
18
18
|
PyLegendDict,
|
|
19
19
|
PyLegendUnion,
|
|
20
20
|
)
|
|
21
|
+
from pylegend.core.language.shared.operations.date_operation_expressions import PyLegendDateTimeBucketExpression
|
|
22
|
+
from pylegend.core.language.shared.primitives.integer import PyLegendInteger
|
|
21
23
|
from pylegend.core.language.shared.primitives.date import PyLegendDate
|
|
22
24
|
from pylegend.core.language.shared.expression import (
|
|
23
25
|
PyLegendExpressionDateTimeReturn,
|
|
24
26
|
)
|
|
25
27
|
from pylegend.core.language.shared.literal_expressions import (
|
|
26
28
|
PyLegendDateTimeLiteralExpression,
|
|
29
|
+
PyLegendIntegerLiteralExpression,
|
|
30
|
+
PyLegendStringLiteralExpression,
|
|
27
31
|
)
|
|
28
32
|
from pylegend.core.sql.metamodel import (
|
|
29
33
|
Expression,
|
|
@@ -57,6 +61,20 @@ class PyLegendDateTime(PyLegendDate):
|
|
|
57
61
|
def value(self) -> PyLegendExpressionDateTimeReturn:
|
|
58
62
|
return self.__value
|
|
59
63
|
|
|
64
|
+
def time_bucket(
|
|
65
|
+
self,
|
|
66
|
+
quantity: PyLegendUnion[int, "PyLegendInteger"],
|
|
67
|
+
duration_unit: str) -> "PyLegendDate":
|
|
68
|
+
self.validate_param_to_be_int_or_int_expr(quantity, "time bucket quantity parameter")
|
|
69
|
+
quantity_op = PyLegendIntegerLiteralExpression(quantity) if isinstance(quantity, int) else quantity.value()
|
|
70
|
+
self.validate_duration_unit_param(duration_unit)
|
|
71
|
+
duration_unit_op = PyLegendStringLiteralExpression(duration_unit.upper())
|
|
72
|
+
return PyLegendDate(PyLegendDateTimeBucketExpression([
|
|
73
|
+
self.__value,
|
|
74
|
+
quantity_op,
|
|
75
|
+
duration_unit_op,
|
|
76
|
+
PyLegendStringLiteralExpression("DATETIME")]))
|
|
77
|
+
|
|
60
78
|
@staticmethod
|
|
61
79
|
def __convert_to_datetime_expr(
|
|
62
80
|
val: PyLegendUnion[datetime, "PyLegendDateTime"]
|