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.
Files changed (24) hide show
  1. pylegend/__init__.py +9 -1
  2. pylegend/core/database/sql_to_string/db_extension.py +3 -0
  3. pylegend/core/language/__init__.py +2 -0
  4. pylegend/core/language/shared/functions.py +9 -0
  5. pylegend/core/language/shared/helpers.py +1 -9
  6. pylegend/core/language/shared/operations/binary_expression.py +22 -22
  7. pylegend/core/language/shared/operations/boolean_operation_expressions.py +13 -16
  8. pylegend/core/language/shared/operations/date_operation_expressions.py +208 -42
  9. pylegend/core/language/shared/operations/float_operation_expressions.py +20 -25
  10. pylegend/core/language/shared/operations/integer_operation_expressions.py +25 -30
  11. pylegend/core/language/shared/operations/nullary_expression.py +6 -1
  12. pylegend/core/language/shared/operations/number_operation_expressions.py +109 -90
  13. pylegend/core/language/shared/operations/primitive_operation_expressions.py +59 -7
  14. pylegend/core/language/shared/operations/string_operation_expressions.py +67 -25
  15. pylegend/core/language/shared/operations/unary_expression.py +16 -1
  16. pylegend/core/language/shared/primitives/date.py +37 -0
  17. pylegend/core/language/shared/primitives/primitive.py +16 -0
  18. pylegend/core/sql/metamodel_extension.py +12 -0
  19. {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/METADATA +1 -1
  20. {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/RECORD +24 -24
  21. {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/LICENSE +0 -0
  22. {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/LICENSE.spdx +0 -0
  23. {pylegend-0.4.0.dist-info → pylegend-0.6.0.dist-info}/NOTICE +0 -0
  24. {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 agg
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 to_pure_expression_with_to_one_on_both_operands(self, config: FrameToPureConfig) -> str:
82
- op1_expr = self.__operand1.to_pure_expression(config)
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 f"{op_expr}->map(op | !$op)"
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
  )