pytrilogy 0.0.2.48__py3-none-any.whl → 0.0.2.49__py3-none-any.whl

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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.2.48
3
+ Version: 0.0.2.49
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,4 +1,4 @@
1
- trilogy/__init__.py,sha256=rBXQoKLExpvOodgSnjarZ5SG_tlNVQvyadW0PFK1aFs,291
1
+ trilogy/__init__.py,sha256=hG5X0wOuxbm75ZaOS3dSSefwEZ4P5yCHSSmZ1x9LX4I,291
2
2
  trilogy/compiler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  trilogy/constants.py,sha256=qZ1d0hoKPPV2HHCoFwPYTVB7b6bXjpWvXd3lE-zEhy8,1494
4
4
  trilogy/engine.py,sha256=yOPnR7XCjWG82Gym_LLZBkYKKJdLCvqdCyt8zguNcnM,1103
@@ -16,18 +16,18 @@ trilogy/core/exceptions.py,sha256=1c1lQCwSw4_5CQS3q7scOkXU8GQvullJXfPHubprl90,61
16
16
  trilogy/core/functions.py,sha256=qpVLwTNU_qHQyIvNish5O2AlbpRMQQOqZWEUiSMnpqE,10721
17
17
  trilogy/core/graph_models.py,sha256=mameUTiuCajtihDw_2-W218xyJlvTusOWrEKP1yAWgk,2003
18
18
  trilogy/core/internal.py,sha256=-CykZknaWieFh5begaQJ4EgGP9qJccGg4XXdmBirxEc,1074
19
- trilogy/core/models.py,sha256=UjuDuda6TWk_y5Pq3mx_BVfmLP3U6WH4EHhd88ddp4E,166378
19
+ trilogy/core/models.py,sha256=GLy30_Rhvb9Z1atXPlK-sOSeN4lBzBspyMiqti5wS50,166562
20
20
  trilogy/core/optimization.py,sha256=Jy3tVJNeqhpK6VSyTvgIWKCao6y-VCZ7mYA69MIF6L0,7989
21
- trilogy/core/query_processor.py,sha256=eIRV7WEeEI-3OICEdXjJoQe2DhCimJfyFVW9CI6tU-Q,18845
21
+ trilogy/core/query_processor.py,sha256=keXQMpvM-S4rYU1YhzRAkvB1bVlbcX4CKNFafhVRgiI,18635
22
22
  trilogy/core/optimizations/__init__.py,sha256=EBanqTXEzf1ZEYjAneIWoIcxtMDite5-n2dQ5xcfUtg,356
23
23
  trilogy/core/optimizations/base_optimization.py,sha256=P4kF-eCXkBxO-5c6tLHhMZ4ODRH1A04hb_6ovkaVyLw,505
24
24
  trilogy/core/optimizations/inline_constant.py,sha256=c-YHOg6eAufL4EaCf4-0PbY_D4skBHW0ldR55_phsMA,1277
25
25
  trilogy/core/optimizations/inline_datasource.py,sha256=LsngRKBy-LYcx1sfo1-rnDym_ly73YV9WkEngSjpFx8,3943
26
26
  trilogy/core/optimizations/predicate_pushdown.py,sha256=XPWEBv8jXnc0OL2JDPNwFvJ5AtOE7dLzJK0LzdmdZMo,9252
27
27
  trilogy/core/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- trilogy/core/processing/concept_strategies_v3.py,sha256=tODAJjYyIwR1RII_4GjZ8f0TP18GvOe49aF1x8MxXto,36985
28
+ trilogy/core/processing/concept_strategies_v3.py,sha256=0xN1AMBGPKfl2Bbl0zIIGJYcmaNl9PFl2ESzBniVO24,37104
29
29
  trilogy/core/processing/graph_utils.py,sha256=stbYnDxnK-1kbo9L4XNU85FQhWCP-oZYO7LCXhAdC5M,1198
30
- trilogy/core/processing/utility.py,sha256=kwv-eEnFxZTLbZvJxhVxK-IUPBa83VII3gqXmXMBzBM,18709
30
+ trilogy/core/processing/utility.py,sha256=RG0v0hCgyWsxRHzDx2-ME0ENp1LlahLk4zB--Hfrsbc,18717
31
31
  trilogy/core/processing/node_generators/__init__.py,sha256=s_YV1OYc336DuS9591259qjI_K_CtOCuhkf4t2aOgYs,733
32
32
  trilogy/core/processing/node_generators/basic_node.py,sha256=VqVyb4wXI_B2OmfwtpsypimzcevoPe_pnstlKLU3S5s,2878
