pytrilogy 0.0.3.84__tar.gz → 0.0.3.86__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.
Potentially problematic release.
This version of pytrilogy might be problematic. Click here for more details.
- {pytrilogy-0.0.3.84/pytrilogy.egg-info → pytrilogy-0.0.3.86}/PKG-INFO +1 -1
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86/pytrilogy.egg-info}/PKG-INFO +1 -1
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_datatypes.py +1 -1
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/author.py +10 -12
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/utility.py +23 -13
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/duckdb.py +1 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/parse_engine.py +3 -1
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/trilogy.lark +1 -1
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/std/geography.preql +3 -2
- pytrilogy-0.0.3.86/trilogy/std/net.preql +14 -0
- pytrilogy-0.0.3.84/trilogy/std/net.preql +0 -9
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/LICENSE.md +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/README.md +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/pyproject.toml +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/SOURCES.txt +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/requires.txt +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/setup.cfg +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/setup.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_derived_concepts.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_enums.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_environment.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_execute_models.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_executor.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_failure.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_functions.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_metadata.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_models.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_parse_engine.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_parsing.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_parsing_failures.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_query_processing.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_query_render.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_select.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_show.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_typing.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_user_functions.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/tests/test_where_clause.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/authoring/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/compiler.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/constants.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/enums.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/env_processor.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/environment_helpers.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/exceptions.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/functions.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/graph_models.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/internal.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/build.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/build_environment.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/core.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/datasource.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/environment.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/models/execute.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/optimization.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/base_optimization.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/inline_datasource.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/concept_strategies_v3.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_loop.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_node_factory.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_utility.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_validation.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/basic_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/common.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/constant_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/filter_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/group_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/recursive_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/union_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/base_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/group_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/merge_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/recursive_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/union_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/query_processor.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/statements/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/statements/author.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/statements/build.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/statements/common.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/statements/execute.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/utility.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/base.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/dataframe.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/dialect/sql_server.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/engine.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/executor.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/hooks/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/hooks/graph_hook.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/metadata/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/common.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/parsing/render.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/render.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/scripts/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/scripts/trilogy.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/std/__init__.py +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/std/date.preql +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/std/display.preql +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/std/money.preql +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/std/ranking.preql +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/std/report.preql +0 -0
- {pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/utility.py +0 -0
|
@@ -30,7 +30,7 @@ def test_cast_error():
|
|
|
30
30
|
"""
|
|
31
31
|
)
|
|
32
32
|
except InvalidSyntaxException as e:
|
|
33
|
-
assert "Cannot compare
|
|
33
|
+
assert "Cannot compare INTEGER (ref:local.x) and STRING (ref:local.y)" in str(e)
|
|
34
34
|
found = True
|
|
35
35
|
if not found:
|
|
36
36
|
assert False, "Expected InvalidSyntaxException not raised"
|
|
@@ -637,33 +637,31 @@ class Comparison(ConceptArgs, Mergeable, DataTyped, Namespaced, BaseModel):
|
|
|
637
637
|
|
|
638
638
|
@model_validator(mode="after")
|
|
639
639
|
def validate_comparison(self):
|
|
640
|
+
left_type = arg_to_datatype(self.left)
|
|
641
|
+
right_type = arg_to_datatype(self.right)
|
|
640
642
|
if self.operator in (ComparisonOperator.IS, ComparisonOperator.IS_NOT):
|
|
641
|
-
if self.right != MagicConstants.NULL and DataType.BOOL !=
|
|
642
|
-
self.right
|
|
643
|
-
):
|
|
643
|
+
if self.right != MagicConstants.NULL and DataType.BOOL != right_type:
|
|
644
644
|
raise SyntaxError(
|
|
645
645
|
f"Cannot use {self.operator.value} with non-null or boolean value {self.right}"
|
|
646
646
|
)
|
|
647
647
|
elif self.operator in (ComparisonOperator.IN, ComparisonOperator.NOT_IN):
|
|
648
|
-
|
|
648
|
+
|
|
649
649
|
if isinstance(right_type, ArrayType) and not is_compatible_datatype(
|
|
650
|
-
|
|
650
|
+
left_type, right_type.value_data_type
|
|
651
651
|
):
|
|
652
652
|
raise SyntaxError(
|
|
653
|
-
f"Cannot compare {
|
|
653
|
+
f"Cannot compare {left_type} and {right_type} with operator {self.operator} in {str(self)}"
|
|
654
654
|
)
|
|
655
655
|
elif isinstance(self.right, Concept) and not is_compatible_datatype(
|
|
656
|
-
|
|
656
|
+
left_type, right_type
|
|
657
657
|
):
|
|
658
658
|
raise SyntaxError(
|
|
659
|
-
f"Cannot compare {
|
|
659
|
+
f"Cannot compare {left_type.name} and {right_type.name} with operator {self.operator} in {str(self)}"
|
|
660
660
|
)
|
|
661
661
|
else:
|
|
662
|
-
if not is_compatible_datatype(
|
|
663
|
-
arg_to_datatype(self.left), arg_to_datatype(self.right)
|
|
664
|
-
):
|
|
662
|
+
if not is_compatible_datatype(left_type, right_type):
|
|
665
663
|
raise SyntaxError(
|
|
666
|
-
f"Cannot compare {
|
|
664
|
+
f"Cannot compare {left_type.name} ({self.left}) and {right_type.name} ({self.right}) of different types with operator {self.operator.value} in {str(self)}"
|
|
667
665
|
)
|
|
668
666
|
|
|
669
667
|
return self
|
|
@@ -161,6 +161,9 @@ def resolve_join_order_v2(
|
|
|
161
161
|
left_is_partial = any(
|
|
162
162
|
key in partials.get(left_candidate, []) for key in common
|
|
163
163
|
)
|
|
164
|
+
left_is_nullable = any(
|
|
165
|
+
key in nullables.get(left_candidate, []) for key in common
|
|
166
|
+
)
|
|
164
167
|
right_is_partial = any(key in partials.get(right, []) for key in common)
|
|
165
168
|
# we don't care if left is nullable for join type (just keys), but if we did
|
|
166
169
|
# left_is_nullable = any(
|
|
@@ -169,21 +172,29 @@ def resolve_join_order_v2(
|
|
|
169
172
|
right_is_nullable = any(
|
|
170
173
|
key in nullables.get(right, []) for key in common
|
|
171
174
|
)
|
|
172
|
-
if
|
|
175
|
+
if left_is_nullable and right_is_nullable:
|
|
176
|
+
join_type = JoinType.FULL
|
|
177
|
+
elif left_is_partial and right_is_partial:
|
|
178
|
+
join_type = JoinType.FULL
|
|
179
|
+
elif left_is_partial:
|
|
173
180
|
join_type = JoinType.FULL
|
|
174
|
-
elif
|
|
181
|
+
elif right_is_nullable:
|
|
182
|
+
join_type = JoinType.RIGHT_OUTER
|
|
183
|
+
elif right_is_partial or left_is_nullable:
|
|
175
184
|
join_type = JoinType.LEFT_OUTER
|
|
176
185
|
# we can't inner join if the left was an outer join
|
|
177
186
|
else:
|
|
178
187
|
join_type = JoinType.INNER
|
|
188
|
+
|
|
179
189
|
join_types.add(join_type)
|
|
180
190
|
joinkeys[left_candidate] = common
|
|
181
|
-
|
|
182
191
|
final_join_type = JoinType.INNER
|
|
183
|
-
if any([x == JoinType.
|
|
184
|
-
final_join_type = JoinType.LEFT_OUTER
|
|
185
|
-
elif any([x == JoinType.FULL for x in join_types]):
|
|
192
|
+
if any([x == JoinType.FULL for x in join_types]):
|
|
186
193
|
final_join_type = JoinType.FULL
|
|
194
|
+
elif any([x == JoinType.LEFT_OUTER for x in join_types]):
|
|
195
|
+
final_join_type = JoinType.LEFT_OUTER
|
|
196
|
+
elif any([x == JoinType.RIGHT_OUTER for x in join_types]):
|
|
197
|
+
final_join_type = JoinType.RIGHT_OUTER
|
|
187
198
|
output.append(
|
|
188
199
|
JoinOrderOutput(
|
|
189
200
|
# left=left_candidate,
|
|
@@ -608,13 +619,12 @@ def find_nullable_concepts(
|
|
|
608
619
|
local_nullable = [
|
|
609
620
|
x for x in datasources if k in [v.address for v in x.nullable_concepts]
|
|
610
621
|
]
|
|
611
|
-
|
|
612
|
-
[
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
):
|
|
622
|
+
nullable_matches = [
|
|
623
|
+
k in [v.address for v in x.nullable_concepts]
|
|
624
|
+
for x in datasources
|
|
625
|
+
if k in [z.address for z in x.output_concepts]
|
|
626
|
+
]
|
|
627
|
+
if all(nullable_matches) and len(nullable_matches) > 0:
|
|
618
628
|
final_nullable.add(k)
|
|
619
629
|
all_ds = set([ds for ds in local_nullable]).union(nullable_datasources)
|
|
620
630
|
if nullable_datasources:
|
|
@@ -76,6 +76,7 @@ FUNCTION_MAP = {
|
|
|
76
76
|
FunctionType.DATE: lambda x: f"cast({x[0]} as date)",
|
|
77
77
|
FunctionType.DATE_TRUNCATE: lambda x: f"date_trunc('{x[1]}', {x[0]})",
|
|
78
78
|
FunctionType.DATE_ADD: lambda x: f"date_add({x[0]}, {x[2]} * INTERVAL 1 {x[1]})",
|
|
79
|
+
FunctionType.DATE_SUB: lambda x: f"date_add({x[0]}, -{x[2]} * INTERVAL 1 {x[1]})",
|
|
79
80
|
FunctionType.DATE_PART: lambda x: f"date_part('{x[1]}', {x[0]})",
|
|
80
81
|
FunctionType.DATE_DIFF: lambda x: f"date_diff('{x[2]}', {x[0]}, {x[1]})",
|
|
81
82
|
FunctionType.CONCAT: lambda x: f"({' || '.join(x)})",
|
|
@@ -683,7 +683,9 @@ class ParseToObjects(Transformer):
|
|
|
683
683
|
)
|
|
684
684
|
# let constant purposes exist to support round-tripping
|
|
685
685
|
# as a build concept may end up with a constant based on constant inlining happening recursively
|
|
686
|
-
if
|
|
686
|
+
if purpose == Purpose.KEY and concept.purpose != Purpose.KEY:
|
|
687
|
+
concept.purpose = Purpose.KEY
|
|
688
|
+
elif (
|
|
687
689
|
purpose
|
|
688
690
|
and purpose != Purpose.AUTO
|
|
689
691
|
and concept.purpose != purpose
|
|
@@ -367,7 +367,7 @@
|
|
|
367
367
|
fyear: _YEAR expr ")"
|
|
368
368
|
|
|
369
369
|
DATE_PART: "DAY"i | "WEEK"i | "MONTH"i | "QUARTER"i | "YEAR"i | "MINUTE"i | "HOUR"i | "SECOND"i | "DAY_OF_WEEK"i
|
|
370
|
-
_DATE_TRUNC.1: "date_trunc("i
|
|
370
|
+
_DATE_TRUNC.1: "date_trunc("i | "date_truncate("i
|
|
371
371
|
fdate_trunc: _DATE_TRUNC expr "," DATE_PART ")"
|
|
372
372
|
_DATE_PART.1: "date_part("i
|
|
373
373
|
fdate_part: _DATE_PART expr "," DATE_PART ")"
|
|
@@ -9,10 +9,11 @@ type us_zip_code string; # US ZIP code
|
|
|
9
9
|
## generic types
|
|
10
10
|
type latitude float; # Latitude in degrees
|
|
11
11
|
type longitude float; # Longitude in degrees
|
|
12
|
-
type lat_long string; # Latitude and longitude in degrees
|
|
12
|
+
type lat_long string; # Latitude and longitude in degrees, as a coordinate pair
|
|
13
13
|
|
|
14
14
|
type city string; # City name
|
|
15
|
-
type country string; # Country
|
|
15
|
+
type country string; # Full Country Name
|
|
16
|
+
type country_code string; # ISO-3166 Country code - ex US, CA, GB
|
|
16
17
|
type timezone string; # Timezone name
|
|
17
18
|
type region string; # Region name
|
|
18
19
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
## network types
|
|
3
|
+
type url string; # URL string
|
|
4
|
+
type url_image string; # URL of an image
|
|
5
|
+
type domain string; # Domain name
|
|
6
|
+
type ip_net_mask string; # IP network mask
|
|
7
|
+
type ipv6_address string; # IPv6 address
|
|
8
|
+
type ipv4_address string; # IPv4 address
|
|
9
|
+
|
|
10
|
+
## communication types
|
|
11
|
+
type email_address string; # Email address, including @
|
|
12
|
+
|
|
13
|
+
## shared types
|
|
14
|
+
type suffix string; # A file suffix or extension, like .txt, .jpg, etc.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/__init__.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/basic_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/constant_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/filter_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/group_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/group_to_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/node_merge_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/recursive_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/rowset_node.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/synonym_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/union_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/unnest_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.84 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/window_node.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|