pytrilogy 0.0.2.4__tar.gz → 0.0.2.5__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.2.4/pytrilogy.egg-info → pytrilogy-0.0.2.5}/PKG-INFO +1 -1
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5/pytrilogy.egg-info}/PKG-INFO +1 -1
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_where_clause.py +31 -2
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/models.py +10 -6
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/inline_datasource.py +6 -2
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/base.py +3 -2
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/duckdb.py +0 -1
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/LICENSE.md +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/README.md +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pyproject.toml +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/SOURCES.txt +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/requires.txt +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/setup.cfg +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/setup.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_datatypes.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_derived_concepts.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_environment.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_functions.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_metadata.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_models.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_parsing.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_query_processing.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_select.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/compiler.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/constants.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/enums.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/env_processor.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/environment_helpers.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/exceptions.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/functions.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/graph_models.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/internal.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimization.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/base_optimization.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/inline_constant.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/concept_strategies_v3.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/basic_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/common.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/filter_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/group_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/select_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/base_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/group_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/merge_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/utility.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/query_processor.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/sql_server.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/engine.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/executor.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/graph_hook.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/metadata/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/common.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/parse_engine.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/render.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/trilogy.lark +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/scripts/__init__.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/scripts/trilogy.py +0 -0
- {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/utility.py +0 -0
|
@@ -227,5 +227,34 @@ where
|
|
|
227
227
|
select: SelectStatement = parsed[-1]
|
|
228
228
|
|
|
229
229
|
assert is_scalar_condition(select.where_clause.conditional) is False
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
_ = BaseDialect().compile_statement(process_query(test_environment, select))
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def test_case_where(test_environment):
|
|
234
|
+
from trilogy.hooks.query_debugger import DebuggingHook
|
|
235
|
+
|
|
236
|
+
declarations = """property order_id_even_name <- CASE
|
|
237
|
+
when order_id %2 = 0 then 'even'
|
|
238
|
+
else 'odd'
|
|
239
|
+
END;
|
|
240
|
+
|
|
241
|
+
const test <- 1;
|
|
242
|
+
|
|
243
|
+
auto order_even_class_filter <- filter category_id where order_id_even_name = 'even' and 1= test;
|
|
244
|
+
|
|
245
|
+
select
|
|
246
|
+
category_id,
|
|
247
|
+
category_name
|
|
248
|
+
where
|
|
249
|
+
category_name like '%abc%' and category_id not in order_even_class_filter
|
|
250
|
+
and category_id = test
|
|
251
|
+
;"""
|
|
252
|
+
env, parsed = parse(declarations, environment=test_environment)
|
|
253
|
+
select: SelectStatement = parsed[-1]
|
|
254
|
+
|
|
255
|
+
query = BaseDialect().compile_statement(
|
|
256
|
+
process_query(test_environment, select, hooks=[DebuggingHook()])
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# check to make sure our subselect is well-formed
|
|
260
|
+
assert "`category_id` not in (select" in query, query
|
|
@@ -2433,7 +2433,13 @@ class CTE(BaseModel):
|
|
|
2433
2433
|
# if we've entirely removed the need to join to someplace to get the concept
|
|
2434
2434
|
# drop the join as well.
|
|
2435
2435
|
for removed_cte in removed:
|
|
2436
|
-
still_required = any(
|
|
2436
|
+
still_required = any(
|
|
2437
|
+
[
|
|
2438
|
+
removed_cte in x
|
|
2439
|
+
for x in self.source_map.values()
|
|
2440
|
+
or self.existence_source_map.values()
|
|
2441
|
+
]
|
|
2442
|
+
)
|
|
2437
2443
|
if not still_required:
|
|
2438
2444
|
self.joins = [
|
|
2439
2445
|
join
|
|
@@ -2451,6 +2457,7 @@ class CTE(BaseModel):
|
|
|
2451
2457
|
candidates = [x.name for x in self.parent_ctes]
|
|
2452
2458
|
self.base_name_override = candidates[0] if candidates else None
|
|
2453
2459
|
self.base_alias_override = candidates[0] if candidates else None
|
|
2460
|
+
return True
|
|
2454
2461
|
|
|
2455
2462
|
def inline_parent_datasource(self, parent: CTE, force_group: bool = False) -> bool:
|
|
2456
2463
|
qds_being_inlined = parent.source
|
|
@@ -3315,7 +3322,7 @@ class Comparison(
|
|
|
3315
3322
|
and self.operator == other.operator
|
|
3316
3323
|
)
|
|
3317
3324
|
|
|
3318
|
-
def inline_constant(self, constant: Concept)
|
|
3325
|
+
def inline_constant(self, constant: Concept):
|
|
3319
3326
|
assert isinstance(constant.lineage, Function)
|
|
3320
3327
|
new_val = constant.lineage.arguments[0]
|
|
3321
3328
|
if isinstance(self.left, ConstantInlineable):
|
|
@@ -3332,10 +3339,7 @@ class Comparison(
|
|
|
3332
3339
|
else:
|
|
3333
3340
|
new_right = self.right
|
|
3334
3341
|
|
|
3335
|
-
|
|
3336
|
-
new_right = new_val
|
|
3337
|
-
|
|
3338
|
-
return Comparison(
|
|
3342
|
+
return self.__class__(
|
|
3339
3343
|
left=new_left,
|
|
3340
3344
|
right=new_right,
|
|
3341
3345
|
operator=self.operator,
|
|
@@ -43,10 +43,14 @@ class InlineDatasource(OptimizationRule):
|
|
|
43
43
|
continue
|
|
44
44
|
root_outputs = {x.address for x in root.output_concepts}
|
|
45
45
|
cte_outputs = {x.address for x in cte.output_columns}
|
|
46
|
+
inherited = {x for x, v in cte.source_map.items() if v}
|
|
46
47
|
# cte_inherited_outputs = {x.address for x in parent_cte.output_columns if parent_cte.source_map.get(x.address)}
|
|
47
48
|
grain_components = {x.address for x in root.grain.components}
|
|
48
|
-
if not
|
|
49
|
-
|
|
49
|
+
if not inherited.issubset(root_outputs):
|
|
50
|
+
cte_missing = inherited - root_outputs
|
|
51
|
+
self.log(
|
|
52
|
+
f"Not all {parent_cte.name} require inputs are found on datasource, missing {cte_missing}"
|
|
53
|
+
)
|
|
50
54
|
continue
|
|
51
55
|
if not grain_components.issubset(cte_outputs):
|
|
52
56
|
self.log("Not all datasource components in cte outputs, forcing group")
|
|
@@ -188,10 +188,11 @@ FUNCTION_GRAIN_MATCH_MAP = {
|
|
|
188
188
|
GENERIC_SQL_TEMPLATE = Template(
|
|
189
189
|
"""{%- if ctes %}
|
|
190
190
|
WITH {% for cte in ctes %}
|
|
191
|
-
{{cte.name}} as (
|
|
191
|
+
{{cte.name}} as (
|
|
192
|
+
{{cte.statement}}){% if not loop.last %},{% endif %}{% endfor %}{% endif %}
|
|
192
193
|
{%- if full_select -%}
|
|
193
194
|
{{full_select}}
|
|
194
|
-
{
|
|
195
|
+
{% else -%}
|
|
195
196
|
SELECT
|
|
196
197
|
{%- if limit is not none %}
|
|
197
198
|
TOP {{ limit }}{% endif %}
|
|
@@ -49,7 +49,6 @@ WITH {% for cte in ctes %}
|
|
|
49
49
|
{{cte.name}} as ({{cte.statement}}){% if not loop.last %},{% endif %}{% endfor %}{% endif %}
|
|
50
50
|
{% if full_select -%}{{full_select}}
|
|
51
51
|
{% else -%}
|
|
52
|
-
|
|
53
52
|
SELECT
|
|
54
53
|
{%- for select in select_columns %}
|
|
55
54
|
{{ select }}{% if not loop.last %},{% endif %}{% endfor %}
|
|
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.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/basic_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/filter_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/group_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/group_to_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/multiselect_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/node_merge_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/rowset_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/select_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/unnest_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/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
|