예제 #1
0
 def return_type(self, context: TelRootContext) -> TelType:
     if self._calculation_expr:
         return self._calculation_expr.return_type(context)
     elif self._taxon:
         return TelType.from_taxon_validation_type(self._taxon.validation_type)
     else:
         # Taxon is not set. That can happen only if the taxon is optional and out of data source scope
         # If taxon is required and out of scope, it will fail in validation step.
         return TelType(TelDataType.NONE_OPTIONAL)
예제 #2
0
    def return_type(self, context: TelRootContext) -> TelType:
        types = []

        if not self._left_invalid:
            types.append(self._left.return_type(context))

        if not self._right_invalid:
            types.append(self._right.return_type(context))

        if not types:
            types.append(TelType(TelDataType.ANY))

        return TelType.return_common_type(types)
예제 #3
0
 def __init__(
     self,
     pre_formulas: List[PreFormula] = None,
     post_formula=None,
     dimension_formulas: List[PreFormula] = None,
     data_source_formula_templates: List[SqlFormulaTemplate] = None,
     phase: TelPhase = TelPhase.any,
     used_taxons: Optional[UsedTaxonSlugsContainer] = None,
     invalid_value: bool = False,
     return_data_sources: Set[Optional[str]] = None,
     return_type: Optional[TelType] = None,
     template_slugs: Set[TaxonExpressionStr] = None,
     debug_info: Optional[Any] = None,
     override_mappings: Optional[OverrideMappingTelData] = None,
 ):
     self.pre_formulas = [] if pre_formulas is None else pre_formulas
     self.dimension_formulas = [] if dimension_formulas is None else dimension_formulas
     self.post_formula = post_formula
     self._output = []
     self.used_taxons = used_taxons or UsedTaxonSlugsContainer()
     self.invalid_value = invalid_value
     self.return_data_sources = return_data_sources or set()
     self.return_type = return_type or TelType(TelDataType.ANY,
                                               is_constant=True)
     self.phase = phase
     self.data_source_formula_templates = data_source_formula_templates or []
     self.template_slugs = template_slugs or set()
     self.debug_info = debug_info
     self.override_mappings = override_mappings or set()
예제 #4
0
    def validate(self, context: TelValidationContext) -> TelValidationContext:
        super().validate(context)

        if not TelType.are_compatible_data_types(
            [self._left.return_type(context.root_context), self._right.return_type(context.root_context)]
        ):
            context.with_error('Operands in logical expression must have compatible data types', location=self.location)

        return context
예제 #5
0
    def return_type(self, context: TelRootContext) -> TelType:
        types = []

        if not self._left_invalid:
            types.append(self._left.return_type(context))
        if not self._right_invalid:
            types.append(self._right.return_type(context))

        return TelType.return_common_type(types).copy(data_type=TelDataType.BOOLEAN)
예제 #6
0
def test_tel_type_data_type():
    assert TelType(TelDataType.STRING).is_string()
    assert TelType(TelDataType.INTEGER).is_integer()
    assert TelType(TelDataType.INTEGER).is_number()
    assert TelType(TelDataType.NUMERIC).is_number()
    assert TelType(TelDataType.DATETIME).is_date()
    assert TelType(TelDataType.DATETIME).is_datetime()
    assert TelType(TelDataType.BOOLEAN).is_boolean()
예제 #7
0
def test_tel_type_copy():
    tel_type = TelType(TelDataType.ANY, is_constant=False)

    assert tel_type.copy().data_type is TelDataType.ANY
    assert tel_type.copy().is_constant is False

    assert tel_type.copy(
        data_type=TelDataType.STRING).data_type is TelDataType.STRING
    assert tel_type.copy(data_type=TelDataType.STRING).is_constant is False

    assert tel_type.copy(is_constant=True).data_type is TelDataType.ANY
    assert tel_type.copy(is_constant=True).is_constant is True

    assert tel_type.copy(data_type=TelDataType.STRING,
                         is_constant=True).data_type is TelDataType.STRING
    assert tel_type.copy(data_type=TelDataType.STRING,
                         is_constant=True).is_constant is True
예제 #8
0
    def merge_with(self, other: 'ExprResult', with_type: bool = True):
        """
        Helper fn to copy various values from other result to self.
        """
        if self.invalid_value is False and other.invalid_value is False:
            # Copy the values only if source and target results are valid.
            self.used_taxons.update_from(other.used_taxons)
            self.data_source_formula_templates.extend(
                other.data_source_formula_templates)
            self.dimension_formulas.extend(other.dimension_formulas)
            self.pre_formulas.extend(other.pre_formulas)
            self.return_data_sources.update(other.return_data_sources)
            self.template_slugs.update(other.template_slugs)
            self.override_mappings.update(other.override_mappings)

            if with_type:
                self.return_type = TelType.return_common_type(
                    [self.return_type, other.return_type])
