pytrilogy 0.0.2.1__tar.gz → 0.0.2.2__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.1/pytrilogy.egg-info → pytrilogy-0.0.2.2}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_statements.py +19 -0
  4. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/models.py +8 -0
  6. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/select_node.py +2 -3
  7. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/parse_engine.py +4 -0
  8. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/render.py +7 -3
  9. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/trilogy.lark +1 -1
  10. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/LICENSE.md +0 -0
  11. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/README.md +0 -0
  12. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/pyproject.toml +0 -0
  13. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/pytrilogy.egg-info/SOURCES.txt +0 -0
  14. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/pytrilogy.egg-info/dependency_links.txt +0 -0
  15. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/pytrilogy.egg-info/entry_points.txt +0 -0
  16. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/pytrilogy.egg-info/requires.txt +0 -0
  17. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/pytrilogy.egg-info/top_level.txt +0 -0
  18. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/setup.cfg +0 -0
  19. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/setup.py +0 -0
  20. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_datatypes.py +0 -0
  21. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_declarations.py +0 -0
  22. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_derived_concepts.py +0 -0
  23. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_discovery_nodes.py +0 -0
  24. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_environment.py +0 -0
  25. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_functions.py +0 -0
  26. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_imports.py +0 -0
  27. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_metadata.py +0 -0
  28. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_models.py +0 -0
  29. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_multi_join_assignments.py +0 -0
  30. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_parsing.py +0 -0
  31. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_partial_handling.py +0 -0
  32. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_query_processing.py +0 -0
  33. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_select.py +0 -0
  34. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_undefined_concept.py +0 -0
  35. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/tests/test_where_clause.py +0 -0
  36. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/compiler.py +0 -0
  37. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/constants.py +0 -0
  38. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/__init__.py +0 -0
  39. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/constants.py +0 -0
  40. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/enums.py +0 -0
  41. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/env_processor.py +0 -0
  42. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/environment_helpers.py +0 -0
  43. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/ergonomics.py +0 -0
  44. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/exceptions.py +0 -0
  45. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/functions.py +0 -0
  46. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/graph_models.py +0 -0
  47. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/internal.py +0 -0
  48. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/optimization.py +0 -0
  49. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/optimizations/__init__.py +0 -0
  50. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/optimizations/base_optimization.py +0 -0
  51. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/optimizations/inline_constant.py +0 -0
  52. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/optimizations/inline_datasource.py +0 -0
  53. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  54. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/__init__.py +0 -0
  55. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  56. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/graph_utils.py +0 -0
  57. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/__init__.py +0 -0
  58. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  59. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/common.py +0 -0
  60. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  61. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/group_node.py +0 -0
  62. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  63. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  64. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  65. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  66. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  67. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/node_generators/window_node.py +0 -0
  68. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/__init__.py +0 -0
  69. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/base_node.py +0 -0
  70. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/filter_node.py +0 -0
  71. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/group_node.py +0 -0
  72. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/merge_node.py +0 -0
  73. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  74. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  75. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/nodes/window_node.py +0 -0
  76. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/processing/utility.py +0 -0
  77. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/core/query_processor.py +0 -0
  78. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/__init__.py +0 -0
  79. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/base.py +0 -0
  80. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/bigquery.py +0 -0
  81. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/common.py +0 -0
  82. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/config.py +0 -0
  83. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/duckdb.py +0 -0
  84. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/enums.py +0 -0
  85. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/postgres.py +0 -0
  86. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/presto.py +0 -0
  87. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/snowflake.py +0 -0
  88. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/dialect/sql_server.py +0 -0
  89. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/engine.py +0 -0
  90. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/executor.py +0 -0
  91. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/hooks/__init__.py +0 -0
  92. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/hooks/base_hook.py +0 -0
  93. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/hooks/graph_hook.py +0 -0
  94. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/hooks/query_debugger.py +0 -0
  95. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/metadata/__init__.py +0 -0
  96. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parser.py +0 -0
  97. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/__init__.py +0 -0
  98. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/common.py +0 -0
  99. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/config.py +0 -0
  100. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/exceptions.py +0 -0
  101. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/parsing/helpers.py +0 -0
  102. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/py.typed +0 -0
  103. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/scripts/__init__.py +0 -0
  104. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/scripts/trilogy.py +0 -0
  105. {pytrilogy-0.0.2.1 → pytrilogy-0.0.2.2}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.2.1
