pytrilogy 0.0.2.7__py3-none-any.whl → 0.0.2.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pytrilogy might be problematic. Click here for more details.
- {pytrilogy-0.0.2.7.dist-info → pytrilogy-0.0.2.9.dist-info}/METADATA +1 -1
- {pytrilogy-0.0.2.7.dist-info → pytrilogy-0.0.2.9.dist-info}/RECORD +34 -34
- {pytrilogy-0.0.2.7.dist-info → pytrilogy-0.0.2.9.dist-info}/WHEEL +1 -1
- trilogy/__init__.py +1 -1
- trilogy/constants.py +1 -0
- trilogy/core/enums.py +1 -0
- trilogy/core/models.py +154 -56
- trilogy/core/optimization.py +44 -5
- trilogy/core/optimizations/inline_datasource.py +14 -8
- trilogy/core/optimizations/predicate_pushdown.py +73 -44
- trilogy/core/processing/concept_strategies_v3.py +69 -28
- trilogy/core/processing/node_generators/common.py +42 -16
- trilogy/core/processing/node_generators/filter_node.py +89 -48
- trilogy/core/processing/node_generators/group_node.py +3 -1
- trilogy/core/processing/node_generators/rowset_node.py +13 -54
- trilogy/core/processing/node_generators/select_node.py +10 -13
- trilogy/core/processing/node_generators/unnest_node.py +5 -3
- trilogy/core/processing/node_generators/window_node.py +23 -2
- trilogy/core/processing/nodes/__init__.py +34 -6
- trilogy/core/processing/nodes/base_node.py +67 -13
- trilogy/core/processing/nodes/filter_node.py +3 -0
- trilogy/core/processing/nodes/group_node.py +3 -0
- trilogy/core/processing/nodes/merge_node.py +1 -11
- trilogy/core/processing/nodes/select_node_v2.py +1 -0
- trilogy/core/processing/utility.py +29 -10
- trilogy/core/query_processor.py +47 -20
- trilogy/dialect/base.py +47 -14
- trilogy/dialect/common.py +15 -3
- trilogy/dialect/presto.py +2 -1
- trilogy/parsing/parse_engine.py +20 -1
- trilogy/parsing/trilogy.lark +3 -1
- {pytrilogy-0.0.2.7.dist-info → pytrilogy-0.0.2.9.dist-info}/LICENSE.md +0 -0
- {pytrilogy-0.0.2.7.dist-info → pytrilogy-0.0.2.9.dist-info}/entry_points.txt +0 -0
- {pytrilogy-0.0.2.7.dist-info → pytrilogy-0.0.2.9.dist-info}/top_level.txt +0 -0
trilogy/dialect/common.py
CHANGED
|
@@ -9,6 +9,18 @@ def null_wrapper(lval: str, rval: str, concept: Concept) -> str:
|
|
|
9
9
|
return f"{lval} = {rval}"
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
def render_unnest(
|
|
13
|
+
unnest_mode: UnnestMode,
|
|
14
|
+
quote_character: str,
|
|
15
|
+
concept: Concept,
|
|
16
|
+
render_func: Callable[[Concept, CTE, bool], str],
|
|
17
|
+
cte: CTE,
|
|
18
|
+
):
|
|
19
|
+
if unnest_mode == UnnestMode.CROSS_JOIN:
|
|
20
|
+
return f"{render_func(concept, cte, False)} as {quote_character}{concept.safe_address}{quote_character}"
|
|
21
|
+
return f"{render_func(concept, cte, False)} as unnest_wrapper ({quote_character}{concept.safe_address}{quote_character})"
|
|
22
|
+
|
|
23
|
+
|
|
12
24
|
def render_join(
|
|
13
25
|
join: Join | InstantiatedUnnestJoin,
|
|
14
26
|
quote_character: str,
|
|
@@ -25,10 +37,10 @@ def render_join(
|
|
|
25
37
|
if not cte:
|
|
26
38
|
raise ValueError("must provide a cte to build an unnest joins")
|
|
27
39
|
if unnest_mode == UnnestMode.CROSS_JOIN:
|
|
28
|
-
return f"CROSS JOIN {
|
|
40
|
+
return f"CROSS JOIN {render_unnest(unnest_mode, quote_character, join.concept, render_func, cte)}"
|
|
29
41
|
if unnest_mode == UnnestMode.CROSS_JOIN_ALIAS:
|
|
30
|
-
return f"CROSS JOIN {
|
|
31
|
-
return f"FULL JOIN {
|
|
42
|
+
return f"CROSS JOIN {render_unnest(unnest_mode, quote_character, join.concept, render_func, cte)}"
|
|
43
|
+
return f"FULL JOIN {render_unnest(unnest_mode, quote_character, join.concept, render_func, cte)}"
|
|
32
44
|
left_name = join.left_name
|
|
33
45
|
right_name = join.right_name
|
|
34
46
|
right_base = join.right_ref
|
trilogy/dialect/presto.py
CHANGED
|
@@ -33,6 +33,7 @@ FUNCTION_MAP = {
|
|
|
33
33
|
FunctionType.DATE_ADD: lambda x: f"DATE_ADD('{x[1]}', {x[2]}, {x[0]})",
|
|
34
34
|
FunctionType.CURRENT_DATE: lambda x: "CURRENT_DATE",
|
|
35
35
|
FunctionType.CURRENT_DATETIME: lambda x: "CURRENT_TIMESTAMP",
|
|
36
|
+
FunctionType.ARRAY: lambda x: f"ARRAY[{', '.join(x)}]",
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
FUNCTION_GRAIN_MATCH_MAP = {
|
|
@@ -86,7 +87,7 @@ class PrestoDialect(BaseDialect):
|
|
|
86
87
|
QUOTE_CHARACTER = '"'
|
|
87
88
|
SQL_TEMPLATE = SQL_TEMPLATE
|
|
88
89
|
DATATYPE_MAP = {**BaseDialect.DATATYPE_MAP, DataType.NUMERIC: "DECIMAL"}
|
|
89
|
-
UNNEST_MODE = UnnestMode.
|
|
90
|
+
UNNEST_MODE = UnnestMode.CROSS_JOIN_ALIAS
|
|
90
91
|
|
|
91
92
|
|
|
92
93
|
class TrinoDialect(PrestoDialect):
|
trilogy/parsing/parse_engine.py
CHANGED
|
@@ -108,6 +108,7 @@ from trilogy.core.models import (
|
|
|
108
108
|
list_to_wrapper,
|
|
109
109
|
dict_to_map_wrapper,
|
|
110
110
|
NumericType,
|
|
111
|
+
HavingClause,
|
|
111
112
|
)
|
|
112
113
|
from trilogy.parsing.exceptions import ParseError
|
|
113
114
|
from trilogy.utility import string_to_hash
|
|
@@ -960,6 +961,7 @@ class ParseToObjects(Transformer):
|
|
|
960
961
|
limit = None
|
|
961
962
|
order_by = None
|
|
962
963
|
where = None
|
|
964
|
+
having = None
|
|
963
965
|
for arg in args:
|
|
964
966
|
if isinstance(arg, List):
|
|
965
967
|
select_items = arg
|
|
@@ -967,13 +969,16 @@ class ParseToObjects(Transformer):
|
|
|
967
969
|
limit = arg.count
|
|
968
970
|
elif isinstance(arg, OrderBy):
|
|
969
971
|
order_by = arg
|
|
970
|
-
elif isinstance(arg, WhereClause):
|
|
972
|
+
elif isinstance(arg, WhereClause) and not isinstance(arg, HavingClause):
|
|
971
973
|
where = arg
|
|
974
|
+
elif isinstance(arg, HavingClause):
|
|
975
|
+
having = arg
|
|
972
976
|
if not select_items:
|
|
973
977
|
raise ValueError("Malformed select, missing select items")
|
|
974
978
|
output = SelectStatement(
|
|
975
979
|
selection=select_items,
|
|
976
980
|
where_clause=where,
|
|
981
|
+
having_clause=having,
|
|
977
982
|
limit=limit,
|
|
978
983
|
order_by=order_by,
|
|
979
984
|
meta=Metadata(line_number=meta.line),
|
|
@@ -991,6 +996,7 @@ class ParseToObjects(Transformer):
|
|
|
991
996
|
and output.where_clause_category == SelectFiltering.IMPLICIT
|
|
992
997
|
else None
|
|
993
998
|
),
|
|
999
|
+
environment=self.environment,
|
|
994
1000
|
)
|
|
995
1001
|
self.environment.add_concept(new_concept, meta=meta)
|
|
996
1002
|
item.content.output = new_concept
|
|
@@ -1032,6 +1038,19 @@ class ParseToObjects(Transformer):
|
|
|
1032
1038
|
)
|
|
1033
1039
|
return WhereClause(conditional=root)
|
|
1034
1040
|
|
|
1041
|
+
def having(self, args):
|
|
1042
|
+
root = args[0]
|
|
1043
|
+
if not isinstance(root, (Comparison, Conditional, Parenthetical)):
|
|
1044
|
+
if arg_to_datatype(root) == DataType.BOOL:
|
|
1045
|
+
root = Comparison(left=root, right=True, operator=ComparisonOperator.EQ)
|
|
1046
|
+
else:
|
|
1047
|
+
root = Comparison(
|
|
1048
|
+
left=root,
|
|
1049
|
+
right=MagicConstants.NULL,
|
|
1050
|
+
operator=ComparisonOperator.IS_NOT,
|
|
1051
|
+
)
|
|
1052
|
+
return HavingClause(conditional=root)
|
|
1053
|
+
|
|
1035
1054
|
@v_args(meta=True)
|
|
1036
1055
|
def function_binding_list(self, meta: Meta, args) -> Concept:
|
|
1037
1056
|
return args
|
trilogy/parsing/trilogy.lark
CHANGED
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
persist_statement: "persist"i IDENTIFIER "into"i IDENTIFIER "from"i select_statement grain_clause?
|
|
62
62
|
|
|
63
63
|
// select statement
|
|
64
|
-
select_statement: "select"i select_list
|
|
64
|
+
select_statement: where? "select"i select_list where? having? order_by? limit?
|
|
65
65
|
|
|
66
66
|
// multiple_selects
|
|
67
67
|
multi_select_statement: select_statement ("merge" select_statement)+ "align"i align_clause where? order_by? limit?
|
|
@@ -134,6 +134,8 @@
|
|
|
134
134
|
|
|
135
135
|
where: "WHERE"i conditional
|
|
136
136
|
|
|
137
|
+
having: "HAVING"i conditional
|
|
138
|
+
|
|
137
139
|
!array_comparison: ( ("NOT"i "IN"i) | "IN"i)
|
|
138
140
|
|
|
139
141
|
COMPARISON_OPERATOR: (/is[\s]+not/ | "is" |"=" | ">" | "<" | ">=" | "<=" | "!=")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|