vtlengine 1.0.3rc3__py3-none-any.whl → 1.0.4__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 +55 -20
- vtlengine/API/__init__.py +11 -2
- vtlengine/API/data/schema/json_schema_2.1.json +116 -0
- vtlengine/AST/ASTConstructor.py +5 -4
- vtlengine/AST/ASTConstructorModules/Expr.py +47 -48
- vtlengine/AST/ASTConstructorModules/ExprComponents.py +45 -23
- vtlengine/AST/ASTConstructorModules/Terminals.py +21 -11
- vtlengine/AST/ASTEncoders.py +1 -1
- vtlengine/AST/DAG/__init__.py +0 -3
- vtlengine/AST/Grammar/lexer.py +0 -1
- vtlengine/AST/Grammar/parser.py +185 -440
- vtlengine/AST/VtlVisitor.py +0 -1
- vtlengine/DataTypes/TimeHandling.py +50 -15
- vtlengine/DataTypes/__init__.py +79 -7
- vtlengine/Exceptions/__init__.py +3 -5
- vtlengine/Exceptions/messages.py +65 -105
- vtlengine/Interpreter/__init__.py +83 -38
- vtlengine/Model/__init__.py +7 -9
- vtlengine/Operators/Aggregation.py +13 -7
- vtlengine/Operators/Analytic.py +48 -9
- vtlengine/Operators/Assignment.py +0 -1
- vtlengine/Operators/CastOperator.py +44 -44
- vtlengine/Operators/Clause.py +16 -10
- vtlengine/Operators/Comparison.py +20 -12
- vtlengine/Operators/Conditional.py +30 -13
- vtlengine/Operators/General.py +9 -4
- vtlengine/Operators/HROperators.py +4 -14
- vtlengine/Operators/Join.py +15 -14
- vtlengine/Operators/Numeric.py +32 -26
- vtlengine/Operators/RoleSetter.py +6 -2
- vtlengine/Operators/Set.py +12 -8
- vtlengine/Operators/String.py +9 -9
- vtlengine/Operators/Time.py +136 -116
- vtlengine/Operators/Validation.py +10 -4
- vtlengine/Operators/__init__.py +56 -69
- vtlengine/Utils/__init__.py +6 -1
- vtlengine/files/output/__init__.py +0 -1
- vtlengine/files/output/_time_period_representation.py +2 -1
- vtlengine/files/parser/__init__.py +44 -10
- vtlengine/files/parser/_rfc_dialect.py +1 -1
- vtlengine/files/parser/_time_checking.py +4 -4
- {vtlengine-1.0.3rc3.dist-info → vtlengine-1.0.4.dist-info}/METADATA +7 -6
- vtlengine-1.0.4.dist-info/RECORD +58 -0
- {vtlengine-1.0.3rc3.dist-info → vtlengine-1.0.4.dist-info}/WHEEL +1 -1
- vtlengine/DataTypes/NumericTypesHandling.py +0 -38
- vtlengine-1.0.3rc3.dist-info/RECORD +0 -58
- {vtlengine-1.0.3rc3.dist-info → vtlengine-1.0.4.dist-info}/LICENSE.md +0 -0
vtlengine/Operators/Join.py
CHANGED
|
@@ -70,7 +70,9 @@ class Join(Operator):
|
|
|
70
70
|
comp.role = (
|
|
71
71
|
Role.IDENTIFIER
|
|
72
72
|
if is_identifier
|
|
73
|
-
else Role.MEASURE
|
|
73
|
+
else Role.MEASURE
|
|
74
|
+
if comp.role == Role.IDENTIFIER
|
|
75
|
+
else comp.role
|
|
74
76
|
)
|
|
75
77
|
if comp.name not in nullability:
|
|
76
78
|
nullability[comp.name] = copy(comp.nullable)
|
|
@@ -107,7 +109,8 @@ class Join(Operator):
|
|
|
107
109
|
else:
|
|
108
110
|
if component_name in using and component_name in merged_components:
|
|
109
111
|
data_type = binary_implicit_promotion(
|
|
110
|
-
merged_components[component_name].data_type,
|
|
112
|
+
merged_components[component_name].data_type,
|
|
113
|
+
component.data_type,
|
|
111
114
|
)
|
|
112
115
|
component.data_type = data_type
|
|
113
116
|
merged_components[component_name] = component
|
|
@@ -216,7 +219,6 @@ class Join(Operator):
|
|
|
216
219
|
|
|
217
220
|
@classmethod
|
|
218
221
|
def identifiers_validation(cls, operands: List[Dataset], using: Optional[List[str]]) -> None:
|
|
219
|
-
|
|
220
222
|
# (Case A)
|
|
221
223
|
info = {op.name: op.get_identifiers_names() for op in operands}
|
|
222
224
|
for op_name, identifiers in info.items():
|
|
@@ -224,11 +226,12 @@ class Join(Operator):
|
|
|
224
226
|
raise SemanticError("1-1-13-14", op=cls.op, name=op_name)
|
|
225
227
|
|
|
226
228
|
for op_name, identifiers in info.items():
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
if (
|
|
230
|
+
using is None
|
|
231
|
+
and op_name != cls.reference_dataset.name
|
|
232
|
+
and not set(identifiers).issubset(set(info[cls.reference_dataset.name]))
|
|
233
|
+
):
|
|
234
|
+
missing_components = list(set(identifiers) - set(info[cls.reference_dataset.name]))
|
|
232
235
|
raise SemanticError(
|
|
233
236
|
"1-1-13-11",
|
|
234
237
|
op=cls.op,
|
|
@@ -277,7 +280,6 @@ class InnerJoin(Join):
|
|
|
277
280
|
def generate_result_components(
|
|
278
281
|
cls, operands: List[Dataset], using: Optional[List[str]] = None
|
|
279
282
|
) -> Dict[str, Component]:
|
|
280
|
-
|
|
281
283
|
if using is None:
|
|
282
284
|
return super().generate_result_components(operands, using)
|
|
283
285
|
|
|
@@ -334,7 +336,9 @@ class CrossJoin(Join):
|
|
|
334
336
|
else:
|
|
335
337
|
if result.data is not None:
|
|
336
338
|
result.data = pd.merge(
|
|
337
|
-
result.data,
|
|
339
|
+
result.data,
|
|
340
|
+
op.data,
|
|
341
|
+
how=cls.how, # type: ignore[arg-type]
|
|
338
342
|
)
|
|
339
343
|
if result.data is not None:
|
|
340
344
|
result.data = result.data.rename(
|
|
@@ -357,7 +361,6 @@ class CrossJoin(Join):
|
|
|
357
361
|
|
|
358
362
|
|
|
359
363
|
class Apply(Operator):
|
|
360
|
-
|
|
361
364
|
@classmethod
|
|
362
365
|
def evaluate(cls, dataset: Dataset, expression: Any, op_map: Dict[str, Any]) -> Dataset:
|
|
363
366
|
for child in expression:
|
|
@@ -424,9 +427,7 @@ class Apply(Operator):
|
|
|
424
427
|
return Dataset(name=name, components=components, data=data)
|
|
425
428
|
|
|
426
429
|
@classmethod
|
|
427
|
-
def get_common_components(
|
|
428
|
-
cls, left: Dataset, right: Dataset
|
|
429
|
-
) -> (Dataset, Dataset): # type: ignore[syntax]
|
|
430
|
+
def get_common_components(cls, left: Dataset, right: Dataset) -> (Dataset, Dataset): # type: ignore[syntax]
|
|
430
431
|
common = set(left.get_components_names()) & set(right.get_components_names())
|
|
431
432
|
left.components = {
|
|
432
433
|
comp.name: comp for comp in left.components.values() if comp.name in common
|
vtlengine/Operators/Numeric.py
CHANGED
|
@@ -73,7 +73,7 @@ class Binary(Operator.Binary):
|
|
|
73
73
|
class UnPlus(Unary):
|
|
74
74
|
"""
|
|
75
75
|
`Plus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=94&zoom=100,72,142> `_ unary operator
|
|
76
|
-
"""
|
|
76
|
+
""" # noqa E501
|
|
77
77
|
|
|
78
78
|
op = PLUS
|
|
79
79
|
py_op = operator.pos
|
|
@@ -86,7 +86,7 @@ class UnPlus(Unary):
|
|
|
86
86
|
class UnMinus(Unary):
|
|
87
87
|
"""
|
|
88
88
|
`Minus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=95&zoom=100,72,414> `_unary operator
|
|
89
|
-
"""
|
|
89
|
+
""" # noqa E501
|
|
90
90
|
|
|
91
91
|
op = MINUS
|
|
92
92
|
py_op = operator.neg
|
|
@@ -95,7 +95,7 @@ class UnMinus(Unary):
|
|
|
95
95
|
class AbsoluteValue(Unary):
|
|
96
96
|
"""
|
|
97
97
|
`Absolute <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=112&zoom=100,72,801> `_ unary operator
|
|
98
|
-
"""
|
|
98
|
+
""" # noqa E501
|
|
99
99
|
|
|
100
100
|
op = ABS
|
|
101
101
|
py_op = operator.abs
|
|
@@ -104,7 +104,7 @@ class AbsoluteValue(Unary):
|
|
|
104
104
|
class Exponential(Unary):
|
|
105
105
|
"""
|
|
106
106
|
`Exponential <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=114&zoom=100,72,94>`_ unary operator
|
|
107
|
-
"""
|
|
107
|
+
""" # noqa E501
|
|
108
108
|
|
|
109
109
|
op = EXP
|
|
110
110
|
py_op = math.exp
|
|
@@ -115,7 +115,7 @@ class NaturalLogarithm(Unary):
|
|
|
115
115
|
"""
|
|
116
116
|
`Natural logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=115&zoom=100,72,394> `_
|
|
117
117
|
unary operator
|
|
118
|
-
"""
|
|
118
|
+
""" # noqa E501
|
|
119
119
|
|
|
120
120
|
op = LN
|
|
121
121
|
py_op = math.log
|
|
@@ -126,7 +126,7 @@ class SquareRoot(Unary):
|
|
|
126
126
|
"""
|
|
127
127
|
`Square Root <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=119&zoom=100,72,556> '_
|
|
128
128
|
unary operator
|
|
129
|
-
"""
|
|
129
|
+
""" # noqa E501
|
|
130
130
|
|
|
131
131
|
op = SQRT
|
|
132
132
|
py_op = math.sqrt
|
|
@@ -136,7 +136,7 @@ class SquareRoot(Unary):
|
|
|
136
136
|
class Ceil(Unary):
|
|
137
137
|
"""
|
|
138
138
|
`Ceilling <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=110&zoom=100,72,94> `_ unary operator
|
|
139
|
-
"""
|
|
139
|
+
""" # noqa E501
|
|
140
140
|
|
|
141
141
|
op = CEIL
|
|
142
142
|
py_op = math.ceil
|
|
@@ -146,7 +146,7 @@ class Ceil(Unary):
|
|
|
146
146
|
class Floor(Unary):
|
|
147
147
|
"""
|
|
148
148
|
`Floor <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=111&zoom=100,72,442> `_ unary operator
|
|
149
|
-
"""
|
|
149
|
+
""" # noqa E501
|
|
150
150
|
|
|
151
151
|
op = FLOOR
|
|
152
152
|
py_op = math.floor
|
|
@@ -156,7 +156,7 @@ class Floor(Unary):
|
|
|
156
156
|
class BinPlus(Binary):
|
|
157
157
|
"""
|
|
158
158
|
`Addition <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=96&zoom=100,72,692> `_ binary operator
|
|
159
|
-
"""
|
|
159
|
+
""" # noqa E501
|
|
160
160
|
|
|
161
161
|
op = PLUS
|
|
162
162
|
py_op = operator.add
|
|
@@ -166,7 +166,7 @@ class BinPlus(Binary):
|
|
|
166
166
|
class BinMinus(Binary):
|
|
167
167
|
"""
|
|
168
168
|
`Subtraction <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=98&zoom=100,72,448> `_ binary operator
|
|
169
|
-
"""
|
|
169
|
+
""" # noqa E501
|
|
170
170
|
|
|
171
171
|
op = MINUS
|
|
172
172
|
py_op = operator.sub
|
|
@@ -177,7 +177,7 @@ class Mult(Binary):
|
|
|
177
177
|
"""
|
|
178
178
|
`Multiplication <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=100&zoom=100,72,254>`_
|
|
179
179
|
binary operator
|
|
180
|
-
"""
|
|
180
|
+
""" # noqa E501
|
|
181
181
|
|
|
182
182
|
op = MULT
|
|
183
183
|
py_op = operator.mul
|
|
@@ -187,7 +187,7 @@ class Div(Binary):
|
|
|
187
187
|
"""
|
|
188
188
|
`Division <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=102&zoom=100,72,94>`_
|
|
189
189
|
binary operator
|
|
190
|
-
"""
|
|
190
|
+
""" # noqa E501
|
|
191
191
|
|
|
192
192
|
op = DIV
|
|
193
193
|
py_op = operator.truediv
|
|
@@ -197,7 +197,7 @@ class Div(Binary):
|
|
|
197
197
|
class Logarithm(Binary):
|
|
198
198
|
"""
|
|
199
199
|
`Logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=118&zoom=100,72,228>`_ operator
|
|
200
|
-
"""
|
|
200
|
+
""" # noqa E501
|
|
201
201
|
|
|
202
202
|
op = LOG
|
|
203
203
|
return_type = Number
|
|
@@ -215,7 +215,7 @@ class Logarithm(Binary):
|
|
|
215
215
|
class Modulo(Binary):
|
|
216
216
|
"""
|
|
217
217
|
`Module <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=104&zoom=100,72,94>`_ operator
|
|
218
|
-
"""
|
|
218
|
+
""" # noqa E501
|
|
219
219
|
|
|
220
220
|
op = MOD
|
|
221
221
|
py_op = operator.mod
|
|
@@ -224,7 +224,7 @@ class Modulo(Binary):
|
|
|
224
224
|
class Power(Binary):
|
|
225
225
|
"""
|
|
226
226
|
`Power <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=116&zoom=100,72,693>`_ operator
|
|
227
|
-
"""
|
|
227
|
+
""" # noqa E501
|
|
228
228
|
|
|
229
229
|
op = POWER
|
|
230
230
|
return_type = Number
|
|
@@ -248,14 +248,15 @@ class Parameterized(Unary):
|
|
|
248
248
|
operand: Operator.ALL_MODEL_DATA_TYPES,
|
|
249
249
|
param: Optional[Union[DataComponent, Scalar]] = None,
|
|
250
250
|
) -> Any:
|
|
251
|
-
|
|
252
251
|
if param is not None:
|
|
253
252
|
if isinstance(param, Dataset):
|
|
254
253
|
raise SemanticError("1-1-15-8", op=cls.op, comp_type="Dataset")
|
|
255
254
|
if isinstance(param, DataComponent):
|
|
256
255
|
if isinstance(operand, Scalar):
|
|
257
256
|
raise SemanticError(
|
|
258
|
-
"1-1-15-8",
|
|
257
|
+
"1-1-15-8",
|
|
258
|
+
op=cls.op,
|
|
259
|
+
comp_type="DataComponent and an Scalar operand",
|
|
259
260
|
)
|
|
260
261
|
cls.validate_type_compatibility(param.data_type)
|
|
261
262
|
else:
|
|
@@ -298,14 +299,19 @@ class Parameterized(Unary):
|
|
|
298
299
|
)
|
|
299
300
|
except ValueError:
|
|
300
301
|
raise SemanticError(
|
|
301
|
-
"2-1-15-1",
|
|
302
|
+
"2-1-15-1",
|
|
303
|
+
op=cls.op,
|
|
304
|
+
comp_name=measure_name,
|
|
305
|
+
dataset_name=operand.name,
|
|
302
306
|
) from None
|
|
303
307
|
result.data = result.data[result.get_components_names()]
|
|
304
308
|
return result
|
|
305
309
|
|
|
306
310
|
@classmethod
|
|
307
311
|
def component_evaluation(
|
|
308
|
-
cls,
|
|
312
|
+
cls,
|
|
313
|
+
operand: DataComponent,
|
|
314
|
+
param: Optional[Union[DataComponent, Scalar]] = None,
|
|
309
315
|
) -> DataComponent:
|
|
310
316
|
result = cls.validate(operand, param)
|
|
311
317
|
if operand.data is None:
|
|
@@ -327,7 +333,9 @@ class Parameterized(Unary):
|
|
|
327
333
|
|
|
328
334
|
@classmethod
|
|
329
335
|
def evaluate(
|
|
330
|
-
cls,
|
|
336
|
+
cls,
|
|
337
|
+
operand: ALL_MODEL_DATA_TYPES,
|
|
338
|
+
param: Optional[Union[DataComponent, Scalar]] = None,
|
|
331
339
|
) -> Union[DataComponent, Dataset, Scalar]:
|
|
332
340
|
if isinstance(operand, Dataset):
|
|
333
341
|
return cls.dataset_evaluation(operand, param)
|
|
@@ -340,7 +348,7 @@ class Parameterized(Unary):
|
|
|
340
348
|
class Round(Parameterized):
|
|
341
349
|
"""
|
|
342
350
|
`Round <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=106&zoom=100,72,94>`_ operator
|
|
343
|
-
"""
|
|
351
|
+
""" # noqa E501
|
|
344
352
|
|
|
345
353
|
op = ROUND
|
|
346
354
|
return_type = Integer
|
|
@@ -365,14 +373,14 @@ class Round(Parameterized):
|
|
|
365
373
|
class Trunc(Parameterized):
|
|
366
374
|
"""
|
|
367
375
|
`Trunc <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=108&zoom=100,72,94>`_ operator.
|
|
368
|
-
"""
|
|
376
|
+
""" # noqa E501
|
|
369
377
|
|
|
370
378
|
op = TRUNC
|
|
371
379
|
|
|
372
380
|
@classmethod
|
|
373
381
|
def py_op(cls, x: float, param: Optional[float]) -> Any:
|
|
374
382
|
multiplier = 1.0
|
|
375
|
-
if not pd.isnull(param):
|
|
383
|
+
if not pd.isnull(param) and param is not None:
|
|
376
384
|
multiplier = 10**param
|
|
377
385
|
|
|
378
386
|
truncated_value = int(x * multiplier) / multiplier
|
|
@@ -384,14 +392,12 @@ class Trunc(Parameterized):
|
|
|
384
392
|
|
|
385
393
|
|
|
386
394
|
class PseudoRandom(_random.Random):
|
|
387
|
-
|
|
388
395
|
def __init__(self, seed: Union[int, float]) -> None:
|
|
389
396
|
super().__init__()
|
|
390
397
|
self.seed(seed)
|
|
391
398
|
|
|
392
399
|
|
|
393
400
|
class Random(Parameterized):
|
|
394
|
-
|
|
395
401
|
op = RANDOM
|
|
396
402
|
return_type = Number
|
|
397
403
|
|
|
@@ -403,7 +409,7 @@ class Random(Parameterized):
|
|
|
403
409
|
raise SemanticError("2-1-15-2", op=cls.op, value=index)
|
|
404
410
|
if index.value > 10000:
|
|
405
411
|
warnings.warn(
|
|
406
|
-
"Random: The value of 'index' is very big. This can affect
|
|
412
|
+
"Random: The value of 'index' is very big. This can affect performance.",
|
|
407
413
|
UserWarning,
|
|
408
414
|
)
|
|
409
415
|
return super().validate(seed, index)
|
|
@@ -35,8 +35,12 @@ class RoleSetter(Unary):
|
|
|
35
35
|
|
|
36
36
|
@classmethod
|
|
37
37
|
def evaluate(cls, operand: Any, data_size: int = 0) -> DataComponent:
|
|
38
|
-
if (
|
|
39
|
-
|
|
38
|
+
if (
|
|
39
|
+
isinstance(operand, DataComponent)
|
|
40
|
+
and operand.data is not None
|
|
41
|
+
and not operand.nullable
|
|
42
|
+
and any(operand.data.isnull())
|
|
43
|
+
):
|
|
40
44
|
raise SemanticError("1-1-1-16")
|
|
41
45
|
result = cls.validate(operand, data_size)
|
|
42
46
|
if isinstance(operand, Scalar):
|
vtlengine/Operators/Set.py
CHANGED
|
@@ -13,12 +13,14 @@ from vtlengine.Operators import Operator
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class Set(Operator):
|
|
16
|
-
|
|
17
16
|
@classmethod
|
|
18
17
|
def check_same_structure(cls, dataset_1: Dataset, dataset_2: Dataset) -> None:
|
|
19
18
|
if len(dataset_1.components) != len(dataset_2.components):
|
|
20
19
|
raise SemanticError(
|
|
21
|
-
"1-1-17-1",
|
|
20
|
+
"1-1-17-1",
|
|
21
|
+
op=cls.op,
|
|
22
|
+
dataset_1=dataset_1.name,
|
|
23
|
+
dataset_2=dataset_2.name,
|
|
22
24
|
)
|
|
23
25
|
|
|
24
26
|
for comp in dataset_1.components.values():
|
|
@@ -26,7 +28,10 @@ class Set(Operator):
|
|
|
26
28
|
raise Exception(f"Component {comp.name} not found in dataset {dataset_2.name}")
|
|
27
29
|
second_comp = dataset_2.components[comp.name]
|
|
28
30
|
binary_implicit_promotion(
|
|
29
|
-
comp.data_type,
|
|
31
|
+
comp.data_type,
|
|
32
|
+
second_comp.data_type,
|
|
33
|
+
cls.type_to_check,
|
|
34
|
+
cls.return_type,
|
|
30
35
|
)
|
|
31
36
|
if comp.role != second_comp.role:
|
|
32
37
|
raise Exception(
|
|
@@ -36,7 +41,6 @@ class Set(Operator):
|
|
|
36
41
|
|
|
37
42
|
@classmethod
|
|
38
43
|
def validate(cls, operands: List[Dataset]) -> Dataset:
|
|
39
|
-
|
|
40
44
|
base_operand = operands[0]
|
|
41
45
|
for operand in operands[1:]:
|
|
42
46
|
cls.check_same_structure(base_operand, operand)
|
|
@@ -70,7 +74,6 @@ class Union(Set):
|
|
|
70
74
|
|
|
71
75
|
|
|
72
76
|
class Intersection(Set):
|
|
73
|
-
|
|
74
77
|
@classmethod
|
|
75
78
|
def evaluate(cls, operands: List[Dataset]) -> Dataset:
|
|
76
79
|
result = cls.validate(operands)
|
|
@@ -97,7 +100,6 @@ class Intersection(Set):
|
|
|
97
100
|
|
|
98
101
|
|
|
99
102
|
class Symdiff(Set):
|
|
100
|
-
|
|
101
103
|
@classmethod
|
|
102
104
|
def evaluate(cls, operands: List[Dataset]) -> Dataset:
|
|
103
105
|
result = cls.validate(operands)
|
|
@@ -110,7 +112,10 @@ class Symdiff(Set):
|
|
|
110
112
|
else:
|
|
111
113
|
# Realiza la operación equivalente en pyspark.pandas
|
|
112
114
|
result.data = result.data.merge(
|
|
113
|
-
data,
|
|
115
|
+
data,
|
|
116
|
+
how="outer",
|
|
117
|
+
on=result.get_identifiers_names(),
|
|
118
|
+
suffixes=("_x", "_y"),
|
|
114
119
|
)
|
|
115
120
|
|
|
116
121
|
for measure in result.get_measures_names():
|
|
@@ -140,7 +145,6 @@ class Symdiff(Set):
|
|
|
140
145
|
|
|
141
146
|
|
|
142
147
|
class Setdiff(Set):
|
|
143
|
-
|
|
144
148
|
@staticmethod
|
|
145
149
|
def has_null(row: Any) -> bool:
|
|
146
150
|
return row.isnull().any()
|
vtlengine/Operators/String.py
CHANGED
|
@@ -31,7 +31,6 @@ class Unary(Operator.Unary):
|
|
|
31
31
|
|
|
32
32
|
@classmethod
|
|
33
33
|
def op_func(cls, x: Any) -> Any:
|
|
34
|
-
|
|
35
34
|
x = "" if pd.isnull(x) else str(x)
|
|
36
35
|
return cls.py_op(x)
|
|
37
36
|
|
|
@@ -116,7 +115,6 @@ class Concatenate(Binary):
|
|
|
116
115
|
|
|
117
116
|
|
|
118
117
|
class Parameterized(Unary):
|
|
119
|
-
|
|
120
118
|
@classmethod
|
|
121
119
|
def validate(cls, *args: Any) -> Any:
|
|
122
120
|
operand: Operator.ALL_MODEL_DATA_TYPES
|
|
@@ -353,7 +351,6 @@ class Instr(Parameterized):
|
|
|
353
351
|
param2: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
|
|
354
352
|
param3: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
|
|
355
353
|
) -> Any:
|
|
356
|
-
|
|
357
354
|
if (
|
|
358
355
|
isinstance(param1, Dataset)
|
|
359
356
|
or isinstance(param2, Dataset)
|
|
@@ -395,7 +392,10 @@ class Instr(Parameterized):
|
|
|
395
392
|
else:
|
|
396
393
|
if not check_unary_implicit_promotion(data_type, Integer):
|
|
397
394
|
raise SemanticError(
|
|
398
|
-
"1-1-18-4",
|
|
395
|
+
"1-1-18-4",
|
|
396
|
+
op=cls.op,
|
|
397
|
+
param_type="Occurrence",
|
|
398
|
+
correct_type="Integer",
|
|
399
399
|
)
|
|
400
400
|
if isinstance(param, DataComponent):
|
|
401
401
|
if param.data is not None:
|
|
@@ -408,9 +408,7 @@ class Instr(Parameterized):
|
|
|
408
408
|
if position == 2 and not pd.isnull(param) and param < 1:
|
|
409
409
|
raise SemanticError("1-1-18-4", op=cls.op, param_type="Start", correct_type=">= 1")
|
|
410
410
|
elif position == 3 and not pd.isnull(param) and param < 1:
|
|
411
|
-
raise SemanticError(
|
|
412
|
-
"1-1-18-4", op=cls.op, param_type="Occurrence", correct_type=">= 1"
|
|
413
|
-
)
|
|
411
|
+
raise SemanticError("1-1-18-4", op=cls.op, param_type="Occurrence", correct_type=">= 1")
|
|
414
412
|
|
|
415
413
|
@classmethod
|
|
416
414
|
def apply_operation_series_scalar(
|
|
@@ -529,7 +527,6 @@ class Instr(Parameterized):
|
|
|
529
527
|
param2: Optional[Any],
|
|
530
528
|
param3: Optional[Any],
|
|
531
529
|
) -> Any:
|
|
532
|
-
|
|
533
530
|
if pd.isnull(x):
|
|
534
531
|
return None
|
|
535
532
|
return cls.py_op(x, param1, param2, param3)
|
|
@@ -560,7 +557,10 @@ class Instr(Parameterized):
|
|
|
560
557
|
else:
|
|
561
558
|
# OPERATORS_STRINGOPERATORS.93
|
|
562
559
|
raise SemanticError(
|
|
563
|
-
"1-1-18-4",
|
|
560
|
+
"1-1-18-4",
|
|
561
|
+
op=cls.op,
|
|
562
|
+
param_type="Occurrence",
|
|
563
|
+
correct_type="Integer",
|
|
564
564
|
)
|
|
565
565
|
else:
|
|
566
566
|
occurrence = 0
|