3
+ Version: 0.0.2.2
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.1
3
+ Version: 0.0.2.2
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -41,3 +41,22 @@ datasource posts (
41
41
  ;
42
42
  """
43
43
  parse(text)
44
+
45
+
46
+ def test_datasource_where():
47
+ text = """key user_id int metadata(description="the description");
48
+ property user_id.display_name string metadata(description="The display name ");
49
+ property user_id.about_me string metadata(description="User provided description");
50
+ key post_id int;
51
+
52
+
53
+ datasource x_posts (
54
+ user_id: user_id,
55
+ id: post_id
56
+ )
57
+ grain (post_id)
58
+ address bigquery-public-data.stackoverflow.post_history
59
+ where post_id = 2
60
+ ;
61
+ """
62
+ parse(text)
@@ -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.1"
7
+ __version__ = "0.0.2.2"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -1822,6 +1822,7 @@ class Datasource(Namespaced, BaseModel):
1822
1822
  metadata: DatasourceMetadata = Field(
1823
1823
  default_factory=lambda: DatasourceMetadata(freshness_concept=None)
1824
1824
  )
1825
+ where: Optional[WhereClause] = None
1825
1826
 
1826
1827
  def merge_concept(
1827
1828
  self, source: Concept, target: Concept, modifiers: List[Modifier]
@@ -1837,6 +1838,9 @@ class Datasource(Namespaced, BaseModel):
1837
1838
  for c in self.columns
1838
1839
  ] + original
1839
1840
  self.grain = self.grain.with_merge(source, target, modifiers)
1841
+ self.where = (
1842
+ self.where.with_merge(source, target, modifiers) if self.where else None
1843
+ )
1840
1844
  del self.output_lcl
1841
1845
 
1842
1846
  @property
@@ -1929,6 +1933,7 @@ class Datasource(Namespaced, BaseModel):
1929
1933
  grain=self.grain.with_namespace(namespace),
1930
1934
  address=self.address,
1931
1935
  columns=[c.with_namespace(namespace) for c in self.columns],
1936
+ where=self.where.with_namespace(namespace) if self.where else None,
1932
1937
  )
1933
1938
 
1934
1939
  @cached_property
@@ -2806,6 +2811,9 @@ class EnvironmentDatasourceDict(dict):
2806
2811
  return self.__getitem__(key.split(".")[1])
2807
2812
  raise
2808
2813
 
2814
+ def values(self) -> ValuesView[Datasource]: # type: ignore
2815
+ return super().values()
2816
+
2809
2817
 
2810
2818
  class EnvironmentConceptDict(dict):
2811
2819
  def __init__(self, *args, **kwargs) -> None:
@@ -89,6 +89,7 @@ def dm_to_strategy_node(
89
89
  accept_partial=accept_partial,
90
90
  datasource=datasource,
91
91
  grain=datasource.grain,
92
+ conditions=datasource.where.conditional if datasource.where else None,
92
93
  )
93
94
  # we need to nest the group node one further
94
95
  if force_group is True:
@@ -295,9 +296,6 @@ def gen_select_node_from_table(
295
296
  g.nodes[ncandidate]
296
297
  except KeyError:
297
298
  raise nx.exception.NetworkXNoPath
298
- raise SyntaxError(
299
- f"Could not find node {ncandidate}, have {list(g.nodes())}"
300
- )
301
299
  raise e
302
300
  except nx.exception.NetworkXNoPath:
303
301
  all_found = False
@@ -372,6 +370,7 @@ def gen_select_node_from_table(
372
370
  accept_partial=accept_partial,
373
371
  datasource=datasource,
374
372
  grain=Grain(components=all_concepts),
373
+ conditions=datasource.where.conditional if datasource.where else None,
375
374
  )
376
375
  # we need to nest the group node one further
377
376
  if force_group is True:
@@ -605,6 +605,7 @@ class ParseToObjects(Transformer):
605
605
  columns: List[ColumnAssignment] = args[1]
606
606
  grain: Optional[Grain] = None
607
607
  address: Optional[Address] = None
608
+ where: Optional[WhereClause] = None
608
609
  for val in args[1:]:
609
610
  if isinstance(val, Address):
610
611
  address = val
@@ -612,6 +613,8 @@ class ParseToObjects(Transformer):
612
613
  grain = val
613
614
  elif isinstance(val, Query):
614
615
  address = Address(location=f"({val.text})", is_query=True)
616
+ elif isinstance(val, WhereClause):
617
+ where = val
615
618
  if not address:
616
619
  raise ValueError(
617
620
  "Malformed datasource, missing address or query declaration"
@@ -624,6 +627,7 @@ class ParseToObjects(Transformer):
624
627
  grain=grain, # type: ignore
625
628
  address=address,
626
629
  namespace=self.environment.namespace,
630
+ where=where,
627
631
  )
628
632
  for column in columns:
629
633
  column.concept = column.concept.with_grain(datasource.grain)
@@ -131,11 +131,15 @@ class Renderer:
131
131
  @to_string.register
132
132
  def _(self, arg: Datasource):
133
133
  assignments = ",\n\t".join([self.to_string(x) for x in arg.columns])
134
- return f"""datasource {arg.name} (
134
+ base = f"""datasource {arg.name} (
135
135
  {assignments}
136
136
  )
137
137
  {self.to_string(arg.grain)}
138
- {self.to_string(arg.address)};"""
138
+ {self.to_string(arg.address)}"""
139
+ if arg.where:
140
+ base += f"\n{self.to_string(arg.where)}"
141
+ base += ";"
142
+ return base
139
143
 
140
144
  @to_string.register
141
145
  def _(self, arg: "Grain"):
@@ -196,7 +200,7 @@ class Renderer:
196
200
 
197
201
  @to_string.register
198
202
  def _(self, arg: "ColumnAssignment"):
199
- return f"{arg.alias}:{self.to_string(arg.concept)}"
203
+ return f"{arg.alias}: {self.to_string(arg.concept)}"
200
204
 
201
205
  @to_string.register
202
206
  def _(self, arg: "ConceptDeclarationStatement"):
@@ -35,7 +35,7 @@
35
35
  prop_ident: "<" IDENTIFIER ("," IDENTIFIER )* ","? ">" "." IDENTIFIER
36
36
 
37
37
  // datasource concepts
38
- datasource: "datasource" IDENTIFIER "(" column_assignment_list ")" grain_clause? (address | query)
38
+ datasource: "datasource" IDENTIFIER "(" column_assignment_list ")" grain_clause? (address | query) where?
39
39
 
40
40
  grain_clause: "grain" "(" column_list ")"
41
41
 
File without changes
File without changes
File without changes
File without changes
File without changes