pydpm_xl 0.1.10__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.
- py_dpm/AST/ASTConstructor.py +503 -0
- py_dpm/AST/ASTObjects.py +827 -0
- py_dpm/AST/ASTTemplate.py +101 -0
- py_dpm/AST/ASTVisitor.py +13 -0
- py_dpm/AST/MLGeneration.py +588 -0
- py_dpm/AST/ModuleAnalyzer.py +79 -0
- py_dpm/AST/ModuleDependencies.py +203 -0
- py_dpm/AST/WhereClauseChecker.py +12 -0
- py_dpm/AST/__init__.py +0 -0
- py_dpm/AST/check_operands.py +302 -0
- py_dpm/DataTypes/ScalarTypes.py +324 -0
- py_dpm/DataTypes/TimeClasses.py +370 -0
- py_dpm/DataTypes/TypePromotion.py +195 -0
- py_dpm/DataTypes/__init__.py +0 -0
- py_dpm/Exceptions/__init__.py +0 -0
- py_dpm/Exceptions/exceptions.py +84 -0
- py_dpm/Exceptions/messages.py +114 -0
- py_dpm/OperationScopes/OperationScopeService.py +247 -0
- py_dpm/OperationScopes/__init__.py +0 -0
- py_dpm/Operators/AggregateOperators.py +138 -0
- py_dpm/Operators/BooleanOperators.py +30 -0
- py_dpm/Operators/ClauseOperators.py +159 -0
- py_dpm/Operators/ComparisonOperators.py +69 -0
- py_dpm/Operators/ConditionalOperators.py +362 -0
- py_dpm/Operators/NumericOperators.py +101 -0
- py_dpm/Operators/Operator.py +388 -0
- py_dpm/Operators/StringOperators.py +27 -0
- py_dpm/Operators/TimeOperators.py +53 -0
- py_dpm/Operators/__init__.py +0 -0
- py_dpm/Utils/ValidationsGenerationUtils.py +429 -0
- py_dpm/Utils/__init__.py +0 -0
- py_dpm/Utils/operands_mapping.py +73 -0
- py_dpm/Utils/operator_mapping.py +89 -0
- py_dpm/Utils/tokens.py +172 -0
- py_dpm/Utils/utils.py +2 -0
- py_dpm/ValidationsGeneration/PropertiesConstraintsProcessor.py +190 -0
- py_dpm/ValidationsGeneration/Utils.py +364 -0
- py_dpm/ValidationsGeneration/VariantsProcessor.py +265 -0
- py_dpm/ValidationsGeneration/__init__.py +0 -0
- py_dpm/ValidationsGeneration/auxiliary_functions.py +98 -0
- py_dpm/__init__.py +61 -0
- py_dpm/api/__init__.py +140 -0
- py_dpm/api/ast_generator.py +438 -0
- py_dpm/api/complete_ast.py +241 -0
- py_dpm/api/data_dictionary_validation.py +577 -0
- py_dpm/api/migration.py +77 -0
- py_dpm/api/semantic.py +224 -0
- py_dpm/api/syntax.py +182 -0
- py_dpm/client.py +106 -0
- py_dpm/data_handlers.py +99 -0
- py_dpm/db_utils.py +117 -0
- py_dpm/grammar/__init__.py +0 -0
- py_dpm/grammar/dist/__init__.py +0 -0
- py_dpm/grammar/dist/dpm_xlLexer.interp +428 -0
- py_dpm/grammar/dist/dpm_xlLexer.py +804 -0
- py_dpm/grammar/dist/dpm_xlLexer.tokens +106 -0
- py_dpm/grammar/dist/dpm_xlParser.interp +249 -0
- py_dpm/grammar/dist/dpm_xlParser.py +5224 -0
- py_dpm/grammar/dist/dpm_xlParser.tokens +106 -0
- py_dpm/grammar/dist/dpm_xlParserListener.py +742 -0
- py_dpm/grammar/dist/dpm_xlParserVisitor.py +419 -0
- py_dpm/grammar/dist/listeners.py +10 -0
- py_dpm/grammar/dpm_xlLexer.g4 +435 -0
- py_dpm/grammar/dpm_xlParser.g4 +260 -0
- py_dpm/migration.py +282 -0
- py_dpm/models.py +2139 -0
- py_dpm/semantics/DAG/DAGAnalyzer.py +158 -0
- py_dpm/semantics/DAG/__init__.py +0 -0
- py_dpm/semantics/SemanticAnalyzer.py +320 -0
- py_dpm/semantics/Symbols.py +223 -0
- py_dpm/semantics/__init__.py +0 -0
- py_dpm/utils/__init__.py +0 -0
- py_dpm/utils/ast_serialization.py +481 -0
- py_dpm/views/data_types.sql +12 -0
- py_dpm/views/datapoints.sql +65 -0
- py_dpm/views/hierarchy_operand_reference.sql +11 -0
- py_dpm/views/hierarchy_preconditions.sql +13 -0
- py_dpm/views/hierarchy_variables.sql +26 -0
- py_dpm/views/hierarchy_variables_context.sql +14 -0
- py_dpm/views/key_components.sql +18 -0
- py_dpm/views/module_from_table.sql +11 -0
- py_dpm/views/open_keys.sql +13 -0
- py_dpm/views/operation_info.sql +27 -0
- py_dpm/views/operation_list.sql +18 -0
- py_dpm/views/operations_versions_from_module_version.sql +30 -0
- py_dpm/views/precondition_info.sql +17 -0
- py_dpm/views/report_type_operand_reference_info.sql +18 -0
- py_dpm/views/subcategory_info.sql +17 -0
- py_dpm/views/table_info.sql +19 -0
- pydpm_xl-0.1.10.dist-info/LICENSE +674 -0
- pydpm_xl-0.1.10.dist-info/METADATA +50 -0
- pydpm_xl-0.1.10.dist-info/RECORD +94 -0
- pydpm_xl-0.1.10.dist-info/WHEEL +4 -0
- pydpm_xl-0.1.10.dist-info/entry_points.txt +3 -0
py_dpm/Utils/tokens.py
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Comparison operators.
|
|
2
|
+
EQ = '='
|
|
3
|
+
NEQ = '!='
|
|
4
|
+
GT = '>'
|
|
5
|
+
GTE = '>='
|
|
6
|
+
LT = '<'
|
|
7
|
+
LTE = '<='
|
|
8
|
+
IN = 'in'
|
|
9
|
+
ISNULL = 'isnull'
|
|
10
|
+
MATCH = 'match'
|
|
11
|
+
|
|
12
|
+
# Numeric operators
|
|
13
|
+
PLUS = '+'
|
|
14
|
+
MINUS = '-'
|
|
15
|
+
MULT = '*'
|
|
16
|
+
DIV = '/'
|
|
17
|
+
ABS = 'abs'
|
|
18
|
+
EXP = 'exp'
|
|
19
|
+
LN = 'ln'
|
|
20
|
+
SQRT = 'sqrt'
|
|
21
|
+
POW = 'power'
|
|
22
|
+
LOG = 'log'
|
|
23
|
+
MAX = 'max'
|
|
24
|
+
MIN = 'min'
|
|
25
|
+
|
|
26
|
+
# Boolean operators.
|
|
27
|
+
AND = 'and'
|
|
28
|
+
OR = 'or'
|
|
29
|
+
XOR = 'xor'
|
|
30
|
+
NOT = 'not'
|
|
31
|
+
|
|
32
|
+
# Conditional operators.
|
|
33
|
+
IF = "if"
|
|
34
|
+
NVL= "nvl"
|
|
35
|
+
|
|
36
|
+
# Clause operators
|
|
37
|
+
WHERE = 'where'
|
|
38
|
+
RENAME = 'rename'
|
|
39
|
+
GET = 'get'
|
|
40
|
+
|
|
41
|
+
# Aggregation operators
|
|
42
|
+
MAX_AGGR = 'max_aggr'
|
|
43
|
+
MIN_AGGR = 'min_aggr'
|
|
44
|
+
SUM = 'sum'
|
|
45
|
+
COUNT = 'count'
|
|
46
|
+
AVG = 'avg'
|
|
47
|
+
MEDIAN = 'median'
|
|
48
|
+
|
|
49
|
+
# String operators
|
|
50
|
+
LENGTH = "len"
|
|
51
|
+
CONCATENATE = "&"
|
|
52
|
+
|
|
53
|
+
# Time operators
|
|
54
|
+
TIME_SHIFT = 'time_shift'
|
|
55
|
+
|
|
56
|
+
# Conditional operators
|
|
57
|
+
FILTER = 'filter'
|
|
58
|
+
|
|
59
|
+
# key Components types
|
|
60
|
+
DPM = "DPM"
|
|
61
|
+
STANDARD = "Standard"
|
|
62
|
+
|
|
63
|
+
# Standard key names
|
|
64
|
+
ROW = 'r'
|
|
65
|
+
COLUMN = 'c'
|
|
66
|
+
SHEET = 's'
|
|
67
|
+
FACT = 'f'
|
|
68
|
+
|
|
69
|
+
# Indexes
|
|
70
|
+
INDEX_X = 'x'
|
|
71
|
+
INDEX_Y = 'y'
|
|
72
|
+
INDEX_Z = 'z'
|
|
73
|
+
|
|
74
|
+
# Cell components
|
|
75
|
+
ROW_CODE = 'row_code'
|
|
76
|
+
COLUMN_CODE = 'column_code'
|
|
77
|
+
SHEET_CODE = 'sheet_code'
|
|
78
|
+
TABLE_CODE = 'table_code'
|
|
79
|
+
CELL_COMPONENTS = [ROW_CODE, COLUMN_CODE, SHEET_CODE]
|
|
80
|
+
|
|
81
|
+
# Generated validations status
|
|
82
|
+
STATUS = 'status'
|
|
83
|
+
STATUS_CORRECT = 'Correct'
|
|
84
|
+
STATUS_INCORRECT = 'Incorrect'
|
|
85
|
+
STATUS_INCOMPLETE = 'Incomplete'
|
|
86
|
+
STATUS_UNKNOWN = 'Unknown'
|
|
87
|
+
TABLE_VERSION_ID = 'table_version_id'
|
|
88
|
+
|
|
89
|
+
# Generated validations constants
|
|
90
|
+
ITEM_ID = 'ItemID'
|
|
91
|
+
PARENT_ITEM_ID = 'ParentItemID'
|
|
92
|
+
VARIABLE_VID = 'variable_vid'
|
|
93
|
+
ARITHMETIC_OPERATOR_ID = 'ArithmeticOperatorID'
|
|
94
|
+
ORDER = 'Order'
|
|
95
|
+
|
|
96
|
+
TABLE_CODE_LEFT = TABLE_CODE + '_left'
|
|
97
|
+
ROW_CODE_LEFT = ROW_CODE + '_left'
|
|
98
|
+
COLUMN_CODE_LEFT = COLUMN_CODE + '_left'
|
|
99
|
+
SHEET_CODE_LEFT = SHEET_CODE + '_left'
|
|
100
|
+
|
|
101
|
+
TABLE_CODE_RIGHT = TABLE_CODE + '_right'
|
|
102
|
+
ROW_CODE_RIGHT = ROW_CODE + '_right'
|
|
103
|
+
COLUMN_CODE_RIGHT = COLUMN_CODE + '_right'
|
|
104
|
+
SHEET_CODE_RIGHT = SHEET_CODE + '_right'
|
|
105
|
+
VARIABLE_PROPERTY_ID = 'variable_property_id'
|
|
106
|
+
|
|
107
|
+
CONTEXT_PROPERTY = 'context_property'
|
|
108
|
+
OPERATOR_ID = 'OperatorID'
|
|
109
|
+
SYMBOL = 'Symbol'
|
|
110
|
+
ARITHMETIC_OPERATOR_SYMBOL = 'arithmetic_operator_symbol'
|
|
111
|
+
COMPARISON_OPERATOR_ID = 'ComparisonOperatorID'
|
|
112
|
+
COMPARISON_OPERATOR_SYMBOL = 'comparison_operator_symbol'
|
|
113
|
+
|
|
114
|
+
OPERATOR = 'operator'
|
|
115
|
+
IS_DEFAULT_ITEM = 'IsDefaultItem'
|
|
116
|
+
PROPERTY_ID = 'property_id'
|
|
117
|
+
CONTEXT_ITEM = 'context_item'
|
|
118
|
+
CONTEXT_ITEM_ID = 'context_item_id'
|
|
119
|
+
METRIC_PROPERTY_ID = 'metric_property_id'
|
|
120
|
+
CONTEXT_PROPERTY_ID = 'context_property_id'
|
|
121
|
+
SUBCATEGORY_PROPERTY = 'subcategory_property'
|
|
122
|
+
|
|
123
|
+
VALIDATION_CODE = 'validation_code'
|
|
124
|
+
TABLE_GROUP_CHILD_TYPE = 'tableGroup_child'
|
|
125
|
+
EXPRESSION = 'expression'
|
|
126
|
+
DUPLICATE_VARIABLES = 'duplicate_variables'
|
|
127
|
+
CELL_ID = 'cell_id'
|
|
128
|
+
SUBCATEGORY_ID = 'subcategory_id'
|
|
129
|
+
SUBCATEGORY_CODE = 'subcategory_code'
|
|
130
|
+
PARENT_ID = 'parent_id'
|
|
131
|
+
LEFT_CELL_IDS = 'left_cell_ids'
|
|
132
|
+
KEY_ID = 'KeyID'
|
|
133
|
+
|
|
134
|
+
# Data types
|
|
135
|
+
PER = "p"
|
|
136
|
+
|
|
137
|
+
INPUTS = 'inputs'
|
|
138
|
+
OUTPUTS = 'outputs'
|
|
139
|
+
|
|
140
|
+
# Prefix
|
|
141
|
+
TABLE_GROUP_PREFIX = 'g'
|
|
142
|
+
|
|
143
|
+
# Modules
|
|
144
|
+
INTRA_MODULE = 'intra-module'
|
|
145
|
+
CROSS_MODULE = 'cross-module'
|
|
146
|
+
REPEATED_INTRA_MODULE = 'repeated-intra-module'
|
|
147
|
+
REPEATED_CROSS_MODULE = 'repeated-cross-module'
|
|
148
|
+
|
|
149
|
+
# Operation scope constants
|
|
150
|
+
WARNING_SEVERITY = 'warning'
|
|
151
|
+
|
|
152
|
+
FILING_INDICATOR = 'filingIndicator'
|
|
153
|
+
OP_VERSION_ID = 'op_version_id'
|
|
154
|
+
|
|
155
|
+
# Report types
|
|
156
|
+
HIERARCHY_REPORT = 'hierarchy_report'
|
|
157
|
+
SIGN_REPORT = 'sign_report'
|
|
158
|
+
EXISTENCE_REPORT = 'existence_report'
|
|
159
|
+
HIERARCHY = 'hierarchy'
|
|
160
|
+
SIGN = 'sign'
|
|
161
|
+
EXISTENCE = 'existence'
|
|
162
|
+
#sign
|
|
163
|
+
POSITIVE = 'positive'
|
|
164
|
+
NEGATIVE = 'negative'
|
|
165
|
+
|
|
166
|
+
# Web service constants
|
|
167
|
+
CODE = 'code'
|
|
168
|
+
ERROR = 'error'
|
|
169
|
+
ERROR_CODE = 'error_code'
|
|
170
|
+
VALIDATIONS = 'validations'
|
|
171
|
+
VARIABLES = 'variables'
|
|
172
|
+
VALIDATION_TYPE = 'validation_type'
|
py_dpm/Utils/utils.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
from py_dpm.AST.ASTObjects import AggregationOp, BinOp, ComplexNumericOp, CondExpr, FilterOp, GetOp, PropertyReference, RenameOp, Scalar, \
|
|
4
|
+
TimeShiftOp, UnaryOp, VarID, WhereClauseOp
|
|
5
|
+
from py_dpm.AST.ASTTemplate import ASTTemplate
|
|
6
|
+
from py_dpm.Exceptions import exceptions
|
|
7
|
+
from py_dpm.models import ItemCategory, ViewDatapoints
|
|
8
|
+
from py_dpm.Utils.ValidationsGenerationUtils import ValidationsGenerationUtils
|
|
9
|
+
from py_dpm.Utils.tokens import *
|
|
10
|
+
|
|
11
|
+
ALLOWED_OPERATORS = [MATCH, IN, EQ, NEQ, GT, GTE, LT, LTE, LENGTH, CONCATENATE]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _check_property_constraint_exists(signature: str, session):
|
|
15
|
+
if ":" in signature:
|
|
16
|
+
property_query = ItemCategory.get_property_from_signature(signature, session)
|
|
17
|
+
else:
|
|
18
|
+
property_query = ItemCategory.get_property_from_code(signature, session)
|
|
19
|
+
if property_query is None:
|
|
20
|
+
return False
|
|
21
|
+
return True
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PropertiesConstraintsChecker(ASTTemplate):
|
|
25
|
+
def __init__(self, ast, session):
|
|
26
|
+
super().__init__()
|
|
27
|
+
self.has_property = False
|
|
28
|
+
self.has_table = False
|
|
29
|
+
self.session = session
|
|
30
|
+
self.visit(ast)
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def is_property_constraint(self):
|
|
34
|
+
if self.has_table:
|
|
35
|
+
return False
|
|
36
|
+
return self.has_property
|
|
37
|
+
|
|
38
|
+
def visit_PropertyReference(self, node: PropertyReference):
|
|
39
|
+
# Optional
|
|
40
|
+
if not ":" in node.code:
|
|
41
|
+
pass # signature should have : to be a property constraint
|
|
42
|
+
signature = node.code
|
|
43
|
+
# look for property in models
|
|
44
|
+
property_query = ItemCategory.get_property_from_signature(signature, self.session)
|
|
45
|
+
if property_query is None:
|
|
46
|
+
raise exceptions.SemanticError("5-1-4", ref=signature)
|
|
47
|
+
self.has_property = True
|
|
48
|
+
|
|
49
|
+
def visit_VarID(self, node: VarID):
|
|
50
|
+
if node.table:
|
|
51
|
+
self.has_table = True
|
|
52
|
+
|
|
53
|
+
def visit_Scalar(self, node: Scalar):
|
|
54
|
+
signature = node.item
|
|
55
|
+
if not self.has_property:
|
|
56
|
+
if getattr(node, "scalar_type", None) == "Item":
|
|
57
|
+
# go to models and check if item exists and is a property
|
|
58
|
+
property_query = ItemCategory.get_property_from_signature(signature, self.session)
|
|
59
|
+
if property_query:
|
|
60
|
+
self.has_property = True
|
|
61
|
+
# other assumption could be always first scalar is a property but this is not true
|
|
62
|
+
# self.has_property = True
|
|
63
|
+
else:
|
|
64
|
+
other_property_query = ItemCategory.get_property_from_signature(signature, self.session)
|
|
65
|
+
if other_property_query:
|
|
66
|
+
raise exceptions.SemanticError("5-1-2")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class PropertiesConstraintsProcessor(ASTTemplate):
|
|
70
|
+
"""
|
|
71
|
+
Class to generate individual validations from properties constraints
|
|
72
|
+
|
|
73
|
+
:parameter expression: DPM-XL expression.
|
|
74
|
+
:parameter ast: Abstract Syntax Tree of expression.
|
|
75
|
+
:parameter validation_code: Code of parent validation.
|
|
76
|
+
:parameter session: SQLAlchemy Session to be used to connect to the DB.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
def __init__(self, expression, ast, validation_code, session, release_id):
|
|
80
|
+
super().__init__()
|
|
81
|
+
self.expression = expression
|
|
82
|
+
self.AST = ast
|
|
83
|
+
self.validation_code = validation_code
|
|
84
|
+
self.session = session
|
|
85
|
+
self.current_validation = 1
|
|
86
|
+
self.property_constraint = None
|
|
87
|
+
self.release_id = release_id
|
|
88
|
+
self.new_expressions = []
|
|
89
|
+
self.visit(self.AST)
|
|
90
|
+
|
|
91
|
+
def generate_validations(self):
|
|
92
|
+
"""
|
|
93
|
+
Generates individual validations using the extracted property constraint in the Abstract Syntax Tree
|
|
94
|
+
"""
|
|
95
|
+
if not self.property_constraint:
|
|
96
|
+
raise exceptions.SemanticError("5-1-1")
|
|
97
|
+
|
|
98
|
+
item_category = ItemCategory.get_property_from_signature(
|
|
99
|
+
signature=self.property_constraint, session=self.session, release_id=self.release_id)
|
|
100
|
+
if item_category is None:
|
|
101
|
+
raise exceptions.SemanticError("1-7", property_code=self.property_constraint)
|
|
102
|
+
variables: pd.DataFrame = ViewDatapoints.get_from_property(self.session, item_category.ItemID, self.release_id)
|
|
103
|
+
for table_code, group_df in variables.groupby(['table_code']):
|
|
104
|
+
datapoints = ViewDatapoints.get_table_data(session=self.session, table=str(table_code))
|
|
105
|
+
self.generate_expressions(table_code, group_df, datapoints)
|
|
106
|
+
|
|
107
|
+
def generate_expressions(self, table_code, data, datapoints_table):
|
|
108
|
+
"""
|
|
109
|
+
Generates new expressions getting their operands by grouping the cells
|
|
110
|
+
:param table_code: code of the operand table
|
|
111
|
+
:param data: dataframe with operand datapoints
|
|
112
|
+
:param datapoints_table: table datapoints
|
|
113
|
+
"""
|
|
114
|
+
groups = ValidationsGenerationUtils.group_cells(datapoints_variable=data,
|
|
115
|
+
datapoints_table=datapoints_table)
|
|
116
|
+
for rows, cols, sheets in groups:
|
|
117
|
+
operand = ValidationsGenerationUtils.write_cell(table_code, rows, cols, sheets)
|
|
118
|
+
new_expression = self.expression
|
|
119
|
+
new_expression = new_expression.replace(f"[{self.property_constraint}]", operand)
|
|
120
|
+
self.new_expressions.append(new_expression)
|
|
121
|
+
|
|
122
|
+
def create_validation(self, expression, status):
|
|
123
|
+
"""
|
|
124
|
+
Creates a dictionary to represent a validation from expression and status information
|
|
125
|
+
:param expression: Expression of validation
|
|
126
|
+
:param status: Status of validation
|
|
127
|
+
:return a dictionary with validation_code, expression and status
|
|
128
|
+
"""
|
|
129
|
+
validation_code = None
|
|
130
|
+
if status == STATUS_CORRECT:
|
|
131
|
+
validation_code = f"{self.validation_code}-{self.current_validation}"
|
|
132
|
+
self.current_validation += 1
|
|
133
|
+
return {
|
|
134
|
+
VALIDATION_CODE: validation_code,
|
|
135
|
+
EXPRESSION: expression,
|
|
136
|
+
STATUS: status
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
def visit_PropertyReference(self, node: PropertyReference):
|
|
140
|
+
if not self.property_constraint:
|
|
141
|
+
self.property_constraint = node.code
|
|
142
|
+
signature = node.code
|
|
143
|
+
if not _check_property_constraint_exists(signature, self.session):
|
|
144
|
+
raise exceptions.SemanticError("5-1-4", ref=signature)
|
|
145
|
+
else:
|
|
146
|
+
raise exceptions.SemanticError("5-1-2")
|
|
147
|
+
|
|
148
|
+
def visit_Scalar(self, node: Scalar):
|
|
149
|
+
if getattr(node, "scalar_type", None) == "Item":
|
|
150
|
+
signature = node.item
|
|
151
|
+
property_query = ItemCategory.get_property_from_signature(signature, self.session)
|
|
152
|
+
if property_query:
|
|
153
|
+
if not self.property_constraint:
|
|
154
|
+
self.property_constraint = signature
|
|
155
|
+
|
|
156
|
+
def visit_BinOp(self, node: BinOp):
|
|
157
|
+
if node.op not in ALLOWED_OPERATORS:
|
|
158
|
+
raise exceptions.SemanticError("5-1-3", operator=node.op)
|
|
159
|
+
|
|
160
|
+
self.visit(node.left)
|
|
161
|
+
self.visit(node.right)
|
|
162
|
+
|
|
163
|
+
def visit_UnaryOp(self, node: UnaryOp):
|
|
164
|
+
if node.op not in ALLOWED_OPERATORS:
|
|
165
|
+
raise exceptions.SemanticError("5-1-3", operator=node.op)
|
|
166
|
+
self.visit(node.operand)
|
|
167
|
+
|
|
168
|
+
def visit_CondExpr(self, node: CondExpr):
|
|
169
|
+
raise exceptions.SemanticError("5-1-3", operator=IF)
|
|
170
|
+
|
|
171
|
+
def visit_AggregationOp(self, node: AggregationOp):
|
|
172
|
+
raise exceptions.SemanticError("5-1-3", operator=node.op)
|
|
173
|
+
|
|
174
|
+
def visit_RenameOp(self, node: RenameOp):
|
|
175
|
+
raise exceptions.SemanticError("5-1-3", operator=RENAME)
|
|
176
|
+
|
|
177
|
+
def visit_TimeShiftOp(self, node: TimeShiftOp):
|
|
178
|
+
raise exceptions.SemanticError("5-1-3", operator=TIME_SHIFT)
|
|
179
|
+
|
|
180
|
+
def visit_FilterOp(self, node: FilterOp):
|
|
181
|
+
raise exceptions.SemanticError("5-1-3", operator=FILTER)
|
|
182
|
+
|
|
183
|
+
def visit_WhereClauseOp(self, node: WhereClauseOp):
|
|
184
|
+
raise exceptions.SemanticError("5-1-3", operator=WHERE)
|
|
185
|
+
|
|
186
|
+
def visit_GetOp(self, node: GetOp):
|
|
187
|
+
raise exceptions.SemanticError("5-1-3", operator=GET)
|
|
188
|
+
|
|
189
|
+
def visit_ComplexNumericOp(self, node: ComplexNumericOp):
|
|
190
|
+
raise exceptions.SemanticError("5-1-3", operator=node.op)
|