pytrilogy 0.0.2.19__tar.gz → 0.0.2.21__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.
- {pytrilogy-0.0.2.19/pytrilogy.egg-info → pytrilogy-0.0.2.21}/PKG-INFO +1 -1
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21/pytrilogy.egg-info}/PKG-INFO +1 -1
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_models.py +6 -2
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/constants.py +1 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/enums.py +1 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/models.py +98 -47
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/select_node.py +2 -1
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/query_processor.py +3 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/parse_engine.py +7 -2
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/LICENSE.md +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/README.md +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/pyproject.toml +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/pytrilogy.egg-info/SOURCES.txt +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/pytrilogy.egg-info/requires.txt +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/setup.cfg +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/setup.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_datatypes.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_derived_concepts.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_environment.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_functions.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_metadata.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_parsing.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_query_processing.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_select.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/tests/test_where_clause.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/compiler.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/env_processor.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/environment_helpers.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/exceptions.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/functions.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/graph_models.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/internal.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/optimization.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/optimizations/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/optimizations/base_optimization.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/optimizations/inline_constant.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/optimizations/inline_datasource.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/concept_strategies_v3.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/basic_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/common.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/filter_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/group_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/base_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/group_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/merge_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/utility.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/base.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/duckdb.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/dialect/sql_server.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/engine.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/executor.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/hooks/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/hooks/graph_hook.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/metadata/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/common.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/render.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/parsing/trilogy.lark +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/scripts/__init__.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/scripts/trilogy.py +0 -0
- {pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/utility.py +0 -0
|
@@ -100,12 +100,16 @@ def test_conditional(test_environment, test_environment_graph):
|
|
|
100
100
|
merged = condition_a + condition_b
|
|
101
101
|
assert merged == condition_a
|
|
102
102
|
|
|
103
|
-
test_concept_two =
|
|
103
|
+
test_concept_two = [
|
|
104
|
+
x
|
|
105
|
+
for x in test_environment.concepts.values()
|
|
106
|
+
if x.address != test_concept.address
|
|
107
|
+
].pop()
|
|
104
108
|
condition_c = Conditional(
|
|
105
109
|
left=test_concept, right=test_concept_two, operator=BooleanOperator.AND
|
|
106
110
|
)
|
|
107
111
|
merged_two = condition_a + condition_c
|
|
108
|
-
assert merged_two.left == condition_a
|
|
112
|
+
assert merged_two.left == condition_a, f"{str(merged_two.left), str(condition_a)}"
|
|
109
113
|
assert merged_two.right == condition_c
|
|
110
114
|
assert merged_two.operator == BooleanOperator.AND
|
|
111
115
|
|
|
@@ -44,6 +44,7 @@ from trilogy.core.constants import (
|
|
|
44
44
|
ALL_ROWS_CONCEPT,
|
|
45
45
|
INTERNAL_NAMESPACE,
|
|
46
46
|
CONSTANT_DATASET,
|
|
47
|
+
PERSISTED_CONCEPT_PREFIX,
|
|
47
48
|
)
|
|
48
49
|
from trilogy.core.enums import (
|
|
49
50
|
InfiniteFunctionArgs,
|
|
@@ -559,19 +560,16 @@ class Concept(Mergeable, Namespaced, SelectContext, BaseModel):
|
|
|
559
560
|
grain = ",".join([str(c.address) for c in self.grain.components])
|
|
560
561
|
return f"{self.namespace}.{self.name}<{grain}>"
|
|
561
562
|
|
|
562
|
-
@
|
|
563
|
+
@cached_property
|
|
563
564
|
def address(self) -> str:
|
|
564
|
-
|
|
565
|
-
self._address_cache = f"{self.namespace}.{self.name}"
|
|
566
|
-
return self._address_cache
|
|
567
|
-
|
|
568
|
-
@address.setter
|
|
569
|
-
def address(self, address: str) -> None:
|
|
570
|
-
self._address_cache = address
|
|
565
|
+
return f"{self.namespace}.{self.name}"
|
|
571
566
|
|
|
572
567
|
def set_name(self, name: str):
|
|
573
568
|
self.name = name
|
|
574
|
-
|
|
569
|
+
try:
|
|
570
|
+
del self.address
|
|
571
|
+
except AttributeError:
|
|
572
|
+
pass
|
|
575
573
|
|
|
576
574
|
@property
|
|
577
575
|
def output(self) -> "Concept":
|
|
@@ -915,10 +913,10 @@ class Grain(Mergeable, BaseModel):
|
|
|
915
913
|
)
|
|
916
914
|
|
|
917
915
|
@cached_property
|
|
918
|
-
def set(self):
|
|
916
|
+
def set(self) -> set[str]:
|
|
919
917
|
base = []
|
|
920
918
|
for x in self.components_copy:
|
|
921
|
-
if x.
|
|
919
|
+
if isinstance(x.lineage, RowsetItem):
|
|
922
920
|
base.append(x.lineage.content.address)
|
|
923
921
|
else:
|
|
924
922
|
base.append(x.address)
|
|
@@ -3134,6 +3132,12 @@ class EnvironmentConceptDict(dict):
|
|
|
3134
3132
|
def values(self) -> ValuesView[Concept]: # type: ignore
|
|
3135
3133
|
return super().values()
|
|
3136
3134
|
|
|
3135
|
+
def get(self, key: str, default: Concept | None = None) -> Concept | None: # type: ignore
|
|
3136
|
+
try:
|
|
3137
|
+
return self.__getitem__(key)
|
|
3138
|
+
except UndefinedConceptException:
|
|
3139
|
+
return default
|
|
3140
|
+
|
|
3137
3141
|
def __getitem__(
|
|
3138
3142
|
self, key, line_no: int | None = None
|
|
3139
3143
|
) -> Concept | UndefinedConcept:
|
|
@@ -3260,34 +3264,62 @@ class Environment(BaseModel):
|
|
|
3260
3264
|
for datasource in self.datasources.values():
|
|
3261
3265
|
for concept in datasource.output_concepts:
|
|
3262
3266
|
concrete_addresses.add(concept.address)
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
]
|
|
3273
|
-
new = [
|
|
3274
|
-
x.address
|
|
3275
|
-
for x in self.materialized_concepts
|
|
3276
|
-
if x.address not in current_mat
|
|
3277
|
-
]
|
|
3278
|
-
if new:
|
|
3279
|
-
logger.debug(f"Environment added new materialized concepts {new}")
|
|
3267
|
+
self.materialized_concepts = unique(
|
|
3268
|
+
[c for c in self.concepts.values() if c.address in concrete_addresses]
|
|
3269
|
+
+ [
|
|
3270
|
+
c
|
|
3271
|
+
for c in self.alias_origin_lookup.values()
|
|
3272
|
+
if c.address in concrete_addresses
|
|
3273
|
+
],
|
|
3274
|
+
"address",
|
|
3275
|
+
)
|
|
3280
3276
|
|
|
3281
|
-
def validate_concept(self,
|
|
3277
|
+
def validate_concept(self, new_concept: Concept, meta: Meta | None = None):
|
|
3278
|
+
lookup = new_concept.address
|
|
3282
3279
|
existing: Concept = self.concepts.get(lookup) # type: ignore
|
|
3283
3280
|
if not existing:
|
|
3284
3281
|
return
|
|
3285
|
-
|
|
3282
|
+
|
|
3283
|
+
def handle_persist():
|
|
3284
|
+
deriv_lookup = (
|
|
3285
|
+
f"{existing.namespace}.{PERSISTED_CONCEPT_PREFIX}_{existing.name}"
|
|
3286
|
+
)
|
|
3287
|
+
|
|
3288
|
+
alt_source = self.alias_origin_lookup.get(deriv_lookup)
|
|
3289
|
+
if not alt_source:
|
|
3290
|
+
return None
|
|
3291
|
+
# if the new concept binding has no lineage
|
|
3292
|
+
# nothing to cause us to think a persist binding
|
|
3293
|
+
# needs to be invalidated
|
|
3294
|
+
if not new_concept.lineage:
|
|
3295
|
+
return existing
|
|
3296
|
+
if str(alt_source.lineage) == str(new_concept.lineage):
|
|
3297
|
+
logger.info(
|
|
3298
|
+
f"Persisted concept {existing.address} matched redeclaration, keeping current persistence binding."
|
|
3299
|
+
)
|
|
3300
|
+
return existing
|
|
3301
|
+
logger.warning(
|
|
3302
|
+
f"Persisted concept {existing.address} lineage {str(alt_source.lineage)} did not match redeclaration {str(new_concept.lineage)}, overwriting and invalidating persist binding."
|
|
3303
|
+
)
|
|
3304
|
+
for k, datasource in self.datasources.items():
|
|
3305
|
+
if existing.address in datasource.output_concepts:
|
|
3306
|
+
datasource.columns = [
|
|
3307
|
+
x
|
|
3308
|
+
for x in datasource.columns
|
|
3309
|
+
if x.concept.address != existing.address
|
|
3310
|
+
]
|
|
3311
|
+
return None
|
|
3312
|
+
|
|
3313
|
+
if existing and self.environment_config.allow_duplicate_declaration:
|
|
3314
|
+
if existing.metadata.concept_source == ConceptSource.PERSIST_STATEMENT:
|
|
3315
|
+
return handle_persist()
|
|
3286
3316
|
return
|
|
3287
3317
|
elif existing.metadata:
|
|
3318
|
+
if existing.metadata.concept_source == ConceptSource.PERSIST_STATEMENT:
|
|
3319
|
+
return handle_persist()
|
|
3288
3320
|
# if the existing concept is auto derived, we can overwrite it
|
|
3289
3321
|
if existing.metadata.concept_source == ConceptSource.AUTO_DERIVED:
|
|
3290
|
-
return
|
|
3322
|
+
return None
|
|
3291
3323
|
elif meta and existing.metadata:
|
|
3292
3324
|
raise ValueError(
|
|
3293
3325
|
f"Assignment to concept '{lookup}' on line {meta.line} is a duplicate"
|
|
@@ -3400,39 +3432,58 @@ class Environment(BaseModel):
|
|
|
3400
3432
|
meta: Meta | None = None,
|
|
3401
3433
|
force: bool = False,
|
|
3402
3434
|
add_derived: bool = True,
|
|
3435
|
+
_ignore_cache: bool = False,
|
|
3403
3436
|
):
|
|
3404
3437
|
if not force:
|
|
3405
|
-
self.validate_concept(concept
|
|
3438
|
+
existing = self.validate_concept(concept, meta=meta)
|
|
3439
|
+
if existing:
|
|
3440
|
+
concept = existing
|
|
3406
3441
|
if concept.namespace == DEFAULT_NAMESPACE:
|
|
3407
3442
|
self.concepts[concept.name] = concept
|
|
3408
|
-
|
|
3409
|
-
self.concepts[concept.address] = concept
|
|
3443
|
+
self.concepts[concept.address] = concept
|
|
3410
3444
|
from trilogy.core.environment_helpers import generate_related_concepts
|
|
3411
3445
|
|
|
3412
3446
|
generate_related_concepts(concept, self, meta=meta, add_derived=add_derived)
|
|
3413
|
-
|
|
3447
|
+
if not _ignore_cache:
|
|
3448
|
+
self.gen_concept_list_caches()
|
|
3414
3449
|
return concept
|
|
3415
3450
|
|
|
3416
3451
|
def add_datasource(
|
|
3417
3452
|
self,
|
|
3418
3453
|
datasource: Datasource,
|
|
3419
3454
|
meta: Meta | None = None,
|
|
3455
|
+
_ignore_cache: bool = False,
|
|
3420
3456
|
):
|
|
3421
|
-
|
|
3422
3457
|
self.datasources[datasource.env_label] = datasource
|
|
3423
|
-
for
|
|
3424
|
-
current_concept = column.concept
|
|
3458
|
+
for current_concept in datasource.output_concepts:
|
|
3425
3459
|
current_derivation = current_concept.derivation
|
|
3460
|
+
# TODO: refine this section;
|
|
3461
|
+
# too hacky for maintainability
|
|
3426
3462
|
if current_derivation not in (PurposeLineage.ROOT, PurposeLineage.CONSTANT):
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3463
|
+
persisted = f"{PERSISTED_CONCEPT_PREFIX}_" + current_concept.name
|
|
3464
|
+
# override the current concept source to reflect that it's now coming from a datasource
|
|
3465
|
+
if (
|
|
3466
|
+
current_concept.metadata.concept_source
|
|
3467
|
+
!= ConceptSource.PERSIST_STATEMENT
|
|
3468
|
+
):
|
|
3469
|
+
new_concept = current_concept.model_copy(deep=True)
|
|
3470
|
+
new_concept.set_name(persisted)
|
|
3471
|
+
self.add_concept(
|
|
3472
|
+
new_concept, meta=meta, force=True, _ignore_cache=True
|
|
3473
|
+
)
|
|
3474
|
+
current_concept.metadata.concept_source = (
|
|
3475
|
+
ConceptSource.PERSIST_STATEMENT
|
|
3476
|
+
)
|
|
3477
|
+
# remove the associated lineage
|
|
3478
|
+
# to make this a root for discovery purposes
|
|
3479
|
+
# as it now "exists" in a table
|
|
3480
|
+
current_concept.lineage = None
|
|
3481
|
+
self.add_concept(
|
|
3482
|
+
current_concept, meta=meta, force=True, _ignore_cache=True
|
|
3483
|
+
)
|
|
3484
|
+
self.merge_concept(new_concept, current_concept, [])
|
|
3485
|
+
if not _ignore_cache:
|
|
3486
|
+
self.gen_concept_list_caches()
|
|
3436
3487
|
return datasource
|
|
3437
3488
|
|
|
3438
3489
|
def delete_datasource(
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/select_node.py
RENAMED
|
@@ -39,9 +39,10 @@ def gen_select_node(
|
|
|
39
39
|
]
|
|
40
40
|
)
|
|
41
41
|
if materialized_lcl != all_lcl:
|
|
42
|
+
missing = all_lcl.difference(materialized_lcl)
|
|
42
43
|
logger.info(
|
|
43
44
|
f"{padding(depth)}{LOGGER_PREFIX} Skipping select node generation for {concept.address}"
|
|
44
|
-
f" as it + optional includes non-materialized concepts (looking for all {all_lcl}) "
|
|
45
|
+
f" as it + optional includes non-materialized concepts (looking for all {all_lcl}, missing {missing}) "
|
|
45
46
|
)
|
|
46
47
|
if fail_if_not_found:
|
|
47
48
|
raise NoDatasourceException(f"No datasource exists for {concept}")
|
|
@@ -11,6 +11,7 @@ from trilogy.core.models import (
|
|
|
11
11
|
Concept,
|
|
12
12
|
Environment,
|
|
13
13
|
PersistStatement,
|
|
14
|
+
ConceptDeclarationStatement,
|
|
14
15
|
SelectStatement,
|
|
15
16
|
MultiSelectStatement,
|
|
16
17
|
CTE,
|
|
@@ -393,6 +394,8 @@ def process_auto(
|
|
|
393
394
|
return process_persist(environment, statement, hooks)
|
|
394
395
|
elif isinstance(statement, SelectStatement):
|
|
395
396
|
return process_query(environment, statement, hooks)
|
|
397
|
+
elif isinstance(statement, ConceptDeclarationStatement):
|
|
398
|
+
return None
|
|
396
399
|
raise ValueError(f"Do not know how to process {type(statement)}")
|
|
397
400
|
|
|
398
401
|
|
|
@@ -814,14 +814,19 @@ class ParseToObjects(Transformer):
|
|
|
814
814
|
raise ImportError(f"Unable to import file {target}, parsing error: {e}")
|
|
815
815
|
|
|
816
816
|
for _, concept in nparser.environment.concepts.items():
|
|
817
|
-
self.environment.add_concept(
|
|
817
|
+
self.environment.add_concept(
|
|
818
|
+
concept.with_namespace(alias), _ignore_cache=True
|
|
819
|
+
)
|
|
818
820
|
|
|
819
821
|
for _, datasource in nparser.environment.datasources.items():
|
|
820
|
-
self.environment.add_datasource(
|
|
822
|
+
self.environment.add_datasource(
|
|
823
|
+
datasource.with_namespace(alias), _ignore_cache=True
|
|
824
|
+
)
|
|
821
825
|
imps = ImportStatement(
|
|
822
826
|
alias=alias, path=Path(args[0]), environment=nparser.environment
|
|
823
827
|
)
|
|
824
828
|
self.environment.imports[alias] = imps
|
|
829
|
+
self.environment.gen_concept_list_caches()
|
|
825
830
|
return imps
|
|
826
831
|
|
|
827
832
|
@v_args(meta=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/__init__.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/basic_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/filter_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/group_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/group_to_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/node_merge_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/rowset_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/unnest_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.19 → pytrilogy-0.0.2.21}/trilogy/core/processing/node_generators/window_node.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|