pylegend 0.4.0__py3-none-any.whl → 0.6.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/__init__.py +9 -1
- pylegend/core/database/sql_to_string/db_extension.py +3 -0
- pylegend/core/language/__init__.py +2 -0
- pylegend/core/language/shared/functions.py +9 -0
- pylegend/core/language/shared/helpers.py +1 -9
- pylegend/core/language/shared/operations/binary_expression.py +22 -22
- pylegend/core/language/shared/operations/boolean_operation_expressions.py +13 -16
- pylegend/core/language/shared/operations/date_operation_expressions.py +208 -42
- pylegend/core/language/shared/operations/float_operation_expressions.py +20 -25
- pylegend/core/language/shared/operations/integer_operation_expressions.py +25 -30
- pylegend/core/language/shared/operations/nullary_expression.py +6 -1
- pylegend/core/language/shared/operations/number_operation_expressions.py +109 -90
- pylegend/core/language/shared/operations/primitive_operation_expressions.py +59 -7
- pylegend/core/language/shared/operations/string_operation_expressions.py +67 -25
- pylegend/core/language/shared/operations/unary_expression.py +16 -1
- pylegend/core/language/shared/primitives/date.py +37 -0
- pylegend/core/language/shared/primitives/primitive.py +16 -0
- pylegend/core/sql/metamodel_extension.py +12 -0
- {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/METADATA +1 -1
- {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/RECORD +24 -24
- {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/LICENSE +0 -0
- {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/LICENSE.spdx +0 -0
- {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/NOTICE +0 -0
- {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/WHEEL +0 -0
pylegend/__init__.py
CHANGED
|
@@ -32,7 +32,12 @@ from pylegend.core.project_cooridnates import (
|
|
|
32
32
|
PersonalWorkspaceProjectCoordinates,
|
|
33
33
|
GroupWorkspaceProjectCoordinates,
|
|
34
34
|
)
|
|
35
|
-
from pylegend.core.language import
|
|
35
|
+
from pylegend.core.language import (
|
|
36
|
+
agg,
|
|
37
|
+
now,
|
|
38
|
+
today,
|
|
39
|
+
current_user,
|
|
40
|
+
)
|
|
36
41
|
|
|
37
42
|
|
|
38
43
|
__all__: PyLegendSequence[str] = [
|
|
@@ -53,6 +58,9 @@ __all__: PyLegendSequence[str] = [
|
|
|
53
58
|
"GroupWorkspaceProjectCoordinates",
|
|
54
59
|
|
|
55
60
|
"agg",
|
|
61
|
+
"now",
|
|
62
|
+
"today",
|
|
63
|
+
"current_user",
|
|
56
64
|
]
|
|
57
65
|
|
|
58
66
|
|
|
@@ -131,6 +131,7 @@ from pylegend.core.sql.metamodel_extension import (
|
|
|
131
131
|
SecondExpression,
|
|
132
132
|
EpochExpression,
|
|
133
133
|
WindowExpression,
|
|
134
|
+
ConstantExpression,
|
|
134
135
|
)
|
|
135
136
|
|
|
136
137
|
|
|
@@ -451,6 +452,8 @@ def expression_processor(
|
|
|
451
452
|
return extension.process_epoch_expression(expression, config)
|
|
452
453
|
elif isinstance(expression, WindowExpression):
|
|
453
454
|
return extension.process_window_expression(expression, config)
|
|
455
|
+
elif isinstance(expression, ConstantExpression):
|
|
456
|
+
return expression.name
|
|
454
457
|
|
|
455
458
|
else:
|
|
456
459
|
raise ValueError("Unsupported expression type: " + str(type(expression))) # pragma: no cover
|
|
@@ -74,6 +74,7 @@ from pylegend.core.language.shared.primitive_collection import (
|
|
|
74
74
|
from pylegend.core.language.shared.functions import (
|
|
75
75
|
today,
|
|
76
76
|
now,
|
|
77
|
+
current_user,
|
|
77
78
|
)
|
|
78
79
|
|
|
79
80
|
__all__: PyLegendSequence[str] = [
|
|
@@ -132,4 +133,5 @@ __all__: PyLegendSequence[str] = [
|
|
|
132
133
|
|
|
133
134
|
"today",
|
|
134
135
|
"now",
|
|
136
|
+
"current_user",
|
|
135
137
|
]
|
|
@@ -18,15 +18,20 @@ from pylegend._typing import (
|
|
|
18
18
|
)
|
|
19
19
|
from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
|
|
20
20
|
from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
|
|
21
|
+
from pylegend.core.language.shared.primitives.string import PyLegendString
|
|
21
22
|
from pylegend.core.language.shared.operations.date_operation_expressions import (
|
|
22
23
|
PyLegendTodayExpression,
|
|
23
24
|
PyLegendNowExpression,
|
|
24
25
|
)
|
|
26
|
+
from pylegend.core.language.shared.operations.string_operation_expressions import (
|
|
27
|
+
PyLegendCurrentUserExpression,
|
|
28
|
+
)
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
__all__: PyLegendSequence[str] = [
|
|
28
32
|
"today",
|
|
29
33
|
"now",
|
|
34
|
+
"current_user",
|
|
30
35
|
]
|
|
31
36
|
|
|
32
37
|
|
|
@@ -36,3 +41,7 @@ def today() -> PyLegendStrictDate:
|
|
|
36
41
|
|
|
37
42
|
def now() -> PyLegendDateTime:
|
|
38
43
|
return PyLegendDateTime(PyLegendNowExpression())
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def current_user() -> PyLegendString:
|
|
47
|
+
return PyLegendString(PyLegendCurrentUserExpression())
|
|
@@ -24,8 +24,7 @@ __all__ = [
|
|
|
24
24
|
def generate_pure_functional_call(
|
|
25
25
|
func: str,
|
|
26
26
|
params: PyLegendList[str],
|
|
27
|
-
force_prefix: bool = False
|
|
28
|
-
auto_map: bool = False
|
|
27
|
+
force_prefix: bool = False
|
|
29
28
|
) -> str:
|
|
30
29
|
should_prefix = force_prefix or (len(params) == 0)
|
|
31
30
|
|
|
@@ -39,13 +38,6 @@ def generate_pure_functional_call(
|
|
|
39
38
|
else:
|
|
40
39
|
updated_params.append(param)
|
|
41
40
|
|
|
42
|
-
if auto_map and len(updated_params) == 1:
|
|
43
|
-
return f"{params[0]}->map(op | {generate_pure_functional_call(func, ['$op'], force_prefix, False)})"
|
|
44
|
-
|
|
45
|
-
if auto_map and len(updated_params) == 2:
|
|
46
|
-
new_params = ['$op'] + [updated_params[1]]
|
|
47
|
-
return f"{params[0]}->map(op | {generate_pure_functional_call(func, new_params, force_prefix, False)})"
|
|
48
|
-
|
|
49
41
|
if should_prefix:
|
|
50
42
|
return f"{func}({', '.join(updated_params)})"
|
|
51
43
|
else:
|
|
@@ -43,6 +43,9 @@ class PyLegendBinaryExpression(PyLegendExpression, metaclass=ABCMeta):
|
|
|
43
43
|
Expression
|
|
44
44
|
]
|
|
45
45
|
__to_pure_func: PyLegendCallable[[str, str, FrameToPureConfig], str]
|
|
46
|
+
__non_nullable: bool
|
|
47
|
+
__first_operand_needs_to_be_non_nullable: bool
|
|
48
|
+
__second_operand_needs_to_be_non_nullable: bool
|
|
46
49
|
|
|
47
50
|
def __init__(
|
|
48
51
|
self,
|
|
@@ -52,12 +55,18 @@ class PyLegendBinaryExpression(PyLegendExpression, metaclass=ABCMeta):
|
|
|
52
55
|
[Expression, Expression, PyLegendDict[str, QuerySpecification], FrameToSqlConfig],
|
|
53
56
|
Expression
|
|
54
57
|
],
|
|
55
|
-
to_pure_func: PyLegendCallable[[str, str, FrameToPureConfig], str]
|
|
58
|
+
to_pure_func: PyLegendCallable[[str, str, FrameToPureConfig], str],
|
|
59
|
+
non_nullable: bool = False,
|
|
60
|
+
first_operand_needs_to_be_non_nullable: bool = False,
|
|
61
|
+
second_operand_needs_to_be_non_nullable: bool = False,
|
|
56
62
|
) -> None:
|
|
57
63
|
self.__operand1 = operand1
|
|
58
64
|
self.__operand2 = operand2
|
|
59
65
|
self.__to_sql_func = to_sql_func
|
|
60
66
|
self.__to_pure_func = to_pure_func
|
|
67
|
+
self.__non_nullable = non_nullable
|
|
68
|
+
self.__first_operand_needs_to_be_non_nullable = first_operand_needs_to_be_non_nullable
|
|
69
|
+
self.__second_operand_needs_to_be_non_nullable = second_operand_needs_to_be_non_nullable
|
|
61
70
|
|
|
62
71
|
def to_sql_expression(
|
|
63
72
|
self,
|
|
@@ -75,27 +84,18 @@ class PyLegendBinaryExpression(PyLegendExpression, metaclass=ABCMeta):
|
|
|
75
84
|
|
|
76
85
|
def to_pure_expression(self, config: FrameToPureConfig) -> str:
|
|
77
86
|
op1_expr = self.__operand1.to_pure_expression(config)
|
|
87
|
+
if self.__first_operand_needs_to_be_non_nullable:
|
|
88
|
+
op1_expr = (
|
|
89
|
+
op1_expr if self.__operand1.is_non_nullable() else
|
|
90
|
+
f"toOne({op1_expr[1:-1] if expr_has_matching_start_and_end_parentheses(op1_expr) else op1_expr})"
|
|
91
|
+
)
|
|
78
92
|
op2_expr = self.__operand2.to_pure_expression(config)
|
|
93
|
+
if self.__second_operand_needs_to_be_non_nullable:
|
|
94
|
+
op2_expr = (
|
|
95
|
+
op2_expr if self.__operand2.is_non_nullable() else
|
|
96
|
+
f"toOne({op2_expr[1:-1] if expr_has_matching_start_and_end_parentheses(op2_expr) else op2_expr})"
|
|
97
|
+
)
|
|
79
98
|
return self.__to_pure_func(op1_expr, op2_expr, config)
|
|
80
99
|
|
|
81
|
-
def
|
|
82
|
-
|
|
83
|
-
op1_expr = (
|
|
84
|
-
op1_expr if self.__operand1.is_non_nullable() else
|
|
85
|
-
f"toOne({op1_expr[1:-1] if expr_has_matching_start_and_end_parentheses(op1_expr) else op1_expr})"
|
|
86
|
-
)
|
|
87
|
-
op2_expr = self.__operand2.to_pure_expression(config)
|
|
88
|
-
op2_expr = (
|
|
89
|
-
op2_expr if self.__operand2.is_non_nullable() else
|
|
90
|
-
f"toOne({op2_expr[1:-1] if expr_has_matching_start_and_end_parentheses(op2_expr) else op2_expr})"
|
|
91
|
-
)
|
|
92
|
-
return self.__to_pure_func(op1_expr, op2_expr, config)
|
|
93
|
-
|
|
94
|
-
def to_pure_expression_with_to_one_on_second_operand(self, config: FrameToPureConfig) -> str:
|
|
95
|
-
op1_expr = self.__operand1.to_pure_expression(config)
|
|
96
|
-
op2_expr = self.__operand2.to_pure_expression(config)
|
|
97
|
-
op2_expr = (
|
|
98
|
-
op2_expr if self.__operand2.is_non_nullable() else
|
|
99
|
-
f"toOne({op2_expr[1:-1] if expr_has_matching_start_and_end_parentheses(op2_expr) else op2_expr})"
|
|
100
|
-
)
|
|
101
|
-
return self.__to_pure_func(op1_expr, op2_expr, config)
|
|
100
|
+
def is_non_nullable(self) -> bool:
|
|
101
|
+
return self.__non_nullable
|
|
@@ -19,6 +19,7 @@ from pylegend._typing import (
|
|
|
19
19
|
from pylegend.core.language.shared.expression import (
|
|
20
20
|
PyLegendExpressionBooleanReturn,
|
|
21
21
|
)
|
|
22
|
+
from pylegend.core.language.shared.helpers import generate_pure_functional_call
|
|
22
23
|
from pylegend.core.language.shared.operations.binary_expression import PyLegendBinaryExpression
|
|
23
24
|
from pylegend.core.language.shared.operations.unary_expression import PyLegendUnaryExpression
|
|
24
25
|
from pylegend.core.sql.metamodel import (
|
|
@@ -61,15 +62,12 @@ class PyLegendBooleanOrExpression(PyLegendBinaryExpression, PyLegendExpressionBo
|
|
|
61
62
|
operand1,
|
|
62
63
|
operand2,
|
|
63
64
|
PyLegendBooleanOrExpression.__to_sql_func,
|
|
64
|
-
PyLegendBooleanOrExpression.__to_pure_func
|
|
65
|
+
PyLegendBooleanOrExpression.__to_pure_func,
|
|
66
|
+
non_nullable=True,
|
|
67
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
68
|
+
second_operand_needs_to_be_non_nullable=True
|
|
65
69
|
)
|
|
66
70
|
|
|
67
|
-
def is_non_nullable(self) -> bool:
|
|
68
|
-
return True
|
|
69
|
-
|
|
70
|
-
def to_pure_expression(self, config: FrameToPureConfig) -> str:
|
|
71
|
-
return PyLegendBinaryExpression.to_pure_expression_with_to_one_on_both_operands(self, config)
|
|
72
|
-
|
|
73
71
|
|
|
74
72
|
class PyLegendBooleanAndExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
75
73
|
|
|
@@ -93,15 +91,12 @@ class PyLegendBooleanAndExpression(PyLegendBinaryExpression, PyLegendExpressionB
|
|
|
93
91
|
operand1,
|
|
94
92
|
operand2,
|
|
95
93
|
PyLegendBooleanAndExpression.__to_sql_func,
|
|
96
|
-
PyLegendBooleanAndExpression.__to_pure_func
|
|
94
|
+
PyLegendBooleanAndExpression.__to_pure_func,
|
|
95
|
+
non_nullable=True,
|
|
96
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
97
|
+
second_operand_needs_to_be_non_nullable=True
|
|
97
98
|
)
|
|
98
99
|
|
|
99
|
-
def is_non_nullable(self) -> bool:
|
|
100
|
-
return True
|
|
101
|
-
|
|
102
|
-
def to_pure_expression(self, config: FrameToPureConfig) -> str:
|
|
103
|
-
return PyLegendBinaryExpression.to_pure_expression_with_to_one_on_both_operands(self, config)
|
|
104
|
-
|
|
105
100
|
|
|
106
101
|
class PyLegendBooleanNotExpression(PyLegendUnaryExpression, PyLegendExpressionBooleanReturn):
|
|
107
102
|
|
|
@@ -115,7 +110,7 @@ class PyLegendBooleanNotExpression(PyLegendUnaryExpression, PyLegendExpressionBo
|
|
|
115
110
|
|
|
116
111
|
@staticmethod
|
|
117
112
|
def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
|
|
118
|
-
return
|
|
113
|
+
return generate_pure_functional_call("not", [op_expr])
|
|
119
114
|
|
|
120
115
|
def __init__(self, operand: PyLegendExpressionBooleanReturn) -> None:
|
|
121
116
|
PyLegendExpressionBooleanReturn.__init__(self)
|
|
@@ -123,5 +118,7 @@ class PyLegendBooleanNotExpression(PyLegendUnaryExpression, PyLegendExpressionBo
|
|
|
123
118
|
self,
|
|
124
119
|
operand,
|
|
125
120
|
PyLegendBooleanNotExpression.__to_sql_func,
|
|
126
|
-
PyLegendBooleanNotExpression.__to_pure_func
|
|
121
|
+
PyLegendBooleanNotExpression.__to_pure_func,
|
|
122
|
+
non_nullable=True,
|
|
123
|
+
operand_needs_to_be_non_nullable=True,
|
|
127
124
|
)
|