pytrilogy 0.0.3.117__py3-none-any.whl → 0.0.3.120__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.117.dist-info → pytrilogy-0.0.3.120.dist-info}/METADATA +1 -1
- {pytrilogy-0.0.3.117.dist-info → pytrilogy-0.0.3.120.dist-info}/RECORD +18 -17
- trilogy/__init__.py +1 -1
- trilogy/ai/conversation.py +3 -4
- trilogy/core/functions.py +31 -1
- trilogy/core/models/author.py +7 -2
- trilogy/core/models/core.py +7 -0
- trilogy/core/models/environment.py +3 -2
- trilogy/core/processing/discovery_utility.py +4 -4
- trilogy/core/processing/nodes/base_node.py +5 -1
- trilogy/parsing/parse_engine.py +37 -5
- trilogy/parsing/trilogy.lark +3 -1
- trilogy/std/ranking.preql +1 -0
- trilogy/std/semantic.preql +6 -0
- {pytrilogy-0.0.3.117.dist-info → pytrilogy-0.0.3.120.dist-info}/WHEEL +0 -0
- {pytrilogy-0.0.3.117.dist-info → pytrilogy-0.0.3.120.dist-info}/entry_points.txt +0 -0
- {pytrilogy-0.0.3.117.dist-info → pytrilogy-0.0.3.120.dist-info}/licenses/LICENSE.md +0 -0
- {pytrilogy-0.0.3.117.dist-info → pytrilogy-0.0.3.120.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.120.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
|
|
2
|
+
trilogy/__init__.py,sha256=BF_I6R5zTDgQVvWrf-0TvooZTV3UV4ex98-KtPY70ak,304
|
|
3
3
|
trilogy/constants.py,sha256=_Tm7YGaAZuxH77X5ve0TajU0dQD7RcGV6ECrTHRL3qQ,2678
|
|
4
4
|
trilogy/engine.py,sha256=v4TpNktM4zZ9OX7jZH2nde4dpX5uAH2U23ELfULTCSg,2280
|
|
5
5
|
trilogy/executor.py,sha256=uKlCnPp4FHkgsa_dDcQJ4y-ObtvKat2KFx05c-z1mZo,17885
|
|
@@ -9,7 +9,7 @@ trilogy/render.py,sha256=qQWwduymauOlB517UtM-VGbVe8Cswa4UJub5aGbSO6c,1512
|
|
|
9
9
|
trilogy/utility.py,sha256=euQccZLKoYBz0LNg5tzLlvv2YHvXh9HArnYp1V3uXsM,763
|
|
10
10
|
trilogy/ai/__init__.py,sha256=H6gpzScruX2xgZNRDMjQ31Wy45irJbdebX1fU_gOwI8,581
|
|
11
11
|
trilogy/ai/constants.py,sha256=Aj-_mFqskcXqIlBjX_A9eqH0V9M8mqX3uJwUhr9puak,5064
|
|
12
|
-
trilogy/ai/conversation.py,sha256=
|
|
12
|
+
trilogy/ai/conversation.py,sha256=yei5iKsVCyo-GRmHtfto2grCjBs_TwAbGChD3w97pqg,3482
|
|
13
13
|
trilogy/ai/enums.py,sha256=vghPPx0W-DioQSgq4T0MGL-8ekFh6O6d52dHo7KsKtg,118
|
|
14
14
|
trilogy/ai/execute.py,sha256=DTARZxm_btCJq4Yd_jPRHJAcbsMLbjEsjR7KKyKBkTI,1335
|
|
15
15
|
trilogy/ai/models.py,sha256=Au4QnTIlv7e-p3XgTJYZqTSndPMGRIbOvCUWlekE81A,683
|
|
@@ -28,19 +28,19 @@ trilogy/core/env_processor.py,sha256=H-rr2ALj31l5oh3FqeI47Qju6OOfiXBacXNJGNZ92zQ
|
|
|
28
28
|
trilogy/core/environment_helpers.py,sha256=TRlqVctqIRBxzfjRBmpQsAVoiCcsEKBhG1B6PUE0l1M,12743
|
|
29
29
|
trilogy/core/ergonomics.py,sha256=e-7gE29vPLFdg0_A1smQ7eOrUwKl5VYdxRSTddHweRA,1631
|
|
30
30
|
trilogy/core/exceptions.py,sha256=axkVXYJYQXCCwMHwlyDA232g4tCOwdCZUt7eHeUMDMg,2829
|
|
31
|
-
trilogy/core/functions.py,sha256=
|
|
31
|
+
trilogy/core/functions.py,sha256=yvy4t1pZmsdTpcP5gxPIpS2G2ULNotmmF7HZcYDH6bE,35857
|
|
32
32
|
trilogy/core/graph_models.py,sha256=4EWFTHGfYd72zvS2HYoV6hm7nMC_VEd7vWr6txY-ig0,3400
|
|
33
33
|
trilogy/core/internal.py,sha256=r9QagDB2GvpqlyD_I7VrsfbVfIk5mnok2znEbv72Aa4,2681
|
|
34
34
|
trilogy/core/optimization.py,sha256=eKieOaWXUtoNTVQbThGA5tqrI06ZR6SUFOqGe4Jw0k4,9262
|
|
35
35
|
trilogy/core/query_processor.py,sha256=rMrtLSQxVm7yeyh0nWjDNI9nnu4Xi0NgHvBJ14gvu4I,20384
|
|
36
36
|
trilogy/core/utility.py,sha256=3VC13uSQWcZNghgt7Ot0ZTeEmNqs__cx122abVq9qhM,410
|
|
37
37
|
trilogy/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
-
trilogy/core/models/author.py,sha256=
|
|
38
|
+
trilogy/core/models/author.py,sha256=gsKPOwgnebnAs2HV72ZHdXYfoUzDs8jQNse8vEwtG3k,86081
|
|
39
39
|
trilogy/core/models/build.py,sha256=zVHD8jo8V8E0aGWtobzXG7hY3VjLChiW4s1QBx9sD5k,72938
|
|
40
40
|
trilogy/core/models/build_environment.py,sha256=mpx7MKGc60fnZLVdeLi2YSREy7eQbQYycCrP4zF-rHU,5258
|
|
41
|
-
trilogy/core/models/core.py,sha256=
|
|
41
|
+
trilogy/core/models/core.py,sha256=mv1QOxf-6uGoWpfwuucNAW3W_ZZGQuxtnPWAXhQsxSI,13290
|
|
42
42
|
trilogy/core/models/datasource.py,sha256=wogTevZ-9CyUW2a8gjzqMCieircxi-J5lkI7EOAZnck,9596
|
|
43
|
-
trilogy/core/models/environment.py,sha256
|
|
43
|
+
trilogy/core/models/environment.py,sha256=m2NZ-UqmHQ1qJo6I-cVGG9Z24O6RTDkrvEd1IfVmWls,28889
|
|
44
44
|
trilogy/core/models/execute.py,sha256=3fgEdho2e7S0outq91cCzb9jFwz6L1hTbsTrJwGvIFs,42311
|
|
45
45
|
trilogy/core/optimizations/__init__.py,sha256=yspWc25M5SgAuvXYoSt5J8atyPbDlOfsKjIo5yGD9s4,368
|
|
46
46
|
trilogy/core/optimizations/base_optimization.py,sha256=gzDOKImoFn36k7XBD3ysEYDnbnb6vdVIztUfFQZsGnM,513
|
|
@@ -50,7 +50,7 @@ trilogy/core/optimizations/predicate_pushdown.py,sha256=5ubatgq1IwWQ4L2FDt4--y16
|
|
|
50
50
|
trilogy/core/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
51
|
trilogy/core/processing/concept_strategies_v3.py,sha256=MBQeJGBDW2w3xxwano43-5MVBqfbIU9M3K7RFbnSKNA,23367
|
|
52
52
|
trilogy/core/processing/discovery_node_factory.py,sha256=llnLxZo1NqBRIuuPz0GUohym6LZFhVkPT3xSiORi3k4,15446
|
|
53
|
-
trilogy/core/processing/discovery_utility.py,sha256=
|
|
53
|
+
trilogy/core/processing/discovery_utility.py,sha256=FpCHCvGslHIJkMIOLBmTJRQKfUtwcwiNgzDxcOsJBIc,13532
|
|
54
54
|
trilogy/core/processing/discovery_validation.py,sha256=eZ4HfHMpqZLI8MGG2jez8arS8THs6ceuVrQFIY6gXrU,5364
|
|
55
55
|
trilogy/core/processing/graph_utils.py,sha256=8QUVrkE9j-9C1AyrCb1nQEh8daCe0u1HuXl-Te85lag,1205
|
|
56
56
|
trilogy/core/processing/utility.py,sha256=ESs6pKqVP2c9eMdfB2JNjw7D7YnoezVwbLFx1D6OUYA,26088
|
|
@@ -74,7 +74,7 @@ trilogy/core/processing/node_generators/window_node.py,sha256=wNvmumGO6AIQ7C9bDU
|
|
|
74
74
|
trilogy/core/processing/node_generators/select_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
75
|
trilogy/core/processing/node_generators/select_helpers/datasource_injection.py,sha256=m2YQ4OmG0N2O61a7NEq1ZzbTa7JsCC00lxB2ymjcYRI,8224
|
|
76
76
|
trilogy/core/processing/nodes/__init__.py,sha256=zTge1EzwzEydlcMliIFO_TT7h7lS8l37lyZuQDir1h0,5487
|
|
77
|
-
trilogy/core/processing/nodes/base_node.py,sha256=
|
|
77
|
+
trilogy/core/processing/nodes/base_node.py,sha256=xrtijyy38xpTt3hzVdEVaDYhk1JWAuB8yGoDJ6R82Jg,18722
|
|
78
78
|
trilogy/core/processing/nodes/filter_node.py,sha256=5VtRfKbCORx0dV-vQfgy3gOEkmmscL9f31ExvlODwvY,2461
|
|
79
79
|
trilogy/core/processing/nodes/group_node.py,sha256=Ku8El9KQvRiTiHCZDS_jX0DjErSDNv7IIQMcd1Gsk7I,7449
|
|
80
80
|
trilogy/core/processing/nodes/merge_node.py,sha256=4y_itKoipHKjpCIQjK9SHga-Fq-HqyeQLwAoSIFQ1hM,16567
|
|
@@ -117,9 +117,9 @@ trilogy/parsing/common.py,sha256=GijDRpysULL6vQWpFcjgxVASuTWXUVUi5fILHvjzkbg,355
|
|
|
117
117
|
trilogy/parsing/config.py,sha256=Z-DaefdKhPDmSXLgg5V4pebhSB0h590vI0_VtHnlukI,111
|
|
118
118
|
trilogy/parsing/exceptions.py,sha256=Xwwsv2C9kSNv2q-HrrKC1f60JNHShXcCMzstTSEbiCw,154
|
|
119
119
|
trilogy/parsing/helpers.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
120
|
-
trilogy/parsing/parse_engine.py,sha256=
|
|
120
|
+
trilogy/parsing/parse_engine.py,sha256=j0lBbJGObcptw4S7xng2hy-Pv-u5aSfFuxYk6TZvciY,87661
|
|
121
121
|
trilogy/parsing/render.py,sha256=k7MNp8EBTqVBSVqFlgTHSwIhfSKLyJfSeb2fSbt9dVA,24307
|
|
122
|
-
trilogy/parsing/trilogy.lark,sha256=
|
|
122
|
+
trilogy/parsing/trilogy.lark,sha256=_FW9Hq7Xo6KDrf1JUxD9NBM0Zn9OyoZzWHj97zFqy-M,17449
|
|
123
123
|
trilogy/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
124
124
|
trilogy/scripts/trilogy.py,sha256=1L0XrH4mVHRt1C9T1HnaDv2_kYEfbWTb5_-cBBke79w,3774
|
|
125
125
|
trilogy/std/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -130,10 +130,11 @@ trilogy/std/geography.preql,sha256=1A9Sq5PPMBnEPPf7f-rPVYxJfsnWpQ8oV_k4Fm3H2dU,6
|
|
|
130
130
|
trilogy/std/metric.preql,sha256=DRECGhkMyqfit5Fl4Ut9zbWrJuSMI1iO9HikuyoBpE0,421
|
|
131
131
|
trilogy/std/money.preql,sha256=XWwvAV3WxBsHX9zfptoYRnBigcfYwrYtBHXTME0xJuQ,2082
|
|
132
132
|
trilogy/std/net.preql,sha256=WZCuvH87_rZntZiuGJMmBDMVKkdhTtxeHOkrXNwJ1EE,416
|
|
133
|
-
trilogy/std/ranking.preql,sha256=
|
|
133
|
+
trilogy/std/ranking.preql,sha256=zDdmHcTerlCjaHDdVyjGTgcc2hAhnlDM_q5tiw0MPGE,108
|
|
134
134
|
trilogy/std/report.preql,sha256=LbV-XlHdfw0jgnQ8pV7acG95xrd1-p65fVpiIc-S7W4,202
|
|
135
|
-
|
|
136
|
-
pytrilogy-0.0.3.
|
|
137
|
-
pytrilogy-0.0.3.
|
|
138
|
-
pytrilogy-0.0.3.
|
|
139
|
-
pytrilogy-0.0.3.
|
|
135
|
+
trilogy/std/semantic.preql,sha256=k9_k672nUb5MKjSD1DW5jjn_odoYHl0yNeRPOjFabsE,95
|
|
136
|
+
pytrilogy-0.0.3.120.dist-info/METADATA,sha256=stpvqxUMDCp2V1Kb5HP-xcjX_H-IscwNLpfDBbFoXL0,12911
|
|
137
|
+
pytrilogy-0.0.3.120.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
138
|
+
pytrilogy-0.0.3.120.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
|
|
139
|
+
pytrilogy-0.0.3.120.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
|
|
140
|
+
pytrilogy-0.0.3.120.dist-info/RECORD,,
|
trilogy/__init__.py
CHANGED
trilogy/ai/conversation.py
CHANGED
|
@@ -61,7 +61,7 @@ class Conversation:
|
|
|
61
61
|
if "```" in content:
|
|
62
62
|
parts = content.split("```")
|
|
63
63
|
if len(parts) >= 3:
|
|
64
|
-
return parts[
|
|
64
|
+
return parts[-2].strip()
|
|
65
65
|
return content
|
|
66
66
|
|
|
67
67
|
def generate_query(
|
|
@@ -78,7 +78,7 @@ class Conversation:
|
|
|
78
78
|
if not response.strip()[-1] == ";":
|
|
79
79
|
response += ";"
|
|
80
80
|
try:
|
|
81
|
-
|
|
81
|
+
_, raw = environment.parse(response)
|
|
82
82
|
process_query(statement=raw[-1], environment=environment)
|
|
83
83
|
return response
|
|
84
84
|
except (
|
|
@@ -90,10 +90,9 @@ class Conversation:
|
|
|
90
90
|
) as e2:
|
|
91
91
|
e = e2
|
|
92
92
|
self.add_message(
|
|
93
|
-
f"
|
|
93
|
+
f"Your extracted response - {response} - could not be parsed due to the error: {str(e)}. Please generate a new query with the issues fixed. Use the same response format.",
|
|
94
94
|
role="user",
|
|
95
95
|
)
|
|
96
|
-
|
|
97
96
|
raise Exception(
|
|
98
97
|
f"Failed to generate a valid query after {attempts} attempts. Last error: {str(e)}. Full conversation: {self.messages}"
|
|
99
98
|
)
|
trilogy/core/functions.py
CHANGED
|
@@ -19,6 +19,7 @@ from trilogy.core.models.author import (
|
|
|
19
19
|
Concept,
|
|
20
20
|
ConceptRef,
|
|
21
21
|
Conditional,
|
|
22
|
+
CustomType,
|
|
22
23
|
Function,
|
|
23
24
|
Parenthetical,
|
|
24
25
|
UndefinedConcept,
|
|
@@ -40,6 +41,11 @@ from trilogy.core.models.environment import Environment
|
|
|
40
41
|
GENERIC_ARGS = Concept | ConceptRef | Function | str | int | float | date | datetime
|
|
41
42
|
|
|
42
43
|
|
|
44
|
+
CUSTOM_PLACEHOLDER = CustomType(
|
|
45
|
+
name="__placeholder__", type=DataType.UNKNOWN, drop_on=[], add_on=[]
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
43
49
|
@dataclass
|
|
44
50
|
class FunctionConfig:
|
|
45
51
|
arg_count: int = 1
|
|
@@ -99,7 +105,18 @@ def get_attr_datatype(
|
|
|
99
105
|
|
|
100
106
|
def get_cast_output_type(
|
|
101
107
|
args: list[Any],
|
|
102
|
-
) -> DataType:
|
|
108
|
+
) -> DataType | TraitDataType:
|
|
109
|
+
base = arg_to_datatype(args[0])
|
|
110
|
+
if isinstance(base, TraitDataType):
|
|
111
|
+
traits = base.traits
|
|
112
|
+
else:
|
|
113
|
+
traits = []
|
|
114
|
+
if isinstance(args[1], TraitDataType):
|
|
115
|
+
return TraitDataType(
|
|
116
|
+
type=args[1].type, traits=list(set(traits + args[1].traits))
|
|
117
|
+
)
|
|
118
|
+
elif traits:
|
|
119
|
+
return TraitDataType(type=args[1], traits=traits)
|
|
103
120
|
return args[1]
|
|
104
121
|
|
|
105
122
|
|
|
@@ -995,6 +1012,19 @@ class FunctionFactory:
|
|
|
995
1012
|
final_output_type = base_output_type
|
|
996
1013
|
else:
|
|
997
1014
|
raise SyntaxError(f"Could not determine output type for {operator}")
|
|
1015
|
+
if isinstance(final_output_type, TraitDataType) and self.environment:
|
|
1016
|
+
final_output_type = TraitDataType(
|
|
1017
|
+
type=final_output_type.type,
|
|
1018
|
+
traits=[
|
|
1019
|
+
x
|
|
1020
|
+
for x in final_output_type.traits
|
|
1021
|
+
if operator
|
|
1022
|
+
not in self.environment.data_types.get(
|
|
1023
|
+
x, CUSTOM_PLACEHOLDER
|
|
1024
|
+
).drop_on
|
|
1025
|
+
],
|
|
1026
|
+
)
|
|
1027
|
+
|
|
998
1028
|
if not output_purpose:
|
|
999
1029
|
if operator in FunctionClass.AGGREGATE_FUNCTIONS.value:
|
|
1000
1030
|
output_purpose = Purpose.METRIC
|
trilogy/core/models/author.py
CHANGED
|
@@ -2598,11 +2598,16 @@ class ArgBinding(Namespaced, DataTyped, BaseModel):
|
|
|
2598
2598
|
|
|
2599
2599
|
class CustomType(BaseModel):
|
|
2600
2600
|
name: str
|
|
2601
|
-
type: DataType
|
|
2601
|
+
type: DataType | list[DataType]
|
|
2602
|
+
drop_on: list[FunctionType] = Field(default_factory=list)
|
|
2603
|
+
add_on: list[FunctionType] = Field(default_factory=list)
|
|
2602
2604
|
|
|
2603
2605
|
def with_namespace(self, namespace: str) -> "CustomType":
|
|
2604
2606
|
return CustomType.model_construct(
|
|
2605
|
-
name=address_with_namespace(self.name, namespace),
|
|
2607
|
+
name=address_with_namespace(self.name, namespace),
|
|
2608
|
+
type=self.type,
|
|
2609
|
+
drop_on=self.drop_on,
|
|
2610
|
+
add_on=self.add_on,
|
|
2606
2611
|
)
|
|
2607
2612
|
|
|
2608
2613
|
|
trilogy/core/models/core.py
CHANGED
|
@@ -99,6 +99,7 @@ class DataType(Enum):
|
|
|
99
99
|
|
|
100
100
|
# PARSING
|
|
101
101
|
UNKNOWN = "unknown"
|
|
102
|
+
ANY = "any"
|
|
102
103
|
|
|
103
104
|
@property
|
|
104
105
|
def data_type(self):
|
|
@@ -411,6 +412,12 @@ def merge_datatypes(
|
|
|
411
412
|
|
|
412
413
|
def is_compatible_datatype(left, right):
|
|
413
414
|
# for unknown types, we can't make any assumptions
|
|
415
|
+
if isinstance(left, list):
|
|
416
|
+
return any(is_compatible_datatype(ltype, right) for ltype in left)
|
|
417
|
+
if isinstance(right, list):
|
|
418
|
+
return any(is_compatible_datatype(left, rtype) for rtype in right)
|
|
419
|
+
if left == DataType.ANY or right == DataType.ANY:
|
|
420
|
+
return True
|
|
414
421
|
if all(
|
|
415
422
|
isinstance(x, NumericType)
|
|
416
423
|
or x in (DataType.INTEGER, DataType.FLOAT, DataType.NUMERIC)
|
|
@@ -215,7 +215,7 @@ class Environment(BaseModel):
|
|
|
215
215
|
functions: Dict[str, CustomFunctionFactory] = Field(default_factory=dict)
|
|
216
216
|
data_types: Dict[str, CustomType] = Field(default_factory=dict)
|
|
217
217
|
named_statements: Dict[str, SelectLineage] = Field(default_factory=dict)
|
|
218
|
-
imports:
|
|
218
|
+
imports: defaultdict[str, list[Import]] = Field(
|
|
219
219
|
default_factory=lambda: defaultdict(list) # type: ignore
|
|
220
220
|
)
|
|
221
221
|
namespace: str = DEFAULT_NAMESPACE
|
|
@@ -252,7 +252,7 @@ class Environment(BaseModel):
|
|
|
252
252
|
concepts=self.concepts.duplicate(),
|
|
253
253
|
functions=dict(self.functions),
|
|
254
254
|
data_types=dict(self.data_types),
|
|
255
|
-
imports=
|
|
255
|
+
imports=defaultdict(list, self.imports),
|
|
256
256
|
namespace=self.namespace,
|
|
257
257
|
working_path=self.working_path,
|
|
258
258
|
environment_config=self.config.model_copy(deep=True),
|
|
@@ -262,6 +262,7 @@ class Environment(BaseModel):
|
|
|
262
262
|
alias_origin_lookup={
|
|
263
263
|
k: v.duplicate() for k, v in self.alias_origin_lookup.items()
|
|
264
264
|
},
|
|
265
|
+
env_file_path=self.env_file_path,
|
|
265
266
|
)
|
|
266
267
|
|
|
267
268
|
def _add_path_concepts(self):
|
|
@@ -40,15 +40,15 @@ def calculate_effective_parent_grain(
|
|
|
40
40
|
pairs = join.concept_pairs or []
|
|
41
41
|
for key in pairs:
|
|
42
42
|
left = key.existing_datasource
|
|
43
|
-
logger.
|
|
43
|
+
logger.debug(f"adding left grain {left.grain} for join key {key.left}")
|
|
44
44
|
grain += left.grain
|
|
45
45
|
seen.add(left.name)
|
|
46
46
|
keys = [key.right for key in pairs]
|
|
47
47
|
join_grain = BuildGrain.from_concepts(keys)
|
|
48
48
|
if join_grain == join.right_datasource.grain:
|
|
49
|
-
logger.
|
|
49
|
+
logger.debug(f"irrelevant right join {join}, does not change grain")
|
|
50
50
|
else:
|
|
51
|
-
logger.
|
|
51
|
+
logger.debug(
|
|
52
52
|
f"join changes grain, adding {join.right_datasource.grain} to {grain}"
|
|
53
53
|
)
|
|
54
54
|
grain += join.right_datasource.grain
|
|
@@ -68,7 +68,7 @@ def calculate_effective_parent_grain(
|
|
|
68
68
|
]
|
|
69
69
|
)
|
|
70
70
|
):
|
|
71
|
-
logger.
|
|
71
|
+
logger.debug(f"adding unjoined grain {x.grain} for datasource {x.name}")
|
|
72
72
|
grain += x.grain
|
|
73
73
|
return grain
|
|
74
74
|
else:
|
|
@@ -258,10 +258,14 @@ class StrategyNode:
|
|
|
258
258
|
self.partial_lcl = LooseBuildConceptList(concepts=partials)
|
|
259
259
|
return partials
|
|
260
260
|
|
|
261
|
-
def add_output_concepts(
|
|
261
|
+
def add_output_concepts(
|
|
262
|
+
self, concepts: List[BuildConcept], rebuild: bool = True, unhide: bool = True
|
|
263
|
+
):
|
|
262
264
|
for concept in concepts:
|
|
263
265
|
if concept.address not in self.output_lcl.addresses:
|
|
264
266
|
self.output_concepts.append(concept)
|
|
267
|
+
if unhide and concept.address in self.hidden_concepts:
|
|
268
|
+
self.hidden_concepts.remove(concept.address)
|
|
265
269
|
self.output_lcl = LooseBuildConceptList(concepts=self.output_concepts)
|
|
266
270
|
if rebuild:
|
|
267
271
|
self.rebuild_cache()
|
trilogy/parsing/parse_engine.py
CHANGED
|
@@ -171,6 +171,16 @@ class FunctionBindingType:
|
|
|
171
171
|
type: DataType | TraitDataType | None = None
|
|
172
172
|
|
|
173
173
|
|
|
174
|
+
@dataclass
|
|
175
|
+
class DropOn:
|
|
176
|
+
functions: List[FunctionType]
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@dataclass
|
|
180
|
+
class AddOn:
|
|
181
|
+
functions: List[FunctionType]
|
|
182
|
+
|
|
183
|
+
|
|
174
184
|
with open(join(dirname(__file__), "trilogy.lark"), "r") as f:
|
|
175
185
|
PARSER = Lark(
|
|
176
186
|
f.read(),
|
|
@@ -1512,11 +1522,35 @@ class ParseToObjects(Transformer):
|
|
|
1512
1522
|
def function(self, meta: Meta, args) -> Function:
|
|
1513
1523
|
return args[0]
|
|
1514
1524
|
|
|
1525
|
+
@v_args(meta=True)
|
|
1526
|
+
def type_drop_clause(self, meta: Meta, args) -> DropOn:
|
|
1527
|
+
return DropOn([FunctionType(x) for x in args])
|
|
1528
|
+
|
|
1529
|
+
@v_args(meta=True)
|
|
1530
|
+
def type_add_clause(self, meta: Meta, args) -> AddOn:
|
|
1531
|
+
return AddOn([FunctionType(x) for x in args])
|
|
1532
|
+
|
|
1515
1533
|
@v_args(meta=True)
|
|
1516
1534
|
def type_declaration(self, meta: Meta, args) -> TypeDeclaration:
|
|
1517
1535
|
key = args[0]
|
|
1518
|
-
datatype = args[1]
|
|
1519
|
-
|
|
1536
|
+
datatype: list[DataType] = [x for x in args[1:] if isinstance(x, DataType)]
|
|
1537
|
+
if len(datatype) == 1:
|
|
1538
|
+
final_datatype: list[DataType] | DataType = datatype[0]
|
|
1539
|
+
else:
|
|
1540
|
+
final_datatype = datatype
|
|
1541
|
+
add_on = None
|
|
1542
|
+
drop_on = None
|
|
1543
|
+
for x in args[1:]:
|
|
1544
|
+
if isinstance(x, AddOn):
|
|
1545
|
+
add_on = x
|
|
1546
|
+
elif isinstance(x, DropOn):
|
|
1547
|
+
drop_on = x
|
|
1548
|
+
new = CustomType(
|
|
1549
|
+
name=key,
|
|
1550
|
+
type=final_datatype,
|
|
1551
|
+
drop_on=drop_on.functions if drop_on else [],
|
|
1552
|
+
add_on=add_on.functions if add_on else [],
|
|
1553
|
+
)
|
|
1520
1554
|
self.environment.data_types[key] = new
|
|
1521
1555
|
return TypeDeclaration(type=new)
|
|
1522
1556
|
|
|
@@ -2349,7 +2383,7 @@ def inject_context_maker(pos: int, text: str, span: int = 40) -> str:
|
|
|
2349
2383
|
rcap = ""
|
|
2350
2384
|
# if it goes beyond the end of text, no ...
|
|
2351
2385
|
# if it terminates on a space, no need for ...
|
|
2352
|
-
if not after[-1].isspace() and not (end > len(text)):
|
|
2386
|
+
if after and not after[-1].isspace() and not (end > len(text)):
|
|
2353
2387
|
rcap = "..."
|
|
2354
2388
|
lcap = ""
|
|
2355
2389
|
if start > 0 and not before[0].isspace():
|
|
@@ -2444,8 +2478,6 @@ def parse_text(
|
|
|
2444
2478
|
else:
|
|
2445
2479
|
new_pos = pos
|
|
2446
2480
|
e.interactive_parser.feed_token(Token("IDENTIFIER", e.token.value))
|
|
2447
|
-
next(e.interactive_parser.iter_parse())
|
|
2448
|
-
|
|
2449
2481
|
raise _create_syntax_error(201, new_pos, text)
|
|
2450
2482
|
except UnexpectedToken:
|
|
2451
2483
|
pass
|
trilogy/parsing/trilogy.lark
CHANGED
|
@@ -109,7 +109,9 @@
|
|
|
109
109
|
raw_function: "def" IDENTIFIER "(" function_binding_list ")" "->" expr
|
|
110
110
|
|
|
111
111
|
// TYPE blocks
|
|
112
|
-
|
|
112
|
+
type_drop_clause: "DROP" IDENTIFIER ("|" IDENTIFIER)*
|
|
113
|
+
//type_add_clause: "ADD" IDENTIFIER ("|" IDENTIFIER)* type_add_clause?
|
|
114
|
+
type_declaration: "type" IDENTIFIER data_type ("|" data_type)* type_drop_clause?
|
|
113
115
|
|
|
114
116
|
// user_id where state = Mexico
|
|
115
117
|
_filter_alt: (IDENTIFIER | literal | "(" expr ")") "?" conditional
|
trilogy/std/ranking.preql
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|