pytrilogy 0.0.2.34__tar.gz → 0.0.2.35__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.34/pytrilogy.egg-info → pytrilogy-0.0.2.35}/PKG-INFO +2 -1
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35/pytrilogy.egg-info}/PKG-INFO +2 -1
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/pytrilogy.egg-info/SOURCES.txt +1 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/pytrilogy.egg-info/requires.txt +1 -0
- pytrilogy-0.0.2.35/tests/test_enums.py +12 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_select.py +19 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/enums.py +17 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/models.py +39 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/parse_engine.py +1 -57
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/LICENSE.md +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/README.md +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/pyproject.toml +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/setup.cfg +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/setup.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_datatypes.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_derived_concepts.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_environment.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_executor.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_functions.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_metadata.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_models.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_parse_engine.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_parsing.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_query_processing.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_show.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/tests/test_where_clause.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/compiler.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/constants.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/env_processor.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/environment_helpers.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/exceptions.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/functions.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/graph_models.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/internal.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/optimization.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/optimizations/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/optimizations/base_optimization.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/optimizations/inline_constant.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/optimizations/inline_datasource.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/concept_strategies_v3.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/basic_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/common.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/filter_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/group_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/select_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/base_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/group_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/merge_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/utility.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/query_processor.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/base.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/duckdb.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/dialect/sql_server.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/engine.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/executor.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/hooks/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/hooks/graph_hook.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/metadata/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/common.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/render.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/parsing/trilogy.lark +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/scripts/__init__.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/scripts/trilogy.py +0 -0
- {pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/utility.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pytrilogy
|
|
3
|
-
Version: 0.0.2.
|
|
3
|
+
Version: 0.0.2.35
|
|
4
4
|
Summary: Declarative, typed query language that compiles to SQL.
|
|
5
5
|
Home-page:
|
|
6
6
|
Author:
|
|
@@ -20,6 +20,7 @@ Requires-Dist: networkx
|
|
|
20
20
|
Requires-Dist: pyodbc
|
|
21
21
|
Requires-Dist: pydantic
|
|
22
22
|
Requires-Dist: duckdb-engine
|
|
23
|
+
Requires-Dist: click
|
|
23
24
|
Provides-Extra: postgres
|
|
24
25
|
Requires-Dist: psycopg2-binary; extra == "postgres"
|
|
25
26
|
Provides-Extra: bigquery
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pytrilogy
|
|
3
|
-
Version: 0.0.2.
|
|
3
|
+
Version: 0.0.2.35
|
|
4
4
|
Summary: Declarative, typed query language that compiles to SQL.
|
|
5
5
|
Home-page:
|
|
6
6
|
Author:
|
|
@@ -20,6 +20,7 @@ Requires-Dist: networkx
|
|
|
20
20
|
Requires-Dist: pyodbc
|
|
21
21
|
Requires-Dist: pydantic
|
|
22
22
|
Requires-Dist: duckdb-engine
|
|
23
|
+
Requires-Dist: click
|
|
23
24
|
Provides-Extra: postgres
|
|
24
25
|
Requires-Dist: psycopg2-binary; extra == "postgres"
|
|
25
26
|
Provides-Extra: bigquery
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from trilogy.core.enums import BooleanOperator, Boolean
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_boolean_operator():
|
|
5
|
+
assert BooleanOperator("AND") == BooleanOperator.AND
|
|
6
|
+
assert BooleanOperator("and") == BooleanOperator.AND
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_boolean():
|
|
10
|
+
assert Boolean("TRUE") == Boolean.TRUE
|
|
11
|
+
assert Boolean("true") == Boolean.TRUE
|
|
12
|
+
assert Boolean(True) == Boolean.TRUE
|
|
@@ -128,3 +128,22 @@ def test_modifiers():
|
|
|
128
128
|
text = generator.compile_statement(query)
|
|
129
129
|
assert "2 = 2" in text
|
|
130
130
|
assert "as `b`" not in text
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_having_without_select():
|
|
134
|
+
q1 = """
|
|
135
|
+
const a <- 1;
|
|
136
|
+
const b <- 2;
|
|
137
|
+
|
|
138
|
+
select
|
|
139
|
+
a,
|
|
140
|
+
|
|
141
|
+
having b =2
|
|
142
|
+
;"""
|
|
143
|
+
failed = False
|
|
144
|
+
try:
|
|
145
|
+
env, parsed = parse(q1)
|
|
146
|
+
except Exception as e:
|
|
147
|
+
assert "that is not in the select projection in the HAVING clause" in str(e)
|
|
148
|
+
failed = True
|
|
149
|
+
assert failed
|
|
@@ -215,11 +215,28 @@ class Boolean(Enum):
|
|
|
215
215
|
TRUE = "true"
|
|
216
216
|
FALSE = "false"
|
|
217
217
|
|
|
218
|
+
@classmethod
|
|
219
|
+
def _missing_(cls, value):
|
|
220
|
+
if value is True:
|
|
221
|
+
return Boolean.TRUE
|
|
222
|
+
elif value is False:
|
|
223
|
+
return Boolean.FALSE
|
|
224
|
+
strval = str(value)
|
|
225
|
+
if strval.lower() != strval:
|
|
226
|
+
return Boolean(strval.lower())
|
|
227
|
+
|
|
218
228
|
|
|
219
229
|
class BooleanOperator(Enum):
|
|
220
230
|
AND = "and"
|
|
221
231
|
OR = "or"
|
|
222
232
|
|
|
233
|
+
@classmethod
|
|
234
|
+
def _missing_(cls, value):
|
|
235
|
+
strval = str(value)
|
|
236
|
+
if strval.lower() != strval:
|
|
237
|
+
return BooleanOperator(strval.lower())
|
|
238
|
+
return None
|
|
239
|
+
|
|
223
240
|
|
|
224
241
|
class ComparisonOperator(Enum):
|
|
225
242
|
LT = "<"
|
|
@@ -1629,6 +1629,45 @@ class SelectStatement(HasUUID, Mergeable, Namespaced, SelectTypeMixin, BaseModel
|
|
|
1629
1629
|
self.grain
|
|
1630
1630
|
)
|
|
1631
1631
|
|
|
1632
|
+
def validate_syntax(self):
|
|
1633
|
+
all_in_output = [x.address for x in self.output_components]
|
|
1634
|
+
if self.where_clause:
|
|
1635
|
+
for concept in self.where_clause.concept_arguments:
|
|
1636
|
+
|
|
1637
|
+
if (
|
|
1638
|
+
concept.lineage
|
|
1639
|
+
and isinstance(concept.lineage, Function)
|
|
1640
|
+
and concept.lineage.operator
|
|
1641
|
+
in FunctionClass.AGGREGATE_FUNCTIONS.value
|
|
1642
|
+
):
|
|
1643
|
+
if concept.address in self.locally_derived:
|
|
1644
|
+
raise SyntaxError(
|
|
1645
|
+
f"Cannot reference an aggregate derived in the select ({concept.address}) in the same statement where clause; move to the HAVING clause instead; Line: {self.meta.line_number}"
|
|
1646
|
+
)
|
|
1647
|
+
|
|
1648
|
+
if (
|
|
1649
|
+
concept.lineage
|
|
1650
|
+
and isinstance(concept.lineage, AggregateWrapper)
|
|
1651
|
+
and concept.lineage.function.operator
|
|
1652
|
+
in FunctionClass.AGGREGATE_FUNCTIONS.value
|
|
1653
|
+
):
|
|
1654
|
+
if concept.address in self.locally_derived:
|
|
1655
|
+
raise SyntaxError(
|
|
1656
|
+
f"Cannot reference an aggregate derived in the select ({concept.address}) in the same statement where clause; move to the HAVING clause instead; Line: {self.meta.line_number}"
|
|
1657
|
+
)
|
|
1658
|
+
if self.having_clause:
|
|
1659
|
+
for concept in self.having_clause.concept_arguments:
|
|
1660
|
+
if concept.address not in [x.address for x in self.output_components]:
|
|
1661
|
+
raise SyntaxError(
|
|
1662
|
+
f"Cannot reference a column ({concept.address}) that is not in the select projection in the HAVING clause, move to WHERE; Line: {self.meta.line_number}"
|
|
1663
|
+
)
|
|
1664
|
+
if self.order_by:
|
|
1665
|
+
for concept in self.order_by.concept_arguments:
|
|
1666
|
+
if concept.address not in all_in_output:
|
|
1667
|
+
raise SyntaxError(
|
|
1668
|
+
f"Cannot order by a column that is not in the output projection; {self.meta.line_number}"
|
|
1669
|
+
)
|
|
1670
|
+
|
|
1632
1671
|
def __str__(self):
|
|
1633
1672
|
from trilogy.parsing.render import render_query
|
|
1634
1673
|
|
|
@@ -30,7 +30,6 @@ from trilogy.core.enums import (
|
|
|
30
30
|
WindowType,
|
|
31
31
|
DatePart,
|
|
32
32
|
ShowCategory,
|
|
33
|
-
FunctionClass,
|
|
34
33
|
IOType,
|
|
35
34
|
ConceptSource,
|
|
36
35
|
)
|
|
@@ -264,7 +263,6 @@ class ParseToObjects(Transformer):
|
|
|
264
263
|
for k, v in self.parsed.items():
|
|
265
264
|
if v.pass_count == 2:
|
|
266
265
|
continue
|
|
267
|
-
print(f"Hydrating {k}")
|
|
268
266
|
v.hydrate_missing()
|
|
269
267
|
self.environment.concepts.fail_on_missing = True
|
|
270
268
|
reparsed = self.transform(self.tokens[self.token_address])
|
|
@@ -988,8 +986,6 @@ class ParseToObjects(Transformer):
|
|
|
988
986
|
order_by=order_by,
|
|
989
987
|
meta=Metadata(line_number=meta.line),
|
|
990
988
|
)
|
|
991
|
-
locally_derived: set[str] = set()
|
|
992
|
-
all_in_output: set[str] = set()
|
|
993
989
|
for item in select_items:
|
|
994
990
|
# we don't know the grain of an aggregate at assignment time
|
|
995
991
|
# so rebuild at this point in the tree
|
|
@@ -998,25 +994,16 @@ class ParseToObjects(Transformer):
|
|
|
998
994
|
new_concept = item.content.output.with_select_context(
|
|
999
995
|
output.grain,
|
|
1000
996
|
conditional=None,
|
|
1001
|
-
# conditional=(
|
|
1002
|
-
# output.where_clause.conditional
|
|
1003
|
-
# if output.where_clause
|
|
1004
|
-
# and output.where_clause_category == SelectFiltering.IMPLICIT
|
|
1005
|
-
# else None
|
|
1006
|
-
# ),
|
|
1007
997
|
environment=self.environment,
|
|
1008
998
|
)
|
|
1009
999
|
self.environment.add_concept(new_concept, meta=meta)
|
|
1010
1000
|
item.content.output = new_concept
|
|
1011
|
-
locally_derived.add(new_concept.address)
|
|
1012
|
-
all_in_output.add(new_concept.address)
|
|
1013
1001
|
elif isinstance(item.content, Concept):
|
|
1014
1002
|
# Sometimes cached values here don't have the latest info
|
|
1015
1003
|
# but we can't just use environment, as it might not have the right grain.
|
|
1016
1004
|
item.content = self.environment.concepts[
|
|
1017
1005
|
item.content.address
|
|
1018
1006
|
].with_grain(item.content.grain)
|
|
1019
|
-
all_in_output.add(item.content.address)
|
|
1020
1007
|
if order_by:
|
|
1021
1008
|
for orderitem in order_by.items:
|
|
1022
1009
|
if isinstance(orderitem.expr, Concept):
|
|
@@ -1024,52 +1011,9 @@ class ParseToObjects(Transformer):
|
|
|
1024
1011
|
orderitem.expr = orderitem.expr.with_select_context(
|
|
1025
1012
|
output.grain,
|
|
1026
1013
|
conditional=None,
|
|
1027
|
-
# conditional=(
|
|
1028
|
-
# output.where_clause.conditional
|
|
1029
|
-
# if output.where_clause
|
|
1030
|
-
# and output.where_clause_category
|
|
1031
|
-
# == SelectFiltering.IMPLICIT
|
|
1032
|
-
# else None
|
|
1033
|
-
# ),
|
|
1034
1014
|
environment=self.environment,
|
|
1035
1015
|
)
|
|
1036
|
-
|
|
1037
|
-
for concept in output.where_clause.concept_arguments:
|
|
1038
|
-
|
|
1039
|
-
if (
|
|
1040
|
-
concept.lineage
|
|
1041
|
-
and isinstance(concept.lineage, Function)
|
|
1042
|
-
and concept.lineage.operator
|
|
1043
|
-
in FunctionClass.AGGREGATE_FUNCTIONS.value
|
|
1044
|
-
):
|
|
1045
|
-
if concept.address in locally_derived:
|
|
1046
|
-
raise SyntaxError(
|
|
1047
|
-
f"Cannot reference an aggregate derived in the select ({concept.address}) in the same statement where clause; move to the HAVING clause instead; Line: {meta.line}"
|
|
1048
|
-
)
|
|
1049
|
-
|
|
1050
|
-
if (
|
|
1051
|
-
concept.lineage
|
|
1052
|
-
and isinstance(concept.lineage, AggregateWrapper)
|
|
1053
|
-
and concept.lineage.function.operator
|
|
1054
|
-
in FunctionClass.AGGREGATE_FUNCTIONS.value
|
|
1055
|
-
):
|
|
1056
|
-
if concept.address in locally_derived:
|
|
1057
|
-
raise SyntaxError(
|
|
1058
|
-
f"Cannot reference an aggregate derived in the select ({concept.address}) in the same statement where clause; move to the HAVING clause instead; Line: {meta.line}"
|
|
1059
|
-
)
|
|
1060
|
-
if output.having_clause:
|
|
1061
|
-
for concept in output.having_clause.concept_arguments:
|
|
1062
|
-
if concept.address not in all_in_output:
|
|
1063
|
-
raise SyntaxError(
|
|
1064
|
-
f"Cannot reference a column ({concept.address}) that is not in the select projection in the HAVING clause, move to WHERE; Line: {meta.line}"
|
|
1065
|
-
)
|
|
1066
|
-
if output.order_by:
|
|
1067
|
-
for concept in output.order_by.concept_arguments:
|
|
1068
|
-
if concept.address not in all_in_output:
|
|
1069
|
-
raise SyntaxError(
|
|
1070
|
-
f"Cannot order by a column that is not in the output projection; {meta.line}"
|
|
1071
|
-
)
|
|
1072
|
-
|
|
1016
|
+
output.validate_syntax()
|
|
1073
1017
|
return output
|
|
1074
1018
|
|
|
1075
1019
|
@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
|
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/__init__.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/basic_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/filter_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/group_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/group_to_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/node_merge_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/rowset_node.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/select_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/trilogy/core/processing/node_generators/unnest_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.2.34 → pytrilogy-0.0.2.35}/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
|