pytrilogy 0.0.3.34__tar.gz → 0.0.3.36__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.3.34/pytrilogy.egg-info → pytrilogy-0.0.3.36}/PKG-INFO +1 -1
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36/pytrilogy.egg-info}/PKG-INFO +1 -1
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/pytrilogy.egg-info/SOURCES.txt +2 -2
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_derived_concepts.py +8 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_metadata.py +13 -13
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/environment_helpers.py +2 -2
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/functions.py +17 -4
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/author.py +20 -4
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/build.py +35 -4
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/statements/author.py +0 -1
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/common.py +1 -1
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/parse_engine.py +15 -12
- pytrilogy-0.0.3.36/trilogy/std/report.preql +5 -0
- pytrilogy-0.0.3.34/trilogy/std/dashboard.preql +0 -5
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/LICENSE.md +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/README.md +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/pyproject.toml +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/pytrilogy.egg-info/requires.txt +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/setup.cfg +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/setup.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_datatypes.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_enums.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_environment.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_executor.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_functions.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_models.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_parse_engine.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_parsing.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_query_processing.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_query_render.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_select.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_show.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_typing.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_user_functions.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/tests/test_where_clause.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/authoring/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/compiler.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/constants.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/enums.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/env_processor.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/exceptions.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/graph_models.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/internal.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/build_environment.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/core.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/datasource.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/environment.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/models/execute.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/optimization.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/optimizations/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/optimizations/base_optimization.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/optimizations/inline_constant.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/optimizations/inline_datasource.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/concept_strategies_v3.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/basic_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/common.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/filter_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/group_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/select_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/union_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/base_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/group_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/merge_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/union_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/utility.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/query_processor.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/statements/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/statements/build.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/statements/common.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/statements/execute.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/base.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/dataframe.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/duckdb.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/dialect/sql_server.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/engine.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/executor.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/hooks/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/hooks/graph_hook.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/metadata/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/render.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/parsing/trilogy.lark +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/render.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/scripts/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/scripts/trilogy.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/std/__init__.py +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/std/date.preql +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/std/display.preql +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/std/geography.preql +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/std/money.preql +0 -0
- {pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/utility.py +0 -0
|
@@ -130,8 +130,8 @@ trilogy/parsing/trilogy.lark
|
|
|
130
130
|
trilogy/scripts/__init__.py
|
|
131
131
|
trilogy/scripts/trilogy.py
|
|
132
132
|
trilogy/std/__init__.py
|
|
133
|
-
trilogy/std/dashboard.preql
|
|
134
133
|
trilogy/std/date.preql
|
|
135
134
|
trilogy/std/display.preql
|
|
136
135
|
trilogy/std/geography.preql
|
|
137
|
-
trilogy/std/money.preql
|
|
136
|
+
trilogy/std/money.preql
|
|
137
|
+
trilogy/std/report.preql
|
|
@@ -11,6 +11,14 @@ def test_derivations(test_environment):
|
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
def test_hour_derivation(test_environment):
|
|
15
|
+
hour_derived = test_environment.concepts["order_timestamp.hour"]
|
|
16
|
+
assert "hour" in hour_derived.datatype.traits, hour_derived
|
|
17
|
+
|
|
18
|
+
year_derived = test_environment.concepts["order_timestamp.year"]
|
|
19
|
+
assert "year" in year_derived.datatype.traits, year_derived
|
|
20
|
+
|
|
21
|
+
|
|
14
22
|
def test_filtering_where_on_derived_aggregate(test_environment):
|
|
15
23
|
exception = False
|
|
16
24
|
try:
|
|
@@ -14,16 +14,16 @@ property user_id.display_name string metadata(description="The display name");""
|
|
|
14
14
|
assert env.concepts["display_name"].metadata.description == "The display name"
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def test_import_metadata():
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
# def test_import_metadata():
|
|
18
|
+
# env = Environment(working_path=Path(__file__).parent)
|
|
19
|
+
# env, _ = parse(
|
|
20
|
+
# """import test_env as env; # Dragon metrics
|
|
21
|
+
# import test_env as env2;""",
|
|
22
|
+
# environment=env,
|
|
23
|
+
# )
|
|
24
|
+
|
|
25
|
+
# assert "Dragon metrics" in env.concepts["env.id"].metadata.description
|
|
26
|
+
|
|
27
|
+
# env2 = env.concepts["env2.id"]
|
|
28
|
+
# assert env2.namespace == "env2"
|
|
29
|
+
# assert env.concepts["env2.id"].metadata.description is None
|
|
@@ -47,7 +47,7 @@ def generate_date_concepts(concept: Concept, environment: Environment):
|
|
|
47
47
|
)
|
|
48
48
|
new_concept = Concept(
|
|
49
49
|
name=f"{concept.name}.{fname}",
|
|
50
|
-
datatype=
|
|
50
|
+
datatype=function.output_datatype,
|
|
51
51
|
purpose=default_type,
|
|
52
52
|
lineage=function,
|
|
53
53
|
grain=concept.grain,
|
|
@@ -119,7 +119,7 @@ def generate_datetime_concepts(concept: Concept, environment: Environment):
|
|
|
119
119
|
)
|
|
120
120
|
new_concept = Concept(
|
|
121
121
|
name=f"{concept.name}.{fname}",
|
|
122
|
-
datatype=
|
|
122
|
+
datatype=const_function.output_datatype,
|
|
123
123
|
purpose=default_type,
|
|
124
124
|
lineage=const_function,
|
|
125
125
|
grain=concept.grain,
|
|
@@ -111,11 +111,14 @@ def validate_case_output(
|
|
|
111
111
|
if output_datatype != DataType.NULL:
|
|
112
112
|
datatypes.add(output_datatype.data_type)
|
|
113
113
|
mapz[str(arg.expr)] = output_datatype
|
|
114
|
-
|
|
114
|
+
known = [x for x in datatypes if x != DataType.UNKNOWN]
|
|
115
|
+
if len(known) == 0:
|
|
116
|
+
return DataType.UNKNOWN
|
|
117
|
+
if not len(known) == 1:
|
|
115
118
|
raise SyntaxError(
|
|
116
119
|
f"All case expressions must have the same output datatype, got {datatypes} from {mapz}"
|
|
117
120
|
)
|
|
118
|
-
return
|
|
121
|
+
return known.pop()
|
|
119
122
|
|
|
120
123
|
|
|
121
124
|
def create_struct_output(
|
|
@@ -672,12 +675,22 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
|
|
|
672
675
|
arg_count=1,
|
|
673
676
|
),
|
|
674
677
|
FunctionType.SUM: FunctionConfig(
|
|
675
|
-
valid_inputs={
|
|
678
|
+
valid_inputs={
|
|
679
|
+
DataType.INTEGER,
|
|
680
|
+
DataType.FLOAT,
|
|
681
|
+
DataType.NUMBER,
|
|
682
|
+
DataType.NUMERIC,
|
|
683
|
+
},
|
|
676
684
|
output_purpose=Purpose.METRIC,
|
|
677
685
|
arg_count=1,
|
|
678
686
|
),
|
|
679
687
|
FunctionType.AVG: FunctionConfig(
|
|
680
|
-
valid_inputs={
|
|
688
|
+
valid_inputs={
|
|
689
|
+
DataType.INTEGER,
|
|
690
|
+
DataType.FLOAT,
|
|
691
|
+
DataType.NUMBER,
|
|
692
|
+
DataType.NUMERIC,
|
|
693
|
+
},
|
|
681
694
|
output_purpose=Purpose.METRIC,
|
|
682
695
|
arg_count=1,
|
|
683
696
|
),
|
|
@@ -107,6 +107,10 @@ class ConceptRef(Addressable, Namespaced, DataTyped, Mergeable, BaseModel):
|
|
|
107
107
|
) = DataType.UNKNOWN
|
|
108
108
|
metadata: Optional["Metadata"] = None
|
|
109
109
|
|
|
110
|
+
@property
|
|
111
|
+
def reference(self):
|
|
112
|
+
return self
|
|
113
|
+
|
|
110
114
|
@property
|
|
111
115
|
def line_no(self) -> int | None:
|
|
112
116
|
if self.metadata:
|
|
@@ -1426,7 +1430,7 @@ def get_basic_type(
|
|
|
1426
1430
|
return type
|
|
1427
1431
|
|
|
1428
1432
|
|
|
1429
|
-
class CaseWhen(Namespaced, ConceptArgs, Mergeable, BaseModel):
|
|
1433
|
+
class CaseWhen(Namespaced, DataTyped, ConceptArgs, Mergeable, BaseModel):
|
|
1430
1434
|
comparison: Conditional | SubselectComparison | Comparison
|
|
1431
1435
|
expr: "Expr"
|
|
1432
1436
|
|
|
@@ -1436,6 +1440,10 @@ class CaseWhen(Namespaced, ConceptArgs, Mergeable, BaseModel):
|
|
|
1436
1440
|
return v.reference
|
|
1437
1441
|
return v
|
|
1438
1442
|
|
|
1443
|
+
@property
|
|
1444
|
+
def output_datatype(self):
|
|
1445
|
+
return arg_to_datatype(self.expr)
|
|
1446
|
+
|
|
1439
1447
|
def __str__(self):
|
|
1440
1448
|
return self.__repr__()
|
|
1441
1449
|
|
|
@@ -1488,7 +1496,7 @@ class CaseWhen(Namespaced, ConceptArgs, Mergeable, BaseModel):
|
|
|
1488
1496
|
)
|
|
1489
1497
|
|
|
1490
1498
|
|
|
1491
|
-
class CaseElse(Namespaced, ConceptArgs, Mergeable, BaseModel):
|
|
1499
|
+
class CaseElse(Namespaced, ConceptArgs, DataTyped, Mergeable, BaseModel):
|
|
1492
1500
|
expr: "Expr"
|
|
1493
1501
|
# this ensures that it's easily differentiable from CaseWhen
|
|
1494
1502
|
discriminant: ComparisonOperator = ComparisonOperator.ELSE
|
|
@@ -1499,6 +1507,10 @@ class CaseElse(Namespaced, ConceptArgs, Mergeable, BaseModel):
|
|
|
1499
1507
|
def __repr__(self):
|
|
1500
1508
|
return f"ELSE {str(self.expr)}"
|
|
1501
1509
|
|
|
1510
|
+
@property
|
|
1511
|
+
def output_datatype(self):
|
|
1512
|
+
return arg_to_datatype(self.expr)
|
|
1513
|
+
|
|
1502
1514
|
@field_validator("expr", mode="before")
|
|
1503
1515
|
def enforce_expr(cls, v):
|
|
1504
1516
|
if isinstance(v, Concept):
|
|
@@ -1837,7 +1849,7 @@ class FunctionCallWrapper(
|
|
|
1837
1849
|
|
|
1838
1850
|
class AggregateWrapper(Mergeable, DataTyped, ConceptArgs, Namespaced, BaseModel):
|
|
1839
1851
|
function: Function
|
|
1840
|
-
by: List[ConceptRef] = Field(default_factory=list)
|
|
1852
|
+
by: List[ConceptRef | Concept] = Field(default_factory=list)
|
|
1841
1853
|
|
|
1842
1854
|
def __init__(self, **kwargs):
|
|
1843
1855
|
super().__init__(**kwargs)
|
|
@@ -1863,7 +1875,7 @@ class AggregateWrapper(Mergeable, DataTyped, ConceptArgs, Namespaced, BaseModel)
|
|
|
1863
1875
|
|
|
1864
1876
|
@property
|
|
1865
1877
|
def concept_arguments(self) -> List[ConceptRef]:
|
|
1866
|
-
return self.function.concept_arguments + self.by
|
|
1878
|
+
return self.function.concept_arguments + [x.reference for x in self.by]
|
|
1867
1879
|
|
|
1868
1880
|
@property
|
|
1869
1881
|
def output_datatype(self):
|
|
@@ -2392,4 +2404,8 @@ FuncArgs = (
|
|
|
2392
2404
|
| NumericType
|
|
2393
2405
|
| list
|
|
2394
2406
|
| ListWrapper[Any]
|
|
2407
|
+
| TupleWrapper[Any]
|
|
2408
|
+
| Comparison
|
|
2409
|
+
| Conditional
|
|
2410
|
+
| MagicConstants
|
|
2395
2411
|
)
|
|
@@ -1538,9 +1538,23 @@ class Factory:
|
|
|
1538
1538
|
|
|
1539
1539
|
@build.register
|
|
1540
1540
|
def _(self, base: CaseWhen) -> BuildCaseWhen:
|
|
1541
|
+
from trilogy.parsing.common import arbitrary_to_concept
|
|
1542
|
+
|
|
1543
|
+
comparison = base.comparison
|
|
1544
|
+
if isinstance(comparison, (AggregateWrapper, FilterItem, WindowItem)):
|
|
1545
|
+
comparison = arbitrary_to_concept(
|
|
1546
|
+
comparison,
|
|
1547
|
+
environment=self.environment,
|
|
1548
|
+
)
|
|
1549
|
+
expr: Concept | FuncArgs = base.expr
|
|
1550
|
+
if isinstance(expr, (AggregateWrapper, FilterItem, WindowItem)):
|
|
1551
|
+
expr = arbitrary_to_concept(
|
|
1552
|
+
expr,
|
|
1553
|
+
environment=self.environment,
|
|
1554
|
+
)
|
|
1541
1555
|
return BuildCaseWhen.model_construct(
|
|
1542
|
-
comparison=self.build(
|
|
1543
|
-
expr=
|
|
1556
|
+
comparison=self.build(comparison),
|
|
1557
|
+
expr=self.build(expr),
|
|
1544
1558
|
)
|
|
1545
1559
|
|
|
1546
1560
|
@build.register
|
|
@@ -1647,10 +1661,27 @@ class Factory:
|
|
|
1647
1661
|
@build.register
|
|
1648
1662
|
def _(self, base: WindowItem) -> BuildWindowItem:
|
|
1649
1663
|
# to do proper discovery, we need to inject virtual intermediate ocncepts
|
|
1664
|
+
from trilogy.parsing.common import arbitrary_to_concept
|
|
1665
|
+
|
|
1666
|
+
content: Concept | FuncArgs = base.content
|
|
1667
|
+
if isinstance(content, (AggregateWrapper, FilterItem, WindowItem)):
|
|
1668
|
+
content = arbitrary_to_concept(
|
|
1669
|
+
content,
|
|
1670
|
+
environment=self.environment,
|
|
1671
|
+
)
|
|
1672
|
+
final_by = []
|
|
1673
|
+
for x in base.order_by:
|
|
1674
|
+
if (
|
|
1675
|
+
isinstance(x.expr, AggregateWrapper)
|
|
1676
|
+
and not x.expr.by
|
|
1677
|
+
and isinstance(content, (ConceptRef, Concept))
|
|
1678
|
+
):
|
|
1679
|
+
x.expr.by = [content]
|
|
1680
|
+
final_by.append(x)
|
|
1650
1681
|
return BuildWindowItem.model_construct(
|
|
1651
1682
|
type=base.type,
|
|
1652
|
-
content=self.build(
|
|
1653
|
-
order_by=[self.build(x) for x in
|
|
1683
|
+
content=self.build(content),
|
|
1684
|
+
order_by=[self.build(x) for x in final_by],
|
|
1654
1685
|
over=[self.build(x) for x in base.over],
|
|
1655
1686
|
index=base.index,
|
|
1656
1687
|
)
|
|
@@ -135,7 +135,6 @@ class SelectStatement(HasUUID, SelectTypeMixin, BaseModel):
|
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
output.grain = output.calculate_grain(environment)
|
|
138
|
-
|
|
139
138
|
for x in selection:
|
|
140
139
|
if x.is_undefined and environment.concepts.fail_on_missing:
|
|
141
140
|
environment.concepts.raise_undefined(
|
|
@@ -270,7 +270,7 @@ def _get_relevant_parent_concepts(arg) -> tuple[list[ConceptRef], bool]:
|
|
|
270
270
|
elif isinstance(arg, AggregateWrapper) and not arg.by:
|
|
271
271
|
return [], True
|
|
272
272
|
elif isinstance(arg, AggregateWrapper) and arg.by:
|
|
273
|
-
return arg.by, True
|
|
273
|
+
return [x.reference for x in arg.by], True
|
|
274
274
|
elif isinstance(arg, FunctionCallWrapper):
|
|
275
275
|
return get_relevant_parent_concepts(arg.content)
|
|
276
276
|
return get_concept_arguments(arg), False
|
|
@@ -368,18 +368,21 @@ class ParseToObjects(Transformer):
|
|
|
368
368
|
output.concept.metadata.description
|
|
369
369
|
or args[1].text.split("#")[1].strip()
|
|
370
370
|
)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
371
|
+
# this is a bad plan for now;
|
|
372
|
+
# because a comment after an import statement is very common
|
|
373
|
+
# and it's not intuitive that it modifies the import description
|
|
374
|
+
# if isinstance(output, ImportStatement):
|
|
375
|
+
# if len(args) > 1 and isinstance(args[1], Comment):
|
|
376
|
+
# comment = args[1].text.split("#")[1].strip()
|
|
377
|
+
# namespace = output.alias
|
|
378
|
+
# for _, v in self.environment.concepts.items():
|
|
379
|
+
# if v.namespace == namespace:
|
|
380
|
+
# if v.metadata.description:
|
|
381
|
+
# v.metadata.description = (
|
|
382
|
+
# f"{comment}: {v.metadata.description}"
|
|
383
|
+
# )
|
|
384
|
+
# else:
|
|
385
|
+
# v.metadata.description = comment
|
|
383
386
|
|
|
384
387
|
return args[0]
|
|
385
388
|
|
|
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
|
|
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.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/__init__.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/basic_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/filter_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/group_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/group_to_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/node_merge_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/rowset_node.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/select_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/synonym_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/union_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/trilogy/core/processing/node_generators/unnest_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.3.34 → pytrilogy-0.0.3.36}/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
|
|
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
|