pylegend 0.2.2__py3-none-any.whl → 0.4.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 (123) hide show
  1. pylegend/__init__.py +9 -5
  2. pylegend/core/{databse → database}/sql_to_string/__init__.py +3 -3
  3. pylegend/core/{databse → database}/sql_to_string/db_extension.py +11 -5
  4. pylegend/core/{databse → database}/sql_to_string/generator.py +2 -2
  5. pylegend/core/language/__init__.py +10 -10
  6. pylegend/core/language/legacy_api/__init__.py +13 -0
  7. pylegend/core/language/{aggregate_specification.py → legacy_api/aggregate_specification.py} +10 -10
  8. pylegend/core/language/legacy_api/legacy_api_tds_row.py +32 -0
  9. pylegend/core/language/legendql_api/__init__.py +13 -0
  10. pylegend/core/language/legendql_api/legendql_api_custom_expressions.py +541 -0
  11. pylegend/core/language/legendql_api/legendql_api_tds_row.py +292 -0
  12. pylegend/core/language/shared/__init__.py +13 -0
  13. pylegend/core/language/{column_expressions.py → shared/column_expressions.py} +32 -31
  14. pylegend/core/language/{expression.py → shared/expression.py} +8 -0
  15. pylegend/core/language/{functions.py → shared/functions.py} +3 -3
  16. pylegend/core/language/shared/helpers.py +75 -0
  17. pylegend/core/language/{literal_expressions.py → shared/literal_expressions.py} +39 -1
  18. pylegend/core/language/{operations → shared/operations}/binary_expression.py +34 -2
  19. pylegend/core/language/{operations → shared/operations}/boolean_operation_expressions.py +34 -6
  20. pylegend/core/language/{operations → shared/operations}/collection_operation_expressions.py +146 -26
  21. pylegend/core/language/{operations → shared/operations}/date_operation_expressions.py +164 -24
  22. pylegend/core/language/{operations → shared/operations}/float_operation_expressions.py +53 -8
  23. pylegend/core/language/{operations → shared/operations}/integer_operation_expressions.py +62 -9
  24. pylegend/core/language/{operations → shared/operations}/nullary_expression.py +9 -2
  25. pylegend/core/language/{operations → shared/operations}/number_operation_expressions.py +211 -30
  26. pylegend/core/language/{operations → shared/operations}/primitive_operation_expressions.py +42 -3
  27. pylegend/core/language/{operations → shared/operations}/string_operation_expressions.py +169 -21
  28. pylegend/core/language/{operations → shared/operations}/unary_expression.py +10 -2
  29. pylegend/core/language/{primitive_collection.py → shared/primitive_collection.py} +2 -2
  30. pylegend/core/language/{primitives → shared/primitives}/__init__.py +9 -9
  31. pylegend/core/language/{primitives → shared/primitives}/boolean.py +9 -5
  32. pylegend/core/language/{primitives → shared/primitives}/date.py +23 -15
  33. pylegend/core/language/{primitives → shared/primitives}/datetime.py +4 -5
  34. pylegend/core/language/{primitives → shared/primitives}/float.py +6 -6
  35. pylegend/core/language/{primitives → shared/primitives}/integer.py +6 -6
  36. pylegend/core/language/{primitives → shared/primitives}/number.py +16 -13
  37. pylegend/core/language/{primitives → shared/primitives}/primitive.py +25 -5
  38. pylegend/core/language/{primitives → shared/primitives}/strictdate.py +4 -5
  39. pylegend/core/language/{primitives → shared/primitives}/string.py +18 -19
  40. pylegend/core/language/{tds_row.py → shared/tds_row.py} +46 -16
  41. pylegend/core/request/__init__.py +8 -1
  42. pylegend/core/request/auth.py +89 -11
  43. pylegend/core/request/legend_client.py +32 -0
  44. pylegend/core/sql/metamodel_extension.py +16 -0
  45. pylegend/core/tds/abstract/__init__.py +13 -0
  46. pylegend/core/tds/abstract/frames/__init__.py +13 -0
  47. pylegend/core/tds/{legend_api/frames/legend_api_applied_function_tds_frame.py → abstract/frames/applied_function_tds_frame.py} +19 -13
  48. pylegend/core/tds/abstract/frames/base_tds_frame.py +125 -0
  49. pylegend/core/tds/{legend_api/frames/legend_api_input_tds_frame.py → abstract/frames/input_tds_frame.py} +9 -12
  50. pylegend/core/tds/{legend_api/frames/functions → abstract}/function_helpers.py +1 -1
  51. pylegend/core/tds/{legend_api/frames/functions/concatenate_function.py → legacy_api/frames/functions/legacy_api_concatenate_function.py} +25 -13
  52. pylegend/core/tds/{legend_api/frames/functions/distinct_function.py → legacy_api/frames/functions/legacy_api_distinct_function.py} +13 -8
  53. pylegend/core/tds/{legend_api/frames/functions/drop_function.py → legacy_api/frames/functions/legacy_api_drop_function.py} +13 -8
  54. pylegend/core/tds/{legend_api/frames/functions/extend_function.py → legacy_api/frames/functions/legacy_api_extend_function.py} +36 -16
  55. pylegend/core/tds/{legend_api/frames/functions/filter_function.py → legacy_api/frames/functions/legacy_api_filter_function.py} +25 -13
  56. pylegend/core/tds/{legend_api/frames/functions/group_by_function.py → legacy_api/frames/functions/legacy_api_group_by_function.py} +44 -17
  57. pylegend/core/tds/{legend_api/frames/functions/head_function.py → legacy_api/frames/functions/legacy_api_head_function.py} +13 -8
  58. pylegend/core/tds/{legend_api/frames/functions/join_by_columns_function.py → legacy_api/frames/functions/legacy_api_join_by_columns_function.py} +40 -13
  59. pylegend/core/tds/{legend_api/frames/functions/join_function.py → legacy_api/frames/functions/legacy_api_join_function.py} +44 -20
  60. pylegend/core/tds/{legend_api/frames/functions/rename_columns_function.py → legacy_api/frames/functions/legacy_api_rename_columns_function.py} +20 -8
  61. pylegend/core/tds/{legend_api/frames/functions/restrict_function.py → legacy_api/frames/functions/legacy_api_restrict_function.py} +17 -8
  62. pylegend/core/tds/{legend_api/frames/functions/slice_function.py → legacy_api/frames/functions/legacy_api_slice_function.py} +13 -8
  63. pylegend/core/tds/{legend_api/frames/functions/sort_function.py → legacy_api/frames/functions/legacy_api_sort_function.py} +19 -8
  64. pylegend/core/tds/legacy_api/frames/legacy_api_applied_function_tds_frame.py +37 -0
  65. pylegend/core/tds/legacy_api/frames/legacy_api_base_tds_frame.py +204 -0
  66. pylegend/core/tds/legacy_api/frames/legacy_api_input_tds_frame.py +51 -0
  67. pylegend/core/tds/{legend_api/frames/legend_api_tds_frame.py → legacy_api/frames/legacy_api_tds_frame.py} +28 -28
  68. pylegend/core/tds/legendql_api/__init__.py +13 -0
  69. pylegend/core/tds/legendql_api/frames/__init__.py +13 -0
  70. pylegend/core/tds/legendql_api/frames/functions/__init__.py +13 -0
  71. pylegend/core/tds/legendql_api/frames/functions/legendql_api_asofjoin_function.py +156 -0
  72. pylegend/core/tds/legendql_api/frames/functions/legendql_api_concatenate_function.py +139 -0
  73. pylegend/core/tds/legendql_api/frames/functions/legendql_api_distinct_function.py +69 -0
  74. pylegend/core/tds/legendql_api/frames/functions/legendql_api_drop_function.py +74 -0
  75. pylegend/core/tds/legendql_api/frames/functions/legendql_api_extend_function.py +256 -0
  76. pylegend/core/tds/legendql_api/frames/functions/legendql_api_filter_function.py +121 -0
  77. pylegend/core/tds/legendql_api/frames/functions/legendql_api_function_helpers.py +137 -0
  78. pylegend/core/tds/legendql_api/frames/functions/legendql_api_groupby_function.py +256 -0
  79. pylegend/core/tds/legendql_api/frames/functions/legendql_api_head_function.py +74 -0
  80. pylegend/core/tds/legendql_api/frames/functions/legendql_api_join_function.py +214 -0
  81. pylegend/core/tds/legendql_api/frames/functions/legendql_api_project_function.py +169 -0
  82. pylegend/core/tds/legendql_api/frames/functions/legendql_api_rename_function.py +189 -0
  83. pylegend/core/tds/legendql_api/frames/functions/legendql_api_select_function.py +131 -0
  84. pylegend/core/tds/legendql_api/frames/functions/legendql_api_slice_function.py +82 -0
  85. pylegend/core/tds/legendql_api/frames/functions/legendql_api_sort_function.py +93 -0
  86. pylegend/core/tds/legendql_api/frames/functions/legendql_api_window_extend_function.py +283 -0
  87. pylegend/core/tds/legendql_api/frames/legendql_api_applied_function_tds_frame.py +37 -0
  88. pylegend/core/tds/legendql_api/frames/legendql_api_base_tds_frame.py +419 -0
  89. pylegend/core/tds/legendql_api/frames/legendql_api_input_tds_frame.py +50 -0
  90. pylegend/core/tds/legendql_api/frames/legendql_api_tds_frame.py +327 -0
  91. pylegend/core/tds/pandas_api/frames/functions/assign_function.py +6 -6
  92. pylegend/core/tds/pandas_api/frames/pandas_api_applied_function_tds_frame.py +4 -0
  93. pylegend/core/tds/pandas_api/frames/pandas_api_base_tds_frame.py +11 -3
  94. pylegend/core/tds/pandas_api/frames/pandas_api_tds_frame.py +2 -2
  95. pylegend/core/tds/tds_frame.py +32 -2
  96. pylegend/extensions/database/vendors/postgres/postgres_sql_to_string.py +1 -1
  97. pylegend/extensions/tds/abstract/legend_function_input_frame.py +4 -0
  98. pylegend/extensions/tds/abstract/legend_service_input_frame.py +4 -0
  99. pylegend/extensions/tds/abstract/table_spec_input_frame.py +4 -0
  100. pylegend/extensions/tds/{legend_api/frames/legend_api_legend_function_input_frame.py → legacy_api/frames/legacy_api_legend_function_input_frame.py} +5 -5
  101. pylegend/extensions/tds/{legend_api/frames/legend_api_legend_service_input_frame.py → legacy_api/frames/legacy_api_legend_service_input_frame.py} +6 -6
  102. pylegend/extensions/tds/{legend_api/frames/legend_api_table_spec_input_frame.py → legacy_api/frames/legacy_api_table_spec_input_frame.py} +5 -5
  103. pylegend/extensions/tds/legendql_api/__init__.py +13 -0
  104. pylegend/extensions/tds/legendql_api/frames/__init__.py +13 -0
  105. pylegend/extensions/tds/legendql_api/frames/legendql_api_legend_service_input_frame.py +46 -0
  106. pylegend/extensions/tds/legendql_api/frames/legendql_api_table_spec_input_frame.py +36 -0
  107. pylegend/{legend_api_tds_client.py → legacy_api_tds_client.py} +15 -15
  108. {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/METADATA +7 -8
  109. pylegend-0.4.0.dist-info/NOTICE +5 -0
  110. pylegend-0.4.0.dist-info/RECORD +155 -0
  111. {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/WHEEL +1 -1
  112. pylegend/core/tds/legend_api/frames/legend_api_base_tds_frame.py +0 -294
  113. pylegend-0.2.2.dist-info/RECORD +0 -115
  114. /pylegend/core/{databse → database}/__init__.py +0 -0
  115. /pylegend/core/{databse → database}/sql_to_string/config.py +0 -0
  116. /pylegend/core/language/{operations → shared/operations}/__init__.py +0 -0
  117. /pylegend/core/tds/{legend_api → legacy_api}/__init__.py +0 -0
  118. /pylegend/core/tds/{legend_api → legacy_api}/frames/__init__.py +0 -0
  119. /pylegend/core/tds/{legend_api → legacy_api}/frames/functions/__init__.py +0 -0
  120. /pylegend/extensions/tds/{legend_api → legacy_api}/__init__.py +0 -0
  121. /pylegend/extensions/tds/{legend_api → legacy_api}/frames/__init__.py +0 -0
  122. {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/LICENSE +0 -0
  123. {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/LICENSE.spdx +0 -0
@@ -16,14 +16,15 @@ from pylegend._typing import (
16
16
  PyLegendSequence,
17
17
  PyLegendDict,
18
18
  )
19
- from pylegend.core.language.expression import (
19
+ from pylegend.core.language.shared.expression import (
20
20
  PyLegendExpressionStringReturn,
21
21
  PyLegendExpressionIntegerReturn,
22
22
  PyLegendExpressionFloatReturn,
23
23
  PyLegendExpressionBooleanReturn,
24
24
  )
25
- from pylegend.core.language.operations.binary_expression import PyLegendBinaryExpression
26
- from pylegend.core.language.operations.unary_expression import PyLegendUnaryExpression
25
+ from pylegend.core.language.shared.operations.binary_expression import PyLegendBinaryExpression
26
+ from pylegend.core.language.shared.operations.unary_expression import PyLegendUnaryExpression
27
+ from pylegend.core.language.shared.helpers import generate_pure_functional_call
27
28
  from pylegend.core.sql.metamodel import (
28
29
  Expression,
29
30
  QuerySpecification,
@@ -31,6 +32,7 @@ from pylegend.core.sql.metamodel import (
31
32
  Cast,
32
33
  ComparisonOperator,
33
34
  ComparisonExpression,
35
+ StringLiteral,
34
36
  )
35
37
  from pylegend.core.sql.metamodel_extension import (
36
38
  StringLengthExpression,
@@ -43,11 +45,14 @@ from pylegend.core.sql.metamodel_extension import (
43
45
  StringConcatExpression,
44
46
  )
45
47
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
48
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
46
49
 
47
50
 
48
51
  __all__: PyLegendSequence[str] = [
49
52
  "PyLegendStringLengthExpression",
50
- "PyLegendStringLikeExpression",
53
+ "PyLegendStringStartsWithExpression",
54
+ "PyLegendStringEndsWithExpression",
55
+ "PyLegendStringContainsExpression",
51
56
  "PyLegendStringUpperExpression",
52
57
  "PyLegendStringLowerExpression",
53
58
  "PyLegendStringLTrimExpression",
@@ -74,16 +79,77 @@ class PyLegendStringLengthExpression(PyLegendUnaryExpression, PyLegendExpression
74
79
  ) -> Expression:
75
80
  return StringLengthExpression(expression)
76
81
 
82
+ @staticmethod
83
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
84
+ return generate_pure_functional_call("length", [op_expr], auto_map=True)
85
+
77
86
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
78
87
  PyLegendExpressionIntegerReturn.__init__(self)
79
88
  PyLegendUnaryExpression.__init__(
80
89
  self,
81
90
  operand,
82
- PyLegendStringLengthExpression.__to_sql_func
91
+ PyLegendStringLengthExpression.__to_sql_func,
92
+ PyLegendStringLengthExpression.__to_pure_func
93
+ )
94
+
95
+
96
+ class PyLegendStringStartsWithExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
97
+
98
+ @staticmethod
99
+ def __to_sql_func(
100
+ expression1: Expression,
101
+ expression2: Expression,
102
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
103
+ config: FrameToSqlConfig
104
+ ) -> Expression:
105
+ assert isinstance(expression2, StringLiteral)
106
+ escaped = _escape_like_param(expression2.value)
107
+ return StringLikeExpression(expression1, StringLiteral(value=escaped + "%", quoted=False))
108
+
109
+ @staticmethod
110
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
111
+ return generate_pure_functional_call("startsWith", [op1_expr, op2_expr])
112
+
113
+ def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
114
+ PyLegendExpressionBooleanReturn.__init__(self)
115
+ PyLegendBinaryExpression.__init__(
116
+ self,
117
+ operand1,
118
+ operand2,
119
+ PyLegendStringStartsWithExpression.__to_sql_func,
120
+ PyLegendStringStartsWithExpression.__to_pure_func
121
+ )
122
+
123
+
124
+ class PyLegendStringEndsWithExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
125
+
126
+ @staticmethod
127
+ def __to_sql_func(
128
+ expression1: Expression,
129
+ expression2: Expression,
130
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
131
+ config: FrameToSqlConfig
132
+ ) -> Expression:
133
+ assert isinstance(expression2, StringLiteral)
134
+ escaped = _escape_like_param(expression2.value)
135
+ return StringLikeExpression(expression1, StringLiteral(value="%" + escaped, quoted=False))
136
+
137
+ @staticmethod
138
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
139
+ return generate_pure_functional_call("endsWith", [op1_expr, op2_expr])
140
+
141
+ def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
142
+ PyLegendExpressionBooleanReturn.__init__(self)
143
+ PyLegendBinaryExpression.__init__(
144
+ self,
145
+ operand1,
146
+ operand2,
147
+ PyLegendStringEndsWithExpression.__to_sql_func,
148
+ PyLegendStringEndsWithExpression.__to_pure_func
83
149
  )
84
150
 
85
151
 
86
- class PyLegendStringLikeExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
152
+ class PyLegendStringContainsExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
87
153
 
88
154
  @staticmethod
89
155
  def __to_sql_func(
@@ -92,7 +158,13 @@ class PyLegendStringLikeExpression(PyLegendBinaryExpression, PyLegendExpressionB
92
158
  frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
93
159
  config: FrameToSqlConfig
94
160
  ) -> Expression:
95
- return StringLikeExpression(expression1, expression2)
161
+ assert isinstance(expression2, StringLiteral)
162
+ escaped = _escape_like_param(expression2.value)
163
+ return StringLikeExpression(expression1, StringLiteral(value="%" + escaped + "%", quoted=False))
164
+
165
+ @staticmethod
166
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
167
+ return generate_pure_functional_call("contains", [op1_expr, op2_expr])
96
168
 
97
169
  def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
98
170
  PyLegendExpressionBooleanReturn.__init__(self)
@@ -100,7 +172,8 @@ class PyLegendStringLikeExpression(PyLegendBinaryExpression, PyLegendExpressionB
100
172
  self,
101
173
  operand1,
102
174
  operand2,
103
- PyLegendStringLikeExpression.__to_sql_func
175
+ PyLegendStringContainsExpression.__to_sql_func,
176
+ PyLegendStringContainsExpression.__to_pure_func
104
177
  )
105
178
 
106
179
 
@@ -114,12 +187,17 @@ class PyLegendStringUpperExpression(PyLegendUnaryExpression, PyLegendExpressionS
114
187
  ) -> Expression:
115
188
  return StringUpperExpression(expression)
116
189
 
190
+ @staticmethod
191
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
192
+ return generate_pure_functional_call("toUpper", [op_expr], auto_map=True)
193
+
117
194
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
118
195
  PyLegendExpressionStringReturn.__init__(self)
119
196
  PyLegendUnaryExpression.__init__(
120
197
  self,
121
198
  operand,
122
- PyLegendStringUpperExpression.__to_sql_func
199
+ PyLegendStringUpperExpression.__to_sql_func,
200
+ PyLegendStringUpperExpression.__to_pure_func
123
201
  )
124
202
 
125
203
 
@@ -133,12 +211,17 @@ class PyLegendStringLowerExpression(PyLegendUnaryExpression, PyLegendExpressionS
133
211
  ) -> Expression:
134
212
  return StringLowerExpression(expression)
135
213
 
214
+ @staticmethod
215
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
216
+ return generate_pure_functional_call("toLower", [op_expr], auto_map=True)
217
+
136
218
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
137
219
  PyLegendExpressionStringReturn.__init__(self)
138
220
  PyLegendUnaryExpression.__init__(
139
221
  self,
140
222
  operand,
141
- PyLegendStringLowerExpression.__to_sql_func
223
+ PyLegendStringLowerExpression.__to_sql_func,
224
+ PyLegendStringLowerExpression.__to_pure_func
142
225
  )
143
226
 
144
227
 
@@ -152,12 +235,17 @@ class PyLegendStringLTrimExpression(PyLegendUnaryExpression, PyLegendExpressionS
152
235
  ) -> Expression:
153
236
  return StringTrimExpression(expression, trim_type=TrimType.Left)
154
237
 
238
+ @staticmethod
239
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
240
+ return generate_pure_functional_call("ltrim", [op_expr], auto_map=True)
241
+
155
242
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
156
243
  PyLegendExpressionStringReturn.__init__(self)
157
244
  PyLegendUnaryExpression.__init__(
158
245
  self,
159
246
  operand,
160
- PyLegendStringLTrimExpression.__to_sql_func
247
+ PyLegendStringLTrimExpression.__to_sql_func,
248
+ PyLegendStringLTrimExpression.__to_pure_func
161
249
  )
162
250
 
163
251
 
@@ -171,12 +259,17 @@ class PyLegendStringRTrimExpression(PyLegendUnaryExpression, PyLegendExpressionS
171
259
  ) -> Expression:
172
260
  return StringTrimExpression(expression, trim_type=TrimType.Right)
173
261
 
262
+ @staticmethod
263
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
264
+ return generate_pure_functional_call("rtrim", [op_expr], auto_map=True)
265
+
174
266
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
175
267
  PyLegendExpressionStringReturn.__init__(self)
176
268
  PyLegendUnaryExpression.__init__(
177
269
  self,
178
270
  operand,
179
- PyLegendStringRTrimExpression.__to_sql_func
271
+ PyLegendStringRTrimExpression.__to_sql_func,
272
+ PyLegendStringRTrimExpression.__to_pure_func
180
273
  )
181
274
 
182
275
 
@@ -190,12 +283,17 @@ class PyLegendStringBTrimExpression(PyLegendUnaryExpression, PyLegendExpressionS
190
283
  ) -> Expression:
191
284
  return StringTrimExpression(expression, trim_type=TrimType.Both)
192
285
 
286
+ @staticmethod
287
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
288
+ return generate_pure_functional_call("trim", [op_expr], auto_map=True)
289
+
193
290
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
194
291
  PyLegendExpressionStringReturn.__init__(self)
195
292
  PyLegendUnaryExpression.__init__(
196
293
  self,
197
294
  operand,
198
- PyLegendStringBTrimExpression.__to_sql_func
295
+ PyLegendStringBTrimExpression.__to_sql_func,
296
+ PyLegendStringBTrimExpression.__to_pure_func
199
297
  )
200
298
 
201
299
 
@@ -210,15 +308,23 @@ class PyLegendStringPosExpression(PyLegendBinaryExpression, PyLegendExpressionIn
210
308
  ) -> Expression:
211
309
  return StringPosExpression(expression1, expression2)
212
310
 
311
+ @staticmethod
312
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
313
+ return generate_pure_functional_call("indexOf", [op1_expr, op2_expr], auto_map=True)
314
+
213
315
  def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
214
316
  PyLegendExpressionIntegerReturn.__init__(self)
215
317
  PyLegendBinaryExpression.__init__(
216
318
  self,
217
319
  operand1,
218
320
  operand2,
219
- PyLegendStringPosExpression.__to_sql_func
321
+ PyLegendStringPosExpression.__to_sql_func,
322
+ PyLegendStringPosExpression.__to_pure_func
220
323
  )
221
324
 
325
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
326
+ return PyLegendBinaryExpression.to_pure_expression_with_to_one_on_second_operand(self, config)
327
+
222
328
 
223
329
  class PyLegendStringParseIntExpression(PyLegendUnaryExpression, PyLegendExpressionIntegerReturn):
224
330
 
@@ -230,12 +336,17 @@ class PyLegendStringParseIntExpression(PyLegendUnaryExpression, PyLegendExpressi
230
336
  ) -> Expression:
231
337
  return Cast(expression, ColumnType(name="INTEGER", parameters=[]))
232
338
 
339
+ @staticmethod
340
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
341
+ return generate_pure_functional_call("parseInteger", [op_expr], auto_map=True)
342
+
233
343
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
234
344
  PyLegendExpressionIntegerReturn.__init__(self)
235
345
  PyLegendUnaryExpression.__init__(
236
346
  self,
237
347
  operand,
238
- PyLegendStringParseIntExpression.__to_sql_func
348
+ PyLegendStringParseIntExpression.__to_sql_func,
349
+ PyLegendStringParseIntExpression.__to_pure_func
239
350
  )
240
351
 
241
352
 
@@ -249,12 +360,17 @@ class PyLegendStringParseFloatExpression(PyLegendUnaryExpression, PyLegendExpres
249
360
  ) -> Expression:
250
361
  return Cast(expression, ColumnType(name="DOUBLE PRECISION", parameters=[]))
251
362
 
363
+ @staticmethod
364
+ def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
365
+ return generate_pure_functional_call("parseFloat", [op_expr], auto_map=True)
366
+
252
367
  def __init__(self, operand: PyLegendExpressionStringReturn) -> None:
253
368
  PyLegendExpressionFloatReturn.__init__(self)
254
369
  PyLegendUnaryExpression.__init__(
255
370
  self,
256
371
  operand,
257
- PyLegendStringParseFloatExpression.__to_sql_func
372
+ PyLegendStringParseFloatExpression.__to_sql_func,
373
+ PyLegendStringParseFloatExpression.__to_pure_func
258
374
  )
259
375
 
260
376
 
@@ -269,15 +385,23 @@ class PyLegendStringConcatExpression(PyLegendBinaryExpression, PyLegendExpressio
269
385
  ) -> Expression:
270
386
  return StringConcatExpression(expression1, expression2)
271
387
 
388
+ @staticmethod
389
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
390
+ return f"({op1_expr} + {op2_expr})"
391
+
272
392
  def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
273
393
  PyLegendExpressionStringReturn.__init__(self)
274
394
  PyLegendBinaryExpression.__init__(
275
395
  self,
276
396
  operand1,
277
397
  operand2,
278
- PyLegendStringConcatExpression.__to_sql_func
398
+ PyLegendStringConcatExpression.__to_sql_func,
399
+ PyLegendStringConcatExpression.__to_pure_func
279
400
  )
280
401
 
402
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
403
+ return PyLegendBinaryExpression.to_pure_expression_with_to_one_on_both_operands(self, config)
404
+
281
405
 
282
406
  class PyLegendStringLessThanExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
283
407
 
@@ -290,13 +414,18 @@ class PyLegendStringLessThanExpression(PyLegendBinaryExpression, PyLegendExpress
290
414
  ) -> Expression:
291
415
  return ComparisonExpression(expression1, expression2, ComparisonOperator.LESS_THAN)
292
416
 
417
+ @staticmethod
418
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
419
+ return f"({op1_expr} < {op2_expr})"
420
+
293
421
  def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
294
422
  PyLegendExpressionBooleanReturn.__init__(self)
295
423
  PyLegendBinaryExpression.__init__(
296
424
  self,
297
425
  operand1,
298
426
  operand2,
299
- PyLegendStringLessThanExpression.__to_sql_func
427
+ PyLegendStringLessThanExpression.__to_sql_func,
428
+ PyLegendStringLessThanExpression.__to_pure_func
300
429
  )
301
430
 
302
431
 
@@ -311,13 +440,18 @@ class PyLegendStringLessThanEqualExpression(PyLegendBinaryExpression, PyLegendEx
311
440
  ) -> Expression:
312
441
  return ComparisonExpression(expression1, expression2, ComparisonOperator.LESS_THAN_OR_EQUAL)
313
442
 
443
+ @staticmethod
444
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
445
+ return f"({op1_expr} <= {op2_expr})"
446
+
314
447
  def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
315
448
  PyLegendExpressionBooleanReturn.__init__(self)
316
449
  PyLegendBinaryExpression.__init__(
317
450
  self,
318
451
  operand1,
319
452
  operand2,
320
- PyLegendStringLessThanEqualExpression.__to_sql_func
453
+ PyLegendStringLessThanEqualExpression.__to_sql_func,
454
+ PyLegendStringLessThanEqualExpression.__to_pure_func
321
455
  )
322
456
 
323
457
 
@@ -332,13 +466,18 @@ class PyLegendStringGreaterThanExpression(PyLegendBinaryExpression, PyLegendExpr
332
466
  ) -> Expression:
333
467
  return ComparisonExpression(expression1, expression2, ComparisonOperator.GREATER_THAN)
334
468
 
469
+ @staticmethod
470
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
471
+ return f"({op1_expr} > {op2_expr})"
472
+
335
473
  def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
336
474
  PyLegendExpressionBooleanReturn.__init__(self)
337
475
  PyLegendBinaryExpression.__init__(
338
476
  self,
339
477
  operand1,
340
478
  operand2,
341
- PyLegendStringGreaterThanExpression.__to_sql_func
479
+ PyLegendStringGreaterThanExpression.__to_sql_func,
480
+ PyLegendStringGreaterThanExpression.__to_pure_func
342
481
  )
343
482
 
344
483
 
@@ -353,11 +492,20 @@ class PyLegendStringGreaterThanEqualExpression(PyLegendBinaryExpression, PyLegen
353
492
  ) -> Expression:
354
493
  return ComparisonExpression(expression1, expression2, ComparisonOperator.GREATER_THAN_OR_EQUAL)
355
494
 
495
+ @staticmethod
496
+ def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
497
+ return f"({op1_expr} >= {op2_expr})"
498
+
356
499
  def __init__(self, operand1: PyLegendExpressionStringReturn, operand2: PyLegendExpressionStringReturn) -> None:
357
500
  PyLegendExpressionBooleanReturn.__init__(self)
358
501
  PyLegendBinaryExpression.__init__(
359
502
  self,
360
503
  operand1,
361
504
  operand2,
362
- PyLegendStringGreaterThanEqualExpression.__to_sql_func
505
+ PyLegendStringGreaterThanEqualExpression.__to_sql_func,
506
+ PyLegendStringGreaterThanEqualExpression.__to_pure_func
363
507
  )
508
+
509
+
510
+ def _escape_like_param(param: str) -> str:
511
+ return param.replace("_", "\\_").replace("%", "\\%")
@@ -18,7 +18,7 @@ from pylegend._typing import (
18
18
  PyLegendDict,
19
19
  PyLegendCallable,
20
20
  )
21
- from pylegend.core.language.expression import (
21
+ from pylegend.core.language.shared.expression import (
22
22
  PyLegendExpression,
23
23
  )
24
24
  from pylegend.core.sql.metamodel import (
@@ -26,6 +26,7 @@ from pylegend.core.sql.metamodel import (
26
26
  QuerySpecification,
27
27
  )
28
28
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
29
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
29
30
 
30
31
 
31
32
  __all__: PyLegendSequence[str] = [
@@ -39,6 +40,7 @@ class PyLegendUnaryExpression(PyLegendExpression, metaclass=ABCMeta):
39
40
  [Expression, PyLegendDict[str, QuerySpecification], FrameToSqlConfig],
40
41
  Expression
41
42
  ]
43
+ __to_pure_func: PyLegendCallable[[str, FrameToPureConfig], str]
42
44
 
43
45
  def __init__(
44
46
  self,
@@ -46,10 +48,12 @@ class PyLegendUnaryExpression(PyLegendExpression, metaclass=ABCMeta):
46
48
  to_sql_func: PyLegendCallable[
47
49
  [Expression, PyLegendDict[str, QuerySpecification], FrameToSqlConfig],
48
50
  Expression
49
- ]
51
+ ],
52
+ to_pure_func: PyLegendCallable[[str, FrameToPureConfig], str]
50
53
  ) -> None:
51
54
  self.__operand = operand
52
55
  self.__to_sql_func = to_sql_func
56
+ self.__to_pure_func = to_pure_func
53
57
 
54
58
  def to_sql_expression(
55
59
  self,
@@ -62,3 +66,7 @@ class PyLegendUnaryExpression(PyLegendExpression, metaclass=ABCMeta):
62
66
  frame_name_to_base_query_map,
63
67
  config
64
68
  )
69
+
70
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
71
+ op_expr = self.__operand.to_pure_expression(config)
72
+ return self.__to_pure_func(op_expr, config)
@@ -18,7 +18,7 @@ from pylegend._typing import (
18
18
  PyLegendSequence,
19
19
  PyLegendUnion,
20
20
  )
21
- from pylegend.core.language.primitives.primitive import PyLegendPrimitiveOrPythonPrimitive
21
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitiveOrPythonPrimitive
22
22
  from pylegend.core.language import (
23
23
  PyLegendInteger,
24
24
  PyLegendFloat,
@@ -30,7 +30,7 @@ from pylegend.core.language import (
30
30
  PyLegendStrictDate,
31
31
  convert_literal_to_literal_expression,
32
32
  )
33
- from pylegend.core.language.operations.collection_operation_expressions import (
33
+ from pylegend.core.language.shared.operations.collection_operation_expressions import (
34
34
  PyLegendCountExpression,
35
35
  PyLegendDistinctCountExpression,
36
36
  PyLegendAverageExpression,
@@ -16,15 +16,15 @@
16
16
  from pylegend._typing import (
17
17
  PyLegendSequence,
18
18
  )
19
- from pylegend.core.language.primitives.primitive import PyLegendPrimitive, PyLegendPrimitiveOrPythonPrimitive
20
- from pylegend.core.language.primitives.boolean import PyLegendBoolean
21
- from pylegend.core.language.primitives.string import PyLegendString
22
- from pylegend.core.language.primitives.number import PyLegendNumber
23
- from pylegend.core.language.primitives.integer import PyLegendInteger
24
- from pylegend.core.language.primitives.float import PyLegendFloat
25
- from pylegend.core.language.primitives.date import PyLegendDate
26
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
27
- from pylegend.core.language.primitives.strictdate import PyLegendStrictDate
19
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitive, PyLegendPrimitiveOrPythonPrimitive
20
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
21
+ from pylegend.core.language.shared.primitives.string import PyLegendString
22
+ from pylegend.core.language.shared.primitives.number import PyLegendNumber
23
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
24
+ from pylegend.core.language.shared.primitives.float import PyLegendFloat
25
+ from pylegend.core.language.shared.primitives.date import PyLegendDate
26
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
27
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
28
28
 
29
29
 
30
30
  __all__: PyLegendSequence[str] = [
@@ -17,10 +17,10 @@ from pylegend._typing import (
17
17
  PyLegendDict,
18
18
  PyLegendUnion,
19
19
  )
20
- from pylegend.core.language.primitives.primitive import PyLegendPrimitive
21
- from pylegend.core.language.expression import PyLegendExpressionBooleanReturn, PyLegendExpression
22
- from pylegend.core.language.literal_expressions import PyLegendBooleanLiteralExpression
23
- from pylegend.core.language.operations.boolean_operation_expressions import (
20
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitive
21
+ from pylegend.core.language.shared.expression import PyLegendExpressionBooleanReturn
22
+ from pylegend.core.language.shared.literal_expressions import PyLegendBooleanLiteralExpression
23
+ from pylegend.core.language.shared.operations.boolean_operation_expressions import (
24
24
  PyLegendBooleanOrExpression,
25
25
  PyLegendBooleanAndExpression,
26
26
  PyLegendBooleanNotExpression,
@@ -30,6 +30,7 @@ from pylegend.core.sql.metamodel import (
30
30
  QuerySpecification
31
31
  )
32
32
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
33
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
33
34
 
34
35
 
35
36
  __all__: PyLegendSequence[str] = [
@@ -53,7 +54,10 @@ class PyLegendBoolean(PyLegendPrimitive):
53
54
  ) -> Expression:
54
55
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
55
56
 
56
- def value(self) -> PyLegendExpression:
57
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
58
+ return self.__value.to_pure_expression(config)
59
+
60
+ def value(self) -> PyLegendExpressionBooleanReturn:
57
61
  return self.__value
58
62
 
59
63
  def __or__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
@@ -19,17 +19,16 @@ from pylegend._typing import (
19
19
  PyLegendUnion,
20
20
  TYPE_CHECKING,
21
21
  )
22
- from pylegend.core.language.primitives.primitive import PyLegendPrimitive
23
- from pylegend.core.language.primitives.integer import PyLegendInteger
24
- from pylegend.core.language.expression import (
25
- PyLegendExpression,
22
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitive
23
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
24
+ from pylegend.core.language.shared.expression import (
26
25
  PyLegendExpressionDateReturn,
27
26
  )
28
- from pylegend.core.language.literal_expressions import (
27
+ from pylegend.core.language.shared.literal_expressions import (
29
28
  PyLegendDateTimeLiteralExpression,
30
29
  PyLegendStrictDateLiteralExpression,
31
30
  )
32
- from pylegend.core.language.operations.date_operation_expressions import (
31
+ from pylegend.core.language.shared.operations.date_operation_expressions import (
33
32
  PyLegendFirstDayOfYearExpression,
34
33
  PyLegendFirstDayOfQuarterExpression,
35
34
  PyLegendFirstDayOfMonthExpression,
@@ -49,15 +48,17 @@ from pylegend.core.language.operations.date_operation_expressions import (
49
48
  PyLegendMinuteExpression,
50
49
  PyLegendSecondExpression,
51
50
  PyLegendEpochExpression,
51
+ PyLegendDatePartExpression,
52
52
  )
53
53
  from pylegend.core.sql.metamodel import (
54
54
  Expression,
55
55
  QuerySpecification
56
56
  )
57
57
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
58
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
58
59
  if TYPE_CHECKING:
59
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
60
- from pylegend.core.language.primitives.strictdate import PyLegendStrictDate
60
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
61
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
61
62
 
62
63
 
63
64
  __all__: PyLegendSequence[str] = [
@@ -81,7 +82,10 @@ class PyLegendDate(PyLegendPrimitive):
81
82
  ) -> Expression:
82
83
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
83
84
 
84
- def value(self) -> PyLegendExpression:
85
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
86
+ return self.__value.to_pure_expression(config)
87
+
88
+ def value(self) -> PyLegendExpressionDateReturn:
85
89
  return self.__value
86
90
 
87
91
  def first_day_of_year(self) -> "PyLegendDate":
@@ -97,19 +101,19 @@ class PyLegendDate(PyLegendPrimitive):
97
101
  return PyLegendDate(PyLegendFirstDayOfWeekExpression(self.__value))
98
102
 
99
103
  def first_hour_of_day(self) -> "PyLegendDateTime":
100
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
104
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
101
105
  return PyLegendDateTime(PyLegendFirstHourOfDayExpression(self.__value))
102
106
 
103
107
  def first_minute_of_hour(self) -> "PyLegendDateTime":
104
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
108
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
105
109
  return PyLegendDateTime(PyLegendFirstMinuteOfHourExpression(self.__value))
106
110
 
107
111
  def first_second_of_minute(self) -> "PyLegendDateTime":
108
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
112
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
109
113
  return PyLegendDateTime(PyLegendFirstSecondOfMinuteExpression(self.__value))
110
114
 
111
115
  def first_millisecond_of_second(self) -> "PyLegendDateTime":
112
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
116
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
113
117
  return PyLegendDateTime(PyLegendFirstMillisecondOfSecondExpression(self.__value))
114
118
 
115
119
  def year(self) -> "PyLegendInteger":
@@ -145,6 +149,10 @@ class PyLegendDate(PyLegendPrimitive):
145
149
  def day_of_week(self) -> "PyLegendInteger":
146
150
  return PyLegendInteger(PyLegendDayOfWeekExpression(self.__value))
147
151
 
152
+ def date_part(self) -> "PyLegendStrictDate":
153
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
154
+ return PyLegendStrictDate(PyLegendDatePartExpression(self.__value))
155
+
148
156
  @staticmethod
149
157
  def __convert_to_date_expr(
150
158
  val: PyLegendUnion[date, datetime, "PyLegendDateTime", "PyLegendStrictDate", "PyLegendDate"]
@@ -160,8 +168,8 @@ class PyLegendDate(PyLegendPrimitive):
160
168
  param: PyLegendUnion[date, datetime, "PyLegendDateTime", "PyLegendStrictDate", "PyLegendDate"],
161
169
  desc: str
162
170
  ) -> None:
163
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
164
- from pylegend.core.language.primitives.strictdate import PyLegendStrictDate
171
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
172
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
165
173
  if not isinstance(param, (date, datetime, PyLegendDateTime, PyLegendStrictDate, PyLegendDate)):
166
174
  raise TypeError(desc + " should be a datetime.date/datetime.datetime or a Date expression"
167
175
  " (PyLegendDateTime/PyLegendStrictDate/PyLegendDate)."
@@ -18,12 +18,11 @@ from pylegend._typing import (
18
18
  PyLegendDict,
19
19
  PyLegendUnion,
20
20
  )
21
- from pylegend.core.language.primitives.date import PyLegendDate
22
- from pylegend.core.language.expression import (
23
- PyLegendExpression,
21
+ from pylegend.core.language.shared.primitives.date import PyLegendDate
22
+ from pylegend.core.language.shared.expression import (
24
23
  PyLegendExpressionDateTimeReturn,
25
24
  )
26
- from pylegend.core.language.literal_expressions import (
25
+ from pylegend.core.language.shared.literal_expressions import (
27
26
  PyLegendDateTimeLiteralExpression,
28
27
  )
29
28
  from pylegend.core.sql.metamodel import (
@@ -55,7 +54,7 @@ class PyLegendDateTime(PyLegendDate):
55
54
  ) -> Expression:
56
55
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
57
56
 
58
- def value(self) -> PyLegendExpression:
57
+ def value(self) -> PyLegendExpressionDateTimeReturn:
59
58
  return self.__value
60
59
 
61
60
  @staticmethod