vtlengine 1.0__py3-none-any.whl → 1.0.2__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 vtlengine might be problematic. Click here for more details.
- vtlengine/API/_InternalApi.py +159 -102
- vtlengine/API/__init__.py +110 -68
- vtlengine/AST/ASTConstructor.py +188 -98
- vtlengine/AST/ASTConstructorModules/Expr.py +402 -205
- vtlengine/AST/ASTConstructorModules/ExprComponents.py +248 -104
- vtlengine/AST/ASTConstructorModules/Terminals.py +158 -95
- vtlengine/AST/ASTEncoders.py +1 -1
- vtlengine/AST/ASTTemplate.py +24 -9
- vtlengine/AST/ASTVisitor.py +8 -12
- vtlengine/AST/DAG/__init__.py +43 -35
- vtlengine/AST/DAG/_words.py +4 -4
- vtlengine/AST/Grammar/Vtl.g4 +49 -20
- vtlengine/AST/Grammar/VtlTokens.g4 +13 -1
- vtlengine/AST/Grammar/lexer.py +2012 -1312
- vtlengine/AST/Grammar/parser.py +7524 -4343
- vtlengine/AST/Grammar/tokens.py +140 -128
- vtlengine/AST/VtlVisitor.py +16 -5
- vtlengine/AST/__init__.py +41 -11
- vtlengine/DataTypes/NumericTypesHandling.py +5 -4
- vtlengine/DataTypes/TimeHandling.py +196 -301
- vtlengine/DataTypes/__init__.py +304 -218
- vtlengine/Exceptions/__init__.py +96 -27
- vtlengine/Exceptions/messages.py +149 -69
- vtlengine/Interpreter/__init__.py +817 -497
- vtlengine/Model/__init__.py +172 -121
- vtlengine/Operators/Aggregation.py +156 -95
- vtlengine/Operators/Analytic.py +167 -79
- vtlengine/Operators/Assignment.py +7 -4
- vtlengine/Operators/Boolean.py +27 -32
- vtlengine/Operators/CastOperator.py +177 -131
- vtlengine/Operators/Clause.py +137 -99
- vtlengine/Operators/Comparison.py +148 -117
- vtlengine/Operators/Conditional.py +290 -98
- vtlengine/Operators/General.py +68 -47
- vtlengine/Operators/HROperators.py +91 -72
- vtlengine/Operators/Join.py +217 -118
- vtlengine/Operators/Numeric.py +129 -46
- vtlengine/Operators/RoleSetter.py +16 -15
- vtlengine/Operators/Set.py +61 -36
- vtlengine/Operators/String.py +213 -139
- vtlengine/Operators/Time.py +467 -215
- vtlengine/Operators/Validation.py +117 -76
- vtlengine/Operators/__init__.py +340 -213
- vtlengine/Utils/__init__.py +232 -41
- vtlengine/__init__.py +1 -1
- vtlengine/files/output/__init__.py +15 -6
- vtlengine/files/output/_time_period_representation.py +10 -9
- vtlengine/files/parser/__init__.py +79 -52
- vtlengine/files/parser/_rfc_dialect.py +6 -5
- vtlengine/files/parser/_time_checking.py +48 -37
- vtlengine-1.0.2.dist-info/METADATA +245 -0
- vtlengine-1.0.2.dist-info/RECORD +58 -0
- {vtlengine-1.0.dist-info → vtlengine-1.0.2.dist-info}/WHEEL +1 -1
- vtlengine-1.0.dist-info/METADATA +0 -104
- vtlengine-1.0.dist-info/RECORD +0 -58
- {vtlengine-1.0.dist-info → vtlengine-1.0.2.dist-info}/LICENSE.md +0 -0
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
from antlr4.tree.Tree import TerminalNodeImpl
|
|
2
2
|
|
|
3
|
-
from vtlengine.AST import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
from vtlengine.AST import (
|
|
4
|
+
Aggregation,
|
|
5
|
+
If,
|
|
6
|
+
BinOp,
|
|
7
|
+
UnaryOp,
|
|
8
|
+
ID,
|
|
9
|
+
ParamOp,
|
|
10
|
+
MulOp,
|
|
11
|
+
Constant,
|
|
12
|
+
ParamConstant,
|
|
13
|
+
TimeAggregation,
|
|
14
|
+
Identifier,
|
|
15
|
+
EvalOp,
|
|
16
|
+
VarID,
|
|
17
|
+
Analytic,
|
|
18
|
+
UDOCall,
|
|
19
|
+
Case,
|
|
20
|
+
CaseObj,
|
|
21
|
+
)
|
|
7
22
|
from vtlengine.AST.ASTConstructorModules.Terminals import Terminals
|
|
8
23
|
from vtlengine.AST.Grammar.parser import Parser
|
|
9
24
|
from vtlengine.AST.VtlVisitor import VtlVisitor
|
|
@@ -14,26 +29,26 @@ class ExprComp(VtlVisitor):
|
|
|
14
29
|
"""______________________________________________________________________________________
|
|
15
30
|
|
|
16
31
|
|
|
17
|
-
|
|
32
|
+
ExprComponent Definition.
|
|
18
33
|
|
|
19
|
-
|
|
34
|
+
_______________________________________________________________________________________"""
|
|
20
35
|
|
|
21
36
|
def visitExprComponent(self, ctx: Parser.ExprComponentContext):
|
|
22
37
|
"""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
exprComponent:
|
|
39
|
+
LPAREN exprComponent RPAREN # parenthesisExprComp # noqa E501
|
|
40
|
+
| functionsComponents # functionsExpressionComp # noqa E501
|
|
41
|
+
| op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp # noqa E501
|
|
42
|
+
| left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp # noqa E501
|
|
43
|
+
| left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp # noqa E501
|
|
44
|
+
| left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp # noqa E501
|
|
45
|
+
| left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp # noqa E501
|
|
46
|
+
| left=exprComponent op=AND right=exprComponent # booleanExprComp # noqa E501
|
|
47
|
+
| left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp # noqa E501
|
|
48
|
+
| IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp # noqa E501
|
|
49
|
+
| constant # constantExprComp # noqa E501
|
|
50
|
+
| componentID # compId # noqa E501
|
|
51
|
+
;
|
|
37
52
|
"""
|
|
38
53
|
ctx_list = list(ctx.getChildren())
|
|
39
54
|
c = ctx_list[0]
|
|
@@ -74,6 +89,10 @@ class ExprComp(VtlVisitor):
|
|
|
74
89
|
elif isinstance(ctx, Parser.IfExprCompContext):
|
|
75
90
|
return self.visitIfExprComp(ctx)
|
|
76
91
|
|
|
92
|
+
# CASE WHEN conditionalExpr=expr THEN thenExpr=expr ELSE elseExpr=expr END # caseExpr
|
|
93
|
+
elif isinstance(ctx, Parser.CaseExprCompContext):
|
|
94
|
+
return self.visitCaseExprComp(ctx)
|
|
95
|
+
|
|
77
96
|
# constant
|
|
78
97
|
elif isinstance(ctx, Parser.ConstantExprCompContext):
|
|
79
98
|
return Terminals().visitConstant(c)
|
|
@@ -85,9 +104,9 @@ class ExprComp(VtlVisitor):
|
|
|
85
104
|
return Terminals().visitComponentID(c)
|
|
86
105
|
token = c.children[0].getSymbol()
|
|
87
106
|
# check token text
|
|
88
|
-
has_scaped_char = token.text.find("
|
|
107
|
+
has_scaped_char = token.text.find("'") != -1
|
|
89
108
|
if has_scaped_char:
|
|
90
|
-
token.text = str(token.text.replace("
|
|
109
|
+
token.text = str(token.text.replace("'", ""))
|
|
91
110
|
var_id_node = VarID(token.text)
|
|
92
111
|
return var_id_node
|
|
93
112
|
|
|
@@ -156,6 +175,26 @@ class ExprComp(VtlVisitor):
|
|
|
156
175
|
|
|
157
176
|
return if_node
|
|
158
177
|
|
|
178
|
+
def visitCaseExprComp(self, ctx: Parser.CaseExprCompContext):
|
|
179
|
+
ctx_list = list(ctx.getChildren())
|
|
180
|
+
|
|
181
|
+
if len(ctx_list) % 4 != 3:
|
|
182
|
+
raise ValueError("Syntax error.")
|
|
183
|
+
|
|
184
|
+
else_node = self.visitExprComponent(ctx_list[-1])
|
|
185
|
+
ctx_list = ctx_list[1:-2]
|
|
186
|
+
cases = []
|
|
187
|
+
|
|
188
|
+
for i in range(0, len(ctx_list), 4):
|
|
189
|
+
condition = self.visitExprComponent(ctx_list[i + 1])
|
|
190
|
+
thenOp = self.visitExprComponent(ctx_list[i + 3])
|
|
191
|
+
case_obj = CaseObj(condition, thenOp)
|
|
192
|
+
cases.append(case_obj)
|
|
193
|
+
|
|
194
|
+
case_node = Case(cases, else_node)
|
|
195
|
+
|
|
196
|
+
return case_node
|
|
197
|
+
|
|
159
198
|
def visitOptionalExprComponent(self, ctx: Parser.OptionalExprComponentContext):
|
|
160
199
|
"""
|
|
161
200
|
optionalExpr: expr
|
|
@@ -170,14 +209,14 @@ class ExprComp(VtlVisitor):
|
|
|
170
209
|
elif isinstance(c, TerminalNodeImpl):
|
|
171
210
|
token = c.getSymbol()
|
|
172
211
|
opt = token.text
|
|
173
|
-
return ID(
|
|
212
|
+
return ID("OPTIONAL", opt)
|
|
174
213
|
|
|
175
|
-
"""
|
|
214
|
+
"""____________________________________________________________________________________
|
|
176
215
|
|
|
177
216
|
|
|
178
|
-
|
|
217
|
+
FunctionsComponents Definition.
|
|
179
218
|
|
|
180
|
-
|
|
219
|
+
_____________________________________________________________________________________"""
|
|
181
220
|
|
|
182
221
|
def visitFunctionsComponents(self, ctx: Parser.FunctionsComponentsContext):
|
|
183
222
|
"""
|
|
@@ -224,7 +263,7 @@ class ExprComp(VtlVisitor):
|
|
|
224
263
|
|
|
225
264
|
"""
|
|
226
265
|
-----------------------------------
|
|
227
|
-
Generic Functions Components
|
|
266
|
+
Generic Functions Components
|
|
228
267
|
-----------------------------------
|
|
229
268
|
"""
|
|
230
269
|
|
|
@@ -240,56 +279,74 @@ class ExprComp(VtlVisitor):
|
|
|
240
279
|
|
|
241
280
|
def visitCallComponent(self, ctx: Parser.CallComponentContext):
|
|
242
281
|
"""
|
|
243
|
-
callFunction: operatorID LPAREN (parameterComponent (COMMA parameterComponent)*)? RPAREN # callComponent
|
|
282
|
+
callFunction: operatorID LPAREN (parameterComponent (COMMA parameterComponent)*)? RPAREN # callComponent # noqa E501
|
|
244
283
|
"""
|
|
245
284
|
ctx_list = list(ctx.getChildren())
|
|
246
285
|
c = ctx_list[0]
|
|
247
286
|
|
|
248
287
|
op = Terminals().visitOperatorID(c)
|
|
249
|
-
param_nodes = [
|
|
250
|
-
|
|
288
|
+
param_nodes = [
|
|
289
|
+
self.visitParameterComponent(element)
|
|
290
|
+
for element in ctx_list
|
|
291
|
+
if isinstance(element, Parser.ParameterComponentContext)
|
|
292
|
+
]
|
|
251
293
|
|
|
252
294
|
return UDOCall(op=op, params=param_nodes)
|
|
253
295
|
|
|
254
296
|
def visitEvalAtomComponent(self, ctx: Parser.EvalAtomComponentContext):
|
|
255
297
|
"""
|
|
256
|
-
|
|
298
|
+
| EVAL LPAREN routineName LPAREN (componentID|scalarItem)? (COMMA (componentID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS outputParameterTypeComponent)? RPAREN # evalAtomComponent # noqa E501
|
|
257
299
|
"""
|
|
258
300
|
ctx_list = list(ctx.getChildren())
|
|
259
301
|
|
|
260
302
|
routine_name = Terminals().visitRoutineName(ctx_list[2])
|
|
261
303
|
|
|
262
304
|
# Think of a way to maintain the order, for now its not necessary.
|
|
263
|
-
var_ids_nodes = [
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
305
|
+
var_ids_nodes = [
|
|
306
|
+
Terminals().visitVarID(varID)
|
|
307
|
+
for varID in ctx_list
|
|
308
|
+
if isinstance(varID, Parser.VarIDContext)
|
|
309
|
+
]
|
|
310
|
+
constant_nodes = [
|
|
311
|
+
Terminals().visitScalarItem(scalar)
|
|
312
|
+
for scalar in ctx_list
|
|
313
|
+
if isinstance(scalar, Parser.ScalarItemContext)
|
|
314
|
+
]
|
|
267
315
|
children_nodes = var_ids_nodes + constant_nodes
|
|
268
316
|
|
|
269
317
|
if len(children_nodes) > 1:
|
|
270
318
|
raise Exception("Only one operand is allowed in Eval")
|
|
271
319
|
|
|
272
320
|
# Reference manual says it is mandatory.
|
|
273
|
-
language_name = [
|
|
274
|
-
|
|
275
|
-
|
|
321
|
+
language_name = [
|
|
322
|
+
language
|
|
323
|
+
for language in ctx_list
|
|
324
|
+
if isinstance(language, TerminalNodeImpl)
|
|
325
|
+
and language.getSymbol().type == Parser.STRING_CONSTANT
|
|
326
|
+
]
|
|
276
327
|
if len(language_name) == 0:
|
|
277
328
|
# AST_ASTCONSTRUCTOR.12
|
|
278
|
-
raise SemanticError("1-4-2-1", option=
|
|
329
|
+
raise SemanticError("1-4-2-1", option="language")
|
|
279
330
|
# Reference manual says it is mandatory.
|
|
280
|
-
output_node = [
|
|
281
|
-
|
|
282
|
-
|
|
331
|
+
output_node = [
|
|
332
|
+
Terminals().visitOutputParameterTypeComponent(output)
|
|
333
|
+
for output in ctx_list
|
|
334
|
+
if isinstance(output, Parser.OutputParameterTypeComponentContext)
|
|
335
|
+
]
|
|
283
336
|
if len(output_node) == 0:
|
|
284
337
|
# AST_ASTCONSTRUCTOR.13
|
|
285
|
-
raise SemanticError("1-4-2-1", option=
|
|
338
|
+
raise SemanticError("1-4-2-1", option="output")
|
|
286
339
|
|
|
287
|
-
return EvalOp(
|
|
288
|
-
|
|
340
|
+
return EvalOp(
|
|
341
|
+
name=routine_name,
|
|
342
|
+
operands=children_nodes[0],
|
|
343
|
+
output=output_node[0],
|
|
344
|
+
language=language_name[0].getSymbol().text,
|
|
345
|
+
)
|
|
289
346
|
|
|
290
347
|
def visitCastExprComponent(self, ctx: Parser.CastExprComponentContext):
|
|
291
348
|
"""
|
|
292
|
-
|
|
349
|
+
| CAST LPAREN exprComponent COMMA (basicScalarType|valueDomainName) (COMMA STRING_CONSTANT)? RPAREN # castExprComponent # noqa E501
|
|
293
350
|
"""
|
|
294
351
|
ctx_list = list(ctx.getChildren())
|
|
295
352
|
c = ctx_list[0]
|
|
@@ -297,19 +354,30 @@ class ExprComp(VtlVisitor):
|
|
|
297
354
|
token = c.getSymbol()
|
|
298
355
|
|
|
299
356
|
op = token.text
|
|
300
|
-
expr_node = [
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
357
|
+
expr_node = [
|
|
358
|
+
self.visitExprComponent(expr)
|
|
359
|
+
for expr in ctx_list
|
|
360
|
+
if isinstance(expr, Parser.ExprComponentContext)
|
|
361
|
+
]
|
|
362
|
+
basic_scalar_type = [
|
|
363
|
+
Terminals().visitBasicScalarType(type_)
|
|
364
|
+
for type_ in ctx_list
|
|
365
|
+
if isinstance(type_, Parser.BasicScalarTypeContext)
|
|
366
|
+
]
|
|
367
|
+
|
|
368
|
+
[
|
|
369
|
+
Terminals().visitValueDomainName(valueD)
|
|
370
|
+
for valueD in ctx_list
|
|
371
|
+
if isinstance(valueD, Parser.ValueDomainNameContext)
|
|
372
|
+
]
|
|
307
373
|
|
|
308
374
|
if len(ctx_list) > 6:
|
|
309
|
-
param_node = [
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
375
|
+
param_node = [
|
|
376
|
+
ParamConstant("PARAM_CAST", str_.symbol.text.strip('"'))
|
|
377
|
+
for str_ in ctx_list
|
|
378
|
+
if isinstance(str_, TerminalNodeImpl)
|
|
379
|
+
and str_.getSymbol().type == Parser.STRING_CONSTANT
|
|
380
|
+
]
|
|
313
381
|
else:
|
|
314
382
|
param_node = []
|
|
315
383
|
|
|
@@ -330,13 +398,13 @@ class ExprComp(VtlVisitor):
|
|
|
330
398
|
if isinstance(c, Parser.ExprComponentContext):
|
|
331
399
|
return self.visitExprComponent(c)
|
|
332
400
|
elif isinstance(c, TerminalNodeImpl):
|
|
333
|
-
return ID(
|
|
401
|
+
return ID("OPTIONAL", c.getSymbol().text)
|
|
334
402
|
else:
|
|
335
403
|
raise NotImplementedError
|
|
336
404
|
|
|
337
405
|
"""
|
|
338
406
|
-----------------------------------
|
|
339
|
-
String Functions
|
|
407
|
+
String Functions
|
|
340
408
|
-----------------------------------
|
|
341
409
|
"""
|
|
342
410
|
|
|
@@ -370,8 +438,9 @@ class ExprComp(VtlVisitor):
|
|
|
370
438
|
|
|
371
439
|
token = c.getSymbol()
|
|
372
440
|
childrens = [expr for expr in ctx_list if isinstance(expr, Parser.ExprComponentContext)]
|
|
373
|
-
params = [
|
|
374
|
-
|
|
441
|
+
params = [
|
|
442
|
+
param for param in ctx_list if isinstance(param, Parser.OptionalExprComponentContext)
|
|
443
|
+
]
|
|
375
444
|
|
|
376
445
|
op_node = token.text
|
|
377
446
|
for children in childrens:
|
|
@@ -388,10 +457,16 @@ class ExprComp(VtlVisitor):
|
|
|
388
457
|
c = ctx_list[0]
|
|
389
458
|
|
|
390
459
|
token = c.getSymbol()
|
|
391
|
-
expressions = [
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
460
|
+
expressions = [
|
|
461
|
+
self.visitExprComponent(expr)
|
|
462
|
+
for expr in ctx_list
|
|
463
|
+
if isinstance(expr, Parser.ExprComponentContext)
|
|
464
|
+
]
|
|
465
|
+
params = [
|
|
466
|
+
self.visitOptionalExprComponent(param)
|
|
467
|
+
for param in ctx_list
|
|
468
|
+
if isinstance(param, Parser.OptionalExprComponentContext)
|
|
469
|
+
]
|
|
395
470
|
|
|
396
471
|
op_node = token.text
|
|
397
472
|
|
|
@@ -405,10 +480,16 @@ class ExprComp(VtlVisitor):
|
|
|
405
480
|
c = ctx_list[0]
|
|
406
481
|
|
|
407
482
|
token = c.getSymbol()
|
|
408
|
-
expressions = [
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
483
|
+
expressions = [
|
|
484
|
+
self.visitExprComponent(expr)
|
|
485
|
+
for expr in ctx_list
|
|
486
|
+
if isinstance(expr, Parser.ExprComponentContext)
|
|
487
|
+
]
|
|
488
|
+
params = [
|
|
489
|
+
self.visitOptionalExprComponent(param)
|
|
490
|
+
for param in ctx_list
|
|
491
|
+
if isinstance(param, Parser.OptionalExprComponentContext)
|
|
492
|
+
]
|
|
412
493
|
|
|
413
494
|
op_node = token.text
|
|
414
495
|
|
|
@@ -419,7 +500,7 @@ class ExprComp(VtlVisitor):
|
|
|
419
500
|
|
|
420
501
|
"""
|
|
421
502
|
-----------------------------------
|
|
422
|
-
Numeric Component Functions
|
|
503
|
+
Numeric Component Functions
|
|
423
504
|
-----------------------------------
|
|
424
505
|
"""
|
|
425
506
|
|
|
@@ -442,8 +523,9 @@ class ExprComp(VtlVisitor):
|
|
|
442
523
|
operand_node = self.visitExprComponent(ctx_list[2])
|
|
443
524
|
return UnaryOp(op_node, operand_node)
|
|
444
525
|
|
|
445
|
-
def visitUnaryWithOptionalNumericComponent(
|
|
446
|
-
|
|
526
|
+
def visitUnaryWithOptionalNumericComponent(
|
|
527
|
+
self, ctx: Parser.UnaryWithOptionalNumericComponentContext
|
|
528
|
+
):
|
|
447
529
|
ctx_list = list(ctx.getChildren())
|
|
448
530
|
c = ctx_list[0]
|
|
449
531
|
|
|
@@ -452,8 +534,9 @@ class ExprComp(VtlVisitor):
|
|
|
452
534
|
|
|
453
535
|
token = c.getSymbol()
|
|
454
536
|
childrens = [expr for expr in ctx_list if isinstance(expr, Parser.ExprComponentContext)]
|
|
455
|
-
params = [
|
|
456
|
-
|
|
537
|
+
params = [
|
|
538
|
+
param for param in ctx_list if isinstance(param, Parser.OptionalExprComponentContext)
|
|
539
|
+
]
|
|
457
540
|
|
|
458
541
|
op_node = token.text
|
|
459
542
|
for children in childrens:
|
|
@@ -478,13 +561,13 @@ class ExprComp(VtlVisitor):
|
|
|
478
561
|
|
|
479
562
|
"""
|
|
480
563
|
-----------------------------------
|
|
481
|
-
Time Functions
|
|
564
|
+
Time Functions
|
|
482
565
|
-----------------------------------
|
|
483
566
|
"""
|
|
484
567
|
|
|
485
568
|
def visitTimeFunctionsComponents(self, ctx: Parser.TimeFunctionsComponentsContext):
|
|
486
569
|
if isinstance(ctx, Parser.PeriodAtomComponentContext):
|
|
487
|
-
return self.
|
|
570
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
488
571
|
elif isinstance(ctx, Parser.FillTimeAtomComponentContext):
|
|
489
572
|
return self.visitFillTimeAtomComponent(ctx)
|
|
490
573
|
elif isinstance(ctx, Parser.FlowAtomComponentContext):
|
|
@@ -495,10 +578,30 @@ class ExprComp(VtlVisitor):
|
|
|
495
578
|
return self.visitTimeAggAtomComponent(ctx)
|
|
496
579
|
elif isinstance(ctx, Parser.CurrentDateAtomComponentContext):
|
|
497
580
|
return self.visitCurrentDateAtomComponent(ctx)
|
|
581
|
+
elif isinstance(ctx, Parser.DateDiffAtomComponentContext):
|
|
582
|
+
return self.visitDateAddAtomComponentContext(ctx)
|
|
583
|
+
elif isinstance(ctx, Parser.DateAddAtomComponentContext):
|
|
584
|
+
return self.visitDateAddAtomComponentContext(ctx)
|
|
585
|
+
elif isinstance(ctx, Parser.YearAtomComponentContext):
|
|
586
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
587
|
+
elif isinstance(ctx, Parser.MonthAtomComponentContext):
|
|
588
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
589
|
+
elif isinstance(ctx, Parser.DayOfMonthAtomComponentContext):
|
|
590
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
591
|
+
elif isinstance(ctx, Parser.DayOfYearAtomComponentContext):
|
|
592
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
593
|
+
elif isinstance(ctx, Parser.DayToYearAtomComponentContext):
|
|
594
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
595
|
+
elif isinstance(ctx, Parser.DayToMonthAtomComponentContext):
|
|
596
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
597
|
+
elif isinstance(ctx, Parser.YearToDayAtomComponentContext):
|
|
598
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
599
|
+
elif isinstance(ctx, Parser.MonthToDayAtomComponentContext):
|
|
600
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
498
601
|
else:
|
|
499
602
|
raise NotImplementedError
|
|
500
603
|
|
|
501
|
-
def
|
|
604
|
+
def visitTimeUnaryAtomComponent(self, ctx: Parser.PeriodAtomComponentContext):
|
|
502
605
|
"""
|
|
503
606
|
periodExpr: PERIOD_INDICATOR '(' expr? ')' ;
|
|
504
607
|
"""
|
|
@@ -506,8 +609,11 @@ class ExprComp(VtlVisitor):
|
|
|
506
609
|
c = ctx_list[0]
|
|
507
610
|
|
|
508
611
|
op = c.getSymbol().text
|
|
509
|
-
operand_node = [
|
|
510
|
-
|
|
612
|
+
operand_node = [
|
|
613
|
+
self.visitExprComponent(operand)
|
|
614
|
+
for operand in ctx_list
|
|
615
|
+
if isinstance(operand, Parser.ExprComponentContext)
|
|
616
|
+
]
|
|
511
617
|
|
|
512
618
|
if len(operand_node) == 0:
|
|
513
619
|
# AST_ASTCONSTRUCTOR.15
|
|
@@ -524,7 +630,7 @@ class ExprComp(VtlVisitor):
|
|
|
524
630
|
|
|
525
631
|
op = c.getSymbol().text
|
|
526
632
|
left_node = self.visitExprComponent(ctx_list[2])
|
|
527
|
-
right_node = Constant(
|
|
633
|
+
right_node = Constant("INTEGER_CONSTANT", int(ctx_list[4].getSymbol().text))
|
|
528
634
|
|
|
529
635
|
return BinOp(left=left_node, op=op, right=right_node)
|
|
530
636
|
|
|
@@ -539,7 +645,7 @@ class ExprComp(VtlVisitor):
|
|
|
539
645
|
children_node = [self.visitExprComponent(ctx_list[2])]
|
|
540
646
|
|
|
541
647
|
if len(ctx_list) > 4:
|
|
542
|
-
param_constant_node = [ParamConstant(
|
|
648
|
+
param_constant_node = [ParamConstant("PARAM_TIMESERIES", ctx_list[4].getSymbol().text)]
|
|
543
649
|
else:
|
|
544
650
|
param_constant_node = []
|
|
545
651
|
|
|
@@ -547,8 +653,8 @@ class ExprComp(VtlVisitor):
|
|
|
547
653
|
|
|
548
654
|
def visitTimeAggAtomComponent(self, ctx: Parser.TimeAggAtomComponentContext):
|
|
549
655
|
"""
|
|
550
|
-
TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))?
|
|
551
|
-
(COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent;
|
|
656
|
+
TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))? # noqa E501
|
|
657
|
+
(COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent; # noqa E501
|
|
552
658
|
"""
|
|
553
659
|
ctx_list = list(ctx.getChildren())
|
|
554
660
|
c = ctx_list[0]
|
|
@@ -561,9 +667,12 @@ class ExprComp(VtlVisitor):
|
|
|
561
667
|
# raise SemanticError("periodIndFrom is not allowed in Time_agg")
|
|
562
668
|
period_from = str(ctx.periodIndFrom.text)[1:-1]
|
|
563
669
|
|
|
564
|
-
conf = [
|
|
565
|
-
|
|
566
|
-
|
|
670
|
+
conf = [
|
|
671
|
+
str_.getSymbol().text
|
|
672
|
+
for str_ in ctx_list
|
|
673
|
+
if isinstance(str_, TerminalNodeImpl)
|
|
674
|
+
and str_.getSymbol().type in [Parser.FIRST, Parser.LAST]
|
|
675
|
+
]
|
|
567
676
|
|
|
568
677
|
if len(conf) == 0:
|
|
569
678
|
conf = None
|
|
@@ -582,21 +691,51 @@ class ExprComp(VtlVisitor):
|
|
|
582
691
|
if operand_node is None:
|
|
583
692
|
# AST_ASTCONSTRUCTOR.17
|
|
584
693
|
raise SemanticError("1-4-2-2")
|
|
585
|
-
return TimeAggregation(
|
|
586
|
-
|
|
694
|
+
return TimeAggregation(
|
|
695
|
+
op=op, operand=operand_node, period_to=period_to, period_from=period_from, conf=conf
|
|
696
|
+
)
|
|
587
697
|
|
|
588
698
|
def visitCurrentDateAtomComponent(self, ctx: Parser.CurrentDateAtomComponentContext):
|
|
589
699
|
c = list(ctx.getChildren())[0]
|
|
590
700
|
return MulOp(op=c.getSymbol().text, children=[])
|
|
591
701
|
|
|
702
|
+
def visitDateDiffAtomComponent(self, ctx: Parser.TimeShiftAtomComponentContext):
|
|
703
|
+
""" """
|
|
704
|
+
ctx_list = list(ctx.getChildren())
|
|
705
|
+
c = ctx_list[0]
|
|
706
|
+
|
|
707
|
+
op = c.getSymbol().text
|
|
708
|
+
left_node = self.visitExprComponent(ctx_list[2])
|
|
709
|
+
right_node = Constant("INTEGER_CONSTANT", int(ctx_list[4].getSymbol().text))
|
|
710
|
+
|
|
711
|
+
return BinOp(left=left_node, op=op, right=right_node)
|
|
712
|
+
|
|
713
|
+
def visitDateAddAtomComponentContext(self, ctx: Parser.DateAddAtomComponentContext):
|
|
714
|
+
""" """
|
|
715
|
+
ctx_list = list(ctx.getChildren())
|
|
716
|
+
c = ctx_list[0]
|
|
717
|
+
|
|
718
|
+
op = c.getSymbol().text
|
|
719
|
+
children_node = [self.visitExprComponent(ctx_list[2])]
|
|
720
|
+
|
|
721
|
+
param_constant_node = []
|
|
722
|
+
|
|
723
|
+
if len(ctx_list) > 4:
|
|
724
|
+
param_constant_node = [self.visitExprComponent(ctx_list[4])]
|
|
725
|
+
if len(ctx_list) > 6:
|
|
726
|
+
param_constant_node.append(self.visitExprComponent(ctx_list[6]))
|
|
727
|
+
|
|
728
|
+
return ParamOp(op=op, children=children_node, params=param_constant_node)
|
|
729
|
+
|
|
592
730
|
"""
|
|
593
731
|
-----------------------------------
|
|
594
|
-
Conditional Functions
|
|
732
|
+
Conditional Functions
|
|
595
733
|
-----------------------------------
|
|
596
734
|
"""
|
|
597
735
|
|
|
598
|
-
def visitConditionalFunctionsComponents(
|
|
599
|
-
|
|
736
|
+
def visitConditionalFunctionsComponents(
|
|
737
|
+
self, ctx: Parser.ConditionalFunctionsComponentsContext
|
|
738
|
+
):
|
|
600
739
|
if isinstance(ctx, Parser.NvlAtomComponentContext):
|
|
601
740
|
return self.visitNvlAtomComponent(ctx)
|
|
602
741
|
else:
|
|
@@ -615,7 +754,7 @@ class ExprComp(VtlVisitor):
|
|
|
615
754
|
|
|
616
755
|
"""
|
|
617
756
|
-----------------------------------
|
|
618
|
-
Comparison Components Functions
|
|
757
|
+
Comparison Components Functions
|
|
619
758
|
-----------------------------------
|
|
620
759
|
"""
|
|
621
760
|
|
|
@@ -664,7 +803,7 @@ class ExprComp(VtlVisitor):
|
|
|
664
803
|
|
|
665
804
|
"""
|
|
666
805
|
-----------------------------------
|
|
667
|
-
Aggregate Components Functions
|
|
806
|
+
Aggregate Components Functions
|
|
668
807
|
-----------------------------------
|
|
669
808
|
"""
|
|
670
809
|
|
|
@@ -689,7 +828,7 @@ class ExprComp(VtlVisitor):
|
|
|
689
828
|
|
|
690
829
|
"""
|
|
691
830
|
-----------------------------------
|
|
692
|
-
|
|
831
|
+
Analytic Components Functions
|
|
693
832
|
-----------------------------------
|
|
694
833
|
"""
|
|
695
834
|
|
|
@@ -729,8 +868,9 @@ class ExprComp(VtlVisitor):
|
|
|
729
868
|
else:
|
|
730
869
|
raise NotImplementedError
|
|
731
870
|
|
|
732
|
-
return Analytic(
|
|
733
|
-
|
|
871
|
+
return Analytic(
|
|
872
|
+
op=op_node, operand=operand, partition_by=partition_by, order_by=order_by, window=params
|
|
873
|
+
)
|
|
734
874
|
|
|
735
875
|
def visitLagOrLeadAnComponent(self, ctx: Parser.LagOrLeadAnComponentContext):
|
|
736
876
|
ctx_list = list(ctx.getChildren())
|
|
@@ -749,8 +889,9 @@ class ExprComp(VtlVisitor):
|
|
|
749
889
|
elif isinstance(c, Parser.OrderByClauseContext):
|
|
750
890
|
order_by = Terminals().visitOrderByClause(c)
|
|
751
891
|
continue
|
|
752
|
-
elif isinstance(c, Parser.SignedIntegerContext) or isinstance(
|
|
753
|
-
|
|
892
|
+
elif isinstance(c, Parser.SignedIntegerContext) or isinstance(
|
|
893
|
+
c, Parser.ScalarItemContext
|
|
894
|
+
):
|
|
754
895
|
if params is None:
|
|
755
896
|
params = []
|
|
756
897
|
if isinstance(c, Parser.SignedIntegerContext):
|
|
@@ -759,8 +900,9 @@ class ExprComp(VtlVisitor):
|
|
|
759
900
|
params.append(Terminals().visitScalarItem(c))
|
|
760
901
|
continue
|
|
761
902
|
|
|
762
|
-
return Analytic(
|
|
763
|
-
|
|
903
|
+
return Analytic(
|
|
904
|
+
op=op_node, operand=operand, partition_by=partition_by, order_by=order_by, params=params
|
|
905
|
+
)
|
|
764
906
|
|
|
765
907
|
def visitRankAnComponent(self, ctx: Parser.RankAnComponentContext):
|
|
766
908
|
ctx_list = list(ctx.getChildren())
|
|
@@ -778,8 +920,9 @@ class ExprComp(VtlVisitor):
|
|
|
778
920
|
order_by = Terminals().visitOrderByClause(c)
|
|
779
921
|
continue
|
|
780
922
|
|
|
781
|
-
return Analytic(
|
|
782
|
-
|
|
923
|
+
return Analytic(
|
|
924
|
+
op=op_node, operand=None, partition_by=partition_by, order_by=order_by, window=None
|
|
925
|
+
)
|
|
783
926
|
|
|
784
927
|
def visitRatioToReportAnComponent(self, ctx: Parser.RatioToReportAnComponentContext):
|
|
785
928
|
ctx_list = list(ctx.getChildren())
|
|
@@ -792,5 +935,6 @@ class ExprComp(VtlVisitor):
|
|
|
792
935
|
|
|
793
936
|
partition_by = Terminals().visitPartitionByClause(ctx_list[5])
|
|
794
937
|
|
|
795
|
-
return Analytic(
|
|
796
|
-
|
|
938
|
+
return Analytic(
|
|
939
|
+
op=op_node, operand=operand, partition_by=partition_by, order_by=order_by, window=params
|
|
940
|
+
)
|