vtlengine 1.0.1__py3-none-any.whl → 1.0.3__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 +19 -8
- vtlengine/API/__init__.py +9 -9
- vtlengine/AST/ASTConstructor.py +23 -43
- vtlengine/AST/ASTConstructorModules/Expr.py +147 -71
- vtlengine/AST/ASTConstructorModules/ExprComponents.py +104 -40
- vtlengine/AST/ASTConstructorModules/Terminals.py +28 -39
- vtlengine/AST/ASTTemplate.py +16 -1
- vtlengine/AST/DAG/__init__.py +12 -15
- vtlengine/AST/Grammar/Vtl.g4 +49 -20
- vtlengine/AST/Grammar/VtlTokens.g4 +13 -1
- vtlengine/AST/Grammar/lexer.py +1293 -1183
- vtlengine/AST/Grammar/parser.py +5758 -3939
- vtlengine/AST/Grammar/tokens.py +12 -0
- vtlengine/AST/VtlVisitor.py +9 -2
- vtlengine/AST/__init__.py +21 -3
- vtlengine/DataTypes/TimeHandling.py +12 -7
- vtlengine/DataTypes/__init__.py +17 -24
- vtlengine/Exceptions/__init__.py +43 -1
- vtlengine/Exceptions/messages.py +82 -62
- vtlengine/Interpreter/__init__.py +125 -120
- vtlengine/Model/__init__.py +17 -12
- vtlengine/Operators/Aggregation.py +14 -14
- vtlengine/Operators/Analytic.py +56 -31
- vtlengine/Operators/Assignment.py +2 -3
- vtlengine/Operators/Boolean.py +5 -7
- vtlengine/Operators/CastOperator.py +12 -13
- vtlengine/Operators/Clause.py +11 -13
- vtlengine/Operators/Comparison.py +31 -17
- vtlengine/Operators/Conditional.py +157 -17
- vtlengine/Operators/General.py +4 -4
- vtlengine/Operators/HROperators.py +41 -34
- vtlengine/Operators/Join.py +18 -22
- vtlengine/Operators/Numeric.py +76 -39
- vtlengine/Operators/RoleSetter.py +6 -8
- vtlengine/Operators/Set.py +7 -12
- vtlengine/Operators/String.py +19 -27
- vtlengine/Operators/Time.py +366 -43
- vtlengine/Operators/Validation.py +4 -7
- vtlengine/Operators/__init__.py +38 -41
- vtlengine/Utils/__init__.py +149 -94
- vtlengine/__init__.py +1 -1
- vtlengine/files/output/__init__.py +2 -2
- vtlengine/files/output/_time_period_representation.py +0 -1
- vtlengine/files/parser/__init__.py +18 -18
- vtlengine/files/parser/_time_checking.py +3 -2
- {vtlengine-1.0.1.dist-info → vtlengine-1.0.3.dist-info}/METADATA +17 -5
- vtlengine-1.0.3.dist-info/RECORD +58 -0
- vtlengine-1.0.1.dist-info/RECORD +0 -58
- {vtlengine-1.0.1.dist-info → vtlengine-1.0.3.dist-info}/LICENSE.md +0 -0
- {vtlengine-1.0.1.dist-info → vtlengine-1.0.3.dist-info}/WHEEL +0 -0
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
from antlr4.tree.Tree import TerminalNodeImpl
|
|
2
2
|
|
|
3
3
|
from vtlengine.AST import (
|
|
4
|
+
ID,
|
|
4
5
|
Aggregation,
|
|
5
|
-
|
|
6
|
+
Analytic,
|
|
6
7
|
BinOp,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ParamOp,
|
|
10
|
-
MulOp,
|
|
8
|
+
Case,
|
|
9
|
+
CaseObj,
|
|
11
10
|
Constant,
|
|
11
|
+
EvalOp,
|
|
12
|
+
Identifier,
|
|
13
|
+
If,
|
|
14
|
+
MulOp,
|
|
12
15
|
ParamConstant,
|
|
16
|
+
ParamOp,
|
|
13
17
|
TimeAggregation,
|
|
14
|
-
Identifier,
|
|
15
|
-
EvalOp,
|
|
16
|
-
VarID,
|
|
17
|
-
Analytic,
|
|
18
18
|
UDOCall,
|
|
19
|
+
UnaryOp,
|
|
20
|
+
VarID,
|
|
19
21
|
)
|
|
20
22
|
from vtlengine.AST.ASTConstructorModules.Terminals import Terminals
|
|
21
23
|
from vtlengine.AST.Grammar.parser import Parser
|
|
@@ -34,20 +36,20 @@ class ExprComp(VtlVisitor):
|
|
|
34
36
|
def visitExprComponent(self, ctx: Parser.ExprComponentContext):
|
|
35
37
|
"""
|
|
36
38
|
exprComponent:
|
|
37
|
-
LPAREN exprComponent RPAREN # parenthesisExprComp
|
|
38
|
-
| functionsComponents # functionsExpressionComp
|
|
39
|
-
| op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp
|
|
40
|
-
| left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp
|
|
41
|
-
| left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp
|
|
42
|
-
| left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp
|
|
43
|
-
| left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp
|
|
44
|
-
| left=exprComponent op=AND right=exprComponent # booleanExprComp
|
|
45
|
-
| left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp
|
|
46
|
-
| IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp
|
|
47
|
-
| constant # constantExprComp
|
|
48
|
-
| componentID # compId
|
|
39
|
+
LPAREN exprComponent RPAREN # parenthesisExprComp
|
|
40
|
+
| functionsComponents # functionsExpressionComp
|
|
41
|
+
| op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp
|
|
42
|
+
| left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp
|
|
43
|
+
| left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp
|
|
44
|
+
| left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp
|
|
45
|
+
| left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp
|
|
46
|
+
| left=exprComponent op=AND right=exprComponent # booleanExprComp
|
|
47
|
+
| left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp
|
|
48
|
+
| IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp
|
|
49
|
+
| constant # constantExprComp
|
|
50
|
+
| componentID # compId
|
|
49
51
|
;
|
|
50
|
-
"""
|
|
52
|
+
""" # noqa E501
|
|
51
53
|
ctx_list = list(ctx.getChildren())
|
|
52
54
|
c = ctx_list[0]
|
|
53
55
|
|
|
@@ -87,6 +89,10 @@ class ExprComp(VtlVisitor):
|
|
|
87
89
|
elif isinstance(ctx, Parser.IfExprCompContext):
|
|
88
90
|
return self.visitIfExprComp(ctx)
|
|
89
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
|
+
|
|
90
96
|
# constant
|
|
91
97
|
elif isinstance(ctx, Parser.ConstantExprCompContext):
|
|
92
98
|
return Terminals().visitConstant(c)
|
|
@@ -169,6 +175,26 @@ class ExprComp(VtlVisitor):
|
|
|
169
175
|
|
|
170
176
|
return if_node
|
|
171
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
|
+
|
|
172
198
|
def visitOptionalExprComponent(self, ctx: Parser.OptionalExprComponentContext):
|
|
173
199
|
"""
|
|
174
200
|
optionalExpr: expr
|
|
@@ -253,8 +279,8 @@ class ExprComp(VtlVisitor):
|
|
|
253
279
|
|
|
254
280
|
def visitCallComponent(self, ctx: Parser.CallComponentContext):
|
|
255
281
|
"""
|
|
256
|
-
callFunction: operatorID LPAREN (parameterComponent (COMMA parameterComponent)*)? RPAREN # callComponent
|
|
257
|
-
"""
|
|
282
|
+
callFunction: operatorID LPAREN (parameterComponent (COMMA parameterComponent)*)? RPAREN # callComponent
|
|
283
|
+
""" # noqa E501
|
|
258
284
|
ctx_list = list(ctx.getChildren())
|
|
259
285
|
c = ctx_list[0]
|
|
260
286
|
|
|
@@ -269,8 +295,8 @@ class ExprComp(VtlVisitor):
|
|
|
269
295
|
|
|
270
296
|
def visitEvalAtomComponent(self, ctx: Parser.EvalAtomComponentContext):
|
|
271
297
|
"""
|
|
272
|
-
| EVAL LPAREN routineName LPAREN (componentID|scalarItem)? (COMMA (componentID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS outputParameterTypeComponent)? RPAREN # evalAtomComponent
|
|
273
|
-
"""
|
|
298
|
+
| EVAL LPAREN routineName LPAREN (componentID|scalarItem)? (COMMA (componentID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS outputParameterTypeComponent)? RPAREN # evalAtomComponent
|
|
299
|
+
""" # noqa E501
|
|
274
300
|
ctx_list = list(ctx.getChildren())
|
|
275
301
|
|
|
276
302
|
routine_name = Terminals().visitRoutineName(ctx_list[2])
|
|
@@ -320,8 +346,8 @@ class ExprComp(VtlVisitor):
|
|
|
320
346
|
|
|
321
347
|
def visitCastExprComponent(self, ctx: Parser.CastExprComponentContext):
|
|
322
348
|
"""
|
|
323
|
-
| CAST LPAREN exprComponent COMMA (basicScalarType|valueDomainName) (COMMA STRING_CONSTANT)? RPAREN # castExprComponent
|
|
324
|
-
"""
|
|
349
|
+
| CAST LPAREN exprComponent COMMA (basicScalarType|valueDomainName) (COMMA STRING_CONSTANT)? RPAREN # castExprComponent
|
|
350
|
+
""" # noqa E501
|
|
325
351
|
ctx_list = list(ctx.getChildren())
|
|
326
352
|
c = ctx_list[0]
|
|
327
353
|
|
|
@@ -541,7 +567,7 @@ class ExprComp(VtlVisitor):
|
|
|
541
567
|
|
|
542
568
|
def visitTimeFunctionsComponents(self, ctx: Parser.TimeFunctionsComponentsContext):
|
|
543
569
|
if isinstance(ctx, Parser.PeriodAtomComponentContext):
|
|
544
|
-
return self.
|
|
570
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
545
571
|
elif isinstance(ctx, Parser.FillTimeAtomComponentContext):
|
|
546
572
|
return self.visitFillTimeAtomComponent(ctx)
|
|
547
573
|
elif isinstance(ctx, Parser.FlowAtomComponentContext):
|
|
@@ -552,10 +578,25 @@ class ExprComp(VtlVisitor):
|
|
|
552
578
|
return self.visitTimeAggAtomComponent(ctx)
|
|
553
579
|
elif isinstance(ctx, Parser.CurrentDateAtomComponentContext):
|
|
554
580
|
return self.visitCurrentDateAtomComponent(ctx)
|
|
581
|
+
elif isinstance(ctx, Parser.DateDiffAtomComponentContext):
|
|
582
|
+
return self.visitDateDiffAtomComponent(ctx)
|
|
583
|
+
elif isinstance(ctx, Parser.DateAddAtomComponentContext):
|
|
584
|
+
return self.visitDateAddAtomComponentContext(ctx)
|
|
585
|
+
elif (isinstance(ctx, (
|
|
586
|
+
Parser.YearAtomComponentContext,
|
|
587
|
+
Parser.MonthAtomComponentContext,
|
|
588
|
+
Parser.DayOfMonthAtomComponentContext,
|
|
589
|
+
Parser.DayOfYearAtomComponentContext,
|
|
590
|
+
Parser.DayToYearAtomComponentContext,
|
|
591
|
+
Parser.DayToMonthAtomComponentContext,
|
|
592
|
+
Parser.YearToDayAtomComponentContext,
|
|
593
|
+
Parser.MonthToDayAtomComponentContext
|
|
594
|
+
))):
|
|
595
|
+
return self.visitTimeUnaryAtomComponent(ctx)
|
|
555
596
|
else:
|
|
556
597
|
raise NotImplementedError
|
|
557
598
|
|
|
558
|
-
def
|
|
599
|
+
def visitTimeUnaryAtomComponent(self, ctx: Parser.PeriodAtomComponentContext):
|
|
559
600
|
"""
|
|
560
601
|
periodExpr: PERIOD_INDICATOR '(' expr? ')' ;
|
|
561
602
|
"""
|
|
@@ -607,9 +648,9 @@ class ExprComp(VtlVisitor):
|
|
|
607
648
|
|
|
608
649
|
def visitTimeAggAtomComponent(self, ctx: Parser.TimeAggAtomComponentContext):
|
|
609
650
|
"""
|
|
610
|
-
TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))?
|
|
611
|
-
(COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent;
|
|
612
|
-
"""
|
|
651
|
+
TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))?
|
|
652
|
+
(COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent;
|
|
653
|
+
""" # noqa E501
|
|
613
654
|
ctx_list = list(ctx.getChildren())
|
|
614
655
|
c = ctx_list[0]
|
|
615
656
|
|
|
@@ -628,10 +669,7 @@ class ExprComp(VtlVisitor):
|
|
|
628
669
|
and str_.getSymbol().type in [Parser.FIRST, Parser.LAST]
|
|
629
670
|
]
|
|
630
671
|
|
|
631
|
-
if len(conf) == 0
|
|
632
|
-
conf = None
|
|
633
|
-
else:
|
|
634
|
-
conf = conf[0]
|
|
672
|
+
conf = None if len(conf) == 0 else conf[0]
|
|
635
673
|
|
|
636
674
|
if ctx.op is not None:
|
|
637
675
|
operand_node = self.visitOptionalExprComponent(ctx.op)
|
|
@@ -653,6 +691,34 @@ class ExprComp(VtlVisitor):
|
|
|
653
691
|
c = list(ctx.getChildren())[0]
|
|
654
692
|
return MulOp(op=c.getSymbol().text, children=[])
|
|
655
693
|
|
|
694
|
+
def visitDateDiffAtomComponent(self, ctx: Parser.TimeShiftAtomComponentContext):
|
|
695
|
+
""" """
|
|
696
|
+
ctx_list = list(ctx.getChildren())
|
|
697
|
+
c = ctx_list[0]
|
|
698
|
+
|
|
699
|
+
op = c.getSymbol().text
|
|
700
|
+
left_node = self.visitExprComponent(ctx_list[2])
|
|
701
|
+
right_node = self.visitExprComponent(ctx_list[4])
|
|
702
|
+
|
|
703
|
+
return BinOp(left=left_node, op=op, right=right_node)
|
|
704
|
+
|
|
705
|
+
def visitDateAddAtomComponentContext(self, ctx: Parser.DateAddAtomComponentContext):
|
|
706
|
+
""" """
|
|
707
|
+
ctx_list = list(ctx.getChildren())
|
|
708
|
+
c = ctx_list[0]
|
|
709
|
+
|
|
710
|
+
op = c.getSymbol().text
|
|
711
|
+
children_node = [self.visitExprComponent(ctx_list[2])]
|
|
712
|
+
|
|
713
|
+
param_constant_node = []
|
|
714
|
+
|
|
715
|
+
if len(ctx_list) > 4:
|
|
716
|
+
param_constant_node = [self.visitExprComponent(ctx_list[4])]
|
|
717
|
+
if len(ctx_list) > 6:
|
|
718
|
+
param_constant_node.append(self.visitExprComponent(ctx_list[6]))
|
|
719
|
+
|
|
720
|
+
return ParamOp(op=op, children=children_node, params=param_constant_node)
|
|
721
|
+
|
|
656
722
|
"""
|
|
657
723
|
-----------------------------------
|
|
658
724
|
Conditional Functions
|
|
@@ -815,9 +881,7 @@ class ExprComp(VtlVisitor):
|
|
|
815
881
|
elif isinstance(c, Parser.OrderByClauseContext):
|
|
816
882
|
order_by = Terminals().visitOrderByClause(c)
|
|
817
883
|
continue
|
|
818
|
-
elif isinstance(c, Parser.SignedIntegerContext)
|
|
819
|
-
c, Parser.ScalarItemContext
|
|
820
|
-
):
|
|
884
|
+
elif isinstance(c, (Parser.SignedIntegerContext, Parser.ScalarItemContext)):
|
|
821
885
|
if params is None:
|
|
822
886
|
params = []
|
|
823
887
|
if isinstance(c, Parser.SignedIntegerContext):
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
from vtlengine.DataTypes import (
|
|
2
|
-
Boolean,
|
|
3
|
-
Date,
|
|
4
|
-
Duration,
|
|
5
|
-
Integer,
|
|
6
|
-
Number,
|
|
7
|
-
String,
|
|
8
|
-
TimeInterval,
|
|
9
|
-
TimePeriod,
|
|
10
|
-
)
|
|
11
1
|
from antlr4.tree.Tree import TerminalNodeImpl
|
|
12
2
|
|
|
13
3
|
from vtlengine.AST import (
|
|
@@ -24,6 +14,16 @@ from vtlengine.AST import (
|
|
|
24
14
|
)
|
|
25
15
|
from vtlengine.AST.Grammar.parser import Parser
|
|
26
16
|
from vtlengine.AST.VtlVisitor import VtlVisitor
|
|
17
|
+
from vtlengine.DataTypes import (
|
|
18
|
+
Boolean,
|
|
19
|
+
Date,
|
|
20
|
+
Duration,
|
|
21
|
+
Integer,
|
|
22
|
+
Number,
|
|
23
|
+
String,
|
|
24
|
+
TimeInterval,
|
|
25
|
+
TimePeriod,
|
|
26
|
+
)
|
|
27
27
|
from vtlengine.Model import Component, Dataset, Role, Scalar
|
|
28
28
|
|
|
29
29
|
|
|
@@ -377,21 +377,21 @@ class Terminals(VtlVisitor):
|
|
|
377
377
|
|
|
378
378
|
def visitDpRuleset(self, ctx: Parser.DpRulesetContext):
|
|
379
379
|
"""
|
|
380
|
-
DATAPOINT # dataPoint
|
|
381
|
-
| DATAPOINT_ON_VD (GLPAREN valueDomainName (MUL valueDomainName)* GRPAREN )? # dataPointVd
|
|
382
|
-
| DATAPOINT_ON_VAR (GLPAREN varID (MUL varID)* GRPAREN )? # dataPointVar
|
|
380
|
+
DATAPOINT # dataPoint
|
|
381
|
+
| DATAPOINT_ON_VD (GLPAREN valueDomainName (MUL valueDomainName)* GRPAREN )? # dataPointVd
|
|
382
|
+
| DATAPOINT_ON_VAR (GLPAREN varID (MUL varID)* GRPAREN )? # dataPointVar
|
|
383
383
|
;
|
|
384
|
-
"""
|
|
384
|
+
""" # noqa E501
|
|
385
385
|
# AST_ASTCONSTRUCTOR.54
|
|
386
386
|
raise NotImplementedError
|
|
387
387
|
|
|
388
388
|
def visitHrRuleset(self, ctx: Parser.HrRulesetContext):
|
|
389
389
|
"""
|
|
390
|
-
hrRuleset: HIERARCHICAL # hrRulesetType
|
|
391
|
-
| HIERARCHICAL_ON_VD ( GLPAREN vdName=IDENTIFIER (LPAREN valueDomainName (MUL valueDomainName)* RPAREN)? GRPAREN )? # hrRulesetVdType
|
|
392
|
-
| HIERARCHICAL_ON_VAR ( GLPAREN varName=varID (LPAREN varID (MUL varID)* RPAREN)? GRPAREN )? # hrRulesetVarType
|
|
390
|
+
hrRuleset: HIERARCHICAL # hrRulesetType
|
|
391
|
+
| HIERARCHICAL_ON_VD ( GLPAREN vdName=IDENTIFIER (LPAREN valueDomainName (MUL valueDomainName)* RPAREN)? GRPAREN )? # hrRulesetVdType
|
|
392
|
+
| HIERARCHICAL_ON_VAR ( GLPAREN varName=varID (LPAREN varID (MUL varID)* RPAREN)? GRPAREN )? # hrRulesetVarType
|
|
393
393
|
;
|
|
394
|
-
"""
|
|
394
|
+
""" # noqa E501
|
|
395
395
|
# AST_ASTCONSTRUCTOR.55
|
|
396
396
|
raise NotImplementedError
|
|
397
397
|
|
|
@@ -407,15 +407,9 @@ class Terminals(VtlVisitor):
|
|
|
407
407
|
for constraint in ctx_list
|
|
408
408
|
if isinstance(constraint, Parser.ScalarTypeContext)
|
|
409
409
|
]
|
|
410
|
-
if len(data_type) > 0
|
|
411
|
-
data_type = data_type[0]
|
|
412
|
-
else:
|
|
413
|
-
data_type = String()
|
|
410
|
+
data_type = data_type[0] if len(data_type) > 0 else String()
|
|
414
411
|
|
|
415
|
-
|
|
416
|
-
nullable = False
|
|
417
|
-
else:
|
|
418
|
-
nullable = True
|
|
412
|
+
nullable = role_node != Role.IDENTIFIER
|
|
419
413
|
|
|
420
414
|
return Component(name="Component", data_type=data_type, role=role_node, nullable=nullable)
|
|
421
415
|
|
|
@@ -503,7 +497,7 @@ class Terminals(VtlVisitor):
|
|
|
503
497
|
def visitScalarWithCast(self, ctx: Parser.ScalarWithCastContext):
|
|
504
498
|
"""
|
|
505
499
|
| CAST LPAREN constant COMMA (basicScalarType) (COMMA STRING_CONSTANT)? RPAREN #scalarWithCast # noqa E501
|
|
506
|
-
"""
|
|
500
|
+
""" # noqa E501
|
|
507
501
|
ctx_list = list(ctx.getChildren())
|
|
508
502
|
c = ctx_list[0]
|
|
509
503
|
|
|
@@ -513,10 +507,7 @@ class Terminals(VtlVisitor):
|
|
|
513
507
|
const_node = self.visitConstant(ctx_list[2])
|
|
514
508
|
basic_scalar_type = [self.visitBasicScalarType(ctx_list[4])]
|
|
515
509
|
|
|
516
|
-
if len(ctx_list) > 6
|
|
517
|
-
param_node = [ParamConstant("PARAM_CAST", ctx_list[6])]
|
|
518
|
-
else:
|
|
519
|
-
param_node = []
|
|
510
|
+
param_node = [ParamConstant("PARAM_CAST", ctx_list[6])] if len(ctx_list) > 6 else []
|
|
520
511
|
|
|
521
512
|
if len(basic_scalar_type) == 1:
|
|
522
513
|
children_nodes = [const_node, basic_scalar_type[0]]
|
|
@@ -681,14 +672,12 @@ class Terminals(VtlVisitor):
|
|
|
681
672
|
first = num_rows_1 # unbounded (default value)
|
|
682
673
|
second = num_rows_2 # current data point (default value)
|
|
683
674
|
|
|
684
|
-
if mode_2 == "preceding"
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
f"line {ctx_list[3].start.line}"
|
|
691
|
-
)
|
|
675
|
+
if (mode_2 == "preceding" and mode_1 == "preceding" and num_rows_1 == -1
|
|
676
|
+
and num_rows_2 == -1): # preceding and preceding (error)
|
|
677
|
+
raise Exception(
|
|
678
|
+
f"Cannot have 2 preceding clauses with unbounded in analytic clause, "
|
|
679
|
+
f"line {ctx_list[3].start.line}"
|
|
680
|
+
)
|
|
692
681
|
|
|
693
682
|
if (
|
|
694
683
|
mode_1 == "following" and num_rows_1 == -1 and num_rows_2 == -1
|
vtlengine/AST/ASTTemplate.py
CHANGED
|
@@ -10,7 +10,6 @@ Template to start a new visitor for the AST.
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
12
|
import vtlengine.AST as AST
|
|
13
|
-
|
|
14
13
|
from vtlengine.AST.ASTVisitor import NodeVisitor
|
|
15
14
|
|
|
16
15
|
|
|
@@ -314,6 +313,22 @@ class ASTTemplate(NodeVisitor):
|
|
|
314
313
|
self.visit(node.thenOp)
|
|
315
314
|
self.visit(node.elseOp)
|
|
316
315
|
|
|
316
|
+
def visit_Case(self, node: AST.Case) -> Any:
|
|
317
|
+
"""
|
|
318
|
+
Case: (conditions, thenOp, elseOp)
|
|
319
|
+
|
|
320
|
+
Basic usage:
|
|
321
|
+
|
|
322
|
+
for condition in node.conditions:
|
|
323
|
+
self.visit(condition)
|
|
324
|
+
self.visit(node.thenOp)
|
|
325
|
+
self.visit(node.elseOp)
|
|
326
|
+
"""
|
|
327
|
+
for case in node.cases:
|
|
328
|
+
self.visit(case.condition)
|
|
329
|
+
self.visit(case.thenOp)
|
|
330
|
+
self.visit(node.elseOp)
|
|
331
|
+
|
|
317
332
|
def visit_Validation(self, node: AST.Validation) -> Any:
|
|
318
333
|
"""
|
|
319
334
|
Validation: (op, validation, params, inbalance, invalid)
|
vtlengine/AST/DAG/__init__.py
CHANGED
|
@@ -15,24 +15,24 @@ import networkx as nx
|
|
|
15
15
|
|
|
16
16
|
from vtlengine.AST import (
|
|
17
17
|
AST,
|
|
18
|
-
BinOp,
|
|
19
|
-
VarID,
|
|
20
18
|
Aggregation,
|
|
21
19
|
Analytic,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Operator,
|
|
25
|
-
Identifier,
|
|
20
|
+
Assignment,
|
|
21
|
+
BinOp,
|
|
26
22
|
DefIdentifier,
|
|
27
|
-
|
|
23
|
+
DPRuleset,
|
|
28
24
|
HRuleset,
|
|
29
|
-
|
|
25
|
+
Identifier,
|
|
26
|
+
JoinOp,
|
|
27
|
+
Operator,
|
|
28
|
+
ParamOp,
|
|
30
29
|
PersistentAssignment,
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
RegularAggregation,
|
|
31
|
+
Start,
|
|
32
|
+
VarID,
|
|
33
33
|
)
|
|
34
34
|
from vtlengine.AST.ASTTemplate import ASTTemplate
|
|
35
|
-
from vtlengine.AST.DAG._words import
|
|
35
|
+
from vtlengine.AST.DAG._words import DELETE, GLOBAL, INPUTS, INSERT, OUTPUTS, PERSISTENT
|
|
36
36
|
from vtlengine.AST.Grammar.tokens import AS, MEMBERSHIP, TO
|
|
37
37
|
from vtlengine.Exceptions import SemanticError
|
|
38
38
|
|
|
@@ -313,10 +313,7 @@ class DAGAnalyzer(ASTTemplate):
|
|
|
313
313
|
self.visit(node.left)
|
|
314
314
|
self.isDataset = False
|
|
315
315
|
self.visit(node.right)
|
|
316
|
-
elif node.op == AS:
|
|
317
|
-
self.visit(node.left)
|
|
318
|
-
self.alias.append(node.right.value)
|
|
319
|
-
elif node.op == TO:
|
|
316
|
+
elif node.op == AS or node.op == TO:
|
|
320
317
|
self.visit(node.left)
|
|
321
318
|
self.alias.append(node.right.value)
|
|
322
319
|
else:
|
vtlengine/AST/Grammar/Vtl.g4
CHANGED
|
@@ -21,30 +21,33 @@ expr:
|
|
|
21
21
|
| op=(PLUS|MINUS|NOT) right=expr # unaryExpr
|
|
22
22
|
| left=expr op=(MUL|DIV) right=expr # arithmeticExpr
|
|
23
23
|
| left=expr op=(PLUS|MINUS|CONCAT) right=expr # arithmeticExprOrConcat
|
|
24
|
-
| left=expr op=comparisonOperand
|
|
24
|
+
| left=expr op=comparisonOperand right=expr # comparisonExpr
|
|
25
25
|
| left=expr op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExpr
|
|
26
26
|
| left=expr op=AND right=expr # booleanExpr
|
|
27
27
|
| left=expr op=(OR|XOR) right=expr # booleanExpr
|
|
28
28
|
| IF conditionalExpr=expr THEN thenExpr=expr ELSE elseExpr=expr # ifExpr
|
|
29
|
+
| CASE (WHEN expr THEN expr)+ ELSE expr # caseExpr
|
|
29
30
|
| constant # constantExpr
|
|
30
31
|
| varID # varIdExpr
|
|
31
32
|
|
|
33
|
+
|
|
32
34
|
;
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
exprComponent:
|
|
36
|
-
LPAREN exprComponent RPAREN
|
|
37
|
-
| functionsComponents
|
|
38
|
-
| op=(PLUS|MINUS|NOT) right=exprComponent
|
|
39
|
-
| left=exprComponent op=(MUL|DIV) right=exprComponent
|
|
40
|
-
| left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent
|
|
41
|
-
| left=exprComponent comparisonOperand right=exprComponent
|
|
42
|
-
| left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID)
|
|
43
|
-
| left=exprComponent op=AND right=exprComponent
|
|
44
|
-
| left=exprComponent op=(OR|XOR) right=exprComponent
|
|
45
|
-
| IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent
|
|
46
|
-
|
|
|
47
|
-
|
|
|
38
|
+
LPAREN exprComponent RPAREN # parenthesisExprComp
|
|
39
|
+
| functionsComponents # functionsExpressionComp
|
|
40
|
+
| op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp
|
|
41
|
+
| left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp
|
|
42
|
+
| left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp
|
|
43
|
+
| left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp
|
|
44
|
+
| left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp
|
|
45
|
+
| left=exprComponent op=AND right=exprComponent # booleanExprComp
|
|
46
|
+
| left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp
|
|
47
|
+
| IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp
|
|
48
|
+
| CASE (WHEN exprComponent THEN exprComponent)+ ELSE exprComponent # caseExprComp
|
|
49
|
+
| constant # constantExprComp
|
|
50
|
+
| componentID # compId
|
|
48
51
|
;
|
|
49
52
|
|
|
50
53
|
functionsComponents:
|
|
@@ -84,6 +87,7 @@ datasetClause:
|
|
|
84
87
|
| calcClause
|
|
85
88
|
| keepOrDropClause
|
|
86
89
|
| pivotOrUnpivotClause
|
|
90
|
+
/* | customPivotClause */
|
|
87
91
|
| subspaceClause
|
|
88
92
|
;
|
|
89
93
|
|
|
@@ -112,6 +116,10 @@ pivotOrUnpivotClause:
|
|
|
112
116
|
op=(PIVOT|UNPIVOT) id_=componentID COMMA mea=componentID
|
|
113
117
|
;
|
|
114
118
|
|
|
119
|
+
customPivotClause:
|
|
120
|
+
CUSTOMPIVOT id_=componentID COMMA mea=componentID IN constant (COMMA constant)*
|
|
121
|
+
;
|
|
122
|
+
|
|
115
123
|
subspaceClause:
|
|
116
124
|
SUBSPACE subspaceClauseItem (COMMA subspaceClauseItem)*
|
|
117
125
|
;
|
|
@@ -138,7 +146,7 @@ defOperators:
|
|
|
138
146
|
/*---------------------------------------------------FUNCTIONS-------------------------------------------------*/
|
|
139
147
|
genericOperators:
|
|
140
148
|
operatorID LPAREN (parameter (COMMA parameter)*)? RPAREN # callDataset
|
|
141
|
-
| EVAL LPAREN routineName LPAREN (varID|scalarItem)? (COMMA (varID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS evalDatasetType)? RPAREN
|
|
149
|
+
| EVAL LPAREN routineName LPAREN (varID|scalarItem)? (COMMA (varID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS evalDatasetType)? RPAREN # evalAtom
|
|
142
150
|
| CAST LPAREN expr COMMA (basicScalarType|valueDomainName) (COMMA STRING_CONSTANT)? RPAREN # castExprDataset
|
|
143
151
|
;
|
|
144
152
|
|
|
@@ -149,6 +157,7 @@ genericOperatorsComponent:
|
|
|
149
157
|
|
|
150
158
|
;
|
|
151
159
|
|
|
160
|
+
|
|
152
161
|
parameterComponent:
|
|
153
162
|
exprComponent
|
|
154
163
|
| OPTIONAL
|
|
@@ -176,13 +185,13 @@ stringOperatorsComponent:
|
|
|
176
185
|
numericOperators:
|
|
177
186
|
op=(CEIL | FLOOR | ABS | EXP | LN | SQRT) LPAREN expr RPAREN # unaryNumeric
|
|
178
187
|
| op=(ROUND | TRUNC) LPAREN expr (COMMA optionalExpr)? RPAREN # unaryWithOptionalNumeric
|
|
179
|
-
| op=(MOD | POWER|LOG) LPAREN left=expr COMMA right=expr RPAREN
|
|
188
|
+
| op=(MOD | POWER | LOG | RANDOM) LPAREN left=expr COMMA right=expr RPAREN # binaryNumeric
|
|
180
189
|
;
|
|
181
190
|
|
|
182
191
|
numericOperatorsComponent:
|
|
183
|
-
op=(CEIL | FLOOR | ABS | EXP | LN | SQRT) LPAREN exprComponent RPAREN
|
|
184
|
-
| op=(ROUND | TRUNC) LPAREN exprComponent (COMMA optionalExprComponent)? RPAREN
|
|
185
|
-
| op=(MOD | POWER | LOG) LPAREN left=exprComponent COMMA right=exprComponent RPAREN
|
|
192
|
+
op=(CEIL | FLOOR | ABS | EXP | LN | SQRT) LPAREN exprComponent RPAREN # unaryNumericComponent
|
|
193
|
+
| op=(ROUND | TRUNC) LPAREN exprComponent (COMMA optionalExprComponent)? RPAREN # unaryWithOptionalNumericComponent
|
|
194
|
+
| op=(MOD | POWER | LOG | RANDOM) LPAREN left=exprComponent COMMA right=exprComponent RPAREN # binaryNumericComponent
|
|
186
195
|
;
|
|
187
196
|
|
|
188
197
|
comparisonOperators:
|
|
@@ -205,6 +214,16 @@ timeOperators:
|
|
|
205
214
|
| TIMESHIFT LPAREN expr COMMA signedInteger RPAREN # timeShiftAtom
|
|
206
215
|
| TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))? (COMMA op=optionalExpr)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtom
|
|
207
216
|
| CURRENT_DATE LPAREN RPAREN # currentDateAtom
|
|
217
|
+
| DATEDIFF LPAREN dateFrom=expr COMMA dateTo=expr RPAREN # dateDiffAtom
|
|
218
|
+
| DATEADD LPAREN op=expr COMMA shiftNumber=expr COMMA periodInd=expr RPAREN # dateAddAtom
|
|
219
|
+
| YEAR_OP LPAREN expr RPAREN # yearAtom
|
|
220
|
+
| MONTH_OP LPAREN expr RPAREN # monthAtom
|
|
221
|
+
| DAYOFMONTH LPAREN expr RPAREN # dayOfMonthAtom
|
|
222
|
+
| DAYOFYEAR LPAREN expr RPAREN # datOfYearAtom
|
|
223
|
+
| DAYTOYEAR LPAREN expr RPAREN # dayToYearAtom
|
|
224
|
+
| DAYTOMONTH LPAREN expr RPAREN # dayToMonthAtom
|
|
225
|
+
| YEARTODAY LPAREN expr RPAREN # yearTodayAtom
|
|
226
|
+
| MONTHTODAY LPAREN expr RPAREN # monthTodayAtom
|
|
208
227
|
;
|
|
209
228
|
|
|
210
229
|
timeOperatorsComponent:
|
|
@@ -213,7 +232,17 @@ timeOperatorsComponent:
|
|
|
213
232
|
| op=(FLOW_TO_STOCK | STOCK_TO_FLOW) LPAREN exprComponent RPAREN # flowAtomComponent
|
|
214
233
|
| TIMESHIFT LPAREN exprComponent COMMA signedInteger RPAREN # timeShiftAtomComponent
|
|
215
234
|
| TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))? (COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent
|
|
216
|
-
| CURRENT_DATE LPAREN RPAREN
|
|
235
|
+
| CURRENT_DATE LPAREN RPAREN # currentDateAtomComponent
|
|
236
|
+
| DATEDIFF LPAREN dateFrom=exprComponent COMMA dateTo=exprComponent RPAREN # dateDiffAtomComponent
|
|
237
|
+
| DATEADD LPAREN op=exprComponent COMMA shiftNumber=exprComponent COMMA periodInd=exprComponent RPAREN # dateAddAtomComponent
|
|
238
|
+
| YEAR_OP LPAREN exprComponent RPAREN # yearAtomComponent
|
|
239
|
+
| MONTH_OP LPAREN exprComponent RPAREN # monthAtomComponent
|
|
240
|
+
| DAYOFMONTH LPAREN exprComponent RPAREN # dayOfMonthAtomComponent
|
|
241
|
+
| DAYOFYEAR LPAREN exprComponent RPAREN # datOfYearAtomComponent
|
|
242
|
+
| DAYTOYEAR LPAREN exprComponent RPAREN # dayToYearAtomComponent
|
|
243
|
+
| DAYTOMONTH LPAREN exprComponent RPAREN # dayToMonthAtomComponent
|
|
244
|
+
| YEARTODAY LPAREN exprComponent RPAREN # yearTodayAtomComponent
|
|
245
|
+
| MONTHTODAY LPAREN exprComponent RPAREN # monthTodayAtomComponent
|
|
217
246
|
;
|
|
218
247
|
|
|
219
248
|
setOperators:
|
|
@@ -284,7 +313,7 @@ aggrOperatorsGrouping:
|
|
|
284
313
|
| FIRST_VALUE
|
|
285
314
|
| LAST_VALUE)
|
|
286
315
|
LPAREN expr OVER LPAREN (partition=partitionByClause? orderBy=orderByClause? windowing=windowingClause?)RPAREN RPAREN #anSimpleFunction
|
|
287
|
-
| op=(LAG |LEAD) LPAREN expr (COMMA
|
|
316
|
+
| op=(LAG |LEAD) LPAREN expr (COMMA offset=signedInteger(COMMA defaultValue=scalarItem)?)? OVER LPAREN (partition=partitionByClause? orderBy=orderByClause) RPAREN RPAREN # lagOrLeadAn
|
|
288
317
|
| op=RATIO_TO_REPORT LPAREN expr OVER LPAREN (partition=partitionByClause) RPAREN RPAREN # ratioToReportAn
|
|
289
318
|
;
|
|
290
319
|
|
|
@@ -28,11 +28,22 @@ lexer grammar VtlTokens;
|
|
|
28
28
|
MEMBERSHIP : '#';
|
|
29
29
|
EVAL : 'eval';
|
|
30
30
|
IF : 'if';
|
|
31
|
+
CASE : 'case';
|
|
31
32
|
THEN : 'then';
|
|
32
33
|
ELSE : 'else';
|
|
33
34
|
USING : 'using';
|
|
34
35
|
WITH : 'with';
|
|
35
36
|
CURRENT_DATE : 'current_date';
|
|
37
|
+
DATEDIFF : 'datediff';
|
|
38
|
+
DATEADD : 'dateadd';
|
|
39
|
+
YEAR_OP : 'year';
|
|
40
|
+
MONTH_OP : 'month';
|
|
41
|
+
DAYOFMONTH : 'dayofmonth';
|
|
42
|
+
DAYOFYEAR : 'dayofyear';
|
|
43
|
+
DAYTOYEAR : 'daytoyear';
|
|
44
|
+
DAYTOMONTH : 'daytomonth';
|
|
45
|
+
YEARTODAY : 'yeartoday';
|
|
46
|
+
MONTHTODAY : 'monthtoday';
|
|
36
47
|
ON : 'on';
|
|
37
48
|
DROP : 'drop';
|
|
38
49
|
KEEP : 'keep';
|
|
@@ -54,6 +65,7 @@ lexer grammar VtlTokens;
|
|
|
54
65
|
DIFF : 'diff';
|
|
55
66
|
SYMDIFF : 'symdiff';
|
|
56
67
|
INTERSECT : 'intersect';
|
|
68
|
+
RANDOM : 'random';
|
|
57
69
|
KEYS : 'keys';
|
|
58
70
|
INTYEAR : 'intyear';
|
|
59
71
|
INTMONTH : 'intmonth';
|
|
@@ -394,4 +406,4 @@ FREQUENCY
|
|
|
394
406
|
| 'M'
|
|
395
407
|
| 'W'
|
|
396
408
|
| 'D'
|
|
397
|
-
;*/
|
|
409
|
+
;*/
|