pylegend 0.3.0__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 +7 -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 +7 -1
- pylegend/core/request/auth.py +55 -1
- 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.3.0.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.3.0.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.3.0.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.3.0.dist-info → pylegend-0.4.0.dist-info}/LICENSE +0 -0
- {pylegend-0.3.0.dist-info → pylegend-0.4.0.dist-info}/LICENSE.spdx +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Copyright 2023 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
|
+
from pylegend._typing import (
|
|
17
|
+
PyLegendSequence,
|
|
18
|
+
)
|
|
19
|
+
from pylegend.core.tds.abstract.frames.applied_function_tds_frame import AppliedFunction, AppliedFunctionTdsFrame
|
|
20
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_base_tds_frame import LegacyApiBaseTdsFrame
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__: PyLegendSequence[str] = [
|
|
24
|
+
"LegacyApiAppliedFunctionTdsFrame",
|
|
25
|
+
"LegacyApiAppliedFunction",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class LegacyApiAppliedFunction(AppliedFunction, metaclass=ABCMeta):
|
|
30
|
+
@abstractmethod
|
|
31
|
+
def tds_frame_parameters(self) -> PyLegendSequence["LegacyApiBaseTdsFrame"]:
|
|
32
|
+
pass # pragma: no cover
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class LegacyApiAppliedFunctionTdsFrame(LegacyApiBaseTdsFrame, AppliedFunctionTdsFrame):
|
|
36
|
+
def __init__(self, applied_function: LegacyApiAppliedFunction):
|
|
37
|
+
AppliedFunctionTdsFrame.__init__(self, applied_function)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Copyright 2023 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
|
|
16
|
+
|
|
17
|
+
from pylegend._typing import (
|
|
18
|
+
PyLegendSequence,
|
|
19
|
+
PyLegendTypeVar,
|
|
20
|
+
PyLegendList,
|
|
21
|
+
PyLegendOptional,
|
|
22
|
+
PyLegendCallable,
|
|
23
|
+
PyLegendUnion,
|
|
24
|
+
)
|
|
25
|
+
from pylegend.core.language import (
|
|
26
|
+
LegacyApiTdsRow,
|
|
27
|
+
PyLegendBoolean,
|
|
28
|
+
PyLegendPrimitiveOrPythonPrimitive,
|
|
29
|
+
LegacyApiAggregateSpecification,
|
|
30
|
+
)
|
|
31
|
+
from pylegend.core.tds.abstract.frames.base_tds_frame import BaseTdsFrame
|
|
32
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_tds_frame import LegacyApiTdsFrame
|
|
33
|
+
from pylegend.core.tds.tds_column import TdsColumn
|
|
34
|
+
|
|
35
|
+
__all__: PyLegendSequence[str] = [
|
|
36
|
+
"LegacyApiBaseTdsFrame"
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
R = PyLegendTypeVar('R')
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class LegacyApiBaseTdsFrame(LegacyApiTdsFrame, BaseTdsFrame, metaclass=ABCMeta):
|
|
43
|
+
|
|
44
|
+
def __init__(self, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
45
|
+
BaseTdsFrame.__init__(self, columns=columns)
|
|
46
|
+
|
|
47
|
+
def head(self, row_count: int = 5) -> "LegacyApiTdsFrame":
|
|
48
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
49
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
50
|
+
)
|
|
51
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_head_function import (
|
|
52
|
+
LegacyApiHeadFunction
|
|
53
|
+
)
|
|
54
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiHeadFunction(self, row_count))
|
|
55
|
+
|
|
56
|
+
def take(self, row_count: int = 5) -> "LegacyApiTdsFrame":
|
|
57
|
+
return self.head(row_count=row_count)
|
|
58
|
+
|
|
59
|
+
def limit(self, row_count: int = 5) -> "LegacyApiTdsFrame":
|
|
60
|
+
return self.head(row_count=row_count)
|
|
61
|
+
|
|
62
|
+
def drop(self, row_count: int = 5) -> "LegacyApiTdsFrame":
|
|
63
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
64
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
65
|
+
)
|
|
66
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_drop_function import (
|
|
67
|
+
LegacyApiDropFunction
|
|
68
|
+
)
|
|
69
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiDropFunction(self, row_count))
|
|
70
|
+
|
|
71
|
+
def slice(self, start_row: int, end_row_exclusive: int) -> "LegacyApiTdsFrame":
|
|
72
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
73
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
74
|
+
)
|
|
75
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_slice_function import (
|
|
76
|
+
LegacyApiSliceFunction
|
|
77
|
+
)
|
|
78
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiSliceFunction(self, start_row, end_row_exclusive))
|
|
79
|
+
|
|
80
|
+
def distinct(self) -> "LegacyApiTdsFrame":
|
|
81
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
82
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
83
|
+
)
|
|
84
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_distinct_function import (
|
|
85
|
+
LegacyApiDistinctFunction
|
|
86
|
+
)
|
|
87
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiDistinctFunction(self))
|
|
88
|
+
|
|
89
|
+
def restrict(self, column_name_list: PyLegendList[str]) -> "LegacyApiTdsFrame":
|
|
90
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
91
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
92
|
+
)
|
|
93
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_restrict_function import (
|
|
94
|
+
LegacyApiRestrictFunction
|
|
95
|
+
)
|
|
96
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiRestrictFunction(self, column_name_list))
|
|
97
|
+
|
|
98
|
+
def sort(
|
|
99
|
+
self,
|
|
100
|
+
column_name_list: PyLegendList[str],
|
|
101
|
+
direction_list: PyLegendOptional[PyLegendList[str]] = None
|
|
102
|
+
) -> "LegacyApiTdsFrame":
|
|
103
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
104
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
105
|
+
)
|
|
106
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_sort_function import (
|
|
107
|
+
LegacyApiSortFunction
|
|
108
|
+
)
|
|
109
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiSortFunction(self, column_name_list, direction_list))
|
|
110
|
+
|
|
111
|
+
def concatenate(self, other: "LegacyApiTdsFrame") -> "LegacyApiTdsFrame":
|
|
112
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
113
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
114
|
+
)
|
|
115
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_concatenate_function import (
|
|
116
|
+
LegacyApiConcatenateFunction
|
|
117
|
+
)
|
|
118
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiConcatenateFunction(self, other))
|
|
119
|
+
|
|
120
|
+
def rename_columns(
|
|
121
|
+
self,
|
|
122
|
+
column_names: PyLegendList[str],
|
|
123
|
+
renamed_column_names: PyLegendList[str]
|
|
124
|
+
) -> "LegacyApiTdsFrame":
|
|
125
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
126
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
127
|
+
)
|
|
128
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_rename_columns_function import (
|
|
129
|
+
LegacyApiRenameColumnsFunction
|
|
130
|
+
)
|
|
131
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiRenameColumnsFunction(self, column_names, renamed_column_names))
|
|
132
|
+
|
|
133
|
+
def filter(
|
|
134
|
+
self,
|
|
135
|
+
filter_function: PyLegendCallable[[LegacyApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]]
|
|
136
|
+
) -> "LegacyApiTdsFrame":
|
|
137
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
138
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
139
|
+
)
|
|
140
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_filter_function import (
|
|
141
|
+
LegacyApiFilterFunction
|
|
142
|
+
)
|
|
143
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiFilterFunction(self, filter_function))
|
|
144
|
+
|
|
145
|
+
def extend(
|
|
146
|
+
self,
|
|
147
|
+
functions_list: PyLegendList[PyLegendCallable[[LegacyApiTdsRow], PyLegendPrimitiveOrPythonPrimitive]],
|
|
148
|
+
column_names_list: PyLegendList[str]
|
|
149
|
+
) -> "LegacyApiTdsFrame":
|
|
150
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
151
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
152
|
+
)
|
|
153
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_extend_function import (
|
|
154
|
+
LegacyApiExtendFunction
|
|
155
|
+
)
|
|
156
|
+
return LegacyApiAppliedFunctionTdsFrame(LegacyApiExtendFunction(self, functions_list, column_names_list))
|
|
157
|
+
|
|
158
|
+
def join(
|
|
159
|
+
self,
|
|
160
|
+
other: "LegacyApiTdsFrame",
|
|
161
|
+
join_condition: PyLegendCallable[[LegacyApiTdsRow, LegacyApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]],
|
|
162
|
+
join_type: str = 'LEFT_OUTER'
|
|
163
|
+
) -> "LegacyApiTdsFrame":
|
|
164
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
165
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
166
|
+
)
|
|
167
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_join_function import (
|
|
168
|
+
LegacyApiJoinFunction
|
|
169
|
+
)
|
|
170
|
+
return LegacyApiAppliedFunctionTdsFrame(
|
|
171
|
+
LegacyApiJoinFunction(self, other, join_condition, join_type)
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
def join_by_columns(
|
|
175
|
+
self,
|
|
176
|
+
other: "LegacyApiTdsFrame",
|
|
177
|
+
self_columns: PyLegendList[str],
|
|
178
|
+
other_columns: PyLegendList[str],
|
|
179
|
+
join_type: str = 'LEFT_OUTER'
|
|
180
|
+
) -> "LegacyApiTdsFrame":
|
|
181
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
182
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
183
|
+
)
|
|
184
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_join_by_columns_function import (
|
|
185
|
+
LegacyApiJoinByColumnsFunction
|
|
186
|
+
)
|
|
187
|
+
return LegacyApiAppliedFunctionTdsFrame(
|
|
188
|
+
LegacyApiJoinByColumnsFunction(self, other, self_columns, other_columns, join_type)
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
def group_by(
|
|
192
|
+
self,
|
|
193
|
+
grouping_columns: PyLegendList[str],
|
|
194
|
+
aggregations: PyLegendList[LegacyApiAggregateSpecification],
|
|
195
|
+
) -> "LegacyApiTdsFrame":
|
|
196
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_applied_function_tds_frame import (
|
|
197
|
+
LegacyApiAppliedFunctionTdsFrame
|
|
198
|
+
)
|
|
199
|
+
from pylegend.core.tds.legacy_api.frames.functions.legacy_api_group_by_function import (
|
|
200
|
+
LegacyApiGroupByFunction
|
|
201
|
+
)
|
|
202
|
+
return LegacyApiAppliedFunctionTdsFrame(
|
|
203
|
+
LegacyApiGroupByFunction(self, grouping_columns, aggregations)
|
|
204
|
+
)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Copyright 2023 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
|
|
16
|
+
from pylegend._typing import (
|
|
17
|
+
PyLegendSequence,
|
|
18
|
+
)
|
|
19
|
+
from pylegend.core.tds.abstract.frames.input_tds_frame import (
|
|
20
|
+
InputTdsFrame,
|
|
21
|
+
ExecutableInputTdsFrame,
|
|
22
|
+
NonExecutableInputTdsFrame,
|
|
23
|
+
)
|
|
24
|
+
from pylegend.core.tds.tds_column import TdsColumn
|
|
25
|
+
from pylegend.core.tds.legacy_api.frames.legacy_api_base_tds_frame import LegacyApiBaseTdsFrame
|
|
26
|
+
from pylegend.core.request.legend_client import LegendClient
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
__all__: PyLegendSequence[str] = [
|
|
30
|
+
"LegacyApiExecutableInputTdsFrame",
|
|
31
|
+
"LegacyApiNonExecutableInputTdsFrame",
|
|
32
|
+
"LegacyApiInputTdsFrame"
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class LegacyApiInputTdsFrame(LegacyApiBaseTdsFrame, InputTdsFrame, metaclass=ABCMeta):
|
|
37
|
+
def __init__(self, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
38
|
+
LegacyApiBaseTdsFrame.__init__(self, columns=columns)
|
|
39
|
+
InputTdsFrame.__init__(self, columns=columns)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class LegacyApiExecutableInputTdsFrame(LegacyApiInputTdsFrame, ExecutableInputTdsFrame, metaclass=ABCMeta):
|
|
43
|
+
def __init__(self, legend_client: LegendClient, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
44
|
+
LegacyApiInputTdsFrame.__init__(self, columns=columns)
|
|
45
|
+
ExecutableInputTdsFrame.__init__(self, legend_client=legend_client, columns=columns)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class LegacyApiNonExecutableInputTdsFrame(LegacyApiInputTdsFrame, NonExecutableInputTdsFrame, metaclass=ABCMeta):
|
|
49
|
+
def __init__(self, columns: PyLegendSequence[TdsColumn]) -> None:
|
|
50
|
+
LegacyApiInputTdsFrame.__init__(self, columns=columns)
|
|
51
|
+
NonExecutableInputTdsFrame.__init__(self, columns=columns)
|
|
@@ -24,45 +24,45 @@ from pylegend._typing import (
|
|
|
24
24
|
PyLegendUnion,
|
|
25
25
|
)
|
|
26
26
|
from pylegend.core.language import (
|
|
27
|
-
|
|
27
|
+
LegacyApiTdsRow,
|
|
28
28
|
PyLegendBoolean,
|
|
29
29
|
PyLegendPrimitiveOrPythonPrimitive,
|
|
30
|
-
|
|
30
|
+
LegacyApiAggregateSpecification,
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
__all__: PyLegendSequence[str] = [
|
|
34
|
-
"
|
|
34
|
+
"LegacyApiTdsFrame"
|
|
35
35
|
]
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class
|
|
38
|
+
class LegacyApiTdsFrame(PyLegendTdsFrame):
|
|
39
39
|
|
|
40
40
|
@abstractmethod
|
|
41
|
-
def head(self, count: int = 5) -> "
|
|
41
|
+
def head(self, count: int = 5) -> "LegacyApiTdsFrame":
|
|
42
42
|
pass # pragma: no cover
|
|
43
43
|
|
|
44
44
|
@abstractmethod
|
|
45
|
-
def take(self, count: int = 5) -> "
|
|
45
|
+
def take(self, count: int = 5) -> "LegacyApiTdsFrame":
|
|
46
46
|
pass # pragma: no cover
|
|
47
47
|
|
|
48
48
|
@abstractmethod
|
|
49
|
-
def limit(self, count: int = 5) -> "
|
|
49
|
+
def limit(self, count: int = 5) -> "LegacyApiTdsFrame":
|
|
50
50
|
pass # pragma: no cover
|
|
51
51
|
|
|
52
52
|
@abstractmethod
|
|
53
|
-
def drop(self, count: int = 5) -> "
|
|
53
|
+
def drop(self, count: int = 5) -> "LegacyApiTdsFrame":
|
|
54
54
|
pass # pragma: no cover
|
|
55
55
|
|
|
56
56
|
@abstractmethod
|
|
57
|
-
def slice(self, start_row: int, end_row_exclusive: int) -> "
|
|
57
|
+
def slice(self, start_row: int, end_row_exclusive: int) -> "LegacyApiTdsFrame":
|
|
58
58
|
pass # pragma: no cover
|
|
59
59
|
|
|
60
60
|
@abstractmethod
|
|
61
|
-
def distinct(self) -> "
|
|
61
|
+
def distinct(self) -> "LegacyApiTdsFrame":
|
|
62
62
|
pass # pragma: no cover
|
|
63
63
|
|
|
64
64
|
@abstractmethod
|
|
65
|
-
def restrict(self, column_name_list: PyLegendList[str]) -> "
|
|
65
|
+
def restrict(self, column_name_list: PyLegendList[str]) -> "LegacyApiTdsFrame":
|
|
66
66
|
pass # pragma: no cover
|
|
67
67
|
|
|
68
68
|
@abstractmethod
|
|
@@ -70,11 +70,11 @@ class LegendApiTdsFrame(PyLegendTdsFrame):
|
|
|
70
70
|
self,
|
|
71
71
|
column_name_list: PyLegendList[str],
|
|
72
72
|
direction_list: PyLegendOptional[PyLegendList[str]] = None
|
|
73
|
-
) -> "
|
|
73
|
+
) -> "LegacyApiTdsFrame":
|
|
74
74
|
pass # pragma: no cover
|
|
75
75
|
|
|
76
76
|
@abstractmethod
|
|
77
|
-
def concatenate(self, other: "
|
|
77
|
+
def concatenate(self, other: "LegacyApiTdsFrame") -> "LegacyApiTdsFrame":
|
|
78
78
|
pass # pragma: no cover
|
|
79
79
|
|
|
80
80
|
@abstractmethod
|
|
@@ -82,55 +82,55 @@ class LegendApiTdsFrame(PyLegendTdsFrame):
|
|
|
82
82
|
self,
|
|
83
83
|
column_names: PyLegendList[str],
|
|
84
84
|
renamed_column_names: PyLegendList[str]
|
|
85
|
-
) -> "
|
|
85
|
+
) -> "LegacyApiTdsFrame":
|
|
86
86
|
pass # pragma: no cover
|
|
87
87
|
|
|
88
88
|
@abstractmethod
|
|
89
89
|
def filter(
|
|
90
90
|
self,
|
|
91
|
-
filter_function: PyLegendCallable[[
|
|
92
|
-
) -> "
|
|
91
|
+
filter_function: PyLegendCallable[[LegacyApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]]
|
|
92
|
+
) -> "LegacyApiTdsFrame":
|
|
93
93
|
pass # pragma: no cover
|
|
94
94
|
|
|
95
95
|
@abstractmethod
|
|
96
96
|
def extend(
|
|
97
97
|
self,
|
|
98
|
-
functions_list: PyLegendList[PyLegendCallable[[
|
|
98
|
+
functions_list: PyLegendList[PyLegendCallable[[LegacyApiTdsRow], PyLegendPrimitiveOrPythonPrimitive]],
|
|
99
99
|
column_names_list: PyLegendList[str]
|
|
100
|
-
) -> "
|
|
100
|
+
) -> "LegacyApiTdsFrame":
|
|
101
101
|
pass # pragma: no cover
|
|
102
102
|
|
|
103
103
|
@abstractmethod
|
|
104
104
|
def join(
|
|
105
105
|
self,
|
|
106
|
-
other: "
|
|
107
|
-
join_condition: PyLegendCallable[[
|
|
106
|
+
other: "LegacyApiTdsFrame",
|
|
107
|
+
join_condition: PyLegendCallable[[LegacyApiTdsRow, LegacyApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]],
|
|
108
108
|
join_type: str = 'LEFT_OUTER'
|
|
109
|
-
) -> "
|
|
109
|
+
) -> "LegacyApiTdsFrame":
|
|
110
110
|
pass # pragma: no cover
|
|
111
111
|
|
|
112
112
|
@abstractmethod
|
|
113
113
|
def join_by_columns(
|
|
114
114
|
self,
|
|
115
|
-
other: "
|
|
115
|
+
other: "LegacyApiTdsFrame",
|
|
116
116
|
self_columns: PyLegendList[str],
|
|
117
117
|
other_columns: PyLegendList[str],
|
|
118
118
|
join_type: str = 'LEFT_OUTER'
|
|
119
|
-
) -> "
|
|
119
|
+
) -> "LegacyApiTdsFrame":
|
|
120
120
|
pass # pragma: no cover
|
|
121
121
|
|
|
122
122
|
def join_by_function(
|
|
123
123
|
self,
|
|
124
|
-
other: "
|
|
125
|
-
join_condition: PyLegendCallable[[
|
|
124
|
+
other: "LegacyApiTdsFrame",
|
|
125
|
+
join_condition: PyLegendCallable[[LegacyApiTdsRow, LegacyApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]],
|
|
126
126
|
join_type: str = 'LEFT_OUTER'
|
|
127
|
-
) -> "
|
|
127
|
+
) -> "LegacyApiTdsFrame":
|
|
128
128
|
return self.join(other, join_condition, join_type)
|
|
129
129
|
|
|
130
130
|
@abstractmethod
|
|
131
131
|
def group_by(
|
|
132
132
|
self,
|
|
133
133
|
grouping_columns: PyLegendList[str],
|
|
134
|
-
aggregations: PyLegendList[
|
|
135
|
-
) -> "
|
|
134
|
+
aggregations: PyLegendList[LegacyApiAggregateSpecification],
|
|
135
|
+
) -> "LegacyApiTdsFrame":
|
|
136
136
|
pass # pragma: no cover
|
|
@@ -0,0 +1,13 @@
|
|
|
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.
|
|
@@ -0,0 +1,13 @@
|
|
|
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.
|
|
@@ -0,0 +1,13 @@
|
|
|
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.
|
|
@@ -0,0 +1,156 @@
|
|
|
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 pylegend._typing import (
|
|
16
|
+
PyLegendList,
|
|
17
|
+
PyLegendSequence,
|
|
18
|
+
PyLegendUnion,
|
|
19
|
+
PyLegendCallable,
|
|
20
|
+
PyLegendOptional,
|
|
21
|
+
)
|
|
22
|
+
from pylegend.core.language import (
|
|
23
|
+
PyLegendBoolean,
|
|
24
|
+
PyLegendPrimitive,
|
|
25
|
+
convert_literal_to_literal_expression,
|
|
26
|
+
)
|
|
27
|
+
from pylegend.core.language.legendql_api.legendql_api_tds_row import LegendQLApiTdsRow
|
|
28
|
+
from pylegend.core.language.shared.helpers import generate_pure_lambda
|
|
29
|
+
from pylegend.core.sql.metamodel import (
|
|
30
|
+
QuerySpecification,
|
|
31
|
+
)
|
|
32
|
+
from pylegend.core.tds.legendql_api.frames.legendql_api_applied_function_tds_frame import LegendQLApiAppliedFunction
|
|
33
|
+
from pylegend.core.tds.legendql_api.frames.legendql_api_base_tds_frame import LegendQLApiBaseTdsFrame
|
|
34
|
+
from pylegend.core.tds.legendql_api.frames.legendql_api_tds_frame import LegendQLApiTdsFrame
|
|
35
|
+
from pylegend.core.tds.tds_column import TdsColumn
|
|
36
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
37
|
+
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
38
|
+
|
|
39
|
+
__all__: PyLegendSequence[str] = [
|
|
40
|
+
"LegendQLApiAsOfJoinFunction"
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class LegendQLApiAsOfJoinFunction(LegendQLApiAppliedFunction):
|
|
45
|
+
__base_frame: LegendQLApiBaseTdsFrame
|
|
46
|
+
__other_frame: LegendQLApiBaseTdsFrame
|
|
47
|
+
__match_function: PyLegendCallable[[LegendQLApiTdsRow, LegendQLApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]]
|
|
48
|
+
__join_condition: PyLegendOptional[
|
|
49
|
+
PyLegendCallable[[LegendQLApiTdsRow, LegendQLApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]]
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def name(cls) -> str:
|
|
54
|
+
return "asOfJoin"
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
base_frame: LegendQLApiBaseTdsFrame,
|
|
59
|
+
other_frame: LegendQLApiTdsFrame,
|
|
60
|
+
match_function: PyLegendCallable[[LegendQLApiTdsRow, LegendQLApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]],
|
|
61
|
+
join_condition: PyLegendOptional[
|
|
62
|
+
PyLegendCallable[[LegendQLApiTdsRow, LegendQLApiTdsRow], PyLegendUnion[bool, PyLegendBoolean]]
|
|
63
|
+
] = None
|
|
64
|
+
) -> None:
|
|
65
|
+
self.__base_frame = base_frame
|
|
66
|
+
if not isinstance(other_frame, LegendQLApiBaseTdsFrame):
|
|
67
|
+
raise ValueError("Expected LegendQLApiBaseTdsFrame") # pragma: no cover
|
|
68
|
+
self.__other_frame = other_frame
|
|
69
|
+
self.__match_function = match_function
|
|
70
|
+
self.__join_condition = join_condition
|
|
71
|
+
|
|
72
|
+
def to_sql(self, config: FrameToSqlConfig) -> QuerySpecification:
|
|
73
|
+
raise RuntimeError("AsOfJoin SQL translation not supported yet")
|
|
74
|
+
|
|
75
|
+
def to_pure(self, config: FrameToPureConfig) -> str:
|
|
76
|
+
left_row = LegendQLApiTdsRow.from_tds_frame("l", self.__base_frame)
|
|
77
|
+
right_row = LegendQLApiTdsRow.from_tds_frame("r", self.__other_frame)
|
|
78
|
+
match_expr = self.__match_function(left_row, right_row)
|
|
79
|
+
match_string = (match_expr.to_pure_expression(config.push_indent(2))
|
|
80
|
+
if isinstance(match_expr, PyLegendPrimitive) else
|
|
81
|
+
convert_literal_to_literal_expression(match_expr).to_pure_expression(config.push_indent(2)))
|
|
82
|
+
if self.__join_condition is not None:
|
|
83
|
+
join_expr = self.__join_condition(left_row, right_row)
|
|
84
|
+
join_string = (join_expr.to_pure_expression(config.push_indent(2))
|
|
85
|
+
if isinstance(join_expr, PyLegendPrimitive) else
|
|
86
|
+
convert_literal_to_literal_expression(join_expr).to_pure_expression(config.push_indent(2)))
|
|
87
|
+
join_arg = (
|
|
88
|
+
f",{config.separator(2, True)}"
|
|
89
|
+
f"{generate_pure_lambda('l, r', join_string)}{config.separator(1)}"
|
|
90
|
+
)
|
|
91
|
+
else:
|
|
92
|
+
join_arg = f"{config.separator(1)}"
|
|
93
|
+
|
|
94
|
+
return (f"{self.__base_frame.to_pure(config)}{config.separator(1)}" +
|
|
95
|
+
f"->asOfJoin({config.separator(2)}"
|
|
96
|
+
f"{self.__other_frame.to_pure(config.push_indent(2))},{config.separator(2, True)}"
|
|
97
|
+
f"{generate_pure_lambda('l, r', match_string)}"
|
|
98
|
+
f"{join_arg}"
|
|
99
|
+
f")")
|
|
100
|
+
|
|
101
|
+
def base_frame(self) -> LegendQLApiBaseTdsFrame:
|
|
102
|
+
return self.__base_frame
|
|
103
|
+
|
|
104
|
+
def tds_frame_parameters(self) -> PyLegendList["LegendQLApiBaseTdsFrame"]:
|
|
105
|
+
return [self.__other_frame]
|
|
106
|
+
|
|
107
|
+
def calculate_columns(self) -> PyLegendSequence["TdsColumn"]:
|
|
108
|
+
return (
|
|
109
|
+
[c.copy() for c in self.__base_frame.columns()] +
|
|
110
|
+
[c.copy() for c in self.__other_frame.columns()]
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def validate(self) -> bool:
|
|
114
|
+
copy = self.__match_function # For MyPy
|
|
115
|
+
if not isinstance(copy, type(lambda x: 0)) or (copy.__code__.co_argcount != 2):
|
|
116
|
+
raise TypeError("AsOfJoin match function should be a lambda which takes two arguments (TDSRow, TDSRow)")
|
|
117
|
+
|
|
118
|
+
left_row = LegendQLApiTdsRow.from_tds_frame("left", self.__base_frame)
|
|
119
|
+
right_row = LegendQLApiTdsRow.from_tds_frame("right", self.__other_frame)
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
result = self.__match_function(left_row, right_row)
|
|
123
|
+
except Exception as e:
|
|
124
|
+
raise RuntimeError(
|
|
125
|
+
"AsOfJoin match function incompatible. Error occurred while evaluating. Message: " + str(e)
|
|
126
|
+
) from e
|
|
127
|
+
|
|
128
|
+
if not isinstance(result, (bool, PyLegendBoolean)):
|
|
129
|
+
raise RuntimeError("AsOfJoin match function incompatible. Returns non boolean - " + str(type(result)))
|
|
130
|
+
|
|
131
|
+
if self.__join_condition is not None:
|
|
132
|
+
copy = self.__join_condition # For MyPy
|
|
133
|
+
if not isinstance(copy, type(lambda x: 0)) or (copy.__code__.co_argcount != 2):
|
|
134
|
+
raise TypeError("AsOfJoin join function should be a lambda which takes two arguments (TDSRow, TDSRow)")
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
result = self.__join_condition(left_row, right_row)
|
|
138
|
+
except Exception as e:
|
|
139
|
+
raise RuntimeError(
|
|
140
|
+
"AsOfJoin join function incompatible. Error occurred while evaluating. Message: " + str(e)
|
|
141
|
+
) from e
|
|
142
|
+
|
|
143
|
+
if not isinstance(result, (bool, PyLegendBoolean)):
|
|
144
|
+
raise RuntimeError("AsOfJoin join function incompatible. Returns non boolean - " + str(type(result)))
|
|
145
|
+
|
|
146
|
+
left_cols = [c.get_name() for c in self.__base_frame.columns()]
|
|
147
|
+
right_cols = [c.get_name() for c in self.__other_frame.columns()]
|
|
148
|
+
|
|
149
|
+
final_cols = left_cols + right_cols
|
|
150
|
+
if len(final_cols) != len(set(final_cols)):
|
|
151
|
+
raise ValueError(
|
|
152
|
+
"Found duplicate columns in joined frames. Use rename function to ensure there are no duplicate columns "
|
|
153
|
+
f"in joined frames. Columns - Left Frame: {left_cols}, Right Frame: {right_cols}"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
return True
|