pytrilogy 0.0.2.50__tar.gz → 0.0.2.52__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.50/pytrilogy.egg-info → pytrilogy-0.0.2.52}/PKG-INFO +1 -1
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52/pytrilogy.egg-info}/PKG-INFO +1 -1
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/pytrilogy.egg-info/SOURCES.txt +2 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_environment.py +2 -2
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_functions.py +4 -3
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_models.py +5 -3
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_query_processing.py +28 -9
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/internal.py +5 -1
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/models.py +124 -263
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/concept_strategies_v3.py +14 -4
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/basic_node.py +7 -3
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/common.py +8 -3
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/filter_node.py +5 -5
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/group_node.py +24 -8
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/multiselect_node.py +4 -3
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/node_merge_node.py +14 -2
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/rowset_node.py +3 -4
- pytrilogy-0.0.2.52/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +203 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/select_merge_node.py +17 -9
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/base_node.py +2 -33
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/group_node.py +19 -10
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/merge_node.py +2 -2
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/hooks/graph_hook.py +3 -1
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parsing/common.py +54 -12
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parsing/parse_engine.py +39 -20
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parsing/render.py +17 -1
- pytrilogy-0.0.2.52/trilogy/scripts/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/LICENSE.md +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/README.md +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/pyproject.toml +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/pytrilogy.egg-info/requires.txt +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/setup.cfg +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/setup.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_datatypes.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_derived_concepts.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_enums.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_executor.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_metadata.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_parse_engine.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_parsing.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_select.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_show.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/tests/test_where_clause.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/compiler.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/constants.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/enums.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/env_processor.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/environment_helpers.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/exceptions.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/functions.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/graph_models.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/optimization.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/optimizations/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/optimizations/base_optimization.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/optimizations/inline_constant.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/optimizations/inline_datasource.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.2.50/trilogy/dialect → pytrilogy-0.0.2.52/trilogy/core/processing/node_generators/select_helpers}/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/select_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/union_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/union_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/processing/utility.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/core/query_processor.py +0 -0
- {pytrilogy-0.0.2.50/trilogy/hooks → pytrilogy-0.0.2.52/trilogy/dialect}/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/base.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/duckdb.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/dialect/sql_server.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/engine.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/executor.py +0 -0
- {pytrilogy-0.0.2.50/trilogy/metadata → pytrilogy-0.0.2.52/trilogy/hooks}/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.2.50/trilogy/parsing → pytrilogy-0.0.2.52/trilogy/metadata}/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.2.50/trilogy/scripts → pytrilogy-0.0.2.52/trilogy/parsing}/__init__.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/parsing/trilogy.lark +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/scripts/trilogy.py +0 -0
- {pytrilogy-0.0.2.50 → pytrilogy-0.0.2.52}/trilogy/utility.py +0 -0
|
@@ -73,6 +73,8 @@ trilogy/core/processing/node_generators/select_node.py
|
|
|
73
73
|
trilogy/core/processing/node_generators/union_node.py
|
|
74
74
|
trilogy/core/processing/node_generators/unnest_node.py
|
|
75
75
|
trilogy/core/processing/node_generators/window_node.py
|
|
76
|
+
trilogy/core/processing/node_generators/select_helpers/__init__.py
|
|
77
|
+
trilogy/core/processing/node_generators/select_helpers/datasource_injection.py
|
|
76
78
|
trilogy/core/processing/nodes/__init__.py
|
|
77
79
|
trilogy/core/processing/nodes/base_node.py
|
|
78
80
|
trilogy/core/processing/nodes/filter_node.py
|
|
@@ -7,9 +7,9 @@ from trilogy.core.models import Environment
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def test_environment_serialization(test_environment: Environment):
|
|
10
|
-
str(test_environment)
|
|
11
|
-
path = test_environment.to_cache()
|
|
12
10
|
|
|
11
|
+
path = test_environment.to_cache()
|
|
12
|
+
print(path)
|
|
13
13
|
test_environment2 = Environment.from_cache(path)
|
|
14
14
|
assert test_environment2
|
|
15
15
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# from trilogy.compiler import compile
|
|
2
|
+
from datetime import date, datetime
|
|
2
3
|
from logging import INFO
|
|
3
4
|
|
|
4
5
|
from pytest import raises
|
|
5
6
|
|
|
7
|
+
from trilogy import Dialects
|
|
6
8
|
from trilogy.constants import logger
|
|
7
9
|
from trilogy.core.enums import Purpose, PurposeLineage
|
|
8
10
|
from trilogy.core.exceptions import InvalidSyntaxException
|
|
@@ -14,8 +16,6 @@ from trilogy.dialect.duckdb import DuckDBDialect
|
|
|
14
16
|
from trilogy.dialect.snowflake import SnowflakeDialect
|
|
15
17
|
from trilogy.dialect.sql_server import SqlServerDialect
|
|
16
18
|
from trilogy.parser import parse
|
|
17
|
-
from trilogy import Dialects
|
|
18
|
-
from datetime import date, datetime
|
|
19
19
|
|
|
20
20
|
logger.setLevel(INFO)
|
|
21
21
|
|
|
@@ -181,7 +181,7 @@ select
|
|
|
181
181
|
assert z[0].one_datetime == datetime(
|
|
182
182
|
year=2024, month=1, day=1, hour=1, minute=1, second=1
|
|
183
183
|
)
|
|
184
|
-
assert z[0].one_bool
|
|
184
|
+
assert z[0].one_bool
|
|
185
185
|
for dialect in TEST_DIALECTS:
|
|
186
186
|
dialect.compile_statement(process_query(test_environment, select))
|
|
187
187
|
|
|
@@ -242,6 +242,7 @@ def test_case_function(test_environment):
|
|
|
242
242
|
test_upper_case
|
|
243
243
|
;"""
|
|
244
244
|
env, parsed = parse(declarations, environment=test_environment)
|
|
245
|
+
|
|
245
246
|
assert (
|
|
246
247
|
test_environment.concepts["category_name"]
|
|
247
248
|
in test_environment.concepts["test_upper_case"].lineage.concept_arguments
|
|
@@ -68,7 +68,7 @@ def test_cte_merge(test_environment, test_environment_graph):
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
def test_concept(test_environment, test_environment_graph):
|
|
71
|
-
test_concept = list(test_environment.concepts.values())[0]
|
|
71
|
+
test_concept: Concept = list(test_environment.concepts.values())[0]
|
|
72
72
|
new = test_concept.with_namespace("test")
|
|
73
73
|
assert (
|
|
74
74
|
new.namespace == ("test" + "." + test_concept.namespace)
|
|
@@ -129,7 +129,7 @@ def test_grain(test_environment):
|
|
|
129
129
|
x = Grain(components=[oid, pid])
|
|
130
130
|
y = Grain(components=[pid, cid])
|
|
131
131
|
z = Grain(components=[cid])
|
|
132
|
-
z2 = Grain(
|
|
132
|
+
z2 = Grain.from_concepts([cid, cname], environment=test_environment)
|
|
133
133
|
|
|
134
134
|
assert x.intersection(y) == Grain(components=[pid])
|
|
135
135
|
assert x.union(y) == Grain(components=[oid, pid, cid])
|
|
@@ -137,7 +137,9 @@ def test_grain(test_environment):
|
|
|
137
137
|
assert z.isdisjoint(x)
|
|
138
138
|
assert z.issubset(y)
|
|
139
139
|
|
|
140
|
-
assert
|
|
140
|
+
assert (
|
|
141
|
+
z2 == z
|
|
142
|
+
), f"Property should be removed from grain ({z.components}) vs {z2.components}"
|
|
141
143
|
|
|
142
144
|
|
|
143
145
|
def test_select(test_environment: Environment):
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
from trilogy.core.models import
|
|
1
|
+
from trilogy.core.models import (
|
|
2
|
+
Environment,
|
|
3
|
+
Grain,
|
|
4
|
+
QueryDatasource,
|
|
5
|
+
SelectStatement,
|
|
6
|
+
SourceType,
|
|
7
|
+
)
|
|
2
8
|
from trilogy.core.processing.concept_strategies_v3 import search_concepts
|
|
3
9
|
from trilogy.core.query_processor import get_query_datasources, process_query
|
|
4
10
|
|
|
@@ -7,7 +13,7 @@ def test_direct_select(test_environment, test_environment_graph):
|
|
|
7
13
|
product = test_environment.concepts["product_id"]
|
|
8
14
|
# concept, grain: Grain, environment: Environment, g: ReferenceGraph, query_graph: ReferenceGraph
|
|
9
15
|
datasource = search_concepts(
|
|
10
|
-
[product] + product.grain.
|
|
16
|
+
[product] + [test_environment.concepts[c] for c in product.grain.components],
|
|
11
17
|
environment=test_environment,
|
|
12
18
|
g=test_environment_graph,
|
|
13
19
|
depth=0,
|
|
@@ -27,7 +33,8 @@ def test_get_datasource_from_window_function(
|
|
|
27
33
|
# concept, grain: Grain, environment: Environment, g: ReferenceGraph, query_graph: ReferenceGraph
|
|
28
34
|
# assert product_rank.grain.components[0] == test_environment.concepts['name']
|
|
29
35
|
node = search_concepts(
|
|
30
|
-
[product_rank]
|
|
36
|
+
[product_rank]
|
|
37
|
+
+ [test_environment.concepts[c] for c in product_rank.grain.components],
|
|
31
38
|
environment=test_environment,
|
|
32
39
|
g=test_environment_graph,
|
|
33
40
|
depth=0,
|
|
@@ -38,14 +45,18 @@ def test_get_datasource_from_window_function(
|
|
|
38
45
|
assert product_rank in datasource.output_concepts
|
|
39
46
|
# assert datasource.grain == product_rank.grain
|
|
40
47
|
assert isinstance(datasource, QueryDatasource)
|
|
41
|
-
assert datasource.grain.
|
|
48
|
+
assert datasource.grain.components == product_rank.grain.components
|
|
42
49
|
|
|
43
50
|
product_rank_by_category = test_environment.concepts[
|
|
44
51
|
"product_revenue_rank_by_category"
|
|
45
52
|
]
|
|
46
53
|
# concept, grain: Grain, environment: Environment, g: ReferenceGraph, query_graph: ReferenceGraph
|
|
47
54
|
datasource = search_concepts(
|
|
48
|
-
[product_rank_by_category]
|
|
55
|
+
[product_rank_by_category]
|
|
56
|
+
+ [
|
|
57
|
+
test_environment.concepts[c]
|
|
58
|
+
for c in product_rank_by_category.grain.components
|
|
59
|
+
],
|
|
49
60
|
environment=test_environment,
|
|
50
61
|
g=test_environment_graph,
|
|
51
62
|
depth=0,
|
|
@@ -68,7 +79,8 @@ def test_get_datasource_for_filter(
|
|
|
68
79
|
"product_id",
|
|
69
80
|
}
|
|
70
81
|
datasource = search_concepts(
|
|
71
|
-
[hi_rev_product]
|
|
82
|
+
[hi_rev_product]
|
|
83
|
+
+ [test_environment.concepts[c] for c in hi_rev_product.grain.components],
|
|
72
84
|
environment=test_environment,
|
|
73
85
|
g=test_environment_graph,
|
|
74
86
|
depth=0,
|
|
@@ -86,7 +98,7 @@ def test_select_output(test_environment, test_environment_graph):
|
|
|
86
98
|
# concept, grain: Grain, environment: Environment, g: ReferenceGraph, query_graph: ReferenceGraph
|
|
87
99
|
|
|
88
100
|
datasource = search_concepts(
|
|
89
|
-
[product] + product.grain.
|
|
101
|
+
[product] + [test_environment.concepts[c] for c in product.grain.components],
|
|
90
102
|
environment=test_environment,
|
|
91
103
|
g=test_environment_graph,
|
|
92
104
|
depth=0,
|
|
@@ -114,18 +126,25 @@ def test_basic_aggregate(test_environment: Environment, test_environment_graph):
|
|
|
114
126
|
|
|
115
127
|
|
|
116
128
|
def test_join_aggregate(test_environment: Environment, test_environment_graph):
|
|
129
|
+
from trilogy.hooks.query_debugger import DebuggingHook
|
|
130
|
+
|
|
131
|
+
DebuggingHook()
|
|
117
132
|
category_id = test_environment.concepts["category_id"]
|
|
118
133
|
total_revenue = test_environment.concepts["total_revenue"]
|
|
119
134
|
# concept, grain: Grain, environment: Environment, g: ReferenceGraph, query_graph: ReferenceGraph
|
|
120
135
|
datasource = search_concepts(
|
|
121
|
-
[
|
|
136
|
+
[
|
|
137
|
+
total_revenue.with_grain(Grain(components={"local.category_id"})),
|
|
138
|
+
category_id,
|
|
139
|
+
],
|
|
122
140
|
environment=test_environment,
|
|
123
141
|
g=test_environment_graph,
|
|
124
142
|
depth=0,
|
|
125
143
|
).resolve()
|
|
126
144
|
assert isinstance(datasource, QueryDatasource)
|
|
145
|
+
assert datasource.source_type == SourceType.GROUP
|
|
127
146
|
assert len(set([datasource.name for datasource in datasource.datasources])) == 1
|
|
128
|
-
assert datasource.grain.components ==
|
|
147
|
+
assert datasource.grain.components == {"local.category_id"}
|
|
129
148
|
|
|
130
149
|
|
|
131
150
|
def test_query_aggregation(test_environment, test_environment_graph):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from trilogy.core.constants import ALL_ROWS_CONCEPT, INTERNAL_NAMESPACE
|
|
2
2
|
from trilogy.core.enums import FunctionType, Purpose
|
|
3
|
-
from trilogy.core.models import Concept, DataType, Function
|
|
3
|
+
from trilogy.core.models import Concept, DataType, Function, Grain
|
|
4
4
|
|
|
5
5
|
DEFAULT_CONCEPTS = {
|
|
6
6
|
ALL_ROWS_CONCEPT: Concept(
|
|
@@ -8,6 +8,7 @@ DEFAULT_CONCEPTS = {
|
|
|
8
8
|
namespace=INTERNAL_NAMESPACE,
|
|
9
9
|
datatype=DataType.INTEGER,
|
|
10
10
|
purpose=Purpose.CONSTANT,
|
|
11
|
+
grain=Grain(),
|
|
11
12
|
lineage=Function(
|
|
12
13
|
operator=FunctionType.CONSTANT,
|
|
13
14
|
arguments=[1],
|
|
@@ -20,17 +21,20 @@ DEFAULT_CONCEPTS = {
|
|
|
20
21
|
namespace=INTERNAL_NAMESPACE,
|
|
21
22
|
datatype=DataType.STRING,
|
|
22
23
|
purpose=Purpose.KEY,
|
|
24
|
+
grain=Grain(),
|
|
23
25
|
),
|
|
24
26
|
"datasource": Concept(
|
|
25
27
|
name="datasource",
|
|
26
28
|
namespace=INTERNAL_NAMESPACE,
|
|
27
29
|
datatype=DataType.STRING,
|
|
28
30
|
purpose=Purpose.KEY,
|
|
31
|
+
grain=Grain(),
|
|
29
32
|
),
|
|
30
33
|
"query_text": Concept(
|
|
31
34
|
name="query_text",
|
|
32
35
|
namespace=INTERNAL_NAMESPACE,
|
|
33
36
|
datatype=DataType.STRING,
|
|
34
37
|
purpose=Purpose.KEY,
|
|
38
|
+
grain=Grain(),
|
|
35
39
|
),
|
|
36
40
|
}
|