pytrilogy 0.0.1.111__tar.gz → 0.0.1.112__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 (99) hide show
  1. {pytrilogy-0.0.1.111/pytrilogy.egg-info → pytrilogy-0.0.1.112}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_parsing.py +24 -1
  4. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/models.py +8 -0
  6. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/optimization.py +11 -12
  7. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/parse_engine.py +16 -1
  8. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/LICENSE.md +0 -0
  9. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/README.md +0 -0
  10. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pyproject.toml +0 -0
  11. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/SOURCES.txt +0 -0
  12. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/dependency_links.txt +0 -0
  13. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/entry_points.txt +0 -0
  14. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/requires.txt +0 -0
  15. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/top_level.txt +0 -0
  16. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/setup.cfg +0 -0
  17. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/setup.py +0 -0
  18. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_declarations.py +0 -0
  19. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_derived_concepts.py +0 -0
  20. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_discovery_nodes.py +0 -0
  21. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_environment.py +0 -0
  22. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_functions.py +0 -0
  23. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_imports.py +0 -0
  24. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_metadata.py +0 -0
  25. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_models.py +0 -0
  26. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_multi_join_assignments.py +0 -0
  27. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_partial_handling.py +0 -0
  28. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_query_processing.py +0 -0
  29. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_select.py +0 -0
  30. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_statements.py +0 -0
  31. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_undefined_concept.py +0 -0
  32. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_where_clause.py +0 -0
  33. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/compiler.py +0 -0
  34. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/constants.py +0 -0
  35. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/__init__.py +0 -0
  36. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/constants.py +0 -0
  37. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/enums.py +0 -0
  38. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/env_processor.py +0 -0
  39. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/environment_helpers.py +0 -0
  40. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/ergonomics.py +0 -0
  41. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/exceptions.py +0 -0
  42. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/functions.py +0 -0
  43. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/graph_models.py +0 -0
  44. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/internal.py +0 -0
  45. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/__init__.py +0 -0
  46. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  47. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/graph_utils.py +0 -0
  48. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/__init__.py +0 -0
  49. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  50. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/common.py +0 -0
  51. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/concept_merge_node.py +0 -0
  52. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  53. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/group_node.py +0 -0
  54. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  55. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  56. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  57. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  58. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/select_node.py +0 -0
  59. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  60. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/window_node.py +0 -0
  61. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/__init__.py +0 -0
  62. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/base_node.py +0 -0
  63. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/filter_node.py +0 -0
  64. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/group_node.py +0 -0
  65. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/merge_node.py +0 -0
  66. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  67. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  68. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/window_node.py +0 -0
  69. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/utility.py +0 -0
  70. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/query_processor.py +0 -0
  71. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/__init__.py +0 -0
  72. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/base.py +0 -0
  73. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/bigquery.py +0 -0
  74. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/common.py +0 -0
  75. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/config.py +0 -0
  76. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/duckdb.py +0 -0
  77. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/enums.py +0 -0
  78. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/postgres.py +0 -0
  79. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/presto.py +0 -0
  80. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/snowflake.py +0 -0
  81. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/sql_server.py +0 -0
  82. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/engine.py +0 -0
  83. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/executor.py +0 -0
  84. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/__init__.py +0 -0
  85. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/base_hook.py +0 -0
  86. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/graph_hook.py +0 -0
  87. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/query_debugger.py +0 -0
  88. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/metadata/__init__.py +0 -0
  89. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parser.py +0 -0
  90. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/__init__.py +0 -0
  91. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/common.py +0 -0
  92. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/config.py +0 -0
  93. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/exceptions.py +0 -0
  94. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/helpers.py +0 -0
  95. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/render.py +0 -0
  96. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/py.typed +0 -0
  97. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/scripts/__init__.py +0 -0
  98. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/scripts/trilogy.py +0 -0
  99. {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.1.111
3
+ Version: 0.0.1.112
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.1.111
3
+ Version: 0.0.1.112
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,4 +1,4 @@
1
- from trilogy.core.enums import Purpose
1
+ from trilogy.core.enums import Purpose, ComparisonOperator
2
2
  from trilogy.core.models import (
3
3
  DataType,
4
4
  Parenthetical,
@@ -6,6 +6,7 @@ from trilogy.core.models import (
6
6
  ShowStatement,
7
7
  SelectStatement,
8
8
  Environment,
9
+ Comparison,
9
10
  )
10
11
  from trilogy.core.functions import argument_to_purpose, function_args_to_output_purpose
11
12
  from trilogy.parsing.parse_engine import (
@@ -217,3 +218,25 @@ select
217
218
  for name in ["test_name_count"]:
218
219
  assert name in env.concepts
219
220
  assert env.concepts[name].purpose == Purpose.METRIC
221
+
222
+
223
+ def test_between():
224
+ _, parsed = parse_text(
225
+ "const order_id <- 4; SELECT order_id WHERE order_id BETWEEN 3 and 5;"
226
+ )
227
+ query: ProcessedQuery = parsed[-1]
228
+ left = query.where_clause.conditional.left
229
+ assert isinstance(
230
+ left,
231
+ Comparison,
232
+ ), type(left)
233
+ assert left.operator == ComparisonOperator.GTE
234
+ assert left.right == 3
235
+
236
+ right = query.where_clause.conditional.right
237
+ assert isinstance(
238
+ right,
239
+ Comparison,
240
+ ), type(right)
241
+ assert right.operator == ComparisonOperator.LTE
242
+ assert right.right == 5
@@ -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.1.111"
7
+ __version__ = "0.0.1.112"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -2041,6 +2041,14 @@ class CTE(BaseModel):
2041
2041
  ds_being_inlined = qds_being_inlined.datasources[0]
2042
2042
  if not isinstance(ds_being_inlined, Datasource):
2043
2043
  return False
2044
+ if any(
2045
+ [
2046
+ x.identifier == ds_being_inlined.identifier
2047
+ for x in self.source.datasources
2048
+ ]
2049
+ ):
2050
+ return False
2051
+
2044
2052
  self.source.datasources = [
2045
2053
  ds_being_inlined,
2046
2054
  *[
@@ -12,9 +12,6 @@ from trilogy.constants import logger, CONFIG
12
12
  from abc import ABC
13
13
 
14
14
 
15
- REGISTERED_RULES: list["OptimizationRule"] = []
16
-
17
-
18
15
  class OptimizationRule(ABC):
19
16
 
20
17
  def optimize(self, cte: CTE, inverse_map: dict[str, list[CTE]]) -> bool:
@@ -66,13 +63,15 @@ class InlineDatasource(OptimizationRule):
66
63
  to_inline.append(parent_cte)
67
64
 
68
65
  for replaceable in to_inline:
69
- self.log(f"Inlining parent {replaceable.name}")
70
- cte.inline_parent_datasource(replaceable, force_group=force_group)
71
66
 
67
+ result = cte.inline_parent_datasource(replaceable, force_group=force_group)
68
+ if result:
69
+ self.log(f"Inlined parent {replaceable.name}")
70
+ else:
71
+ self.log(f"Failed to inline {replaceable.name}")
72
72
  return optimized
73
73
 
74
74
 
75
- # This will be used in the future for more complex condition decomposition
76
75
  def decompose_condition(conditional: Conditional):
77
76
  chunks = []
78
77
  if conditional.operator == BooleanOperator.AND:
@@ -154,12 +153,6 @@ class PredicatePushdown(OptimizationRule):
154
153
  return optimized
155
154
 
156
155
 
157
- if CONFIG.optimizations.datasource_inlining:
158
- REGISTERED_RULES.append(InlineDatasource())
159
- if CONFIG.optimizations.predicate_pushdown:
160
- REGISTERED_RULES.append(PredicatePushdown())
161
-
162
-
163
156
  def filter_irrelevant_ctes(
164
157
  input: list[CTE],
165
158
  root_cte: CTE,
@@ -233,6 +226,12 @@ def optimize_ctes(
233
226
  input: list[CTE], root_cte: CTE, select: SelectStatement | MultiSelectStatement
234
227
  ):
235
228
  complete = False
229
+ REGISTERED_RULES: list["OptimizationRule"] = []
230
+
231
+ if CONFIG.optimizations.datasource_inlining:
232
+ REGISTERED_RULES.append(InlineDatasource())
233
+ if CONFIG.optimizations.predicate_pushdown:
234
+ REGISTERED_RULES.append(PredicatePushdown())
236
235
 
237
236
  while not complete:
238
237
  actions_taken = False
@@ -250,6 +250,8 @@ grammar = r"""
250
250
 
251
251
  comparison: (expr COMPARISON_OPERATOR expr)
252
252
 
253
+ between_comparison: expr "BETWEEN"i expr "AND"i expr
254
+
253
255
  subselect_comparison: expr array_comparison expr | (expr array_comparison expr_tuple)
254
256
 
255
257
  expr_tuple: "(" (expr ",")* expr ","? ")"
@@ -262,7 +264,7 @@ grammar = r"""
262
264
 
263
265
  parenthetical: "(" (conditional | expr) ")"
264
266
 
265
- expr: window_item | filter_item | comparison | subselect_comparison | fgroup | aggregate_functions | unnest | _string_functions | _math_functions | _generic_functions | _constant_functions| _date_functions | literal | expr_reference | index_access | attr_access | parenthetical
267
+ expr: window_item | filter_item | between_comparison | comparison | subselect_comparison | fgroup | aggregate_functions | unnest | _string_functions | _math_functions | _generic_functions | _constant_functions| _date_functions | literal | expr_reference | index_access | attr_access | parenthetical
266
268
 
267
269
  // functions
268
270
 
@@ -1241,6 +1243,19 @@ class ParseToObjects(Transformer):
1241
1243
  raise SyntaxError
1242
1244
  return Comparison(left=args[0], right=args[2], operator=args[1])
1243
1245
 
1246
+ def between_comparison(self, args) -> Conditional:
1247
+ left_bound = args[1]
1248
+ right_bound = args[2]
1249
+ return Conditional(
1250
+ left=Comparison(
1251
+ left=args[0], right=left_bound, operator=ComparisonOperator.GTE
1252
+ ),
1253
+ right=Comparison(
1254
+ left=args[0], right=right_bound, operator=ComparisonOperator.LTE
1255
+ ),
1256
+ operator=BooleanOperator.AND,
1257
+ )
1258
+
1244
1259
  @v_args(meta=True)
1245
1260
  def subselect_comparison(self, meta: Meta, args) -> SubselectComparison:
1246
1261
  right = args[2]
File without changes
File without changes
File without changes
File without changes