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.

Files changed (105) hide show
  1. {pytrilogy-0.0.2.4/pytrilogy.egg-info → pytrilogy-0.0.2.5}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_where_clause.py +31 -2
  4. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/models.py +10 -6
  6. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/inline_datasource.py +6 -2
  7. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/base.py +3 -2
  8. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/duckdb.py +0 -1
  9. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/LICENSE.md +0 -0
  10. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/README.md +0 -0
  11. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pyproject.toml +0 -0
  12. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/SOURCES.txt +0 -0
  13. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/dependency_links.txt +0 -0
  14. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/entry_points.txt +0 -0
  15. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/requires.txt +0 -0
  16. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/pytrilogy.egg-info/top_level.txt +0 -0
  17. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/setup.cfg +0 -0
  18. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/setup.py +0 -0
  19. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_datatypes.py +0 -0
  20. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_declarations.py +0 -0
  21. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_derived_concepts.py +0 -0
  22. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_discovery_nodes.py +0 -0
  23. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_environment.py +0 -0
  24. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_functions.py +0 -0
  25. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_imports.py +0 -0
  26. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_metadata.py +0 -0
  27. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_models.py +0 -0
  28. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_multi_join_assignments.py +0 -0
  29. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_parsing.py +0 -0
  30. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_partial_handling.py +0 -0
  31. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_query_processing.py +0 -0
  32. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_select.py +0 -0
  33. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_statements.py +0 -0
  34. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/tests/test_undefined_concept.py +0 -0
  35. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/compiler.py +0 -0
  36. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/constants.py +0 -0
  37. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/__init__.py +0 -0
  38. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/constants.py +0 -0
  39. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/enums.py +0 -0
  40. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/env_processor.py +0 -0
  41. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/environment_helpers.py +0 -0
  42. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/ergonomics.py +0 -0
  43. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/exceptions.py +0 -0
  44. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/functions.py +0 -0
  45. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/graph_models.py +0 -0
  46. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/internal.py +0 -0
  47. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimization.py +0 -0
  48. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/__init__.py +0 -0
  49. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/base_optimization.py +0 -0
  50. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/inline_constant.py +0 -0
  51. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  52. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/__init__.py +0 -0
  53. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  54. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/graph_utils.py +0 -0
  55. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/__init__.py +0 -0
  56. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  57. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/common.py +0 -0
  58. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  59. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/group_node.py +0 -0
  60. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  61. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  62. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  63. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  64. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/select_node.py +0 -0
  65. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  66. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/node_generators/window_node.py +0 -0
  67. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/__init__.py +0 -0
  68. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/base_node.py +0 -0
  69. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/filter_node.py +0 -0
  70. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/group_node.py +0 -0
  71. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/merge_node.py +0 -0
  72. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  73. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  74. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/nodes/window_node.py +0 -0
  75. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/processing/utility.py +0 -0
  76. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/core/query_processor.py +0 -0
  77. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/__init__.py +0 -0
  78. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/bigquery.py +0 -0
  79. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/common.py +0 -0
  80. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/config.py +0 -0
  81. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/enums.py +0 -0
  82. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/postgres.py +0 -0
  83. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/presto.py +0 -0
  84. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/snowflake.py +0 -0
  85. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/dialect/sql_server.py +0 -0
  86. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/engine.py +0 -0
  87. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/executor.py +0 -0
  88. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/__init__.py +0 -0
  89. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/base_hook.py +0 -0
  90. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/graph_hook.py +0 -0
  91. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/hooks/query_debugger.py +0 -0
  92. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/metadata/__init__.py +0 -0
  93. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parser.py +0 -0
  94. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/__init__.py +0 -0
  95. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/common.py +0 -0
  96. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/config.py +0 -0
  97. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/exceptions.py +0 -0
  98. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/helpers.py +0 -0
  99. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/parse_engine.py +0 -0
  100. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/render.py +0 -0
  101. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/parsing/trilogy.lark +0 -0
  102. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/py.typed +0 -0
  103. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/scripts/__init__.py +0 -0
  104. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/scripts/trilogy.py +0 -0
  105. {pytrilogy-0.0.2.4 → pytrilogy-0.0.2.5}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.2.4
3
+ Version: 0.0.2.5
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.2.4
3
+ Version: 0.0.2.5
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -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
- query = BaseDialect().compile_statement(process_query(test_environment, select))
231
- print(query)
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
@@ -4,6 +4,6 @@ from trilogy.executor import Executor
4
4
  from trilogy.parser import parse
5
5
  from trilogy.constants import CONFIG
6
6
 
7
- __version__ = "0.0.2.4"
7
+ __version__ = "0.0.2.5"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -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([removed_cte in x for x in self.source_map.values()])
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) -> "Comparison":
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
- if self.right == constant:
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 cte_outputs.issubset(root_outputs):
49
- self.log(f"Not all {parent_cte.name} outputs are found on datasource")
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 ({{cte.statement}}){% if not loop.last %},{% endif %}{% endfor %}{% endif %}
191
+ {{cte.name}} as (
192
+ {{cte.statement}}){% if not loop.last %},{% endif %}{% endfor %}{% endif %}
192
193
  {%- if full_select -%}
193
194
  {{full_select}}
194
- {%- else -%}
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