예제 #9
0
    def validate(
        self,
        position: int,
        fn_name: str,
        exprs: Optional[Iterable[TelExpression]],
        location: ParserRuleContext,
        context: TelValidationContext,
    ) -> TelValidationContext:
        if self._optional and not exprs:
            return context
        elif not self._optional and not exprs:
            return context.with_error(
                f'{fn_name} requires at least 1 argument', location=location)
        elif exprs and not TelType.are_compatible_data_types(
            [expr.return_type(context.root_context) for expr in exprs]):
            context.with_error(
                f'Arguments in function {fn_name} must have compatible data types',
                location=location)

            for expr in exprs:
                self._validate_phase(position, fn_name, expr, context)

        return context
예제 #10
0
 def __call__(self, typ: TelType) -> bool:
     return typ.is_integer()
예제 #11
0
 def __call__(self, typ: TelType) -> bool:
     return typ.is_number()
예제 #12
0
 def __call__(self, typ: TelType) -> bool:
     return typ.is_string()
예제 #13
0
 def return_type(self, context: TelRootContext) -> TelType:
     return TelType.return_common_type([
         arg.return_type(context) for arg in self._args
     ]).copy(is_constant=False)
예제 #14
0
def test_tel_type_from_validation_type():
    tel_type = TelType.from_taxon_validation_type(ValidationType.text)

    assert tel_type.data_type is TelDataType.STRING
    assert tel_type.is_constant is False
예제 #15
0
def test_tel_type_return_common_type(tel_types, expected_common_type):
    assert TelType.return_common_type(
        tel_types).data_type is expected_common_type.data_type
    assert TelType.return_common_type(
        tel_types).is_constant is expected_common_type.is_constant
예제 #16
0
 def __call__(self, typ: TelType) -> bool:
     return typ.is_number() or typ.is_string() or typ.is_boolean()
예제 #17
0
 def return_type(self, context: TelRootContext) -> TelType:
     return TelType(self._data_type, is_constant=True)
예제 #18
0
def test_tel_type_constant():
    assert TelType(TelDataType.ANY, is_constant=True).is_constant
    assert not TelType(TelDataType.ANY, is_constant=False).is_constant
예제 #19
0
 def return_type(self, context: TelRootContext) -> TelType:
     return TelType(TelDataType.UNKNOWN, False)
예제 #20
0
 def __call__(self, typ: TelType) -> bool:
     return typ.is_datetime()
예제 #21
0
 def __call__(self, typ: TelType) -> bool:
     return typ.is_boolean()
예제 #22
0
def test_tel_type_compatible_data_types(tel_types, expected_compatibility):
    assert TelType.are_compatible_data_types(
        tel_types) is expected_compatibility
예제 #23
0
 def __call__(self, typ: TelType) -> bool:
     return typ.is_number() or typ.is_string() or typ.is_datetime()
예제 #24
0
                         is_constant=True).data_type is TelDataType.STRING
    assert tel_type.copy(data_type=TelDataType.STRING,
                         is_constant=True).is_constant is True


def test_tel_type_from_validation_type():
    tel_type = TelType.from_taxon_validation_type(ValidationType.text)

    assert tel_type.data_type is TelDataType.STRING
    assert tel_type.is_constant is False


@pytest.mark.parametrize(
    "tel_types,expected_common_type",
    [
        ([], TelType(TelDataType.UNKNOWN)),
        ([TelType(TelDataType.UNKNOWN)], TelType(TelDataType.UNKNOWN)),
        ([TelType(TelDataType.UNKNOWN),
          TelType(TelDataType.UNKNOWN)], TelType(TelDataType.UNKNOWN)),
        ([TelType(TelDataType.UNKNOWN),
          TelType(TelDataType.ANY)], TelType(TelDataType.UNKNOWN)),
        ([TelType(TelDataType.UNKNOWN),
          TelType(TelDataType.STRING)], TelType(TelDataType.UNKNOWN)),
        ([TelType(TelDataType.NONE_OPTIONAL)], TelType(TelDataType.ANY)),
        ([
            TelType(TelDataType.NONE_OPTIONAL),
            TelType(TelDataType.NONE_OPTIONAL)
        ], TelType(TelDataType.ANY)),
        ([TelType(TelDataType.NONE_OPTIONAL),
          TelType(TelDataType.ANY)], TelType(TelDataType.ANY)),
        ([TelType(TelDataType.NONE_OPTIONAL),