33
33
  trilogy/core/processing/node_generators/common.py,sha256=kETikLR2fWbrKywPL0TXXj6YY4rpOA8PjsUSyx_mNyE,8907
@@ -36,18 +36,18 @@ trilogy/core/processing/node_generators/group_node.py,sha256=wlj8N4Nd1_8cpmccoe0
36
36
  trilogy/core/processing/node_generators/group_to_node.py,sha256=RNvDo0x1TNFCDi97IAZ4taLMEe9Wv0XzNtuCCM9vjvw,2537
37
37
  trilogy/core/processing/node_generators/multiselect_node.py,sha256=abS8mWWoTxRXYdjKTgRgdfeLiWcJjZ7qgESYwDv5e_o,6510
38
38
  trilogy/core/processing/node_generators/node_merge_node.py,sha256=IYDS5DNF-5_dpgwre_n1Kh7RBnt4srzgYkaUahe_K_o,14001
39
- trilogy/core/processing/node_generators/rowset_node.py,sha256=C5aPc-KIcedTepv9HyG5kth2fUkMwLs_uQy5YEgZsVo,4584
39
+ trilogy/core/processing/node_generators/rowset_node.py,sha256=kM4N8n20U0zGeHgQBfyXC7PP-ABIdWUHc1q1vnWkfOw,5297
40
40
  trilogy/core/processing/node_generators/select_merge_node.py,sha256=JFoBKETwhmd2KdmoNq4wT2SOrd3Jh-GGcO5qMiUh8JE,12691
41
41
  trilogy/core/processing/node_generators/select_node.py,sha256=bjTylBa-vYbmzpuSpphmIo_Oi78YZpI8ppHnN9KDYDk,1795
42
42
  trilogy/core/processing/node_generators/union_node.py,sha256=MVmLqOZbCEVqZYVZxxWxtDMvyEdSnAg7pU9NzoOXy1I,2517
43
43
  trilogy/core/processing/node_generators/unnest_node.py,sha256=MNNjWW7Dp3A_Xv_XGjzdHU1PHQBauZHMBVKRJhqRZJY,2255
44
44
  trilogy/core/processing/node_generators/window_node.py,sha256=x4n5NWEouMsOS0V9myyJNmEg2e3kUDPLWXQhq3PyUdY,3510
45
45
  trilogy/core/processing/nodes/__init__.py,sha256=WNUmYmZF3uqF2qiJ1L7y0u9qiVD9YnluKds0wA5opJE,4813
46
- trilogy/core/processing/nodes/base_node.py,sha256=A7Kx_2KlEjE3jcsvvFcwMmvCJiIRFS7jDjePTCpNU9E,15573
46
+ trilogy/core/processing/nodes/base_node.py,sha256=t0SQW6z3OdAMDfyuUUtI8NCbDruJLq2-FgZxPuWZS0Q,16567
47
47
  trilogy/core/processing/nodes/filter_node.py,sha256=metDcI7b2QsONOy5l0Mx7by1OhXac0N8yKUDoL_2WWo,2342
48
- trilogy/core/processing/nodes/group_node.py,sha256=j6uiHmAA01ByhZmeJQrAm4ophdvo517b-OibEZSQFLg,7249
49
- trilogy/core/processing/nodes/merge_node.py,sha256=Nc0nV56C-1DzanTg54llvlkuHyK05A17XMa2ut0OeK0,14921
50
- trilogy/core/processing/nodes/select_node_v2.py,sha256=Hk_fQnI8NzpDSaPDNu_C-2QWktf3ZORhzbx0TeOK5Q8,8144
48
+ trilogy/core/processing/nodes/group_node.py,sha256=NdIrmBg7DjFy8KwvRoI653cOyAi1xChcWdXZS8tqMW0,7488
49
+ trilogy/core/processing/nodes/merge_node.py,sha256=7lhmTyWLV5e9zT_m_UJnUgXVGBEoyX98lcUABstcf3w,14916
50
+ trilogy/core/processing/nodes/select_node_v2.py,sha256=Xx2zT1RLFJCMmRQ0GaZnrrgRo33aI53Lgw3PqHRSCp4,8284
51
51
  trilogy/core/processing/nodes/union_node.py,sha256=WHycDepNr16flkgQdwyZRo1g-kzYKWVUb6CZ7N_U4OA,1402
