pytrilogy 0.0.3.67__py3-none-any.whl → 0.0.3.68__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.
- {pytrilogy-0.0.3.67.dist-info → pytrilogy-0.0.3.68.dist-info}/METADATA +1 -1
- {pytrilogy-0.0.3.67.dist-info → pytrilogy-0.0.3.68.dist-info}/RECORD +12 -12
- trilogy/__init__.py +1 -1
- trilogy/core/processing/discovery_node_factory.py +8 -7
- trilogy/core/processing/node_generators/select_merge_node.py +7 -2
- trilogy/core/processing/node_generators/synonym_node.py +8 -13
- trilogy/core/processing/utility.py +17 -43
- trilogy/dialect/base.py +2 -0
- {pytrilogy-0.0.3.67.dist-info → pytrilogy-0.0.3.68.dist-info}/WHEEL +0 -0
- {pytrilogy-0.0.3.67.dist-info → pytrilogy-0.0.3.68.dist-info}/entry_points.txt +0 -0
- {pytrilogy-0.0.3.67.dist-info → pytrilogy-0.0.3.68.dist-info}/licenses/LICENSE.md +0 -0
- {pytrilogy-0.0.3.67.dist-info → pytrilogy-0.0.3.68.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
pytrilogy-0.0.3.
|
|
2
|
-
trilogy/__init__.py,sha256=
|
|
1
|
+
pytrilogy-0.0.3.68.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
|
|
2
|
+
trilogy/__init__.py,sha256=c1CqFUPhjgRs6876P3SAh2D8kHJp6_QydaF_JJeDlJc,303
|
|
3
3
|
trilogy/compiler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
trilogy/constants.py,sha256=lv_aJWP6dn6e2aF4BAE72jbnNtceFddfqtiDSsvzno0,1692
|
|
5
5
|
trilogy/engine.py,sha256=OK2RuqCIUId6yZ5hfF8J1nxGP0AJqHRZiafcowmW0xc,1728
|
|
@@ -37,11 +37,11 @@ trilogy/core/optimizations/predicate_pushdown.py,sha256=g4AYE8Aw_iMlAh68TjNXGP75
|
|
|
37
37
|
trilogy/core/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
38
|
trilogy/core/processing/concept_strategies_v3.py,sha256=zy5VZa9LITOws6aIILfv_bSR2-jR1Ndldy-nmwMyQ5w,23144
|
|
39
39
|
trilogy/core/processing/discovery_loop.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
-
trilogy/core/processing/discovery_node_factory.py,sha256=
|
|
40
|
+
trilogy/core/processing/discovery_node_factory.py,sha256=Uza_wrB6K965rXbwCuWvBtsDMftq2m0hAav9B5bxQ8k,15049
|
|
41
41
|
trilogy/core/processing/discovery_utility.py,sha256=3xdd1ypKappSDm0SJs7WtW5YegL80SlYhDQlkNePp4E,4549
|
|
42
42
|
trilogy/core/processing/discovery_validation.py,sha256=fGWJmKpgEd1f4RkK-fYOBUT1cwsJnahwXFAdRlou7MI,5365
|
|
43
43
|
trilogy/core/processing/graph_utils.py,sha256=8QUVrkE9j-9C1AyrCb1nQEh8daCe0u1HuXl-Te85lag,1205
|
|
44
|
-
trilogy/core/processing/utility.py,sha256=
|
|
44
|
+
trilogy/core/processing/utility.py,sha256=b1F3NT7-MP_-U4KmpC52BOAwLu6mybfndeA1iiZwChw,22016
|
|
45
45
|
trilogy/core/processing/node_generators/__init__.py,sha256=w8TQQgNhyAra6JQHdg1_Ags4BGyxjXYruu6UeC5yOkI,873
|
|
46
46
|
trilogy/core/processing/node_generators/basic_node.py,sha256=luN8LftafZepoFgDRv4gmvEGFlOI2j0icJ5fz4UT7uo,5165
|
|
47
47
|
trilogy/core/processing/node_generators/common.py,sha256=PdysdroW9DUADP7f5Wv_GKPUyCTROZV1g3L45fawxi8,9443
|
|
@@ -52,9 +52,9 @@ trilogy/core/processing/node_generators/multiselect_node.py,sha256=GWV5yLmKTe1yy
|
|
|
52
52
|
trilogy/core/processing/node_generators/node_merge_node.py,sha256=dSqfqWp2SolhDB16nkPaaTXgNQo4QquEufPdf7q0Tb4,17398
|
|
53
53
|
trilogy/core/processing/node_generators/recursive_node.py,sha256=l5zdh0dURKwmAy8kK4OpMtZfyUEQRk6N-PwSWIyBpSM,2468
|
|
54
54
|
trilogy/core/processing/node_generators/rowset_node.py,sha256=2BiSsegbRF9csJ_Xl8P_CxIm4dAAb7dF29u6v_Odr-A,6709
|
|
55
|
-
trilogy/core/processing/node_generators/select_merge_node.py,sha256=
|
|
55
|
+
trilogy/core/processing/node_generators/select_merge_node.py,sha256=EmU6QUOEKOOKVJreHxDJZakd2FpD1V1W8ZGOOLLaWdo,21462
|
|
56
56
|
trilogy/core/processing/node_generators/select_node.py,sha256=Ta1G39V94gjX_AgyZDz9OqnwLz4BjY3D6Drx9YpziMQ,3555
|
|
57
|
-
trilogy/core/processing/node_generators/synonym_node.py,sha256=
|
|
57
|
+
trilogy/core/processing/node_generators/synonym_node.py,sha256=AnAsa_Wj50NJ_IK0HSgab_7klYmKVrv0WI1uUe-GvEY,3766
|
|
58
58
|
trilogy/core/processing/node_generators/union_node.py,sha256=VNo6Oey4p8etU9xrOh2oTT2lIOTvY6PULUPRvVa2uxU,2877
|
|
59
59
|
trilogy/core/processing/node_generators/unnest_node.py,sha256=ueOQtoTf2iJHO09RzWHDFQ5iKZq2fVhGf2KAF2U2kU8,2677
|
|
60
60
|
trilogy/core/processing/node_generators/window_node.py,sha256=GP3Hvkbb0TDA6ef7W7bmvQEHVH-NRIfBT_0W4fcH3g4,6529
|
|
@@ -76,7 +76,7 @@ trilogy/core/statements/build.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
|
76
76
|
trilogy/core/statements/common.py,sha256=KxEmz2ySySyZ6CTPzn0fJl5NX2KOk1RPyuUSwWhnK1g,759
|
|
77
77
|
trilogy/core/statements/execute.py,sha256=rqfuoMuXPcH7L7TmE1dSiZ_K_A1ohB8whVMfGimZBOk,1294
|
|
78
78
|
trilogy/dialect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
-
trilogy/dialect/base.py,sha256=
|
|
79
|
+
trilogy/dialect/base.py,sha256=CMrYlE-oQzdmefmNPBRzT7OA842UV-P1sCqa0JAcP4Q,43741
|
|
80
80
|
trilogy/dialect/bigquery.py,sha256=6ghCqy-k7UioIJc1EEQ7gRo_PHaO8Vm7yYbiQ-kgpzs,3629
|
|
81
81
|
trilogy/dialect/common.py,sha256=hhzuMTFW9QQIP7TKLT9BlJy6lw2R03a68jKQ-7t4-2c,6070
|
|
82
82
|
trilogy/dialect/config.py,sha256=olnyeVU5W5T6b9-dMeNAnvxuPlyc2uefb7FRME094Ec,3834
|
|
@@ -110,8 +110,8 @@ trilogy/std/money.preql,sha256=XWwvAV3WxBsHX9zfptoYRnBigcfYwrYtBHXTME0xJuQ,2082
|
|
|
110
110
|
trilogy/std/net.preql,sha256=-bMV6dyofskl4Kvows-iQ4JCxjVUwsZOeWCy8JO5Ftw,135
|
|
111
111
|
trilogy/std/ranking.preql,sha256=LDoZrYyz4g3xsII9XwXfmstZD-_92i1Eox1UqkBIfi8,83
|
|
112
112
|
trilogy/std/report.preql,sha256=LbV-XlHdfw0jgnQ8pV7acG95xrd1-p65fVpiIc-S7W4,202
|
|
113
|
-
pytrilogy-0.0.3.
|
|
114
|
-
pytrilogy-0.0.3.
|
|
115
|
-
pytrilogy-0.0.3.
|
|
116
|
-
pytrilogy-0.0.3.
|
|
117
|
-
pytrilogy-0.0.3.
|
|
113
|
+
pytrilogy-0.0.3.68.dist-info/METADATA,sha256=XA1FhFxajFv-4bT9JSbdv5gH5LvikdjwiJ33kAUdfQI,9095
|
|
114
|
+
pytrilogy-0.0.3.68.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
115
|
+
pytrilogy-0.0.3.68.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
|
|
116
|
+
pytrilogy-0.0.3.68.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
|
|
117
|
+
pytrilogy-0.0.3.68.dist-info/RECORD,,
|
trilogy/__init__.py
CHANGED
|
@@ -307,16 +307,17 @@ class RootNodeHandler:
|
|
|
307
307
|
def _resolve_root_concepts(
|
|
308
308
|
self, root_targets: List[BuildConcept]
|
|
309
309
|
) -> Optional[StrategyNode]:
|
|
310
|
-
synonym_node = self._try_synonym_resolution(root_targets)
|
|
311
|
-
if synonym_node:
|
|
312
|
-
logger.info(
|
|
313
|
-
f"{depth_to_prefix(self.ctx.depth)}{LOGGER_PREFIX} "
|
|
314
|
-
f"resolved root concepts through synonyms"
|
|
315
|
-
)
|
|
316
|
-
return synonym_node
|
|
317
310
|
expanded_node = self._try_merge_expansion(root_targets)
|
|
318
311
|
if expanded_node:
|
|
319
312
|
return expanded_node
|
|
313
|
+
if self.ctx.accept_partial:
|
|
314
|
+
synonym_node = self._try_synonym_resolution(root_targets)
|
|
315
|
+
if synonym_node:
|
|
316
|
+
logger.info(
|
|
317
|
+
f"{depth_to_prefix(self.ctx.depth)}{LOGGER_PREFIX} "
|
|
318
|
+
f"resolved root concepts through synonyms"
|
|
319
|
+
)
|
|
320
|
+
return synonym_node
|
|
320
321
|
|
|
321
322
|
return None
|
|
322
323
|
|
|
@@ -493,7 +493,7 @@ def create_select_node(
|
|
|
493
493
|
else:
|
|
494
494
|
|
|
495
495
|
candidate = bcandidate
|
|
496
|
-
|
|
496
|
+
|
|
497
497
|
return candidate
|
|
498
498
|
|
|
499
499
|
|
|
@@ -536,7 +536,12 @@ def gen_select_merge_node(
|
|
|
536
536
|
force_group=False,
|
|
537
537
|
conditions=conditions.conditional if conditions else None,
|
|
538
538
|
)
|
|
539
|
-
|
|
539
|
+
attempts = [
|
|
540
|
+
False,
|
|
541
|
+
]
|
|
542
|
+
if accept_partial:
|
|
543
|
+
attempts.append(True)
|
|
544
|
+
for attempt in attempts:
|
|
540
545
|
pruned_concept_graph = create_pruned_concept_graph(
|
|
541
546
|
g,
|
|
542
547
|
non_constant,
|
|
@@ -3,8 +3,8 @@ from collections import defaultdict
|
|
|
3
3
|
from typing import List
|
|
4
4
|
|
|
5
5
|
from trilogy.constants import logger
|
|
6
|
-
from trilogy.core.enums import
|
|
7
|
-
from trilogy.core.models.build import BuildConcept,
|
|
6
|
+
from trilogy.core.enums import Derivation
|
|
7
|
+
from trilogy.core.models.build import BuildConcept, BuildWhereClause
|
|
8
8
|
from trilogy.core.models.build_environment import BuildEnvironment
|
|
9
9
|
from trilogy.core.processing.nodes import History, StrategyNode
|
|
10
10
|
from trilogy.core.processing.utility import padding
|
|
@@ -12,13 +12,6 @@ from trilogy.core.processing.utility import padding
|
|
|
12
12
|
LOGGER_PREFIX = "[GEN_SYNONYM_NODE]"
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def is_union(c: BuildConcept):
|
|
16
|
-
return (
|
|
17
|
-
isinstance(c.lineage, BuildFunction)
|
|
18
|
-
and c.lineage.operator == FunctionType.UNION
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
15
|
def gen_synonym_node(
|
|
23
16
|
all_concepts: List[BuildConcept],
|
|
24
17
|
environment: BuildEnvironment,
|
|
@@ -41,7 +34,6 @@ def gen_synonym_node(
|
|
|
41
34
|
synonyms[x.address].append(parent)
|
|
42
35
|
has_synonyms = True
|
|
43
36
|
for y in x.pseudonyms:
|
|
44
|
-
|
|
45
37
|
if y in environment.alias_origin_lookup:
|
|
46
38
|
synonyms[x.address].append(environment.alias_origin_lookup[y])
|
|
47
39
|
has_synonyms = True
|
|
@@ -59,11 +51,14 @@ def gen_synonym_node(
|
|
|
59
51
|
itertools.product(*(synonyms[obj] for obj in sorted_keys))
|
|
60
52
|
)
|
|
61
53
|
|
|
62
|
-
def similarity_sort_key(combo):
|
|
54
|
+
def similarity_sort_key(combo: tuple[BuildConcept, ...]):
|
|
63
55
|
addresses = [x.address for x in combo]
|
|
64
56
|
|
|
65
57
|
# Calculate similarity score - count how many pairs share prefixes
|
|
66
58
|
similarity_score = 0
|
|
59
|
+
roots = sum(
|
|
60
|
+
[1 for x in combo if x.derivation in (Derivation.ROOT, Derivation.CONSTANT)]
|
|
61
|
+
)
|
|
67
62
|
for i in range(len(addresses)):
|
|
68
63
|
for j in range(i + 1, len(addresses)):
|
|
69
64
|
# Find common prefix length
|
|
@@ -77,8 +72,8 @@ def gen_synonym_node(
|
|
|
77
72
|
break
|
|
78
73
|
similarity_score += common_prefix_len
|
|
79
74
|
|
|
80
|
-
# Sort by similarity (descending), then by addresses (ascending) for ties
|
|
81
|
-
return (-similarity_score, addresses)
|
|
75
|
+
# Sort by roots, similarity (descending), then by addresses (ascending) for ties
|
|
76
|
+
return (-roots, -similarity_score, addresses)
|
|
82
77
|
|
|
83
78
|
combinations_list.sort(key=similarity_sort_key)
|
|
84
79
|
for combo in combinations_list:
|
|
@@ -322,8 +322,10 @@ def resolve_instantiated_concept(
|
|
|
322
322
|
for k in concept.pseudonyms:
|
|
323
323
|
if k in datasource.output_concepts:
|
|
324
324
|
return [x for x in datasource.output_concepts if x.address == k].pop()
|
|
325
|
+
if any(k in x.pseudonyms for x in datasource.output_concepts):
|
|
326
|
+
return [x for x in datasource.output_concepts if k in x.pseudonyms].pop()
|
|
325
327
|
raise SyntaxError(
|
|
326
|
-
f"Could not find {concept.address} in {datasource.identifier} output {[c.address for c in datasource.output_concepts]}"
|
|
328
|
+
f"Could not find {concept.address} in {datasource.identifier} output {[c.address for c in datasource.output_concepts]}, acceptable synonyms {concept.pseudonyms}"
|
|
327
329
|
)
|
|
328
330
|
|
|
329
331
|
|
|
@@ -601,19 +603,28 @@ def find_nullable_concepts(
|
|
|
601
603
|
|
|
602
604
|
|
|
603
605
|
def sort_select_output_processed(
|
|
604
|
-
cte: CTE | UnionCTE, query: ProcessedQuery
|
|
606
|
+
cte: CTE | UnionCTE, query: SelectStatement | MultiSelectStatement | ProcessedQuery
|
|
605
607
|
) -> CTE | UnionCTE:
|
|
606
|
-
|
|
608
|
+
if isinstance(query, ProcessedQuery):
|
|
609
|
+
targets = query.output_columns
|
|
610
|
+
hidden = query.hidden_columns
|
|
611
|
+
else:
|
|
612
|
+
targets = query.output_components
|
|
613
|
+
hidden = query.hidden_components
|
|
614
|
+
|
|
615
|
+
output_addresses = [c.address for c in targets]
|
|
607
616
|
|
|
608
617
|
mapping = {x.address: x for x in cte.output_columns}
|
|
609
618
|
|
|
610
619
|
new_output: list[BuildConcept] = []
|
|
611
|
-
for x in
|
|
620
|
+
for x in targets:
|
|
612
621
|
if x.address in mapping:
|
|
613
622
|
new_output.append(mapping[x.address])
|
|
614
623
|
for oc in cte.output_columns:
|
|
615
624
|
if x.address in oc.pseudonyms:
|
|
616
625
|
# create a wrapper BuildConcept to render the pseudonym under the original name
|
|
626
|
+
if any(x.address == y for y in mapping.keys()):
|
|
627
|
+
continue
|
|
617
628
|
new_output.append(
|
|
618
629
|
BuildConcept(
|
|
619
630
|
name=x.name,
|
|
@@ -636,10 +647,7 @@ def sort_select_output_processed(
|
|
|
636
647
|
[
|
|
637
648
|
c.address
|
|
638
649
|
for c in cte.output_columns
|
|
639
|
-
if (
|
|
640
|
-
c.address not in query.output_columns
|
|
641
|
-
or c.address in query.hidden_columns
|
|
642
|
-
)
|
|
650
|
+
if (c.address not in targets or c.address in hidden)
|
|
643
651
|
]
|
|
644
652
|
)
|
|
645
653
|
cte.output_columns = new_output
|
|
@@ -650,38 +658,4 @@ def sort_select_output(
|
|
|
650
658
|
cte: CTE | UnionCTE, query: SelectStatement | MultiSelectStatement | ProcessedQuery
|
|
651
659
|
) -> CTE | UnionCTE:
|
|
652
660
|
|
|
653
|
-
|
|
654
|
-
return sort_select_output_processed(cte, query)
|
|
655
|
-
|
|
656
|
-
mapping = {x.address: x for x in cte.output_columns}
|
|
657
|
-
|
|
658
|
-
new_output: list[BuildConcept] = []
|
|
659
|
-
for x in query.output_components:
|
|
660
|
-
if x.address in mapping:
|
|
661
|
-
new_output.append(mapping[x.address])
|
|
662
|
-
else:
|
|
663
|
-
for oc in cte.output_columns:
|
|
664
|
-
if x.address in oc.pseudonyms:
|
|
665
|
-
# create a wrapper BuildConcept to render the pseudonym under the original name
|
|
666
|
-
new_output.append(
|
|
667
|
-
BuildConcept(
|
|
668
|
-
name=x.name,
|
|
669
|
-
namespace=x.namespace,
|
|
670
|
-
pseudonyms={oc.address},
|
|
671
|
-
datatype=oc.datatype,
|
|
672
|
-
purpose=oc.purpose,
|
|
673
|
-
grain=oc.grain,
|
|
674
|
-
build_is_aggregate=oc.build_is_aggregate,
|
|
675
|
-
)
|
|
676
|
-
)
|
|
677
|
-
break
|
|
678
|
-
cte.output_columns = new_output
|
|
679
|
-
cte.hidden_concepts = set(
|
|
680
|
-
[
|
|
681
|
-
c.address
|
|
682
|
-
for c in query.output_components
|
|
683
|
-
if c.address in query.hidden_components
|
|
684
|
-
]
|
|
685
|
-
)
|
|
686
|
-
|
|
687
|
-
return cte
|
|
661
|
+
return sort_select_output_processed(cte, query)
|
trilogy/dialect/base.py
CHANGED
|
@@ -762,6 +762,7 @@ class BaseDialect:
|
|
|
762
762
|
] + [
|
|
763
763
|
f"{self.QUOTE_CHARACTER}{c.safe_address}{self.QUOTE_CHARACTER}"
|
|
764
764
|
for c in cte.join_derived_concepts
|
|
765
|
+
if c.address not in cte.hidden_concepts
|
|
765
766
|
]
|
|
766
767
|
elif self.UNNEST_MODE in (UnnestMode.CROSS_JOIN_UNNEST, UnnestMode.PRESTO):
|
|
767
768
|
select_columns = [
|
|
@@ -772,6 +773,7 @@ class BaseDialect:
|
|
|
772
773
|
] + [
|
|
773
774
|
f"{UNNEST_NAME} as {self.QUOTE_CHARACTER}{c.safe_address}{self.QUOTE_CHARACTER}"
|
|
774
775
|
for c in cte.join_derived_concepts
|
|
776
|
+
if c.address not in cte.hidden_concepts
|
|
775
777
|
]
|
|
776
778
|
else:
|
|
777
779
|
# otherwse, assume we are unnesting directly in the select
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|