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.

Files changed (50) hide show
  1. vtlengine/API/_InternalApi.py +19 -8
  2. vtlengine/API/__init__.py +9 -9
  3. vtlengine/AST/ASTConstructor.py +23 -43
  4. vtlengine/AST/ASTConstructorModules/Expr.py +147 -71
  5. vtlengine/AST/ASTConstructorModules/ExprComponents.py +104 -40
  6. vtlengine/AST/ASTConstructorModules/Terminals.py +28 -39
  7. vtlengine/AST/ASTTemplate.py +16 -1
  8. vtlengine/AST/DAG/__init__.py +12 -15
  9. vtlengine/AST/Grammar/Vtl.g4 +49 -20
  10. vtlengine/AST/Grammar/VtlTokens.g4 +13 -1
  11. vtlengine/AST/Grammar/lexer.py +1293 -1183
  12. vtlengine/AST/Grammar/parser.py +5758 -3939
  13. vtlengine/AST/Grammar/tokens.py +12 -0
  14. vtlengine/AST/VtlVisitor.py +9 -2
  15. vtlengine/AST/__init__.py +21 -3
  16. vtlengine/DataTypes/TimeHandling.py +12 -7
  17. vtlengine/DataTypes/__init__.py +17 -24
  18. vtlengine/Exceptions/__init__.py +43 -1
  19. vtlengine/Exceptions/messages.py +82 -62
  20. vtlengine/Interpreter/__init__.py +125 -120
  21. vtlengine/Model/__init__.py +17 -12
  22. vtlengine/Operators/Aggregation.py +14 -14
  23. vtlengine/Operators/Analytic.py +56 -31
  24. vtlengine/Operators/Assignment.py +2 -3
  25. vtlengine/Operators/Boolean.py +5 -7
  26. vtlengine/Operators/CastOperator.py +12 -13
  27. vtlengine/Operators/Clause.py +11 -13
  28. vtlengine/Operators/Comparison.py +31 -17
  29. vtlengine/Operators/Conditional.py +157 -17
  30. vtlengine/Operators/General.py +4 -4
  31. vtlengine/Operators/HROperators.py +41 -34
  32. vtlengine/Operators/Join.py +18 -22
  33. vtlengine/Operators/Numeric.py +76 -39
  34. vtlengine/Operators/RoleSetter.py +6 -8
  35. vtlengine/Operators/Set.py +7 -12
  36. vtlengine/Operators/String.py +19 -27
  37. vtlengine/Operators/Time.py +366 -43
  38. vtlengine/Operators/Validation.py +4 -7
  39. vtlengine/Operators/__init__.py +38 -41
  40. vtlengine/Utils/__init__.py +149 -94
  41. vtlengine/__init__.py +1 -1
  42. vtlengine/files/output/__init__.py +2 -2
  43. vtlengine/files/output/_time_period_representation.py +0 -1
  44. vtlengine/files/parser/__init__.py +18 -18
  45. vtlengine/files/parser/_time_checking.py +3 -2
  46. {vtlengine-1.0.1.dist-info → vtlengine-1.0.3.dist-info}/METADATA +17 -5
  47. vtlengine-1.0.3.dist-info/RECORD +58 -0
  48. vtlengine-1.0.1.dist-info/RECORD +0 -58
  49. {vtlengine-1.0.1.dist-info → vtlengine-1.0.3.dist-info}/LICENSE.md +0 -0
  50. {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
- If,
6
+ Analytic,
6
7
  BinOp,
7
- UnaryOp,
8
- ID,
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 # noqa E501
38
- | functionsComponents # functionsExpressionComp # noqa E501
39
- | op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp # noqa E501
40
- | left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp # noqa E501
41
- | left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp # noqa E501
42
- | left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp # noqa E501
43
- | left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp # noqa E501
44
- | left=exprComponent op=AND right=exprComponent # booleanExprComp # noqa E501
45
- | left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp # noqa E501
46
- | IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp # noqa E501
47
- | constant # constantExprComp # noqa E501
48
- | componentID # compId # noqa E501
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 # noqa E501
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 # noqa E501
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 # noqa E501
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.visitPeriodAtomComponent(ctx)
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 visitPeriodAtomComponent(self, ctx: Parser.PeriodAtomComponentContext):
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 ))? # noqa E501
611
- (COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent; # noqa E501
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) or isinstance(
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 # noqa E501
381
- | DATAPOINT_ON_VD (GLPAREN valueDomainName (MUL valueDomainName)* GRPAREN )? # dataPointVd # noqa E501
382
- | DATAPOINT_ON_VAR (GLPAREN varID (MUL varID)* GRPAREN )? # dataPointVar # noqa E501
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 # noqa E501
391
- | HIERARCHICAL_ON_VD ( GLPAREN vdName=IDENTIFIER (LPAREN valueDomainName (MUL valueDomainName)* RPAREN)? GRPAREN )? # hrRulesetVdType # noqa E501
392
- | HIERARCHICAL_ON_VAR ( GLPAREN varName=varID (LPAREN varID (MUL varID)* RPAREN)? GRPAREN )? # hrRulesetVarType # noqa E501
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
- if role_node == Role.IDENTIFIER:
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
- if (
686
- mode_1 == "preceding" and num_rows_1 == -1 and num_rows_2 == -1
687
- ): # preceding and preceding (error)
688
- raise Exception(
689
- f"Cannot have 2 preceding clauses with unbounded in analytic clause, "
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
@@ -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)
@@ -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
- JoinOp,
23
- ParamOp,
24
- Operator,
25
- Identifier,
20
+ Assignment,
21
+ BinOp,
26
22
  DefIdentifier,
27
- Start,
23
+ DPRuleset,
28
24
  HRuleset,
29
- RegularAggregation,
25
+ Identifier,
26
+ JoinOp,
27
+ Operator,
28
+ ParamOp,
30
29
  PersistentAssignment,
31
- Assignment,
32
- DPRuleset,
30
+ RegularAggregation,
31
+ Start,
32
+ VarID,
33
33
  )
34
34
  from vtlengine.AST.ASTTemplate import ASTTemplate
35
- from vtlengine.AST.DAG._words import INSERT, DELETE, OUTPUTS, PERSISTENT, INPUTS, GLOBAL
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:
@@ -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 right=expr # comparisonExpr
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 # parenthesisExprComp
37
- | functionsComponents # functionsExpressionComp
38
- | op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp
39
- | left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp
40
- | left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp
41
- | left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp
42
- | left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp
43
- | left=exprComponent op=AND right=exprComponent # booleanExprComp
44
- | left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp
45
- | IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp
46
- | constant # constantExprComp
47
- | componentID # compId
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 # evalAtom
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 # binaryNumeric
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 # unaryNumericComponent
184
- | op=(ROUND | TRUNC) LPAREN exprComponent (COMMA optionalExprComponent)? RPAREN # unaryWithOptionalNumericComponent
185
- | op=(MOD | POWER | LOG) LPAREN left=exprComponent COMMA right=exprComponent RPAREN # binaryNumericComponent
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 # currentDateAtomComponent
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 offet=signedInteger(COMMA defaultValue=scalarItem)?)? OVER LPAREN (partition=partitionByClause? orderBy=orderByClause) RPAREN RPAREN # lagOrLeadAn
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
+ ;*/