pytrilogy 0.0.3.61__py3-none-any.whl → 0.0.3.63__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.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.61
3
+ Version: 0.0.3.63
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,5 +1,5 @@
1
- pytrilogy-0.0.3.61.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
2
- trilogy/__init__.py,sha256=6pE1HEb6lBSW2ODExpQU2E4nDuvhlPqat8goqgVFph4,303
1
+ pytrilogy-0.0.3.63.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
2
+ trilogy/__init__.py,sha256=xI7eP5BeauF-VTS4qQZOvUQEsrA4bRoiDjyUkW0jbZk,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
@@ -43,7 +43,7 @@ trilogy/core/processing/discovery_validation.py,sha256=Ek9jviFgimLMUMYLXBChUQmOD
43
43
  trilogy/core/processing/graph_utils.py,sha256=8QUVrkE9j-9C1AyrCb1nQEh8daCe0u1HuXl-Te85lag,1205
44
44
  trilogy/core/processing/utility.py,sha256=mrfR9pgek-xjxoDQSlvPqOW9dpmREjgzqn4AGoqpGeM,22774
45
45
  trilogy/core/processing/node_generators/__init__.py,sha256=w8TQQgNhyAra6JQHdg1_Ags4BGyxjXYruu6UeC5yOkI,873
46
- trilogy/core/processing/node_generators/basic_node.py,sha256=8NtHZ99mJhJwDIib3xlcrn7oWmE42HHKuBpnwXIzpyo,4861
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
48
48
  trilogy/core/processing/node_generators/filter_node.py,sha256=0hdfiS2I-Jvr6P-il3jnAJK-g-DMG7_cFbZGCnLnJAo,10032
49
49
  trilogy/core/processing/node_generators/group_node.py,sha256=nIfiMrJQEksUfqAeeA3X5PS1343y4lmPTipYuCa-rvs,6141
@@ -54,7 +54,7 @@ trilogy/core/processing/node_generators/recursive_node.py,sha256=l5zdh0dURKwmAy8
54
54
  trilogy/core/processing/node_generators/rowset_node.py,sha256=2BiSsegbRF9csJ_Xl8P_CxIm4dAAb7dF29u6v_Odr-A,6709
55
55
  trilogy/core/processing/node_generators/select_merge_node.py,sha256=lxXhMhDKGbu67QFNbbAT-BO8gbWppIvjn_hAXpLEPe0,19953
56
56
  trilogy/core/processing/node_generators/select_node.py,sha256=3dvw0d53eUtCRCUPN6J48I3qBEX1Wha7saQ_ndPu6_I,1777
57
- trilogy/core/processing/node_generators/synonym_node.py,sha256=BNfdwTunCerIzm7YLISI_XcfxxUzWLrZrRvZvayScSk,2257
57
+ trilogy/core/processing/node_generators/synonym_node.py,sha256=QNAMUknGPKRXkh5M_cQrff3b5B68KNcLxt1WHs8wBy4,3496
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
@@ -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.61.dist-info/METADATA,sha256=rXq2NHO2bCO_JhPw5mu8Xj2lEOHcnX73fENl0m7-P2s,9095
114
- pytrilogy-0.0.3.61.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
115
- pytrilogy-0.0.3.61.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
116
- pytrilogy-0.0.3.61.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
117
- pytrilogy-0.0.3.61.dist-info/RECORD,,
113
+ pytrilogy-0.0.3.63.dist-info/METADATA,sha256=_iY3_JWL-W2VdevN6O37KO4VTlRsftF8w2n3Qqk9fxw,9095
114
+ pytrilogy-0.0.3.63.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
115
+ pytrilogy-0.0.3.63.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
116
+ pytrilogy-0.0.3.63.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
117
+ pytrilogy-0.0.3.63.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.3.61"
7
+ __version__ = "0.0.3.63"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -52,6 +52,9 @@ def gen_basic_node(
52
52
  synonyms: list[BuildConcept] = []
53
53
  ignored_optional: set[str] = set()
54
54
  assert isinstance(concept.lineage, BuildFunction)
55
+ # when we are getting an attribute, if there is anything else
56
+ # that is an attribute of the same struct in local optional
57
+ # select that value for discovery as well
55
58
  if concept.lineage.operator == FunctionType.ATTR_ACCESS:
56
59
  logger.info(
57
60
  f"{depth_prefix}{LOGGER_PREFIX} checking for synonyms for attribute access"
@@ -62,7 +65,10 @@ def gen_basic_node(
62
65
  # gate to ensure we don't match to multiple synonyms
63
66
  if found:
64
67
  continue
65
- s_concept = environment.alias_origin_lookup[z]
68
+ if z in environment.concepts:
69
+ s_concept = environment.concepts[z]
70
+ else:
71
+ s_concept = environment.alias_origin_lookup[z]
66
72
  if is_equivalent_basic_function_lineage(concept, s_concept):
67
73
  found = True
68
74
  synonyms.append(s_concept)
@@ -43,16 +43,45 @@ def gen_synonym_node(
43
43
  elif y in environment.concepts:
44
44
  synonyms[x.address].append(environment.concepts[y])
45
45
  synonym_count += 1
46
+ for address in synonyms:
47
+ synonyms[address].sort(key=lambda obj: obj.address)
46
48
  if synonym_count == 0:
47
49
  return None
48
50
 
49
51
  logger.info(f"{local_prefix} Generating Synonym Node with {len(synonyms)} synonyms")
52
+ sorted_keys = sorted(synonyms.keys())
53
+ combinations_list = list(itertools.product(*(synonyms[obj] for obj in sorted_keys)))
50
54
 
51
- combinations = itertools.product(*(synonyms[obj] for obj in synonyms.keys()))
52
- for combo in combinations:
55
+ def similarity_sort_key(combo):
56
+ addresses = [x.address for x in combo]
57
+
58
+ # Calculate similarity score - count how many pairs share prefixes
59
+ similarity_score = 0
60
+ for i in range(len(addresses)):
61
+ for j in range(i + 1, len(addresses)):
62
+ # Find common prefix length
63
+ addr1_parts = addresses[i].split(".")
64
+ addr2_parts = addresses[j].split(".")
65
+ common_prefix_len = 0
66
+ for k in range(min(len(addr1_parts), len(addr2_parts))):
67
+ if addr1_parts[k] == addr2_parts[k]:
68
+ common_prefix_len += 1
69
+ else:
70
+ break
71
+ similarity_score += common_prefix_len
72
+
73
+ # Sort by similarity (descending), then by addresses (ascending) for ties
74
+ return (-similarity_score, addresses)
75
+
76
+ combinations_list.sort(key=similarity_sort_key)
77
+ logger.info(combinations_list)
78
+ for combo in combinations_list:
53
79
  fingerprint = tuple([x.address for x in combo])
54
80
  if fingerprint == base_fingerprint:
55
81
  continue
82
+ logger.info(
83
+ f"{local_prefix} checking combination {fingerprint} with {len(combo)} concepts"
84
+ )
56
85
  attempt: StrategyNode | None = source_concepts(
57
86
  combo,
58
87
  history=history,