pylegend 0.12.0__tar.gz → 0.13.0__tar.gz
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-0.12.0 → pylegend-0.13.0}/PKG-INFO +1 -1
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/database/sql_to_string/db_extension.py +177 -1
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/expression.py +5 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/literal_expressions.py +22 -1
- pylegend-0.13.0/pylegend/core/language/shared/operations/boolean_operation_expressions.py +268 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/date_operation_expressions.py +91 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/integer_operation_expressions.py +183 -1
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/string_operation_expressions.py +31 -1
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/boolean.py +40 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/date.py +39 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/datetime.py +18 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/integer.py +54 -1
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/strictdate.py +25 -1
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/string.py +16 -2
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/sql/metamodel.py +50 -1
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/sql/metamodel_extension.py +77 -1
- pylegend-0.13.0/pylegend/core/tds/pandas_api/frames/functions/iloc.py +99 -0
- pylegend-0.13.0/pylegend/core/tds/pandas_api/frames/functions/loc.py +136 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/pandas_api_base_tds_frame.py +40 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/pandas_api_tds_frame.py +12 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pyproject.toml +1 -1
- pylegend-0.12.0/pylegend/core/language/shared/operations/boolean_operation_expressions.py +0 -124
- {pylegend-0.12.0 → pylegend-0.13.0}/LICENSE +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/LICENSE.spdx +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/NOTICE +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/README.md +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/_typing.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/database/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/database/sql_to_string/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/database/sql_to_string/config.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/database/sql_to_string/generator.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/legacy_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/legacy_api/aggregate_specification.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/legacy_api/legacy_api_tds_row.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/legendql_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/legendql_api/legendql_api_custom_expressions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/legendql_api/legendql_api_tds_row.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/pandas_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/pandas_api/pandas_api_aggregate_specification.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/pandas_api/pandas_api_custom_expressions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/pandas_api/pandas_api_series.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/pandas_api/pandas_api_tds_row.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/column_expressions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/functions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/helpers.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/binary_expression.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/collection_operation_expressions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/float_operation_expressions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/nary_expression.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/nullary_expression.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/number_operation_expressions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/primitive_operation_expressions.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/operations/unary_expression.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/pct_helpers.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitive_collection.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/float.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/number.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/primitives/primitive.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/language/shared/tds_row.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/project_cooridnates.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/request/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/request/auth.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/request/legend_client.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/request/response_reader.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/request/service_client.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/sql/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/abstract/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/abstract/frames/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/abstract/frames/applied_function_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/abstract/frames/base_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/abstract/frames/input_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/abstract/function_helpers.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_concatenate_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_distinct_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_drop_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_extend_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_filter_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_group_by_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_head_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_join_by_columns_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_join_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_rename_columns_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_restrict_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_slice_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_sort_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/legacy_api_applied_function_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/legacy_api_base_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/legacy_api_input_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legacy_api/frames/legacy_api_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_asofjoin_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_concatenate_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_distinct_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_drop_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_extend_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_filter_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_function_helpers.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_groupby_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_head_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_join_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_project_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_rename_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_select_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_slice_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_sort_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_window_extend_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/legendql_api_applied_function_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/legendql_api_base_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/legendql_api_input_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/legendql_api/frames/legendql_api_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/aggregate_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/assign_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/drop.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/dropna.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/fillna.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/filter.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/filtering.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/merge.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/rename.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/sort_values_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/functions/truncate_function.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/pandas_api_applied_function_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/pandas_api_groupby_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/pandas_api/frames/pandas_api_input_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/result_handler/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/result_handler/result_handler.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/result_handler/to_csv_file_result_handler.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/result_handler/to_json_file_result_handler.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/result_handler/to_string_result_handler.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/sql_query_helpers.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/tds_column.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/core/tds/tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/database/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/database/vendors/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/database/vendors/postgres/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/database/vendors/postgres/postgres_sql_to_string.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/abstract/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/abstract/csv_tds_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/abstract/legend_function_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/abstract/legend_service_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/abstract/table_spec_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legacy_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legacy_api/frames/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legacy_api/frames/legacy_api_legend_function_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legacy_api/frames/legacy_api_legend_service_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legacy_api/frames/legacy_api_table_spec_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legendql_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legendql_api/frames/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_csv_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_legend_function_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_legend_service_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_table_spec_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/pandas_api/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/pandas_api/frames/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_function_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_service_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/pandas_api/frames/pandas_api_table_spec_input_frame.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/result_handler/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/extensions/tds/result_handler/to_pandas_df_result_handler.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/legacy_api_tds_client.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/legendql_api_tds_client.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/utils/__init__.py +0 -0
- {pylegend-0.12.0 → pylegend-0.13.0}/pylegend/utils/class_utils.py +0 -0
|
@@ -75,7 +75,11 @@ from pylegend.core.sql.metamodel import (
|
|
|
75
75
|
WindowFrame,
|
|
76
76
|
WindowFrameMode,
|
|
77
77
|
FrameBound,
|
|
78
|
-
FrameBoundType
|
|
78
|
+
FrameBoundType,
|
|
79
|
+
BitwiseShiftExpression,
|
|
80
|
+
BitwiseShiftDirection,
|
|
81
|
+
BitwiseBinaryExpression,
|
|
82
|
+
BitwiseBinaryOperator
|
|
79
83
|
)
|
|
80
84
|
from pylegend.core.sql.metamodel_extension import (
|
|
81
85
|
StringLengthExpression,
|
|
@@ -137,6 +141,11 @@ from pylegend.core.sql.metamodel_extension import (
|
|
|
137
141
|
WindowExpression,
|
|
138
142
|
ConstantExpression,
|
|
139
143
|
StringSubStringExpression,
|
|
144
|
+
DateAdjustExpression,
|
|
145
|
+
BitwiseNotExpression,
|
|
146
|
+
DateDiffExpression,
|
|
147
|
+
DateTimeBucketExpression,
|
|
148
|
+
DateType,
|
|
140
149
|
)
|
|
141
150
|
|
|
142
151
|
__all__: PyLegendSequence[str] = [
|
|
@@ -460,6 +469,18 @@ def expression_processor(
|
|
|
460
469
|
return expression.name
|
|
461
470
|
elif isinstance(expression, StringSubStringExpression):
|
|
462
471
|
return extension.process_string_substring_expression(expression, config)
|
|
472
|
+
elif isinstance(expression, DateAdjustExpression):
|
|
473
|
+
return extension.process_date_adjust_expression(expression, config)
|
|
474
|
+
elif isinstance(expression, DateDiffExpression):
|
|
475
|
+
return extension.process_date_diff_expression(expression, config)
|
|
476
|
+
elif isinstance(expression, DateTimeBucketExpression):
|
|
477
|
+
return extension.process_date_time_bucket_expression(expression, config)
|
|
478
|
+
elif isinstance(expression, BitwiseNotExpression):
|
|
479
|
+
return extension.process_bitwise_not_expression(expression, config)
|
|
480
|
+
elif isinstance(expression, BitwiseShiftExpression):
|
|
481
|
+
return extension.process_bitwise_shift_expression(expression, config)
|
|
482
|
+
elif isinstance(expression, BitwiseBinaryExpression):
|
|
483
|
+
return extension.process_bitwise_binary_expression(expression, config)
|
|
463
484
|
|
|
464
485
|
else:
|
|
465
486
|
raise ValueError("Unsupported expression type: " + str(type(expression))) # pragma: no cover
|
|
@@ -520,6 +541,139 @@ def logical_binary_expression_processor(
|
|
|
520
541
|
return f"({left} {op} {right})"
|
|
521
542
|
|
|
522
543
|
|
|
544
|
+
def bitwise_binary_expression_processor(
|
|
545
|
+
bitwise: BitwiseBinaryExpression,
|
|
546
|
+
extension: "SqlToStringDbExtension",
|
|
547
|
+
config: SqlToStringConfig
|
|
548
|
+
) -> str:
|
|
549
|
+
op_type = bitwise.operator
|
|
550
|
+
if op_type == BitwiseBinaryOperator.AND:
|
|
551
|
+
op = "&"
|
|
552
|
+
elif op_type == BitwiseBinaryOperator.OR:
|
|
553
|
+
op = "|"
|
|
554
|
+
elif op_type == BitwiseBinaryOperator.XOR:
|
|
555
|
+
op = "#"
|
|
556
|
+
else:
|
|
557
|
+
raise ValueError("Unknown bitwise binary operator type: " + str(op_type)) # pragma: no cover
|
|
558
|
+
|
|
559
|
+
left = extension.process_expression(bitwise.left, config)
|
|
560
|
+
right = extension.process_expression(bitwise.right, config)
|
|
561
|
+
return f"({left} {op} {right})"
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
def date_diff_processor(
|
|
565
|
+
date_diff: DateDiffExpression,
|
|
566
|
+
extension: "SqlToStringDbExtension",
|
|
567
|
+
config: SqlToStringConfig
|
|
568
|
+
) -> str:
|
|
569
|
+
unit = date_diff.duration_unit.value
|
|
570
|
+
|
|
571
|
+
end = extension.process_expression(date_diff.end_date, config)
|
|
572
|
+
start = extension.process_expression(date_diff.start_date, config)
|
|
573
|
+
|
|
574
|
+
def extract_diff(part: str) -> str:
|
|
575
|
+
return f"(EXTRACT({part} FROM {end}) - EXTRACT({part} FROM {start}))"
|
|
576
|
+
|
|
577
|
+
year_diff = extract_diff("YEAR")
|
|
578
|
+
month_diff = extract_diff("MONTH")
|
|
579
|
+
# d1 - d2 → Pure dateDiff(d1, d2) → evaluated as d2 - d1
|
|
580
|
+
# Reverse to preserve expected semantics.
|
|
581
|
+
# only for days
|
|
582
|
+
day_diff = f"CAST(CAST({start} AS DATE) - CAST({end} AS DATE) AS INTEGER)"
|
|
583
|
+
epoch_diff = f"(EXTRACT(EPOCH FROM {end}) - EXTRACT(EPOCH FROM {start}))"
|
|
584
|
+
|
|
585
|
+
if unit == "YEARS":
|
|
586
|
+
return year_diff
|
|
587
|
+
|
|
588
|
+
if unit == "MONTHS":
|
|
589
|
+
return f"({year_diff} * 12 + {month_diff})"
|
|
590
|
+
|
|
591
|
+
if unit == "DAYS":
|
|
592
|
+
return day_diff
|
|
593
|
+
|
|
594
|
+
if unit == "WEEKS":
|
|
595
|
+
return f"CAST(FLOOR({day_diff} / 7) AS INTEGER)"
|
|
596
|
+
|
|
597
|
+
if unit == "HOURS":
|
|
598
|
+
return f"CAST(FLOOR({epoch_diff} / 3600) AS INTEGER)"
|
|
599
|
+
|
|
600
|
+
if unit == "MINUTES":
|
|
601
|
+
return f"CAST(FLOOR({epoch_diff} / 60) AS INTEGER)"
|
|
602
|
+
|
|
603
|
+
if unit == "SECONDS":
|
|
604
|
+
return f"CAST({epoch_diff} AS BIGINT)"
|
|
605
|
+
|
|
606
|
+
if unit == "MILLISECONDS":
|
|
607
|
+
return f"CAST({epoch_diff} * 1000 AS BIGINT)"
|
|
608
|
+
|
|
609
|
+
raise ValueError(f"Unsupported DATE DIFF unit: {unit}") # pragma: no cover
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
def date_time_bucket_processor(
|
|
613
|
+
expression: DateTimeBucketExpression,
|
|
614
|
+
extension: "SqlToStringDbExtension",
|
|
615
|
+
config: SqlToStringConfig
|
|
616
|
+
) -> str:
|
|
617
|
+
unit = expression.duration_unit.value
|
|
618
|
+
ts = extension.process_expression(expression.date, config)
|
|
619
|
+
q = extension.process_expression(expression.quantity, config)
|
|
620
|
+
|
|
621
|
+
def coerce_to_datetime(sql: str) -> str:
|
|
622
|
+
return (
|
|
623
|
+
f"(({sql}) + INTERVAL '0 second')"
|
|
624
|
+
if expression.date_type == DateType.DateTime
|
|
625
|
+
else sql
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
def epoch() -> str:
|
|
629
|
+
return (
|
|
630
|
+
f"EXTRACT(EPOCH FROM {ts})"
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
if unit == "YEARS":
|
|
634
|
+
return coerce_to_datetime(
|
|
635
|
+
f"make_date(1970,1,1) + "
|
|
636
|
+
f"(FLOOR((EXTRACT(YEAR FROM {ts}) - 1970) / {q}) * {q}) * INTERVAL '1 year'"
|
|
637
|
+
)
|
|
638
|
+
|
|
639
|
+
if unit == "MONTHS":
|
|
640
|
+
total_months_sql = f"((EXTRACT(YEAR FROM {ts}) - 1970) * 12 + (EXTRACT(MONTH FROM {ts}) - 1))"
|
|
641
|
+
return coerce_to_datetime(
|
|
642
|
+
f"make_date(1970,1,1) + "
|
|
643
|
+
f"(FLOOR({total_months_sql} / {q}) * {q}) * INTERVAL '1 month'"
|
|
644
|
+
)
|
|
645
|
+
|
|
646
|
+
if unit == "WEEKS":
|
|
647
|
+
return coerce_to_datetime(
|
|
648
|
+
f"make_date(1969,12,29) + ("
|
|
649
|
+
f"FLOOR(("
|
|
650
|
+
f"{epoch()} - EXTRACT(EPOCH FROM make_date(1969,12,29))"
|
|
651
|
+
f") / (86400 * {q} * 7))"
|
|
652
|
+
f") * ({q} * 7) * INTERVAL '1 day'"
|
|
653
|
+
)
|
|
654
|
+
|
|
655
|
+
if unit == "DAYS":
|
|
656
|
+
days_from_1970 = f"({epoch()} / 86400)"
|
|
657
|
+
return coerce_to_datetime(
|
|
658
|
+
f"make_date(1970,1,1) + "
|
|
659
|
+
f"(FLOOR({days_from_1970} / {q}) * {q}) * INTERVAL '1 day'"
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
unit_seconds_map = {
|
|
663
|
+
"HOURS": 3600,
|
|
664
|
+
"MINUTES": 60,
|
|
665
|
+
"SECONDS": 1
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
if unit in unit_seconds_map:
|
|
669
|
+
seconds_per_unit = unit_seconds_map[unit]
|
|
670
|
+
return (f"(make_date(1970,1,1) + "
|
|
671
|
+
f"(FLOOR({epoch()} / ({q} * {seconds_per_unit})) * ({q} * {seconds_per_unit})) "
|
|
672
|
+
f"* INTERVAL '1 second')")
|
|
673
|
+
|
|
674
|
+
raise ValueError(f"Unsupported TIME BUCKET unit: {unit}") # pragma: no cover
|
|
675
|
+
|
|
676
|
+
|
|
523
677
|
def not_expression_processor(
|
|
524
678
|
not_expression: NotExpression,
|
|
525
679
|
extension: "SqlToStringDbExtension",
|
|
@@ -1322,3 +1476,25 @@ class SqlToStringDbExtension:
|
|
|
1322
1476
|
|
|
1323
1477
|
def process_frame_bound(self, frame_bound: FrameBound, config: SqlToStringConfig) -> str:
|
|
1324
1478
|
return frame_bound_processor(frame_bound, self, config)
|
|
1479
|
+
|
|
1480
|
+
def process_date_adjust_expression(self, expr: DateAdjustExpression, config: SqlToStringConfig) -> str:
|
|
1481
|
+
return (f"({self.process_expression(expr.date, config)}::DATE + "
|
|
1482
|
+
f"(INTERVAL '{self.process_expression(expr.number, config)} "
|
|
1483
|
+
f"{expr.duration_unit.value.upper()}'))::DATE")
|
|
1484
|
+
|
|
1485
|
+
def process_bitwise_not_expression(self, expr: BitwiseNotExpression, config: SqlToStringConfig) -> str:
|
|
1486
|
+
return f"~({self.process_expression(expr.value, config)})"
|
|
1487
|
+
|
|
1488
|
+
def process_bitwise_shift_expression(self, expr: BitwiseShiftExpression, config: SqlToStringConfig) -> str:
|
|
1489
|
+
return (f"({self.process_expression(expr.value, config)} "
|
|
1490
|
+
f"{'>>' if expr.direction == BitwiseShiftDirection.RIGHT else '<<'} "
|
|
1491
|
+
f"{self.process_expression(expr.shift, config)})")
|
|
1492
|
+
|
|
1493
|
+
def process_bitwise_binary_expression(self, expr: BitwiseBinaryExpression, config: SqlToStringConfig) -> str:
|
|
1494
|
+
return bitwise_binary_expression_processor(expr, self, config)
|
|
1495
|
+
|
|
1496
|
+
def process_date_diff_expression(self, expr: DateDiffExpression, config: SqlToStringConfig) -> str:
|
|
1497
|
+
return date_diff_processor(expr, self, config)
|
|
1498
|
+
|
|
1499
|
+
def process_date_time_bucket_expression(self, expr: DateTimeBucketExpression, config: SqlToStringConfig) -> str:
|
|
1500
|
+
return date_time_bucket_processor(expr, self, config)
|
|
@@ -36,6 +36,7 @@ __all__: PyLegendSequence[str] = [
|
|
|
36
36
|
"PyLegendExpressionDateReturn",
|
|
37
37
|
"PyLegendExpressionDateTimeReturn",
|
|
38
38
|
"PyLegendExpressionStrictDateReturn",
|
|
39
|
+
"PyLegendExpressionNullReturn"
|
|
39
40
|
]
|
|
40
41
|
|
|
41
42
|
|
|
@@ -86,3 +87,7 @@ class PyLegendExpressionDateTimeReturn(PyLegendExpressionDateReturn, metaclass=A
|
|
|
86
87
|
|
|
87
88
|
class PyLegendExpressionStrictDateReturn(PyLegendExpressionDateReturn, metaclass=ABCMeta):
|
|
88
89
|
pass
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class PyLegendExpressionNullReturn(PyLegendExpression, metaclass=ABCMeta):
|
|
93
|
+
pass
|
|
@@ -27,6 +27,7 @@ from pylegend.core.language.shared.expression import (
|
|
|
27
27
|
PyLegendExpressionFloatReturn,
|
|
28
28
|
PyLegendExpressionDateTimeReturn,
|
|
29
29
|
PyLegendExpressionStrictDateReturn,
|
|
30
|
+
PyLegendExpressionNullReturn,
|
|
30
31
|
)
|
|
31
32
|
from pylegend.core.sql.metamodel import (
|
|
32
33
|
Expression,
|
|
@@ -37,6 +38,7 @@ from pylegend.core.sql.metamodel import (
|
|
|
37
38
|
QuerySpecification,
|
|
38
39
|
Cast,
|
|
39
40
|
ColumnType,
|
|
41
|
+
NullLiteral,
|
|
40
42
|
)
|
|
41
43
|
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
42
44
|
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
@@ -180,8 +182,25 @@ class PyLegendStrictDateLiteralExpression(PyLegendExpressionStrictDateReturn):
|
|
|
180
182
|
return True
|
|
181
183
|
|
|
182
184
|
|
|
185
|
+
class PyLegendNullLiteralExpression(PyLegendExpressionNullReturn):
|
|
186
|
+
__value: None
|
|
187
|
+
|
|
188
|
+
def __init__(self) -> None:
|
|
189
|
+
return
|
|
190
|
+
|
|
191
|
+
def to_sql_expression(
|
|
192
|
+
self,
|
|
193
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
194
|
+
config: FrameToSqlConfig
|
|
195
|
+
) -> Expression:
|
|
196
|
+
return NullLiteral()
|
|
197
|
+
|
|
198
|
+
def to_pure_expression(self, config: FrameToPureConfig) -> str:
|
|
199
|
+
return "[]"
|
|
200
|
+
|
|
201
|
+
|
|
183
202
|
def convert_literal_to_literal_expression(
|
|
184
|
-
literal: PyLegendUnion[int, float, bool, str, datetime, date]
|
|
203
|
+
literal: PyLegendUnion[int, float, bool, str, datetime, date, None]
|
|
185
204
|
) -> PyLegendExpression:
|
|
186
205
|
if isinstance(literal, bool):
|
|
187
206
|
return PyLegendBooleanLiteralExpression(literal)
|
|
@@ -195,5 +214,7 @@ def convert_literal_to_literal_expression(
|
|
|
195
214
|
return PyLegendDateTimeLiteralExpression(literal)
|
|
196
215
|
if isinstance(literal, date):
|
|
197
216
|
return PyLegendStrictDateLiteralExpression(literal)
|
|
217
|
+
if isinstance(literal, type(None)):
|
|
218
|
+
return PyLegendNullLiteralExpression()
|
|
198
219
|
|
|
199
220
|
raise TypeError(f"Cannot convert value - {literal} of type {type(literal)} to literal expression")
|
|
@@ -0,0 +1,268 @@
|
|
|
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 pylegend._typing import (
|
|
16
|
+
PyLegendSequence,
|
|
17
|
+
PyLegendDict,
|
|
18
|
+
)
|
|
19
|
+
from pylegend.core.language.shared.expression import (
|
|
20
|
+
PyLegendExpressionBooleanReturn,
|
|
21
|
+
)
|
|
22
|
+
from pylegend.core.language.shared.helpers import generate_pure_functional_call
|
|
23
|
+
from pylegend.core.language.shared.operations.binary_expression import PyLegendBinaryExpression
|
|
24
|
+
from pylegend.core.language.shared.operations.unary_expression import PyLegendUnaryExpression
|
|
25
|
+
from pylegend.core.sql.metamodel import (
|
|
26
|
+
Expression,
|
|
27
|
+
QuerySpecification,
|
|
28
|
+
LogicalBinaryExpression,
|
|
29
|
+
LogicalBinaryType,
|
|
30
|
+
NotExpression,
|
|
31
|
+
ComparisonExpression,
|
|
32
|
+
ComparisonOperator,
|
|
33
|
+
)
|
|
34
|
+
from pylegend.core.tds.tds_frame import FrameToSqlConfig
|
|
35
|
+
from pylegend.core.tds.tds_frame import FrameToPureConfig
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
__all__: PyLegendSequence[str] = [
|
|
39
|
+
"PyLegendBooleanOrExpression",
|
|
40
|
+
"PyLegendBooleanAndExpression",
|
|
41
|
+
"PyLegendBooleanNotExpression",
|
|
42
|
+
"PyLegendBooleanLessThanExpression",
|
|
43
|
+
"PyLegendBooleanLessThanEqualExpression",
|
|
44
|
+
"PyLegendBooleanGreaterThanExpression",
|
|
45
|
+
"PyLegendBooleanGreaterThanEqualExpression",
|
|
46
|
+
"PyLegendBooleanXorExpression"
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class PyLegendBooleanOrExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def __to_sql_func(
|
|
54
|
+
expression1: Expression,
|
|
55
|
+
expression2: Expression,
|
|
56
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
57
|
+
config: FrameToSqlConfig
|
|
58
|
+
) -> Expression:
|
|
59
|
+
return LogicalBinaryExpression(LogicalBinaryType.OR, expression1, expression2)
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
63
|
+
return f"({op1_expr} || {op2_expr})"
|
|
64
|
+
|
|
65
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
66
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
67
|
+
PyLegendBinaryExpression.__init__(
|
|
68
|
+
self,
|
|
69
|
+
operand1,
|
|
70
|
+
operand2,
|
|
71
|
+
PyLegendBooleanOrExpression.__to_sql_func,
|
|
72
|
+
PyLegendBooleanOrExpression.__to_pure_func,
|
|
73
|
+
non_nullable=True,
|
|
74
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
75
|
+
second_operand_needs_to_be_non_nullable=True
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class PyLegendBooleanAndExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def __to_sql_func(
|
|
83
|
+
expression1: Expression,
|
|
84
|
+
expression2: Expression,
|
|
85
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
86
|
+
config: FrameToSqlConfig
|
|
87
|
+
) -> Expression:
|
|
88
|
+
return LogicalBinaryExpression(LogicalBinaryType.AND, expression1, expression2)
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
92
|
+
return f"({op1_expr} && {op2_expr})"
|
|
93
|
+
|
|
94
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
95
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
96
|
+
PyLegendBinaryExpression.__init__(
|
|
97
|
+
self,
|
|
98
|
+
operand1,
|
|
99
|
+
operand2,
|
|
100
|
+
PyLegendBooleanAndExpression.__to_sql_func,
|
|
101
|
+
PyLegendBooleanAndExpression.__to_pure_func,
|
|
102
|
+
non_nullable=True,
|
|
103
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
104
|
+
second_operand_needs_to_be_non_nullable=True
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class PyLegendBooleanLessThanExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
109
|
+
|
|
110
|
+
@staticmethod
|
|
111
|
+
def __to_sql_func(
|
|
112
|
+
expression1: Expression,
|
|
113
|
+
expression2: Expression,
|
|
114
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
115
|
+
config: FrameToSqlConfig
|
|
116
|
+
) -> Expression:
|
|
117
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.LESS_THAN)
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
121
|
+
return f"({op1_expr} < {op2_expr})"
|
|
122
|
+
|
|
123
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
124
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
125
|
+
PyLegendBinaryExpression.__init__(
|
|
126
|
+
self,
|
|
127
|
+
operand1,
|
|
128
|
+
operand2,
|
|
129
|
+
PyLegendBooleanLessThanExpression.__to_sql_func,
|
|
130
|
+
PyLegendBooleanLessThanExpression.__to_pure_func,
|
|
131
|
+
non_nullable=True
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class PyLegendBooleanLessThanEqualExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
def __to_sql_func(
|
|
139
|
+
expression1: Expression,
|
|
140
|
+
expression2: Expression,
|
|
141
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
142
|
+
config: FrameToSqlConfig
|
|
143
|
+
) -> Expression:
|
|
144
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.LESS_THAN_OR_EQUAL)
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
148
|
+
return f"({op1_expr} <= {op2_expr})"
|
|
149
|
+
|
|
150
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
151
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
152
|
+
PyLegendBinaryExpression.__init__(
|
|
153
|
+
self,
|
|
154
|
+
operand1,
|
|
155
|
+
operand2,
|
|
156
|
+
PyLegendBooleanLessThanEqualExpression.__to_sql_func,
|
|
157
|
+
PyLegendBooleanLessThanEqualExpression.__to_pure_func,
|
|
158
|
+
non_nullable=True
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class PyLegendBooleanGreaterThanExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
163
|
+
|
|
164
|
+
@staticmethod
|
|
165
|
+
def __to_sql_func(
|
|
166
|
+
expression1: Expression,
|
|
167
|
+
expression2: Expression,
|
|
168
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
169
|
+
config: FrameToSqlConfig
|
|
170
|
+
) -> Expression:
|
|
171
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.GREATER_THAN)
|
|
172
|
+
|
|
173
|
+
@staticmethod
|
|
174
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
175
|
+
return f"({op1_expr} > {op2_expr})"
|
|
176
|
+
|
|
177
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
178
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
179
|
+
PyLegendBinaryExpression.__init__(
|
|
180
|
+
self,
|
|
181
|
+
operand1,
|
|
182
|
+
operand2,
|
|
183
|
+
PyLegendBooleanGreaterThanExpression.__to_sql_func,
|
|
184
|
+
PyLegendBooleanGreaterThanExpression.__to_pure_func,
|
|
185
|
+
non_nullable=True
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class PyLegendBooleanGreaterThanEqualExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
190
|
+
|
|
191
|
+
@staticmethod
|
|
192
|
+
def __to_sql_func(
|
|
193
|
+
expression1: Expression,
|
|
194
|
+
expression2: Expression,
|
|
195
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
196
|
+
config: FrameToSqlConfig
|
|
197
|
+
) -> Expression:
|
|
198
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.GREATER_THAN_OR_EQUAL)
|
|
199
|
+
|
|
200
|
+
@staticmethod
|
|
201
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
202
|
+
return f"({op1_expr} >= {op2_expr})"
|
|
203
|
+
|
|
204
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
205
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
206
|
+
PyLegendBinaryExpression.__init__(
|
|
207
|
+
self,
|
|
208
|
+
operand1,
|
|
209
|
+
operand2,
|
|
210
|
+
PyLegendBooleanGreaterThanEqualExpression.__to_sql_func,
|
|
211
|
+
PyLegendBooleanGreaterThanEqualExpression.__to_pure_func,
|
|
212
|
+
non_nullable=True
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class PyLegendBooleanXorExpression(PyLegendBinaryExpression, PyLegendExpressionBooleanReturn):
|
|
217
|
+
|
|
218
|
+
@staticmethod
|
|
219
|
+
def __to_sql_func(
|
|
220
|
+
expression1: Expression,
|
|
221
|
+
expression2: Expression,
|
|
222
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
223
|
+
config: FrameToSqlConfig
|
|
224
|
+
) -> Expression:
|
|
225
|
+
return ComparisonExpression(expression1, expression2, ComparisonOperator.NOT_EQUAL)
|
|
226
|
+
|
|
227
|
+
@staticmethod
|
|
228
|
+
def __to_pure_func(op1_expr: str, op2_expr: str, config: FrameToPureConfig) -> str:
|
|
229
|
+
return generate_pure_functional_call("xor", [op1_expr, op2_expr])
|
|
230
|
+
|
|
231
|
+
def __init__(self, operand1: PyLegendExpressionBooleanReturn, operand2: PyLegendExpressionBooleanReturn) -> None:
|
|
232
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
233
|
+
PyLegendBinaryExpression.__init__(
|
|
234
|
+
self,
|
|
235
|
+
operand1,
|
|
236
|
+
operand2,
|
|
237
|
+
PyLegendBooleanXorExpression.__to_sql_func,
|
|
238
|
+
PyLegendBooleanXorExpression.__to_pure_func,
|
|
239
|
+
non_nullable=True,
|
|
240
|
+
first_operand_needs_to_be_non_nullable=True,
|
|
241
|
+
second_operand_needs_to_be_non_nullable=True
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class PyLegendBooleanNotExpression(PyLegendUnaryExpression, PyLegendExpressionBooleanReturn):
|
|
246
|
+
|
|
247
|
+
@staticmethod
|
|
248
|
+
def __to_sql_func(
|
|
249
|
+
expression: Expression,
|
|
250
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
251
|
+
config: FrameToSqlConfig
|
|
252
|
+
) -> Expression:
|
|
253
|
+
return NotExpression(expression)
|
|
254
|
+
|
|
255
|
+
@staticmethod
|
|
256
|
+
def __to_pure_func(op_expr: str, config: FrameToPureConfig) -> str:
|
|
257
|
+
return generate_pure_functional_call("not", [op_expr])
|
|
258
|
+
|
|
259
|
+
def __init__(self, operand: PyLegendExpressionBooleanReturn) -> None:
|
|
260
|
+
PyLegendExpressionBooleanReturn.__init__(self)
|
|
261
|
+
PyLegendUnaryExpression.__init__(
|
|
262
|
+
self,
|
|
263
|
+
operand,
|
|
264
|
+
PyLegendBooleanNotExpression.__to_sql_func,
|
|
265
|
+
PyLegendBooleanNotExpression.__to_pure_func,
|
|
266
|
+
non_nullable=True,
|
|
267
|
+
operand_needs_to_be_non_nullable=True,
|
|
268
|
+
)
|
|
@@ -22,8 +22,10 @@ from pylegend.core.language.shared.expression import (
|
|
|
22
22
|
PyLegendExpressionStrictDateReturn,
|
|
23
23
|
PyLegendExpressionIntegerReturn,
|
|
24
24
|
PyLegendExpressionBooleanReturn,
|
|
25
|
+
PyLegendExpression
|
|
25
26
|
)
|
|
26
27
|
from pylegend.core.language.shared.operations.binary_expression import PyLegendBinaryExpression
|
|
28
|
+
from pylegend.core.language.shared.operations.nary_expression import PyLegendNaryExpression
|
|
27
29
|
from pylegend.core.language.shared.operations.nullary_expression import PyLegendNullaryExpression
|
|
28
30
|
from pylegend.core.language.shared.operations.unary_expression import PyLegendUnaryExpression
|
|
29
31
|
from pylegend.core.language.shared.helpers import generate_pure_functional_call
|
|
@@ -61,6 +63,10 @@ from pylegend.core.sql.metamodel_extension import (
|
|
|
61
63
|
MinuteExpression,
|
|
62
64
|
SecondExpression,
|
|
63
65
|
EpochExpression,
|
|
66
|
+
DateAdjustExpression,
|
|
67
|
+
DateDiffExpression,
|
|
68
|
+
DateTimeBucketExpression,
|
|
69
|
+
DateType,
|
|
64
70
|
)
|
|
65
71
|
|
|
66
72
|
|
|
@@ -91,6 +97,9 @@ __all__: PyLegendSequence[str] = [
|
|
|
91
97
|
"PyLegendDateLessThanEqualExpression",
|
|
92
98
|
"PyLegendDateGreaterThanExpression",
|
|
93
99
|
"PyLegendDateGreaterThanEqualExpression",
|
|
100
|
+
"PyLegendDateAdjustExpression",
|
|
101
|
+
"PyLegendDateDiffExpression",
|
|
102
|
+
"PyLegendDateTimeBucketExpression",
|
|
94
103
|
]
|
|
95
104
|
|
|
96
105
|
|
|
@@ -780,3 +789,85 @@ class PyLegendDateGreaterThanEqualExpression(PyLegendBinaryExpression, PyLegendE
|
|
|
780
789
|
|
|
781
790
|
def is_non_nullable(self) -> bool:
|
|
782
791
|
return True
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
class PyLegendDateAdjustExpression(PyLegendNaryExpression, PyLegendExpressionDateReturn):
|
|
795
|
+
|
|
796
|
+
@staticmethod
|
|
797
|
+
def __to_sql_func(
|
|
798
|
+
expressions: list[Expression],
|
|
799
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
800
|
+
config: FrameToSqlConfig
|
|
801
|
+
) -> Expression:
|
|
802
|
+
return DateAdjustExpression(expressions[0], expressions[1], expressions[2]) # type:ignore
|
|
803
|
+
|
|
804
|
+
@staticmethod
|
|
805
|
+
def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
|
|
806
|
+
return generate_pure_functional_call("adjust", [op_expr[0], op_expr[1], f"DurationUnit.{op_expr[2]}"])
|
|
807
|
+
|
|
808
|
+
def __init__(self, operands: list[PyLegendExpression]) -> None:
|
|
809
|
+
PyLegendExpressionDateReturn.__init__(self)
|
|
810
|
+
PyLegendNaryExpression.__init__(
|
|
811
|
+
self,
|
|
812
|
+
operands,
|
|
813
|
+
PyLegendDateAdjustExpression.__to_sql_func,
|
|
814
|
+
PyLegendDateAdjustExpression.__to_pure_func,
|
|
815
|
+
non_nullable=True,
|
|
816
|
+
operands_non_nullable_flags=[True, True, True]
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
class PyLegendDateDiffExpression(PyLegendNaryExpression, PyLegendExpressionIntegerReturn):
|
|
821
|
+
|
|
822
|
+
@staticmethod
|
|
823
|
+
def __to_sql_func(
|
|
824
|
+
expressions: list[Expression],
|
|
825
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
826
|
+
config: FrameToSqlConfig
|
|
827
|
+
) -> Expression:
|
|
828
|
+
return DateDiffExpression(expressions[0], expressions[1], expressions[2]) # type: ignore
|
|
829
|
+
|
|
830
|
+
@staticmethod
|
|
831
|
+
def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
|
|
832
|
+
return generate_pure_functional_call("dateDiff", [op_expr[0], op_expr[1], f"DurationUnit.{op_expr[2]}"])
|
|
833
|
+
|
|
834
|
+
def __init__(self, operands: list[PyLegendExpression]) -> None:
|
|
835
|
+
PyLegendExpressionIntegerReturn.__init__(self)
|
|
836
|
+
PyLegendNaryExpression.__init__(
|
|
837
|
+
self,
|
|
838
|
+
operands,
|
|
839
|
+
PyLegendDateDiffExpression.__to_sql_func,
|
|
840
|
+
PyLegendDateDiffExpression.__to_pure_func,
|
|
841
|
+
non_nullable=True,
|
|
842
|
+
operands_non_nullable_flags=[True, True, True]
|
|
843
|
+
)
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
class PyLegendDateTimeBucketExpression(PyLegendNaryExpression, PyLegendExpressionDateReturn):
|
|
847
|
+
|
|
848
|
+
@staticmethod
|
|
849
|
+
def __to_sql_func(
|
|
850
|
+
expressions: list[Expression],
|
|
851
|
+
frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
|
|
852
|
+
config: FrameToSqlConfig
|
|
853
|
+
) -> Expression:
|
|
854
|
+
return DateTimeBucketExpression(
|
|
855
|
+
expressions[0],
|
|
856
|
+
expressions[1],
|
|
857
|
+
expressions[2], # type: ignore
|
|
858
|
+
DateType.DateTime if expressions[3].value == "DATETIME" else DateType.StrictDate) # type: ignore
|
|
859
|
+
|
|
860
|
+
@staticmethod
|
|
861
|
+
def __to_pure_func(op_expr: list[str], config: FrameToPureConfig) -> str:
|
|
862
|
+
return generate_pure_functional_call("timeBucket", [op_expr[0], op_expr[1], f"DurationUnit.{op_expr[2]}"])
|
|
863
|
+
|
|
864
|
+
def __init__(self, operands: list[PyLegendExpression]) -> None:
|
|
865
|
+
PyLegendExpressionDateReturn.__init__(self)
|
|
866
|
+
PyLegendNaryExpression.__init__(
|
|
867
|
+
self,
|
|
868
|
+
operands,
|
|
869
|
+
PyLegendDateTimeBucketExpression.__to_sql_func,
|
|
870
|
+
PyLegendDateTimeBucketExpression.__to_pure_func,
|
|
871
|
+
non_nullable=True,
|
|
872
|
+
operands_non_nullable_flags=[True, True, True]
|
|
873
|
+
)
|