52
52
  trilogy/core/processing/nodes/unnest_node.py,sha256=aR1XKa-bT7f45QYKUOS0EUuc0t4GbvYAEG8ZYFJ67sI,2151
53
53
  trilogy/core/processing/nodes/window_node.py,sha256=kXHhOZ9CZ8AQvUbJXCIxUPQ-NF3ooZT7VBgNUyM3VM8,1213
@@ -72,14 +72,14 @@ trilogy/parsing/common.py,sha256=haPZbJrola5Fvwp940A-MJ1o-EhGXKsRFa-Y2e7OsjU,103
72
72
  trilogy/parsing/config.py,sha256=Z-DaefdKhPDmSXLgg5V4pebhSB0h590vI0_VtHnlukI,111
73
73
  trilogy/parsing/exceptions.py,sha256=92E5i2frv5hj9wxObJZsZqj5T6bglvPzvdvco_vW1Zk,38
74
74
  trilogy/parsing/helpers.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
75
- trilogy/parsing/parse_engine.py,sha256=M2CAqqA-JlR6TK17jkPlcOmy4YhPVlH8YByVTDP3cCI,67122
75
+ trilogy/parsing/parse_engine.py,sha256=CrXaK3KDsMt7C6qYIGy5lH4p3-dQNqRn-34VbI8XRRw,67200
76
76
  trilogy/parsing/render.py,sha256=Dr0QKIaAUi9uxfZZJVNV-todKoTA-tsWXNXPJ4Ohjn0,15650
77
77
  trilogy/parsing/trilogy.lark,sha256=d_d3H8ExBcrVffPLq1TgTcEyWDppPJO2zB6cC6mdq9I,12489
78
78
  trilogy/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
79
  trilogy/scripts/trilogy.py,sha256=DQDW81E5mDMWFP8oPw8q-IyrR2JGxQSDWgUWe2VTSRQ,3731
80
- pytrilogy-0.0.2.48.dist-info/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
81
- pytrilogy-0.0.2.48.dist-info/METADATA,sha256=Rcj4LfUCQoMs2K3dtgpBeFRpNOonJ9A0Q7kstGsMKnk,8426
82
- pytrilogy-0.0.2.48.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
83
- pytrilogy-0.0.2.48.dist-info/entry_points.txt,sha256=0petKryjvvtEfTlbZC1AuMFumH_WQ9v8A19LvoS6G6c,54
84
- pytrilogy-0.0.2.48.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
85
- pytrilogy-0.0.2.48.dist-info/RECORD,,
80
+ pytrilogy-0.0.2.49.dist-info/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
81
+ pytrilogy-0.0.2.49.dist-info/METADATA,sha256=dI1KF17Tz1MjU5LMQwL9wLiQwzI3pUNc469_XthJuTQ,8426
82
+ pytrilogy-0.0.2.49.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
83
+ pytrilogy-0.0.2.49.dist-info/entry_points.txt,sha256=0petKryjvvtEfTlbZC1AuMFumH_WQ9v8A19LvoS6G6c,54
84
+ pytrilogy-0.0.2.49.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
85
+ pytrilogy-0.0.2.49.dist-info/RECORD,,
trilogy/__init__.py CHANGED
@@ -4,6 +4,6 @@ from trilogy.dialect.enums import Dialects
4
4
  from trilogy.executor import Executor
5
5
  from trilogy.parser import parse
6
6
 
7
- __version__ = "0.0.2.48"
7
+ __version__ = "0.0.2.49"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
trilogy/core/models.py CHANGED
@@ -467,7 +467,7 @@ class Concept(Mergeable, Namespaced, SelectContext, BaseModel):
467
467
  )
468
468
 
469
469
  def __repr__(self):
470
- base = f"{self.namespace}.{self.address}@{self.grain}"
470
+ base = f"{self.address}@{self.grain}"
471
471
  return base
472
472
 
473
473
  @property
@@ -662,11 +662,24 @@ class Concept(Mergeable, Namespaced, SelectContext, BaseModel):
662
662
  local_concepts=local_concepts, grain=grain, environment=environment
663
663
  )
664
664
  final_grain = self.grain
665
-
665
+ keys = (
666
+ tuple(
667
+ [
668
+ x.with_select_context(local_concepts, grain, environment)
669
+ for x in self.keys
670
+ ]
671
+ )
672
+ if self.keys
673
+ else None
674
+ )
666
675
  if self.is_aggregate and isinstance(new_lineage, Function):
667
676
  new_lineage = AggregateWrapper(function=new_lineage, by=grain.components)
668
677
  final_grain = grain
