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.
- pylegend/__init__.py +9 -5
- pylegend/core/{databse → database}/sql_to_string/__init__.py +3 -3
- pylegend/core/{databse → database}/sql_to_string/db_extension.py +11 -5
- pylegend/core/{databse → database}/sql_to_string/generator.py +2 -2
- pylegend/core/language/__init__.py +10 -10
- pylegend/core/language/legacy_api/__init__.py +13 -0
- pylegend/core/language/{aggregate_specification.py → legacy_api/aggregate_specification.py} +10 -10
- pylegend/core/language/legacy_api/legacy_api_tds_row.py +32 -0
- pylegend/core/language/legendql_api/__init__.py +13 -0
- pylegend/core/language/legendql_api/legendql_api_custom_expressions.py +541 -0
- pylegend/core/language/legendql_api/legendql_api_tds_row.py +292 -0
- pylegend/core/language/shared/__init__.py +13 -0
- pylegend/core/language/{column_expressions.py → shared/column_expressions.py} +32 -31
- pylegend/core/language/{expression.py → shared/expression.py} +8 -0
- pylegend/core/language/{functions.py → shared/functions.py} +3 -3
- pylegend/core/language/shared/helpers.py +75 -0
- pylegend/core/language/{literal_expressions.py → shared/literal_expressions.py} +39 -1
- pylegend/core/language/{operations → shared/operations}/binary_expression.py +34 -2
- pylegend/core/language/{operations → shared/operations}/boolean_operation_expressions.py +34 -6
- pylegend/core/language/{operations → shared/operations}/collection_operation_expressions.py +146 -26
- pylegend/core/language/{operations → shared/operations}/date_operation_expressions.py +164 -24
- pylegend/core/language/{operations → shared/operations}/float_operation_expressions.py +53 -8
- pylegend/core/language/{operations → shared/operations}/integer_operation_expressions.py +62 -9
- pylegend/core/language/{operations → shared/operations}/nullary_expression.py +9 -2
- pylegend/core/language/{operations → shared/operations}/number_operation_expressions.py +211 -30
- pylegend/core/language/{operations → shared/operations}/primitive_operation_expressions.py +42 -3
- pylegend/core/language/{operations → shared/operations}/string_operation_expressions.py +169 -21
- pylegend/core/language/{operations → shared/operations}/unary_expression.py +10 -2
- pylegend/core/language/{primitive_collection.py → shared/primitive_collection.py} +2 -2
- pylegend/core/language/{primitives → shared/primitives}/__init__.py +9 -9
- pylegend/core/language/{primitives → shared/primitives}/boolean.py +9 -5
- pylegend/core/language/{primitives → shared/primitives}/date.py +23 -15
- pylegend/core/language/{primitives → shared/primitives}/datetime.py +4 -5
- pylegend/core/language/{primitives → shared/primitives}/float.py +6 -6
- pylegend/core/language/{primitives → shared/primitives}/integer.py +6 -6
- pylegend/core/language/{primitives → shared/primitives}/number.py +16 -13
- pylegend/core/language/{primitives → shared/primitives}/primitive.py +25 -5
- pylegend/core/language/{primitives → shared/primitives}/strictdate.py +4 -5
- pylegend/core/language/{primitives → shared/primitives}/string.py +18 -19
- pylegend/core/language/{tds_row.py → shared/tds_row.py} +46 -16
- pylegend/core/request/__init__.py +8 -1
- pylegend/core/request/auth.py +89 -11
- pylegend/core/request/legend_client.py +32 -0
- pylegend/core/sql/metamodel_extension.py +16 -0
- pylegend/core/tds/abstract/__init__.py +13 -0
- pylegend/core/tds/abstract/frames/__init__.py +13 -0
- pylegend/core/tds/{legend_api/frames/legend_api_applied_function_tds_frame.py → abstract/frames/applied_function_tds_frame.py} +19 -13
- pylegend/core/tds/abstract/frames/base_tds_frame.py +125 -0
- pylegend/core/tds/{legend_api/frames/legend_api_input_tds_frame.py → abstract/frames/input_tds_frame.py} +9 -12
- pylegend/core/tds/{legend_api/frames/functions → abstract}/function_helpers.py +1 -1
- pylegend/core/tds/{legend_api/frames/functions/concatenate_function.py → legacy_api/frames/functions/legacy_api_concatenate_function.py} +25 -13
- pylegend/core/tds/{legend_api/frames/functions/distinct_function.py → legacy_api/frames/functions/legacy_api_distinct_function.py} +13 -8
- pylegend/core/tds/{legend_api/frames/functions/drop_function.py → legacy_api/frames/functions/legacy_api_drop_function.py} +13 -8
- pylegend/core/tds/{legend_api/frames/functions/extend_function.py → legacy_api/frames/functions/legacy_api_extend_function.py} +36 -16
- pylegend/core/tds/{legend_api/frames/functions/filter_function.py → legacy_api/frames/functions/legacy_api_filter_function.py} +25 -13
- pylegend/core/tds/{legend_api/frames/functions/group_by_function.py → legacy_api/frames/functions/legacy_api_group_by_function.py} +44 -17
- pylegend/core/tds/{legend_api/frames/functions/head_function.py → legacy_api/frames/functions/legacy_api_head_function.py} +13 -8
- 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
- pylegend/core/tds/{legend_api/frames/functions/join_function.py → legacy_api/frames/functions/legacy_api_join_function.py} +44 -20
- pylegend/core/tds/{legend_api/frames/functions/rename_columns_function.py → legacy_api/frames/functions/legacy_api_rename_columns_function.py} +20 -8
- pylegend/core/tds/{legend_api/frames/functions/restrict_function.py → legacy_api/frames/functions/legacy_api_restrict_function.py} +17 -8
- pylegend/core/tds/{legend_api/frames/functions/slice_function.py → legacy_api/frames/functions/legacy_api_slice_function.py} +13 -8
- pylegend/core/tds/{legend_api/frames/functions/sort_function.py → legacy_api/frames/functions/legacy_api_sort_function.py} +19 -8
- pylegend/core/tds/legacy_api/frames/legacy_api_applied_function_tds_frame.py +37 -0
- pylegend/core/tds/legacy_api/frames/legacy_api_base_tds_frame.py +204 -0
- pylegend/core/tds/legacy_api/frames/legacy_api_input_tds_frame.py +51 -0
- pylegend/core/tds/{legend_api/frames/legend_api_tds_frame.py → legacy_api/frames/legacy_api_tds_frame.py} +28 -28
- pylegend/core/tds/legendql_api/__init__.py +13 -0
- pylegend/core/tds/legendql_api/frames/__init__.py +13 -0
- pylegend/core/tds/legendql_api/frames/functions/__init__.py +13 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_asofjoin_function.py +156 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_concatenate_function.py +139 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_distinct_function.py +69 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_drop_function.py +74 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_extend_function.py +256 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_filter_function.py +121 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_function_helpers.py +137 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_groupby_function.py +256 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_head_function.py +74 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_join_function.py +214 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_project_function.py +169 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_rename_function.py +189 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_select_function.py +131 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_slice_function.py +82 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_sort_function.py +93 -0
- pylegend/core/tds/legendql_api/frames/functions/legendql_api_window_extend_function.py +283 -0
- pylegend/core/tds/legendql_api/frames/legendql_api_applied_function_tds_frame.py +37 -0
- pylegend/core/tds/legendql_api/frames/legendql_api_base_tds_frame.py +419 -0
- pylegend/core/tds/legendql_api/frames/legendql_api_input_tds_frame.py +50 -0
- pylegend/core/tds/legendql_api/frames/legendql_api_tds_frame.py +327 -0
- pylegend/core/tds/pandas_api/frames/functions/assign_function.py +6 -6
- pylegend/core/tds/pandas_api/frames/pandas_api_applied_function_tds_frame.py +4 -0
- pylegend/core/tds/pandas_api/frames/pandas_api_base_tds_frame.py +11 -3
- pylegend/core/tds/pandas_api/frames/pandas_api_tds_frame.py +2 -2
- pylegend/core/tds/tds_frame.py +32 -2
- pylegend/extensions/database/vendors/postgres/postgres_sql_to_string.py +1 -1
- pylegend/extensions/tds/abstract/legend_function_input_frame.py +4 -0
- pylegend/extensions/tds/abstract/legend_service_input_frame.py +4 -0
- pylegend/extensions/tds/abstract/table_spec_input_frame.py +4 -0
- 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
- 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
- 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
- pylegend/extensions/tds/legendql_api/__init__.py +13 -0
- pylegend/extensions/tds/legendql_api/frames/__init__.py +13 -0
- pylegend/extensions/tds/legendql_api/frames/legendql_api_legend_service_input_frame.py +46 -0
- pylegend/extensions/tds/legendql_api/frames/legendql_api_table_spec_input_frame.py +36 -0
- pylegend/{legend_api_tds_client.py → legacy_api_tds_client.py} +15 -15
- {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/METADATA +7 -8
- pylegend-0.4.0.dist-info/NOTICE +5 -0
- pylegend-0.4.0.dist-info/RECORD +155 -0
- {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/WHEEL +1 -1
- pylegend/core/tds/legend_api/frames/legend_api_base_tds_frame.py +0 -294
- pylegend-0.2.2.dist-info/RECORD +0 -115
- /pylegend/core/{databse → database}/__init__.py +0 -0
- /pylegend/core/{databse → database}/sql_to_string/config.py +0 -0
- /pylegend/core/language/{operations → shared/operations}/__init__.py +0 -0
- /pylegend/core/tds/{legend_api → legacy_api}/__init__.py +0 -0
- /pylegend/core/tds/{legend_api → legacy_api}/frames/__init__.py +0 -0
- /pylegend/core/tds/{legend_api → legacy_api}/frames/functions/__init__.py +0 -0
- /pylegend/extensions/tds/{legend_api → legacy_api}/__init__.py +0 -0
- /pylegend/extensions/tds/{legend_api → legacy_api}/frames/__init__.py +0 -0
- {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/LICENSE +0 -0
- {pylegend-0.2.2.dist-info → pylegend-0.4.0.dist-info}/LICENSE.spdx +0 -0
|
@@ -15,21 +15,21 @@
|
|
|
15
15
|
from abc import ABCMeta, abstractmethod
|
|
16
16
|
from pylegend._typing import (
|
|
17
17
|
PyLegendSequence,
|
|
18
|
-
PyLegendList,
|
|
19
18
|
)
|
|
20
19
|
from pylegend.core.sql.metamodel import QuerySpecification
|
|
21
20
|
from pylegend.core.tds.tds_column import TdsColumn
|
|
22
21
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
23
|
-
from pylegend.core.tds.
|
|
22
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
23
|
+
from pylegend.core.tds.abstract.frames.base_tds_frame import BaseTdsFrame
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
__all__: PyLegendSequence[str] = [
|
|
27
|
-
"
|
|
28
|
-
"
|
|
27
|
+
"AppliedFunctionTdsFrame",
|
|
28
|
+
"AppliedFunction",
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
class
|
|
32
|
+
class AppliedFunction(metaclass=ABCMeta):
|
|
33
33
|
@classmethod
|
|
34
34
|
@abstractmethod
|
|
35
35
|
def name(cls) -> str:
|
|
@@ -39,16 +39,19 @@ class LegendApiAppliedFunction(metaclass=ABCMeta):
|
|
|
39
39
|
def to_sql(self, config: FrameToSqlConfig) -> QuerySpecification:
|
|
40
40
|
pass # pragma: no cover
|
|
41
41
|
|
|
42
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
43
|
+
raise RuntimeError("PURE generation not supported for '" + self.name() + "' function")
|
|
44
|
+
|
|
42
45
|
@abstractmethod
|
|
43
|
-
def base_frame(self) ->
|
|
46
|
+
def base_frame(self) -> BaseTdsFrame:
|
|
44
47
|
pass # pragma: no cover
|
|
45
48
|
|
|
46
49
|
@abstractmethod
|
|
47
|
-
def tds_frame_parameters(self) ->
|
|
50
|
+
def tds_frame_parameters(self) -> PyLegendSequence[BaseTdsFrame]:
|
|
48
51
|
pass # pragma: no cover
|
|
49
52
|
|
|
50
53
|
@abstractmethod
|
|
51
|
-
def calculate_columns(self) -> PyLegendSequence[
|
|
54
|
+
def calculate_columns(self) -> PyLegendSequence[TdsColumn]:
|
|
52
55
|
pass # pragma: no cover
|
|
53
56
|
|
|
54
57
|
@abstractmethod
|
|
@@ -56,10 +59,10 @@ class LegendApiAppliedFunction(metaclass=ABCMeta):
|
|
|
56
59
|
pass # pragma: no cover
|
|
57
60
|
|
|
58
61
|
|
|
59
|
-
class
|
|
60
|
-
__applied_function:
|
|
62
|
+
class AppliedFunctionTdsFrame(BaseTdsFrame, metaclass=ABCMeta):
|
|
63
|
+
__applied_function: AppliedFunction
|
|
61
64
|
|
|
62
|
-
def __init__(self, applied_function:
|
|
65
|
+
def __init__(self, applied_function: AppliedFunction):
|
|
63
66
|
applied_function.validate()
|
|
64
67
|
super().__init__(columns=applied_function.calculate_columns())
|
|
65
68
|
self.__applied_function = applied_function
|
|
@@ -67,9 +70,12 @@ class LegendApiAppliedFunctionTdsFrame(LegendApiBaseTdsFrame):
|
|
|
67
70
|
def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
|
|
68
71
|
return self.__applied_function.to_sql(config)
|
|
69
72
|
|
|
70
|
-
def
|
|
73
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
74
|
+
return self.__applied_function.to_pure(config)
|
|
75
|
+
|
|
76
|
+
def get_all_tds_frames(self) -> PyLegendSequence[BaseTdsFrame]:
|
|
71
77
|
return [
|
|
72
78
|
y
|
|
73
|
-
for x in [self.__applied_function.base_frame()] + self.__applied_function.tds_frame_parameters()
|
|
79
|
+
for x in [self.__applied_function.base_frame()] + list(self.__applied_function.tds_frame_parameters())
|
|
74
80
|
for y in x.get_all_tds_frames()
|
|
75
81
|
] + [self]
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Copyright 2025 Goldman Sachs
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from abc import ABCMeta, abstractmethod
|
|
16
|
+
import pandas as pd
|
|
17
|
+
from pylegend._typing import (
|
|
18
|
+
PyLegendSequence,
|
|
19
|
+
PyLegendTypeVar,
|
|
20
|
+
PyLegendOptional,
|
|
21
|
+
)
|
|
22
|
+
from pylegend.core.sql.metamodel import QuerySpecification
|
|
23
|
+
from pylegend.core.database.sql_to_string import (
|
|
24
|
+
SqlToStringConfig,
|
|
25
|
+
SqlToStringFormat
|
|
26
|
+
)
|
|
27
|
+
from pylegend.core.tds.tds_column import TdsColumn
|
|
28
|
+
from pylegend.core.tds.tds_frame import FrameToSqlConfig, PyLegendTdsFrame
|
|
29
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
30
|
+
from pylegend.core.tds.result_handler import (
|
|
31
|
+
ResultHandler,
|
|
32
|
+
ToStringResultHandler,
|
|
33
|
+
)
|
|
34
|
+
from pylegend.extensions.tds.result_handler import (
|
|
35
|
+
ToPandasDfResultHandler,
|
|
36
|
+
PandasDfReadConfig,
|
|
37
|
+
)
|
|
38
|
+
__all__: PyLegendSequence[str] = [
|
|
39
|
+
"BaseTdsFrame"
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
R = PyLegendTypeVar('R')
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BaseTdsFrame(PyLegendTdsFrame, metaclass=ABCMeta):
|
|
46
|
+
__columns: PyLegendSequence[TdsColumn]
|
|
47
|
+
|
|
48
|
+
def __init__(self, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
49
|
+
col_names = [c.get_name() for c in columns]
|
|
50
|
+
if len(col_names) != len(set(col_names)):
|
|
51
|
+
cols = "[" + ", ".join([str(c) for c in columns]) + "]"
|
|
52
|
+
raise ValueError(f"TdsFrame cannot have duplicated column names. Passed columns: {cols}")
|
|
53
|
+
self.__columns = [c.copy() for c in columns]
|
|
54
|
+
|
|
55
|
+
def columns(self) -> PyLegendSequence[TdsColumn]:
|
|
56
|
+
return [c.copy() for c in self.__columns]
|
|
57
|
+
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
|
|
60
|
+
pass # pragma: no cover
|
|
61
|
+
|
|
62
|
+
@abstractmethod
|
|
63
|
+
def get_all_tds_frames(self) -> PyLegendSequence["BaseTdsFrame"]:
|
|
64
|
+
pass # pragma: no cover
|
|
65
|
+
|
|
66
|
+
def to_sql_query(self, config: FrameToSqlConfig = FrameToSqlConfig()) -> str:
|
|
67
|
+
query = self.to_sql_query_object(config)
|
|
68
|
+
sql_to_string_config = SqlToStringConfig(format_=SqlToStringFormat(pretty=config.pretty))
|
|
69
|
+
return config.sql_to_string_generator().generate_sql_string(query, sql_to_string_config)
|
|
70
|
+
|
|
71
|
+
@abstractmethod
|
|
72
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
73
|
+
pass # pragma: no cover
|
|
74
|
+
|
|
75
|
+
def to_pure_query(self, config: FrameToPureConfig = FrameToPureConfig()) -> str:
|
|
76
|
+
return self.to_pure(config)
|
|
77
|
+
|
|
78
|
+
def execute_frame(
|
|
79
|
+
self,
|
|
80
|
+
result_handler: ResultHandler[R],
|
|
81
|
+
chunk_size: PyLegendOptional[int] = None
|
|
82
|
+
) -> R:
|
|
83
|
+
from pylegend.core.tds.abstract.frames.input_tds_frame import InputTdsFrame, ExecutableInputTdsFrame
|
|
84
|
+
|
|
85
|
+
tds_frames = self.get_all_tds_frames()
|
|
86
|
+
input_frames = [x for x in tds_frames if isinstance(x, InputTdsFrame)]
|
|
87
|
+
|
|
88
|
+
non_exec_frames = [x for x in input_frames if not isinstance(x, ExecutableInputTdsFrame)]
|
|
89
|
+
if non_exec_frames:
|
|
90
|
+
raise ValueError(
|
|
91
|
+
"Cannot execute frame as its built on top of non-executable input frames: [" +
|
|
92
|
+
(", ".join([str(f) for f in non_exec_frames]) + "]")
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
exec_frames = [x for x in input_frames if isinstance(x, ExecutableInputTdsFrame)]
|
|
96
|
+
|
|
97
|
+
all_legend_clients = []
|
|
98
|
+
for e in exec_frames:
|
|
99
|
+
c = e.get_legend_client()
|
|
100
|
+
if c not in all_legend_clients:
|
|
101
|
+
all_legend_clients.append(c)
|
|
102
|
+
if len(all_legend_clients) > 1:
|
|
103
|
+
raise ValueError(
|
|
104
|
+
"Found tds frames with multiple legend_clients (which is not supported): [" +
|
|
105
|
+
(", ".join([str(f) for f in all_legend_clients]) + "]")
|
|
106
|
+
)
|
|
107
|
+
legend_client = all_legend_clients[0]
|
|
108
|
+
result = legend_client.execute_sql_string(self.to_sql_query(), chunk_size=chunk_size)
|
|
109
|
+
return result_handler.handle_result(self, result)
|
|
110
|
+
|
|
111
|
+
def execute_frame_to_string(
|
|
112
|
+
self,
|
|
113
|
+
chunk_size: PyLegendOptional[int] = None
|
|
114
|
+
) -> str:
|
|
115
|
+
return self.execute_frame(ToStringResultHandler(), chunk_size)
|
|
116
|
+
|
|
117
|
+
def execute_frame_to_pandas_df(
|
|
118
|
+
self,
|
|
119
|
+
chunk_size: PyLegendOptional[int] = None,
|
|
120
|
+
pandas_df_read_config: PandasDfReadConfig = PandasDfReadConfig()
|
|
121
|
+
) -> pd.DataFrame:
|
|
122
|
+
return self.execute_frame(
|
|
123
|
+
ToPandasDfResultHandler(pandas_df_read_config),
|
|
124
|
+
chunk_size
|
|
125
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 Goldman Sachs
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -15,30 +15,28 @@
|
|
|
15
15
|
from abc import ABCMeta
|
|
16
16
|
from pylegend._typing import (
|
|
17
17
|
PyLegendSequence,
|
|
18
|
-
PyLegendList
|
|
19
18
|
)
|
|
20
19
|
from pylegend.core.tds.tds_column import TdsColumn
|
|
21
|
-
from pylegend.core.tds.
|
|
20
|
+
from pylegend.core.tds.abstract.frames.base_tds_frame import BaseTdsFrame
|
|
22
21
|
from pylegend.core.request.legend_client import LegendClient
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
__all__: PyLegendSequence[str] = [
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
25
|
+
"ExecutableInputTdsFrame",
|
|
26
|
+
"NonExecutableInputTdsFrame",
|
|
27
|
+
"InputTdsFrame"
|
|
29
28
|
]
|
|
30
29
|
|
|
31
30
|
|
|
32
|
-
class
|
|
33
|
-
|
|
31
|
+
class InputTdsFrame(BaseTdsFrame, metaclass=ABCMeta):
|
|
34
32
|
def __init__(self, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
35
33
|
super().__init__(columns=columns)
|
|
36
34
|
|
|
37
|
-
def get_all_tds_frames(self) ->
|
|
35
|
+
def get_all_tds_frames(self) -> PyLegendSequence["BaseTdsFrame"]:
|
|
38
36
|
return [self]
|
|
39
37
|
|
|
40
38
|
|
|
41
|
-
class
|
|
39
|
+
class ExecutableInputTdsFrame(InputTdsFrame, metaclass=ABCMeta):
|
|
42
40
|
__legend_client: LegendClient
|
|
43
41
|
|
|
44
42
|
def __init__(self, legend_client: LegendClient, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
@@ -49,7 +47,6 @@ class LegendApiExecutableInputTdsFrame(LegendApiInputTdsFrame, metaclass=ABCMeta
|
|
|
49
47
|
return self.__legend_client
|
|
50
48
|
|
|
51
49
|
|
|
52
|
-
class
|
|
53
|
-
|
|
50
|
+
class NonExecutableInputTdsFrame(InputTdsFrame, metaclass=ABCMeta):
|
|
54
51
|
def __init__(self, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
55
52
|
super().__init__(columns=columns)
|
|
@@ -16,7 +16,7 @@ from pylegend._typing import (
|
|
|
16
16
|
PyLegendList,
|
|
17
17
|
PyLegendSequence
|
|
18
18
|
)
|
|
19
|
-
from pylegend.core.tds.
|
|
19
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import LegacyApiAppliedFunction
|
|
20
20
|
from pylegend.core.sql.metamodel import (
|
|
21
21
|
QuerySpecification,
|
|
22
22
|
Union,
|
|
@@ -28,29 +28,31 @@ from pylegend.core.sql.metamodel import (
|
|
|
28
28
|
TableSubquery,
|
|
29
29
|
Query,
|
|
30
30
|
)
|
|
31
|
+
from pylegend.core.tds.sql_query_helpers import create_sub_query
|
|
31
32
|
from pylegend.core.tds.tds_column import TdsColumn
|
|
32
33
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
33
|
-
from pylegend.core.tds.
|
|
34
|
-
from pylegend.core.tds.
|
|
34
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
35
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_tds_frame import LegacyApiTdsFrame
|
|
36
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_base_tds_frame import LegacyApiBaseTdsFrame
|
|
35
37
|
|
|
36
38
|
|
|
37
39
|
__all__: PyLegendSequence[str] = [
|
|
38
|
-
"
|
|
40
|
+
"LegacyApiConcatenateFunction"
|
|
39
41
|
]
|
|
40
42
|
|
|
41
43
|
|
|
42
|
-
class
|
|
43
|
-
__base_frame:
|
|
44
|
-
__other_frame:
|
|
44
|
+
class LegacyApiConcatenateFunction(LegacyApiAppliedFunction):
|
|
45
|
+
__base_frame: LegacyApiBaseTdsFrame
|
|
46
|
+
__other_frame: LegacyApiBaseTdsFrame
|
|
45
47
|
|
|
46
48
|
@classmethod
|
|
47
49
|
def name(cls) -> str:
|
|
48
50
|
return "concatenate"
|
|
49
51
|
|
|
50
|
-
def __init__(self, base_frame:
|
|
52
|
+
def __init__(self, base_frame: LegacyApiBaseTdsFrame, other: LegacyApiTdsFrame) -> None:
|
|
51
53
|
self.__base_frame = base_frame
|
|
52
|
-
if not isinstance(other,
|
|
53
|
-
raise ValueError("Expected
|
|
54
|
+
if not isinstance(other, LegacyApiBaseTdsFrame):
|
|
55
|
+
raise ValueError("Expected LegacyApiBaseTdsFrame") # pragma: no cover
|
|
54
56
|
self.__other_frame = other
|
|
55
57
|
|
|
56
58
|
def to_sql(self, config: FrameToSqlConfig) -> QuerySpecification:
|
|
@@ -76,7 +78,11 @@ class ConcatenateFunction(LegendApiAppliedFunction):
|
|
|
76
78
|
AliasedRelation(
|
|
77
79
|
relation=TableSubquery(
|
|
78
80
|
query=Query(
|
|
79
|
-
queryBody=Union(
|
|
81
|
+
queryBody=Union(
|
|
82
|
+
left=create_sub_query(base_query, config, "left"),
|
|
83
|
+
right=create_sub_query(other_query, config, "right"),
|
|
84
|
+
distinct=False
|
|
85
|
+
),
|
|
80
86
|
limit=None, offset=None, orderBy=[]
|
|
81
87
|
)
|
|
82
88
|
),
|
|
@@ -92,10 +98,16 @@ class ConcatenateFunction(LegendApiAppliedFunction):
|
|
|
92
98
|
offset=None
|
|
93
99
|
)
|
|
94
100
|
|
|
95
|
-
def
|
|
101
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
102
|
+
return (f"{self.__base_frame.to_pure(config)}{config.separator(1)}"
|
|
103
|
+
f"->concatenate({config.separator(2)}"
|
|
104
|
+
f"{self.__other_frame.to_pure(config.push_indent(2))}"
|
|
105
|
+
f"{config.separator(1)})")
|
|
106
|
+
|
|
107
|
+
def base_frame(self) -> LegacyApiBaseTdsFrame:
|
|
96
108
|
return self.__base_frame
|
|
97
109
|
|
|
98
|
-
def tds_frame_parameters(self) -> PyLegendList["
|
|
110
|
+
def tds_frame_parameters(self) -> PyLegendList["LegacyApiBaseTdsFrame"]:
|
|
99
111
|
return [self.__other_frame]
|
|
100
112
|
|
|
101
113
|
def calculate_columns(self) -> PyLegendSequence["TdsColumn"]:
|
|
@@ -16,29 +16,30 @@ from pylegend._typing import (
|
|
|
16
16
|
PyLegendList,
|
|
17
17
|
PyLegendSequence
|
|
18
18
|
)
|
|
19
|
-
from pylegend.core.tds.
|
|
19
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import LegacyApiAppliedFunction
|
|
20
20
|
from pylegend.core.tds.sql_query_helpers import copy_query, create_sub_query
|
|
21
21
|
from pylegend.core.sql.metamodel import (
|
|
22
22
|
QuerySpecification,
|
|
23
23
|
)
|
|
24
24
|
from pylegend.core.tds.tds_column import TdsColumn
|
|
25
25
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
26
|
-
from pylegend.core.tds.
|
|
26
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
27
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_base_tds_frame import LegacyApiBaseTdsFrame
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
__all__: PyLegendSequence[str] = [
|
|
30
|
-
"
|
|
31
|
+
"LegacyApiDistinctFunction"
|
|
31
32
|
]
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
class
|
|
35
|
-
__base_frame:
|
|
35
|
+
class LegacyApiDistinctFunction(LegacyApiAppliedFunction):
|
|
36
|
+
__base_frame: LegacyApiBaseTdsFrame
|
|
36
37
|
|
|
37
38
|
@classmethod
|
|
38
39
|
def name(cls) -> str:
|
|
39
40
|
return "distinct"
|
|
40
41
|
|
|
41
|
-
def __init__(self, base_frame:
|
|
42
|
+
def __init__(self, base_frame: LegacyApiBaseTdsFrame) -> None:
|
|
42
43
|
self.__base_frame = base_frame
|
|
43
44
|
|
|
44
45
|
def to_sql(self, config: FrameToSqlConfig) -> QuerySpecification:
|
|
@@ -51,10 +52,14 @@ class DistinctFunction(LegendApiAppliedFunction):
|
|
|
51
52
|
new_query.select.distinct = True
|
|
52
53
|
return new_query
|
|
53
54
|
|
|
54
|
-
def
|
|
55
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
56
|
+
return (f"{self.__base_frame.to_pure(config)}{config.separator(1)}"
|
|
57
|
+
f"->distinct()")
|
|
58
|
+
|
|
59
|
+
def base_frame(self) -> LegacyApiBaseTdsFrame:
|
|
55
60
|
return self.__base_frame
|
|
56
61
|
|
|
57
|
-
def tds_frame_parameters(self) -> PyLegendList["
|
|
62
|
+
def tds_frame_parameters(self) -> PyLegendList["LegacyApiBaseTdsFrame"]:
|
|
58
63
|
return []
|
|
59
64
|
|
|
60
65
|
def calculate_columns(self) -> PyLegendSequence["TdsColumn"]:
|
|
@@ -16,7 +16,7 @@ from pylegend._typing import (
|
|
|
16
16
|
PyLegendList,
|
|
17
17
|
PyLegendSequence
|
|
18
18
|
)
|
|
19
|
-
from pylegend.core.tds.
|
|
19
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import LegacyApiAppliedFunction
|
|
20
20
|
from pylegend.core.tds.sql_query_helpers import copy_query, create_sub_query
|
|
21
21
|
from pylegend.core.sql.metamodel import (
|
|
22
22
|
QuerySpecification,
|
|
@@ -24,23 +24,24 @@ from pylegend.core.sql.metamodel import (
|
|
|
24
24
|
)
|
|
25
25
|
from pylegend.core.tds.tds_column import TdsColumn
|
|
26
26
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
27
|
-
from pylegend.core.tds.
|
|
27
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
28
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_base_tds_frame import LegacyApiBaseTdsFrame
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
__all__: PyLegendSequence[str] = [
|
|
31
|
-
"
|
|
32
|
+
"LegacyApiDropFunction"
|
|
32
33
|
]
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
class
|
|
36
|
-
__base_frame:
|
|
36
|
+
class LegacyApiDropFunction(LegacyApiAppliedFunction):
|
|
37
|
+
__base_frame: LegacyApiBaseTdsFrame
|
|
37
38
|
__row_count: int
|
|
38
39
|
|
|
39
40
|
@classmethod
|
|
40
41
|
def name(cls) -> str:
|
|
41
42
|
return "drop"
|
|
42
43
|
|
|
43
|
-
def __init__(self, base_frame:
|
|
44
|
+
def __init__(self, base_frame: LegacyApiBaseTdsFrame, row_count: int) -> None:
|
|
44
45
|
self.__base_frame = base_frame
|
|
45
46
|
self.__row_count = row_count
|
|
46
47
|
|
|
@@ -54,10 +55,14 @@ class DropFunction(LegendApiAppliedFunction):
|
|
|
54
55
|
new_query.offset = LongLiteral(value=self.__row_count)
|
|
55
56
|
return new_query
|
|
56
57
|
|
|
57
|
-
def
|
|
58
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
59
|
+
return (f"{self.__base_frame.to_pure(config)}{config.separator(1)}"
|
|
60
|
+
f"->drop({self.__row_count})")
|
|
61
|
+
|
|
62
|
+
def base_frame(self) -> LegacyApiBaseTdsFrame:
|
|
58
63
|
return self.__base_frame
|
|
59
64
|
|
|
60
|
-
def tds_frame_parameters(self) -> PyLegendList["
|
|
65
|
+
def tds_frame_parameters(self) -> PyLegendList["LegacyApiBaseTdsFrame"]:
|
|
61
66
|
return []
|
|
62
67
|
|
|
63
68
|
def calculate_columns(self) -> PyLegendSequence["TdsColumn"]:
|
|
@@ -18,7 +18,8 @@ from pylegend._typing import (
|
|
|
18
18
|
PyLegendSequence,
|
|
19
19
|
PyLegendCallable,
|
|
20
20
|
)
|
|
21
|
-
from pylegend.core.tds.
|
|
21
|
+
from pylegend.core.tds.abstract.function_helpers import tds_column_for_primitive
|
|
22
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import LegacyApiAppliedFunction
|
|
22
23
|
from pylegend.core.tds.sql_query_helpers import copy_query, create_sub_query
|
|
23
24
|
from pylegend.core.sql.metamodel import (
|
|
24
25
|
QuerySpecification,
|
|
@@ -26,23 +27,24 @@ from pylegend.core.sql.metamodel import (
|
|
|
26
27
|
)
|
|
27
28
|
from pylegend.core.tds.tds_column import TdsColumn
|
|
28
29
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
29
|
-
from pylegend.core.tds.
|
|
30
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
31
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_base_tds_frame import LegacyApiBaseTdsFrame
|
|
30
32
|
from pylegend.core.language import (
|
|
31
|
-
|
|
33
|
+
LegacyApiTdsRow,
|
|
32
34
|
PyLegendPrimitive,
|
|
33
35
|
PyLegendPrimitiveOrPythonPrimitive,
|
|
34
36
|
convert_literal_to_literal_expression,
|
|
35
37
|
)
|
|
36
|
-
from pylegend.core.
|
|
38
|
+
from pylegend.core.language.shared.helpers import generate_pure_lambda, escape_column_name
|
|
37
39
|
|
|
38
40
|
__all__: PyLegendSequence[str] = [
|
|
39
|
-
"
|
|
41
|
+
"LegacyApiExtendFunction"
|
|
40
42
|
]
|
|
41
43
|
|
|
42
44
|
|
|
43
|
-
class
|
|
44
|
-
__base_frame:
|
|
45
|
-
__functions_list: PyLegendList[PyLegendCallable[[
|
|
45
|
+
class LegacyApiExtendFunction(LegacyApiAppliedFunction):
|
|
46
|
+
__base_frame: LegacyApiBaseTdsFrame
|
|
47
|
+
__functions_list: PyLegendList[PyLegendCallable[[LegacyApiTdsRow], PyLegendPrimitiveOrPythonPrimitive]]
|
|
46
48
|
__column_names_list: PyLegendList[str]
|
|
47
49
|
|
|
48
50
|
@classmethod
|
|
@@ -51,8 +53,8 @@ class ExtendFunction(LegendApiAppliedFunction):
|
|
|
51
53
|
|
|
52
54
|
def __init__(
|
|
53
55
|
self,
|
|
54
|
-
base_frame:
|
|
55
|
-
functions_list: PyLegendList[PyLegendCallable[[
|
|
56
|
+
base_frame: LegacyApiBaseTdsFrame,
|
|
57
|
+
functions_list: PyLegendList[PyLegendCallable[[LegacyApiTdsRow], PyLegendPrimitiveOrPythonPrimitive]],
|
|
56
58
|
column_names_list: PyLegendList[str]
|
|
57
59
|
) -> None:
|
|
58
60
|
self.__base_frame = base_frame
|
|
@@ -69,7 +71,7 @@ class ExtendFunction(LegendApiAppliedFunction):
|
|
|
69
71
|
copy_query(base_query)
|
|
70
72
|
)
|
|
71
73
|
|
|
72
|
-
tds_row =
|
|
74
|
+
tds_row = LegacyApiTdsRow.from_tds_frame("frame", self.__base_frame)
|
|
73
75
|
for (func, name) in zip(self.__functions_list, self.__column_names_list):
|
|
74
76
|
col_expr = func(tds_row)
|
|
75
77
|
|
|
@@ -87,16 +89,34 @@ class ExtendFunction(LegendApiAppliedFunction):
|
|
|
87
89
|
|
|
88
90
|
return new_query
|
|
89
91
|
|
|
90
|
-
def
|
|
92
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
93
|
+
tds_row = LegacyApiTdsRow.from_tds_frame("r", self.__base_frame)
|
|
94
|
+
rendered_columns = []
|
|
95
|
+
for (func, col_name) in zip(self.__functions_list, self.__column_names_list):
|
|
96
|
+
col_expr = func(tds_row)
|
|
97
|
+
escaped_col_name = escape_column_name(col_name)
|
|
98
|
+
pure_expr = (col_expr.to_pure_expression(config) if isinstance(col_expr, PyLegendPrimitive) else
|
|
99
|
+
convert_literal_to_literal_expression(col_expr).to_pure_expression(config))
|
|
100
|
+
rendered_columns.append(f"{escaped_col_name}:{generate_pure_lambda('r', pure_expr)}")
|
|
101
|
+
|
|
102
|
+
return (f"{self.__base_frame.to_pure(config)}{config.separator(1)}" +
|
|
103
|
+
(
|
|
104
|
+
(f"->extend(~{rendered_columns[0]})") if len(rendered_columns) == 1 else
|
|
105
|
+
(f"->extend(~[{config.separator(2)}"
|
|
106
|
+
f"{(',' + config.separator(2, True)).join(rendered_columns)}"
|
|
107
|
+
f"{config.separator(1)}])")
|
|
108
|
+
))
|
|
109
|
+
|
|
110
|
+
def base_frame(self) -> LegacyApiBaseTdsFrame:
|
|
91
111
|
return self.__base_frame
|
|
92
112
|
|
|
93
|
-
def tds_frame_parameters(self) -> PyLegendList["
|
|
113
|
+
def tds_frame_parameters(self) -> PyLegendList["LegacyApiBaseTdsFrame"]:
|
|
94
114
|
return []
|
|
95
115
|
|
|
96
116
|
def calculate_columns(self) -> PyLegendSequence["TdsColumn"]:
|
|
97
117
|
new_columns = [c.copy() for c in self.__base_frame.columns()]
|
|
98
118
|
|
|
99
|
-
tds_row =
|
|
119
|
+
tds_row = LegacyApiTdsRow.from_tds_frame("frame", self.__base_frame)
|
|
100
120
|
for (func, name) in zip(self.__functions_list, self.__column_names_list):
|
|
101
121
|
result = func(tds_row)
|
|
102
122
|
new_columns.append(tds_column_for_primitive(name, result))
|
|
@@ -111,7 +131,7 @@ class ExtendFunction(LegendApiAppliedFunction):
|
|
|
111
131
|
f"Column names: {len(self.__column_names_list)}"
|
|
112
132
|
)
|
|
113
133
|
|
|
114
|
-
tds_row =
|
|
134
|
+
tds_row = LegacyApiTdsRow.from_tds_frame("frame", self.__base_frame)
|
|
115
135
|
index = 0
|
|
116
136
|
for (func, name) in zip(self.__functions_list, self.__column_names_list):
|
|
117
137
|
copy = func # For MyPy
|
|
@@ -134,7 +154,7 @@ class ExtendFunction(LegendApiAppliedFunction):
|
|
|
134
154
|
f"Error occurred while evaluating. Message: {str(e)}"
|
|
135
155
|
) from e
|
|
136
156
|
|
|
137
|
-
if not isinstance(result, (int, float, bool, str, PyLegendPrimitive)):
|
|
157
|
+
if not isinstance(result, (int, float, bool, str, date, datetime, PyLegendPrimitive)):
|
|
138
158
|
raise ValueError(
|
|
139
159
|
f"Extend function at index {index} (0-indexed) incompatible. "
|
|
140
160
|
f"Returns non-primitive - {str(type(result))}"
|
|
@@ -18,7 +18,7 @@ from pylegend._typing import (
|
|
|
18
18
|
PyLegendCallable,
|
|
19
19
|
PyLegendUnion,
|
|
20
20
|
)
|
|
21
|
-
from pylegend.core.tds.
|
|
21
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import LegacyApiAppliedFunction
|
|
22
22
|
from pylegend.core.tds.sql_query_helpers import copy_query, create_sub_query
|
|
23
23
|
from pylegend.core.sql.metamodel import (
|
|
24
24
|
QuerySpecification,
|
|
@@ -27,21 +27,25 @@ from pylegend.core.sql.metamodel import (
|
|
|
27
27
|
)
|
|
28
28
|
from pylegend.core.tds.tds_column import TdsColumn
|
|
29
29
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
30
|
-
from pylegend.core.tds.
|
|
30
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
31
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_base_tds_frame import LegacyApiBaseTdsFrame
|
|
31
32
|
from pylegend.core.language import (
|
|
32
|
-
|
|
33
|
+
LegacyApiTdsRow,
|
|
33
34
|
PyLegendBoolean,
|
|
34
35
|
PyLegendBooleanLiteralExpression,
|
|
36
|
+
PyLegendPrimitive,
|
|
37
|
+
convert_literal_to_literal_expression,
|
|
35
38
|
)
|
|
39
|
+
from pylegend.core.language.shared.helpers import generate_pure_lambda
|
|
36
40
|
|
|
37
41
|
__all__: PyLegendSequence[str] = [
|
|
38
|
-
"
|
|
42
|
+
"LegacyApiFilterFunction"
|
|
39
43
|
]
|
|
40
44
|
|
|
41
45
|
|
|
42
|
-
class
|
|
43
|
-
__base_frame:
|
|
44
|
-
__filter_function: PyLegendCallable[[
|
|
46
|
+
class LegacyApiFilterFunction(LegacyApiAppliedFunction):
|
|
47
|
+
__base_frame: LegacyApiBaseTdsFrame
|
|
48
|
+
__filter_function: PyLegendCallable[[LegacyApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]]
|
|
45
49
|
|
|
46
50
|
@classmethod
|
|
47
51
|
def name(cls) -> str:
|
|
@@ -49,8 +53,8 @@ class FilterFunction(LegendApiAppliedFunction):
|
|
|
49
53
|
|
|
50
54
|
def __init__(
|
|
51
55
|
self,
|
|
52
|
-
base_frame:
|
|
53
|
-
filter_function: PyLegendCallable[[
|
|
56
|
+
base_frame: LegacyApiBaseTdsFrame,
|
|
57
|
+
filter_function: PyLegendCallable[[LegacyApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]]
|
|
54
58
|
) -> None:
|
|
55
59
|
self.__base_frame = base_frame
|
|
56
60
|
self.__filter_function = filter_function
|
|
@@ -64,7 +68,7 @@ class FilterFunction(LegendApiAppliedFunction):
|
|
|
64
68
|
copy_query(base_query)
|
|
65
69
|
)
|
|
66
70
|
|
|
67
|
-
tds_row =
|
|
71
|
+
tds_row = LegacyApiTdsRow.from_tds_frame("frame", self.__base_frame)
|
|
68
72
|
filter_expr = self.__filter_function(tds_row)
|
|
69
73
|
if isinstance(filter_expr, bool):
|
|
70
74
|
filter_expr = PyLegendBoolean(PyLegendBooleanLiteralExpression(filter_expr))
|
|
@@ -80,17 +84,25 @@ class FilterFunction(LegendApiAppliedFunction):
|
|
|
80
84
|
|
|
81
85
|
return new_query
|
|
82
86
|
|
|
83
|
-
def
|
|
87
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
88
|
+
tds_row = LegacyApiTdsRow.from_tds_frame("r", self.__base_frame)
|
|
89
|
+
filter_expr = self.__filter_function(tds_row)
|
|
90
|
+
filter_expr_string = (filter_expr.to_pure_expression(config) if isinstance(filter_expr, PyLegendPrimitive) else
|
|
91
|
+
convert_literal_to_literal_expression(filter_expr).to_pure_expression(config))
|
|
92
|
+
return (f"{self.__base_frame.to_pure(config)}{config.separator(1)}" +
|
|
93
|
+
f"->filter({generate_pure_lambda('r', filter_expr_string)})")
|
|
94
|
+
|
|
95
|
+
def base_frame(self) -> LegacyApiBaseTdsFrame:
|
|
84
96
|
return self.__base_frame
|
|
85
97
|
|
|
86
|
-
def tds_frame_parameters(self) -> PyLegendList["
|
|
98
|
+
def tds_frame_parameters(self) -> PyLegendList["LegacyApiBaseTdsFrame"]:
|
|
87
99
|
return []
|
|
88
100
|
|
|
89
101
|
def calculate_columns(self) -> PyLegendSequence["TdsColumn"]:
|
|
90
102
|
return [c.copy() for c in self.__base_frame.columns()]
|
|
91
103
|
|
|
92
104
|
def validate(self) -> bool:
|
|
93
|
-
tds_row =
|
|
105
|
+
tds_row = LegacyApiTdsRow.from_tds_frame("frame", self.__base_frame)
|
|
94
106
|
|
|
95
107
|
copy = self.__filter_function # For MyPy
|
|
96
108
|
if not isinstance(copy, type(lambda x: 0)) or (copy.__code__.co_argcount != 1):
|