pytrilogy 0.0.2.40__py3-none-any.whl → 0.0.2.41__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.40.dist-info → pytrilogy-0.0.2.41.dist-info}/METADATA +2 -2
- {pytrilogy-0.0.2.40.dist-info → pytrilogy-0.0.2.41.dist-info}/RECORD +13 -13
- trilogy/__init__.py +1 -1
- trilogy/core/models.py +6 -0
- trilogy/core/optimizations/predicate_pushdown.py +11 -2
- trilogy/core/processing/node_generators/basic_node.py +30 -2
- trilogy/core/processing/node_generators/window_node.py +23 -7
- trilogy/dialect/base.py +5 -2
- trilogy/parsing/trilogy.lark +1 -1
- {pytrilogy-0.0.2.40.dist-info → pytrilogy-0.0.2.41.dist-info}/LICENSE.md +0 -0
- {pytrilogy-0.0.2.40.dist-info → pytrilogy-0.0.2.41.dist-info}/WHEEL +0 -0
- {pytrilogy-0.0.2.40.dist-info → pytrilogy-0.0.2.41.dist-info}/entry_points.txt +0 -0
- {pytrilogy-0.0.2.40.dist-info → pytrilogy-0.0.2.41.dist-info}/top_level.txt +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.41
|
|
4
4
|
Summary: Declarative, typed query language that compiles to SQL.
|
|
5
5
|
Home-page:
|
|
6
6
|
Author:
|
|
@@ -186,7 +186,7 @@ datasource usa_names(
|
|
|
186
186
|
gender:gender,
|
|
187
187
|
state:state
|
|
188
188
|
)
|
|
189
|
-
address bigquery-public-data.usa_names.usa_1910_2013
|
|
189
|
+
address `bigquery-public-data.usa_names.usa_1910_2013`;
|
|
190
190
|
|
|
191
191
|
'''
|
|
192
192
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
trilogy/__init__.py,sha256=
|
|
1
|
+
trilogy/__init__.py,sha256=TkwxYmJ568eljR1wX8-wzP48QWvm0V6gSnZBN5DX-jk,291
|
|
2
2
|
trilogy/compiler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
trilogy/constants.py,sha256=UPymm94T2c6a55XdDaXw0aleTe1pOJ6lf6gOWLKZyKg,1430
|
|
4
4
|
trilogy/engine.py,sha256=R5ubIxYyrxRExz07aZCUfrTsoXCHQ8DKFTDsobXdWdA,1102
|
|
@@ -16,20 +16,20 @@ trilogy/core/exceptions.py,sha256=NvV_4qLOgKXbpotgRf7c8BANDEvHxlqRPaA53IThQ2o,56
|
|
|
16
16
|
trilogy/core/functions.py,sha256=IhVpt3n6wEanKHnGu3oA2w6-hKIlxWpEyz7fHN66mpo,10720
|
|
17
17
|
trilogy/core/graph_models.py,sha256=mameUTiuCajtihDw_2-W218xyJlvTusOWrEKP1yAWgk,2003
|
|
18
18
|
trilogy/core/internal.py,sha256=jNGFHKENnbMiMCtAgsnLZYVSENDK4b5ALecXFZpTDzQ,1075
|
|
19
|
-
trilogy/core/models.py,sha256=
|
|
19
|
+
trilogy/core/models.py,sha256=5pUsZoiEHEFLvZTddpy-_u_2w_lH9tJIPe5lQH5Ru-s,163252
|
|
20
20
|
trilogy/core/optimization.py,sha256=VFSvJLNoCCOraip-PZUKeE4qrlxtXARjQUzJZiW-yRk,7325
|
|
21
21
|
trilogy/core/query_processor.py,sha256=mbcZlgjChrRjDHkdmMbKe-T70UpbBkJhS09MyU5a6UY,17785
|
|
22
22
|
trilogy/core/optimizations/__init__.py,sha256=bWQecbeiwiDx9LJnLsa7dkWxdbl2wcnkcTN69JyP8iI,356
|
|
23
23
|
trilogy/core/optimizations/base_optimization.py,sha256=tWWT-xnTbnEU-mNi_isMNbywm8B9WTRsNFwGpeh3rqE,468
|
|
24
24
|
trilogy/core/optimizations/inline_constant.py,sha256=kHNyc2UoaPVdYfVAPAFwnWuk4sJ_IF5faRtVcDOrBtw,1110
|
|
25
25
|
trilogy/core/optimizations/inline_datasource.py,sha256=NqUOVl0pOXF1R_roELVW8I0qN7or2wPtAsRmDD9QJso,3658
|
|
26
|
-
trilogy/core/optimizations/predicate_pushdown.py,sha256=
|
|
26
|
+
trilogy/core/optimizations/predicate_pushdown.py,sha256=oJy09U7lb8FMKexWISjg4Ksyf98Nx22bzIxmm9WuXtk,8899
|
|
27
27
|
trilogy/core/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
trilogy/core/processing/concept_strategies_v3.py,sha256=Qy3WHiKaF371dDmbA0DWVQqSMKptH_gK714Uc41wbqc,36132
|
|
29
29
|
trilogy/core/processing/graph_utils.py,sha256=aq-kqk4Iado2HywDxWEejWc-7PGO6Oa-ZQLAM6XWPHw,1199
|
|
30
30
|
trilogy/core/processing/utility.py,sha256=_sWLDuV8WAEWdEIcAPM8-FcXgBai30UV12i4O9u5Mpc,18680
|
|
31
31
|
trilogy/core/processing/node_generators/__init__.py,sha256=-mzYkRsaRNa_dfTckYkKVFSR8h8a3ihEiPJDU_tAmDo,672
|
|
32
|
-
trilogy/core/processing/node_generators/basic_node.py,sha256=
|
|
32
|
+
trilogy/core/processing/node_generators/basic_node.py,sha256=qsQ8HegQ2qOSpXFleq7yHJ-rYfF6XQGCC7h2pC-t1kQ,2878
|
|
33
33
|
trilogy/core/processing/node_generators/common.py,sha256=eslHTTPFTkmwHwKIuUsbFn54jxj-Avtt-QScqtNwzdg,8945
|
|
34
34
|
trilogy/core/processing/node_generators/filter_node.py,sha256=Vz9Rb67e1dfZgnliekwwLeDPVkthMbdrnrKRdz7J1ik,7654
|
|
35
35
|
trilogy/core/processing/node_generators/group_node.py,sha256=r54IVEhXW-tzod6uEHIQObrxgQt6aNySk5emWkWyqCU,4938
|
|
@@ -40,7 +40,7 @@ trilogy/core/processing/node_generators/rowset_node.py,sha256=KtdN6t2xM8CJxobc4a
|
|
|
40
40
|
trilogy/core/processing/node_generators/select_merge_node.py,sha256=UF4xra2sJ6dGg9TLJUgqtTX-UxqUaCEfAGo-uq7HlVs,12139
|
|
41
41
|
trilogy/core/processing/node_generators/select_node.py,sha256=nwXHQF6C-aQUIelx9dyxN2pK3muL-4-6RIqnqQqNwtw,1808
|
|
42
42
|
trilogy/core/processing/node_generators/unnest_node.py,sha256=cZ26CN338CBnd6asML1OBUtNcDzmNlFpY0Vnade4yrc,2256
|
|
43
|
-
trilogy/core/processing/node_generators/window_node.py,sha256=
|
|
43
|
+
trilogy/core/processing/node_generators/window_node.py,sha256=Jfjjdvn8RqFzrQ1gZc6vS0Bsh_iTA5AmRZ0zLlT4574,3155
|
|
44
44
|
trilogy/core/processing/nodes/__init__.py,sha256=qS5EJDRwwIrCEfS7ibCA2ESE0RPzsAIii1UWd_wNsHA,4760
|
|
45
45
|
trilogy/core/processing/nodes/base_node.py,sha256=sc3HrXkWk-xpsAQ7B7ltX1ZejYAkqFiv8Ei8Jg5VGkQ,15579
|
|
46
46
|
trilogy/core/processing/nodes/filter_node.py,sha256=GfZ9eghpFDI-s7iQP2UqTljCmn25LT_T5TAxDlh7PkQ,2343
|
|
@@ -50,7 +50,7 @@ trilogy/core/processing/nodes/select_node_v2.py,sha256=7WoFxeGEAzhpS4y4Zw2nH2tt7
|
|
|
50
50
|
trilogy/core/processing/nodes/unnest_node.py,sha256=mAmFluzm2yeeiQ6NfIB7BU_8atRGh-UJfPf9ROwbhr8,2152
|
|
51
51
|
trilogy/core/processing/nodes/window_node.py,sha256=ro0QfMFi4ZmIn5Q4D0M_vJWfnHH_C0MN7XkVkx8Gygg,1214
|
|
52
52
|
trilogy/dialect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
-
trilogy/dialect/base.py,sha256=
|
|
53
|
+
trilogy/dialect/base.py,sha256=bevM9mUGSfwt_F-kJpi0nHmMRmE0pINqqvCteqnu5FM,34880
|
|
54
54
|
trilogy/dialect/bigquery.py,sha256=15KJ-cOpBlk9O7FPviPgmg8xIydJeKx7WfmL3SSsPE8,2953
|
|
55
55
|
trilogy/dialect/common.py,sha256=eqJi_Si1iyb2sV0siTf8g8JOHueWu6RkdtQZtutKazk,3826
|
|
56
56
|
trilogy/dialect/config.py,sha256=tLVEMctaTDhUgARKXUNfHUcIolGaALkQ0RavUvXAY4w,2994
|
|
@@ -72,12 +72,12 @@ trilogy/parsing/exceptions.py,sha256=92E5i2frv5hj9wxObJZsZqj5T6bglvPzvdvco_vW1Zk
|
|
|
72
72
|
trilogy/parsing/helpers.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
73
73
|
trilogy/parsing/parse_engine.py,sha256=KMeHQf8iW-UKd4JstGgcoo6O3OZ14MaQW50g1PMjEEQ,65256
|
|
74
74
|
trilogy/parsing/render.py,sha256=-qqpXQg4yHcv284Vosjnsc_vrPveH6oaYbeCd3ZSvs0,15682
|
|
75
|
-
trilogy/parsing/trilogy.lark,sha256=
|
|
75
|
+
trilogy/parsing/trilogy.lark,sha256=B6NM3-rBHtYB_WSEti0DiS8Z-I8YH3kZU47xNzQvBx4,12389
|
|
76
76
|
trilogy/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
77
|
trilogy/scripts/trilogy.py,sha256=PHxvv6f2ODv0esyyhWxlARgra8dVhqQhYl0lTrSyVNo,3729
|
|
78
|
-
pytrilogy-0.0.2.
|
|
79
|
-
pytrilogy-0.0.2.
|
|
80
|
-
pytrilogy-0.0.2.
|
|
81
|
-
pytrilogy-0.0.2.
|
|
82
|
-
pytrilogy-0.0.2.
|
|
83
|
-
pytrilogy-0.0.2.
|
|
78
|
+
pytrilogy-0.0.2.41.dist-info/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
|
|
79
|
+
pytrilogy-0.0.2.41.dist-info/METADATA,sha256=PGYuvWWThHh9Vucj7-eZIWLGu7db7pN7iVyXL9f42-Q,8426
|
|
80
|
+
pytrilogy-0.0.2.41.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
81
|
+
pytrilogy-0.0.2.41.dist-info/entry_points.txt,sha256=0petKryjvvtEfTlbZC1AuMFumH_WQ9v8A19LvoS6G6c,54
|
|
82
|
+
pytrilogy-0.0.2.41.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
|
|
83
|
+
pytrilogy-0.0.2.41.dist-info/RECORD,,
|
trilogy/__init__.py
CHANGED
trilogy/core/models.py
CHANGED
|
@@ -1375,6 +1375,9 @@ class WindowItem(Mergeable, Namespaced, SelectContext, BaseModel):
|
|
|
1375
1375
|
over: List["Concept"] = Field(default_factory=list)
|
|
1376
1376
|
index: Optional[int] = None
|
|
1377
1377
|
|
|
1378
|
+
def __repr__(self) -> str:
|
|
1379
|
+
return f"{self.type}({self.content} {self.index}, {self.over}, {self.order_by})"
|
|
1380
|
+
|
|
1378
1381
|
def with_merge(
|
|
1379
1382
|
self, source: Concept, target: Concept, modifiers: List[Modifier]
|
|
1380
1383
|
) -> "WindowItem":
|
|
@@ -1383,6 +1386,7 @@ class WindowItem(Mergeable, Namespaced, SelectContext, BaseModel):
|
|
|
1383
1386
|
content=self.content.with_merge(source, target, modifiers),
|
|
1384
1387
|
over=[x.with_merge(source, target, modifiers) for x in self.over],
|
|
1385
1388
|
order_by=[x.with_merge(source, target, modifiers) for x in self.order_by],
|
|
1389
|
+
index=self.index,
|
|
1386
1390
|
)
|
|
1387
1391
|
|
|
1388
1392
|
def with_namespace(self, namespace: str) -> "WindowItem":
|
|
@@ -1391,6 +1395,7 @@ class WindowItem(Mergeable, Namespaced, SelectContext, BaseModel):
|
|
|
1391
1395
|
content=self.content.with_namespace(namespace),
|
|
1392
1396
|
over=[x.with_namespace(namespace) for x in self.over],
|
|
1393
1397
|
order_by=[x.with_namespace(namespace) for x in self.order_by],
|
|
1398
|
+
index=self.index,
|
|
1394
1399
|
)
|
|
1395
1400
|
|
|
1396
1401
|
def with_select_context(
|
|
@@ -1410,6 +1415,7 @@ class WindowItem(Mergeable, Namespaced, SelectContext, BaseModel):
|
|
|
1410
1415
|
x.with_select_context(grain, conditional, environment)
|
|
1411
1416
|
for x in self.order_by
|
|
1412
1417
|
],
|
|
1418
|
+
index=self.index,
|
|
1413
1419
|
)
|
|
1414
1420
|
|
|
1415
1421
|
@property
|
|
@@ -6,6 +6,7 @@ from trilogy.core.models import (
|
|
|
6
6
|
ConceptArgs,
|
|
7
7
|
Comparison,
|
|
8
8
|
Parenthetical,
|
|
9
|
+
WindowItem,
|
|
9
10
|
)
|
|
10
11
|
from trilogy.core.optimizations.base_optimization import OptimizationRule
|
|
11
12
|
from trilogy.core.processing.utility import is_scalar_condition
|
|
@@ -45,7 +46,15 @@ class PredicatePushdown(OptimizationRule):
|
|
|
45
46
|
all_inputs = {x.address for x in candidate.concept_arguments}
|
|
46
47
|
if is_child_of(candidate, parent_cte.condition):
|
|
47
48
|
return False
|
|
48
|
-
|
|
49
|
+
non_materialized = [k for k, v in parent_cte.source_map.items() if v == []]
|
|
50
|
+
concrete = [
|
|
51
|
+
x for x in parent_cte.output_columns if x.address in non_materialized
|
|
52
|
+
]
|
|
53
|
+
if any(isinstance(x.lineage, WindowItem) for x in concrete):
|
|
54
|
+
self.debug(
|
|
55
|
+
f"CTE {parent_cte.name} has window clause calculation, cannot push up to this without changing results"
|
|
56
|
+
)
|
|
57
|
+
return False
|
|
49
58
|
materialized = {k for k, v in parent_cte.source_map.items() if v != []}
|
|
50
59
|
if not row_conditions or not materialized:
|
|
51
60
|
return False
|
|
@@ -108,12 +117,12 @@ class PredicatePushdown(OptimizationRule):
|
|
|
108
117
|
|
|
109
118
|
if not cte.parent_ctes:
|
|
110
119
|
self.debug(f"No parent CTEs for {cte.name}")
|
|
111
|
-
|
|
112
120
|
return False
|
|
113
121
|
|
|
114
122
|
if not cte.condition:
|
|
115
123
|
self.debug(f"No CTE condition for {cte.name}")
|
|
116
124
|
return False
|
|
125
|
+
|
|
117
126
|
if self.complete.get(cte.name):
|
|
118
127
|
self.debug("Have done this CTE before")
|
|
119
128
|
return False
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# directly select out a basic derivation
|
|
2
2
|
from typing import List
|
|
3
3
|
|
|
4
|
-
from trilogy.core.models import
|
|
4
|
+
from trilogy.core.models import (
|
|
5
|
+
Concept,
|
|
6
|
+
WhereClause,
|
|
7
|
+
Function,
|
|
8
|
+
FunctionClass,
|
|
9
|
+
)
|
|
5
10
|
from trilogy.core.processing.nodes import StrategyNode, History
|
|
6
11
|
from trilogy.core.processing.node_generators.common import (
|
|
7
12
|
resolve_function_parent_concepts,
|
|
@@ -12,6 +17,22 @@ from trilogy.core.enums import SourceType
|
|
|
12
17
|
LOGGER_PREFIX = "[GEN_BASIC_NODE]"
|
|
13
18
|
|
|
14
19
|
|
|
20
|
+
def is_equivalent_basic_function_lineage(
|
|
21
|
+
x: Concept,
|
|
22
|
+
y: Concept,
|
|
23
|
+
):
|
|
24
|
+
if not isinstance(x.lineage, Function) or not isinstance(y.lineage, Function):
|
|
25
|
+
return False
|
|
26
|
+
if x.lineage.operator == y.lineage.operator:
|
|
27
|
+
return True
|
|
28
|
+
if (
|
|
29
|
+
y.lineage.operator in FunctionClass.AGGREGATE_FUNCTIONS.value
|
|
30
|
+
or y.lineage.operator in FunctionClass.ONE_TO_MANY.value
|
|
31
|
+
):
|
|
32
|
+
return False
|
|
33
|
+
return True
|
|
34
|
+
|
|
35
|
+
|
|
15
36
|
def gen_basic_node(
|
|
16
37
|
concept: Concept,
|
|
17
38
|
local_optional: List[Concept],
|
|
@@ -32,8 +53,15 @@ def gen_basic_node(
|
|
|
32
53
|
equivalent_optional = [
|
|
33
54
|
x
|
|
34
55
|
for x in local_optional
|
|
35
|
-
if
|
|
56
|
+
if is_equivalent_basic_function_lineage(concept, x)
|
|
57
|
+
and x.address != concept.address
|
|
36
58
|
]
|
|
59
|
+
if equivalent_optional:
|
|
60
|
+
logger.info(
|
|
61
|
+
f"{depth_prefix}{LOGGER_PREFIX} basic node for {concept} has equivalent optional {[x.address for x in equivalent_optional]}"
|
|
62
|
+
)
|
|
63
|
+
for eo in equivalent_optional:
|
|
64
|
+
parent_concepts += resolve_function_parent_concepts(eo)
|
|
37
65
|
non_equivalent_optional = [
|
|
38
66
|
x for x in local_optional if x not in equivalent_optional
|
|
39
67
|
]
|
|
@@ -10,16 +10,16 @@ from trilogy.core.processing.utility import padding
|
|
|
10
10
|
LOGGER_PREFIX = "[GEN_WINDOW_NODE]"
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def resolve_window_parent_concepts(concept: Concept) -> List[Concept]:
|
|
13
|
+
def resolve_window_parent_concepts(concept: Concept) -> tuple[Concept, List[Concept]]:
|
|
14
14
|
if not isinstance(concept.lineage, WindowItem):
|
|
15
15
|
raise ValueError
|
|
16
|
-
base = [
|
|
16
|
+
base = []
|
|
17
17
|
if concept.lineage.over:
|
|
18
18
|
base += concept.lineage.over
|
|
19
19
|
if concept.lineage.order_by:
|
|
20
20
|
for item in concept.lineage.order_by:
|
|
21
21
|
base += [item.expr.output]
|
|
22
|
-
return unique(base, "address")
|
|
22
|
+
return concept.lineage.content, unique(base, "address")
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def gen_window_node(
|
|
@@ -32,9 +32,25 @@ def gen_window_node(
|
|
|
32
32
|
history: History | None = None,
|
|
33
33
|
conditions: WhereClause | None = None,
|
|
34
34
|
) -> StrategyNode | None:
|
|
35
|
-
parent_concepts = resolve_window_parent_concepts(concept)
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
base, parent_concepts = resolve_window_parent_concepts(concept)
|
|
36
|
+
equivalent_optional = [
|
|
37
|
+
x
|
|
38
|
+
for x in local_optional
|
|
39
|
+
if isinstance(x.lineage, WindowItem)
|
|
40
|
+
and resolve_window_parent_concepts(x)[1] == parent_concepts
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
non_equivalent_optional = [
|
|
44
|
+
x for x in local_optional if x.address not in equivalent_optional
|
|
45
|
+
]
|
|
46
|
+
targets = [base]
|
|
47
|
+
if equivalent_optional:
|
|
48
|
+
for x in equivalent_optional:
|
|
49
|
+
assert isinstance(x.lineage, WindowItem)
|
|
50
|
+
targets.append(x.lineage.content)
|
|
51
|
+
|
|
52
|
+
parent_node: StrategyNode = source_concepts(
|
|
53
|
+
mandatory_list=parent_concepts + targets + non_equivalent_optional,
|
|
38
54
|
environment=environment,
|
|
39
55
|
g=g,
|
|
40
56
|
depth=depth + 1,
|
|
@@ -61,7 +77,7 @@ def gen_window_node(
|
|
|
61
77
|
)
|
|
62
78
|
raise SyntaxError
|
|
63
79
|
_window_node = WindowNode(
|
|
64
|
-
input_concepts=parent_concepts +
|
|
80
|
+
input_concepts=parent_concepts + targets + non_equivalent_optional,
|
|
65
81
|
output_concepts=[concept] + parent_concepts + local_optional,
|
|
66
82
|
environment=environment,
|
|
67
83
|
g=g,
|
trilogy/dialect/base.py
CHANGED
|
@@ -75,7 +75,7 @@ def window_factory(string: str, include_concept: bool = False) -> Callable:
|
|
|
75
75
|
) -> str:
|
|
76
76
|
if not include_concept:
|
|
77
77
|
concept = ""
|
|
78
|
-
if offset:
|
|
78
|
+
if offset is not None:
|
|
79
79
|
base = f"{string}({concept}, {offset})"
|
|
80
80
|
else:
|
|
81
81
|
base = f"{string}({concept})"
|
|
@@ -313,7 +313,10 @@ class BaseDialect:
|
|
|
313
313
|
)
|
|
314
314
|
for x in c.lineage.over
|
|
315
315
|
]
|
|
316
|
-
rval = f"{self.WINDOW_FUNCTION_MAP[c.lineage.type](concept = self.render_concept_sql(c.lineage.content,
|
|
316
|
+
rval = f"{self.WINDOW_FUNCTION_MAP[c.lineage.type](concept = self.render_concept_sql(c.lineage.content,
|
|
317
|
+
cte=cte, alias=False, raise_invalid=raise_invalid),
|
|
318
|
+
window=','.join(rendered_over_components), sort=','.join(rendered_order_components),
|
|
319
|
+
offset=c.lineage.index)}" # noqa: E501
|
|
317
320
|
elif isinstance(c.lineage, FilterItem):
|
|
318
321
|
# for cases when we've optimized this
|
|
319
322
|
if cte.condition == c.lineage.where.conditional:
|
trilogy/parsing/trilogy.lark
CHANGED
|
@@ -290,7 +290,7 @@
|
|
|
290
290
|
|
|
291
291
|
// base language constructs
|
|
292
292
|
concept_lit: IDENTIFIER
|
|
293
|
-
IDENTIFIER: /[a-zA-Z\_][a-zA-Z0-9\_
|
|
293
|
+
IDENTIFIER: /[a-zA-Z\_][a-zA-Z0-9\_\.]*/
|
|
294
294
|
WILDCARD_IDENTIFIER: /[a-zA-Z\_][a-zA-Z0-9\_\-\.\*]*/
|
|
295
295
|
QUOTED_IDENTIFIER: /`[a-zA-Z\_][a-zA-Z0-9\_\.\-\*\:\s]*`/
|
|
296
296
|
QUOTED_ADDRESS: /`[a-zA-Z\_][a-zA-Z0-9\_\.\-\*\:]*`/
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|