669
-
678
+ keys = tuple(grain.components)
679
+ elif (
680
+ self.is_aggregate and not keys and isinstance(new_lineage, AggregateWrapper)
681
+ ):
682
+ keys = tuple(new_lineage.by)
670
683
  return self.__class__(
671
684
  name=self.name,
672
685
  datatype=self.datatype,
@@ -675,16 +688,7 @@ class Concept(Mergeable, Namespaced, SelectContext, BaseModel):
675
688
  lineage=new_lineage,
676
689
  grain=final_grain,
677
690
  namespace=self.namespace,
678
- keys=(
679
- tuple(
680
- [
681
- x.with_select_context(local_concepts, grain, environment)
682
- for x in self.keys
683
- ]
684
- )
685
- if self.keys
686
- else None
687
- ),
691
+ keys=keys,
688
692
  modifiers=self.modifiers,
689
693
  # a select needs to always defer to the environment for pseudonyms
690
694
  # TODO: evaluate if this should be cached
@@ -2626,7 +2630,7 @@ class QueryDatasource(BaseModel):
2626
2630
  and CONFIG.validate_missing
2627
2631
  ):
2628
2632
  raise SyntaxError(
2629
- f"Missing source map for {concept.address} on {key}, have {v}"
2633
+ f"On query datasource missing source map for {concept.address} on {key}, have {v}"
2630
2634
  )
2631
2635
  return v
2632
2636
 
@@ -569,6 +569,8 @@ def validate_stack(
569
569
  resolved = node.resolve()
570
570
 
571
571
  for concept in resolved.output_concepts:
572
+ if concept in resolved.hidden_concepts:
573
+ continue
572
574
  validate_concept(
573
575
  concept,
574
576
  node,
@@ -836,6 +838,7 @@ def _search_concepts(
836
838
  PurposeLineage.ROWSET,
837
839
  PurposeLineage.BASIC,
838
840
  PurposeLineage.MULTISELECT,
841
+ PurposeLineage.UNION,
839
842
  ]:
840
843
  skip.add(priority_concept.address)
841
844
  break
@@ -38,7 +38,7 @@ def gen_rowset_node(
38
38
  rowset: RowsetDerivationStatement = lineage.rowset
39
39
  select: SelectStatement | MultiSelectStatement = lineage.rowset.select
40
40
 
41
- node = get_query_node(environment, select, graph=g, history=history)
41
+ node = get_query_node(environment, select)
42
42
 
43
43
  if not node:
44
44
  logger.info(
@@ -94,15 +94,22 @@ def gen_rowset_node(
94
94
  logger.info(
95
95
  f"{padding(depth)}{LOGGER_PREFIX} no enrichment required for rowset node as all optional found or no optional; exiting early."
96
96
  )
97
- # node.set_preexisting_conditions(conditions.conditional if conditions else None)
98
97
  return node
99
-
100
- possible_joins = concept_to_relevant_joins(node.output_concepts)
98
+ possible_joins = concept_to_relevant_joins(
99
+ [x for x in node.output_concepts if x.derivation != PurposeLineage.ROWSET]
100
+ )
101
+ logger.info({x.address: x.keys for x in possible_joins})
101
102
  if not possible_joins:
102
103
  logger.info(
103
104
  f"{padding(depth)}{LOGGER_PREFIX} no possible joins for rowset node to get {[x.address for x in local_optional]}; have {[x.address for x in node.output_concepts]}"
104
105
  )
105
106
  return node
107
+ if any(x.derivation == PurposeLineage.ROWSET for x in possible_joins):
108
+ logger.info(
109
+ f"{padding(depth)}{LOGGER_PREFIX} cannot enrich rowset node with rowset concepts; exiting early"
110
+ )
111
+ return node
112
+ logger.info([x.address for x in possible_joins + local_optional])
106
113
  enrich_node: MergeNode = source_concepts( # this fetches the parent + join keys
107
114
  # to then connect to the rest of the query
108
115
  mandatory_list=possible_joins + local_optional,
@@ -110,15 +117,28 @@ def gen_rowset_node(
110
117
  g=g,
111
118
  depth=depth + 1,
112
119
  conditions=conditions,
120
+ history=history,
113
121
  )
114
122
  if not enrich_node:
115
123
  logger.info(
116
124
  f"{padding(depth)}{LOGGER_PREFIX} Cannot generate rowset enrichment node for {concept} with optional {local_optional}, returning just rowset node"
117
125
  )
118
126
  return node
127
+
128
+ non_hidden = [
129
+ x for x in node.output_concepts if x.address not in node.hidden_concepts
130
+ ]
131
+ for x in possible_joins:
132
+ if x.address in node.hidden_concepts:
133
+ node.unhide_output_concepts([x])
134
+ non_hidden_enrich = [
135
+ x
136
+ for x in enrich_node.output_concepts
137
+ if x.address not in enrich_node.hidden_concepts
138
+ ]
119
139
  return MergeNode(
120
- input_concepts=enrich_node.output_concepts + node.output_concepts,
121
- output_concepts=node.output_concepts + local_optional,
140
+ input_concepts=non_hidden + non_hidden_enrich,
141
+ output_concepts=non_hidden + local_optional,
122
142
  environment=environment,
123
143
  g=g,
124
144
  depth=depth,
@@ -126,6 +146,6 @@ def gen_rowset_node(
126
146
  node,
127
147
  enrich_node,
128
148
  ],
129
- partial_concepts=node.partial_concepts,
149
+ partial_concepts=node.partial_concepts + enrich_node.partial_concepts,
130
150
  preexisting_conditions=conditions.conditional if conditions else None,
131
151
  )
@@ -211,8 +211,22 @@ class StrategyNode:
211
211
  operator=BooleanOperator.AND,
212
212
  )
213
213
  self.validate_parents()
214
+ self.validate_inputs()
214
215
  self.log = True
215
216
 
217
+ def validate_inputs(self):
218
+ if not self.parents:
219
+ return
220
+ non_hidden = set()
221
+ for x in self.parents:
222
+ for z in x.usable_outputs:
223
+ non_hidden.add(z.address)
224
+ if not all([x.address in non_hidden for x in self.input_concepts]):
225
+ missing = [x for x in self.input_concepts if x.address not in non_hidden]
226
+ raise ValueError(
227
+ f"Invalid input concepts; {missing} are missing non-hidden parent nodes"
228
+ )
229
+
216
230
  def add_parents(self, parents: list["StrategyNode"]):
217
231
  self.parents += parents
218
232
  self.validate_parents()
@@ -288,6 +302,14 @@ class StrategyNode:
288
302
  self.rebuild_cache()
289
303
  return self
290
304
 
305
+ def unhide_output_concepts(self, concepts: List[Concept], rebuild: bool = True):
306
+ self.hidden_concepts = [
307
+ x for x in self.hidden_concepts if x.address not in concepts
308
+ ]
309
+ if rebuild:
310
+ self.rebuild_cache()
311
+ return self
312
+
291
313
  def remove_output_concepts(self, concepts: List[Concept], rebuild: bool = True):
292
314
  for x in concepts:
293
315
  self.hidden_concepts.append(x)
@@ -299,6 +321,12 @@ class StrategyNode:
299
321
  self.rebuild_cache()
300
322
  return self
301
323
 
324
+ @property
325
+ def usable_outputs(self) -> list[Concept]:
326
+ return [
327
+ x for x in self.output_concepts if x.address not in self.hidden_concepts
328
+ ]
329
+
302
330
  @property
303
331
  def logging_prefix(self) -> str:
304
332
  return "\t" * self.depth
@@ -105,9 +105,9 @@ class GroupNode(StrategyNode):
105
105
  logger.info(
106
106
  f"{self.logging_prefix}{LOGGER_PREFIX} Parent node"
107
107
  f" {[c.address for c in parent.output_concepts[:2]]}... has"
108
- " grain"
108
+ " set node grain"
109
109
  f" {parent.grain}"
110
- f" resolved grain {parent.resolve().grain}"
110
+ f" and resolved grain {parent.resolve().grain}"
111
111
  f" {type(parent)}"
112
112
  )
113
113
  source_type = SourceType.GROUP
@@ -146,7 +146,13 @@ class GroupNode(StrategyNode):
146
146
  # inject an additional CTE
147
147
  if self.conditions and not is_scalar_condition(self.conditions):
148
148
  base.condition = None
149
- base.output_concepts = self.output_concepts + self.conditions.row_arguments
149
+ base.output_concepts = unique(
150
+ base.output_concepts + self.conditions.row_arguments, "address"
151
+ )
152
+ # re-visible any hidden concepts
153
+ base.hidden_concepts = [
154
+ x for x in base.hidden_concepts if x not in base.output_concepts
155
+ ]
150
156
  source_map = resolve_concept_map(
151
157
  [base],
152
158
  targets=self.output_concepts,
@@ -330,8 +330,9 @@ class MergeNode(StrategyNode):
330
330
  force_group = None
331
331
 
332
332
  qd_joins: List[BaseJoin | UnnestJoin] = [*joins]
333
+
333
334
  source_map = resolve_concept_map(
334
- list(merged.values()),
335
+ final_datasets,
335
336
  targets=self.output_concepts,
336
337
  inherited_inputs=self.input_concepts + self.existence_concepts,
337
338
  full_joins=full_join_concepts,
@@ -339,6 +340,7 @@ class MergeNode(StrategyNode):
339
340
  nullable_concepts = find_nullable_concepts(
340
341
  source_map=source_map, joins=joins, datasources=final_datasets
341
342
  )
343
+
342
344
  qds = QueryDatasource(
343
345
  input_concepts=unique(self.input_concepts, "address"),
344
346
  output_concepts=unique(self.output_concepts, "address"),
@@ -67,6 +67,11 @@ class SelectNode(StrategyNode):
67
67
  self.accept_partial = accept_partial
68
68
  self.datasource = datasource
69
69
 
70
+ def validate_inputs(self):
71
+ # we do not need to validate inputs for a select node
72
+ # as it will be a root
73
+ return
74
+
70
75
  def resolve_from_provided_datasource(
71
76
  self,
72
77
  ) -> QueryDatasource:
@@ -214,7 +214,7 @@ def concept_to_relevant_joins(concepts: list[Concept]) -> List[Concept]:
214
214
  x for x in concepts if x.keys and all([key in addresses for key in x.keys])
215
215
  ]
216
216
  )
217
- final = [c for c in concepts if c not in sub_props]
217
+ final = [c for c in concepts if c.address not in sub_props]
218
218
  return unique(final, "address")
219
219
 
220
220
 
@@ -7,7 +7,6 @@ from trilogy.core.constants import CONSTANT_DATASET
7
7
  from trilogy.core.enums import BooleanOperator, SourceType
8
8
  from trilogy.core.env_processor import generate_graph
9
9
  from trilogy.core.ergonomics import generate_cte_names
10
- from trilogy.core.graph_models import ReferenceGraph
11
10
  from trilogy.core.models import (
12
11
  CTE,
13
12
  BaseJoin,
@@ -353,13 +352,12 @@ def datasource_to_cte(
353
352
  def get_query_node(
354
353
  environment: Environment,
355
354
  statement: SelectStatement | MultiSelectStatement,
356
- graph: Optional[ReferenceGraph] = None,
357
355
  history: History | None = None,
358
356
  ) -> StrategyNode:
359
357
  environment = environment.duplicate()
360
358
  for k, v in statement.local_concepts.items():
361
359
  environment.concepts[k] = v
362
- graph = graph or generate_graph(environment)
360
+ graph = generate_graph(environment)
363
361
  logger.info(
364
362
  f"{LOGGER_PREFIX} getting source datasource for query with filtering {statement.where_clause_category} and output {[str(c) for c in statement.output_components]}"
365
363
  )
@@ -403,11 +401,10 @@ def get_query_node(
403
401
  def get_query_datasources(
404
402
  environment: Environment,
405
403
  statement: SelectStatement | MultiSelectStatement,
406
- graph: Optional[ReferenceGraph] = None,
407
404
  hooks: Optional[List[BaseHook]] = None,
408
405
  ) -> QueryDatasource:
409
406
 
410
- ds = get_query_node(environment, statement, graph)
407
+ ds = get_query_node(environment, statement)
411
408
  final_qds = ds.resolve()
412
409
  if hooks:
413
410
  for hook in hooks:
@@ -479,10 +476,9 @@ def process_query(
479
476
  hooks: List[BaseHook] | None = None,
480
477
  ) -> ProcessedQuery:
481
478
  hooks = hooks or []
482
- graph = generate_graph(environment)
483
479
 
484
480
  root_datasource = get_query_datasources(
485
- environment=environment, graph=graph, statement=statement, hooks=hooks
481
+ environment=environment, statement=statement, hooks=hooks
486
482
  )
487
483
  for hook in hooks:
488
484
  hook.process_root_datasource(root_datasource)
@@ -570,6 +570,7 @@ class ParseToObjects(Transformer):
570
570
  for new_concept in output.derived_concepts:
571
571
  if new_concept.metadata:
572
572
  new_concept.metadata.line_number = meta.line
573
+ # output.select.local_concepts[new_concept.address] = new_concept
573
574
  self.environment.add_concept(new_concept)
574
575
 
575
576
  return output