Example #1
0
def parse_parameter(parameter_: Parameter):
    if parameter_.kind == "topic":
        topic = get_topic_by_id(parameter_.topicId)
        topic_name = build_collection_name(topic.name)
        factor = get_factor(parameter_.factorId, topic)
        factor_name = factor.name
        return f'{factor_name.upper()}'
    elif parameter_.kind == 'constant':
        return parameter_.value
    elif parameter_.kind == 'computed':
        if parameter_.type == Operator.add:
            result = None
            for item in parameter_.parameters:
                if result:
                    next_ = parse_parameter(item)
                    result = f'{result}+{next_}'
                else:
                    result = parse_parameter(item)
            return result
        elif parameter_.type == Operator.subtract:
            result = None
            for item in parameter_.parameters:
                if result:
                    next_ = parse_parameter(item)
                    result = f'{result}-{next_}'
                else:
                    result = parse_parameter(item)
            return result
        elif parameter_.type == Operator.multiply:
            result = None
            for item in parameter_.parameters:
                if result:
                    next_ = parse_parameter(item)
                    result = f'{result}*{next_}'
                else:
                    result = parse_parameter(item)
            return result
        elif parameter_.type == Operator.divide:
            result = None
            for item in parameter_.parameters:
                if result:
                    next_ = parse_parameter(item)
                    result = f'{result}/{next_}'
                else:
                    result = parse_parameter(item)
            return result
        elif parameter_.type == Operator.modulus:
            result = None
            for item in parameter_.parameters:
                if result:
                    next_ = parse_parameter(item)
                    result = f'{result}%{next_}'
                else:
                    result = parse_parameter(item)
            return result
        elif parameter_.type == "case-then":
            return parse_oracle_case_then(parameter_.parameters)
        else:
            raise Exception("operator is not supported")
Example #2
0
    def read_factor():
        # begin time
        start = time.time()

        # create action status monitor
        status = ActionStatus()
        status.type = "read-factor"
        status.uid = action_context.unitContext.stageContext.pipelineContext.pipeline.pipelineId

        previous_data = action_context.previousOfTriggerData
        current_data = action_context.currentOfTriggerData
        action = action_context.action

        pipeline_topic = action_context.unitContext.stageContext.pipelineContext.pipelineTopic
        target_topic = get_topic_by_id(action.topicId)
        variables = get_variables(action_context)

        where_ = parse_parameter_joint(action.by, current_data, variables, pipeline_topic, target_topic)
        status.by = where_

        target_factor = get_factor(action.factorId, target_topic)

        if action.arithmetic == "none" or action.arithmetic is None:
            target_data = query_topic_data(where_, target_topic, action_context.get_current_user())
            if target_data is not None:
                if isinstance(target_data, list):
                    raise ValueError("read factor action should just get one factor record")
                else:
                    read_value = target_data[target_factor.name]
                    set_variable(action_context, action.variableName, read_value)
                    status.value = read_value
            else:
                raise ValueError("read factor action must match one factor record")
        else:
            read_value = None
            if action.arithmetic == "sum":
                read_value = query_topic_data_aggregate(where_,
                                                        {target_factor.name: "sum"},
                                                        target_topic, action_context.get_current_user())
            elif action.arithmetic == "count":
                read_value = query_topic_data_aggregate(where_,
                                                        {target_factor.name: "count"},
                                                        target_topic, action_context.get_current_user())
            elif action.arithmetic == "avg":
                read_value = query_topic_data_aggregate(where_,
                                                        {target_factor.name: "avg"},
                                                        target_topic,
                                                        action_context.get_current_user())
            if read_value is not None:
                set_variable(action_context, action.variableName, read_value)
            else:
                raise ValueError("read factor action must match one factor record at least")

            status.value = read_value

        elapsed_time = time.time() - start
        status.completeTime = elapsed_time
        return status, []
def __get_factor_name_by_alias(column_name_list, console_subject):
    factor_name_list = []
    for column_name in column_name_list:
        column = __find_column_by_alias(column_name,
                                        console_subject.dataset.columns)
        factor = get_factor(column.parameter.factorId,
                            get_topic_by_id(column.parameter.topicId))
        factor_name_list.append(factor.name)
    return factor_name_list
def _parse_parameter(parameter_: Parameter):
    if parameter_.kind == "topic":
        topic = get_topic_by_id(parameter_.topicId)
        # topic_name = build_collection_name(topic.name)
        factor = get_factor(parameter_.factorId, topic)
        return f'${factor.name}'
    elif parameter_.kind == 'constant':
        return parameter_.value
    elif parameter_.kind == 'computed':
        if parameter_.type == Operator.add:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = {"$add": [result, _parse_parameter(item)]}
                else:
                    result = _parse_parameter(item)
            return result
        elif parameter_.type == Operator.subtract:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = {"$subtract": [result, _parse_parameter(item)]}
                else:
                    result = _parse_parameter(item)
            return result
        elif parameter_.type == Operator.multiply:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = {"$multiply": [result, _parse_parameter(item)]}
                else:
                    result = _parse_parameter(item)
            return result
        elif parameter_.type == Operator.divide:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = {"$divide": [result, _parse_parameter(item)]}
                else:
                    result = _parse_parameter(item)
            return result
        elif parameter_.type == Operator.modulus:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = {"$mod": [result, _parse_parameter(item)]}
                else:
                    result = _parse_parameter(item)
            return result
        elif parameter_.type == "case-then":
            return parse_mongo_case_then(parameter_.parameters)
        else:
            raise Exception("operator is not supported")
def _join(q: QueryBuilder, join: Join) -> QueryBuilder:
    # left
    topic = get_topic_by_id(join.topicId)
    topic_col_name = build_collection_name(topic.name)
    factor = get_factor(join.factorId, topic)
    left_table = Table(topic_col_name).as_(topic.name)

    # right
    sec_topic = get_topic_by_id(join.secondaryTopicId)
    sec_topic_col_name = build_collection_name(sec_topic.name)
    sec_factor = get_factor(join.secondaryFactorId, sec_topic)
    right_table = Table(sec_topic_col_name).as_(sec_topic.name)

    if join.type == JoinType.inner:
        return q.join(right_table, JoinType.inner).on(
            operator.eq(left_table[factor.name], right_table[sec_factor.name]))

    if join.type == JoinType.left:
        return q.join(right_table, JoinType.left).on(
            operator.eq(left_table[factor.name], right_table[sec_factor.name]))

    if join.type == JoinType.right:
        return q.join(right_table, JoinType.right).on(
            operator.eq(left_table[factor.name], right_table[sec_factor.name]))
 def topic_handler_in_dataset(
         self) -> Tuple[Union[Field, CustomFunction], ParameterValueType]:
     param = self.param
     topic_id = param.topicId
     factor_id = param.factorId
     topic = get_topic_by_id(topic_id)
     table = None
     if self.topic_space_filter:
         if self.topic_space_filter(param.topicId):
             alias_ = self.topic_space_filter(param.topicId)["alias"]
             table = AliasedQuery(alias_)
     if table is None:
         table = build_table_by_topic_id(topic_id)
     factor = get_factor(factor_id, topic)
     result = Field(factor.name, None, table)
     value_type = factor.type
     return result, value_type
def parse_parameter(parameter: Parameter, factor=None):
    if parameter.kind == "topic":
        topic = get_topic_by_id(parameter.topicId)
        topic_col_name = build_collection_name(topic.name)
        factor = get_factor(parameter.factorId, topic)
        result = {
            'type': factor.type,
            'value': Table(topic_col_name).as_(topic.name)[factor.name]
        }
        return result
    elif parameter.kind == 'constant':
        if parameter.value.strip().startswith("{&monthDiff"):
            value_ = parameter.value.strip()
            args_str = value_.replace("{&monthDiff(", "").replace(")}", "")
            expr = _date_diff("month", args_str)
            result = {"type": "number", "value": expr}
            return result
        elif parameter.value.strip().startswith("{&dayDiff"):
            value_ = parameter.value.strip()
            args_str = value_.replace("{&dayDiff(", "").replace(")}", "")
            expr = _date_diff("day", args_str)
            result = {"type": "number", "value": expr}
            return result
        elif parameter.value.strip().startswith("{&yearDiff"):
            value_ = parameter.value.strip()
            args_str = value_.replace("{&yearDiff(", "").replace(")}", "")
            expr = _date_diff("year", args_str)
            result = {"type": "number", "value": expr}
            return result
        else:
            result = {'type': "text", 'value': parameter.value}
            return result
    elif parameter.kind == 'computed':
        result = None
        left = None
        for item in parameter.parameters:
            if left:
                right = parse_parameter(item)
                return _arithmetic_process(parameter.type, left, right)
            else:
                left = parse_parameter(item)
        return result
def __process_read_actions(action: UnitAction, pipeline, temporary_context_dict, current_user):
    if action.type == pipeline_constants.COPY_TO_MEMORY:
        topic = get_topic_by_id(action.source.topicId, current_user)
        factor = get_factor(action.source.factorId, topic)
        temporary_context_dict[action.variableName] = {"topic": topic, "factor": factor}
Example #9
0
def parse_parameter(parameter_: Parameter, current_data, variables,
                    pipeline_topic: Topic, target_topic: Topic):
    """
    the case-then can only be used in one side in expression
    """
    if parameter_.kind == "topic":
        if parameter_.topicId == pipeline_topic.topicId:
            factor = get_factor(parameter_.factorId, pipeline_topic)
            return {
                "value":
                check_and_convert_value_by_factor(
                    factor, cal_factor_value(current_data, factor)),
                "position":
                "right"
            }
        elif parameter_.topicId == target_topic.topicId:
            factor = get_factor(parameter_.factorId, target_topic)
            factor_name = factor.name
            return {"value": factor_name, "factor": factor, "position": "left"}
    elif parameter_.kind == 'constant':
        if parameter_.value is None:
            return {"value": None, "position": "right"}
        elif parameter_.value == '':
            return {"value": None, "position": "right"}
        elif not parameter_.value:
            return {"value": None, "position": "right"}
        elif parameter_.value.startswith("{"):
            constant_variable = parameter_.value.replace("{",
                                                         "").replace("}", "")
            if ".&" in constant_variable:
                return {
                    "value":
                    get_variable_with_func_pattern(constant_variable,
                                                   variables),
                    "position":
                    "right"
                }
            elif "." in constant_variable:
                return {
                    "value":
                    get_variable_with_dot_pattern(constant_variable,
                                                  variables),
                    "position":
                    "right"
                }
            else:
                if constant_variable in variables and variables[
                        constant_variable] is not None:
                    return {
                        "value": variables[constant_variable],
                        "position": "right"
                    }
                else:
                    return {"value": None, "position": "right"}
        elif "," in parameter_.value:
            value_ = parameter_.value.split(",")
            new_value_ = []
            for v in value_:
                if v.isdigit():
                    new_value_.append(int(v))
                else:
                    new_value_.append(v)
            return {"value": new_value_, "position": "right"}
        else:
            return {"value": parameter_.value, "position": "right"}
    elif parameter_.kind == 'computed':
        if parameter_.type == Operator.add:
            result = None
            for item in parameter_.parameters:
                if item.kind == "topic" and item.topicId != pipeline_topic.topicId:
                    raise Exception(
                        "only pipeline topic factor can be used in add operator"
                    )
                if result:
                    next_ = parse_parameter(item, current_data, variables,
                                            pipeline_topic, target_topic)
                    result = {
                        "value": result["value"] + next_["value"],
                        "position": "right"
                    }
                else:
                    result = parse_parameter(item, current_data, variables,
                                             pipeline_topic, target_topic)
            return result
        elif parameter_.type == Operator.subtract:
            result = None
            for item in parameter_.parameters:
                if item.kind == "topic" and item.topicId != pipeline_topic.topicId:
                    raise Exception(
                        "only pipeline topic factor can be used in subtract operator"
                    )
                if result:
                    next_ = parse_parameter(item, current_data, variables,
                                            pipeline_topic, target_topic)
                    result = {
                        "value": result["value"] - next_["value"],
                        "position": "right"
                    }
                else:
                    result = parse_parameter(item, current_data, variables,
                                             pipeline_topic, target_topic)
            return result
        elif parameter_.type == Operator.multiply:
            result = None
            for item in parameter_.parameters:
                if item.kind == "topic" and item.topicId != pipeline_topic.topicId:
                    raise Exception(
                        "only pipeline topic factor can be used in multiply operator"
                    )
                if result:
                    next_ = parse_parameter(item, current_data, variables,
                                            pipeline_topic, target_topic)
                    result = {
                        "value": result["value"] * next_["value"],
                        "position": "right"
                    }
                else:
                    result = parse_parameter(item, current_data, variables,
                                             pipeline_topic, target_topic)
            return result
        elif parameter_.type == Operator.divide:
            result = None
            for item in parameter_.parameters:
                if item.kind == "topic" and item.topicId != pipeline_topic.topicId:
                    raise Exception(
                        "only pipeline topic factor can be used in divide operator"
                    )
                if result:
                    next_ = parse_parameter(item, current_data, variables,
                                            pipeline_topic, target_topic)
                    result = {
                        "value": result["value"] / next_["value"],
                        "position": "right"
                    }
                else:
                    result = parse_parameter(item, current_data, variables,
                                             pipeline_topic, target_topic)
            return result
        elif parameter_.type == Operator.modulus:
            result = None
            for item in parameter_.parameters:
                if item.kind == "topic" and item.topicId != pipeline_topic.topicId:
                    raise Exception(
                        "only pipeline topic factor can be used in modulus operator"
                    )
                if result:
                    next_ = parse_parameter(item, current_data, variables,
                                            pipeline_topic, target_topic)
                    result = {
                        "value": result["value"] % next_["value"],
                        "position": "right"
                    }
                else:
                    result = parse_parameter(item, current_data, variables,
                                             pipeline_topic, target_topic)
            return result
        elif parameter_.type == "year-of":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            return {
                "value": parsing_and_formatting(convert_datetime(value_),
                                                YEAR),
                "position": "right"
            }
        elif parameter_.type == "month-of":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            month_ = parsing_and_formatting(convert_datetime(value_), MONTH)
            return {"value": month_, "position": "right"}
        elif parameter_.type == "week-of-year":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            week_of_year_ = parsing_and_formatting(convert_datetime(value_),
                                                   WEEK_OF_YEAR)
            return {"value": week_of_year_, "position": "right"}
        elif parameter_.type == "day-of-week":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            day_of_week_ = parsing_and_formatting(convert_datetime(value_),
                                                  DAY_OF_WEEK)
            return {"value": day_of_week_, "position": "right"}
        elif parameter_.type == "week-of-month":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            week_of_month_ = parsing_and_formatting(convert_datetime(value_),
                                                    WEEK_OF_MONTH)
            return {"value": week_of_month_, "position": "right"}
        elif parameter_.type == "quarter-of":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            quarter = parsing_and_formatting(convert_datetime(value_), QUARTER)
            return {"value": quarter, "position": "right"}
        elif parameter_.type == "half-year-of":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            half_year_ = parsing_and_formatting(convert_datetime(value_),
                                                HALF_YEAR)
            return {"value": half_year_, "position": "right"}
        elif parameter_.type == "day-of-month":
            result = parse_parameter(parameter_.parameters[0], current_data,
                                     variables, pipeline_topic, target_topic)
            value_ = result["value"]
            return {
                "value":
                parsing_and_formatting(convert_datetime(value_), DAY_OF_MONTH),
                "position":
                "right"
            }
        elif parameter_.type == "case-then":
            parameters_ = parameter_.parameters
            when_ = []
            else_ = None
            for param in parameters_:
                if param.on is not None:
                    condition = parse_parameter_joint(param.on, current_data,
                                                      variables,
                                                      pipeline_topic,
                                                      target_topic)
                    value_ = parse_parameter(param, current_data, variables,
                                             pipeline_topic, target_topic)
                    when_.append({"$when": condition, "$then": value_})
                else:
                    else_ = parse_parameter(param, current_data, variables,
                                            pipeline_topic, target_topic)

            return {
                "value": {
                    "$case": {
                        "$clause": when_,
                        "$else": else_
                    }
                },
                "position": "left"
            }
        else:
            raise Exception("operator is not supported")
def build_dataset_query_for_subject(console_subject,
                                    current_user,
                                    for_count=False):
    dataset = console_subject.dataset
    if dataset is None:
        return None

    topic_space_filter = get_topic_sub_query_with_space_filter(
        console_subject, current_user)

    if dataset.joins and len(dataset.joins) > 0:
        topic_id = dataset.joins[0].topicId
        topic_table = topic_space_filter(topic_id)
        if topic_table:
            q = PrestoQuery.with_(topic_table["query"],
                                  topic_table["alias"]).from_(
                                      topic_table["alias"])
        else:
            table = build_table_by_topic_id(topic_id)
            q = PrestoQuery.from_(table)
    else:

        topic_id = dataset.columns[0].parameter.topicId
        topic_table = topic_space_filter(topic_id)
        if topic_table:
            table = AliasedQuery(topic_table["alias"])
            q = PrestoQuery.with_(topic_table["query"],
                                  topic_table["alias"]).from_(table)
        else:
            table = build_table_by_topic_id(topic_id)
            q = PrestoQuery.from_(table)

    for join in dataset.joins:
        right_topic_id = join.secondaryTopicId
        right_topic = get_topic_by_id(right_topic_id)
        right_topic_table = topic_space_filter(right_topic_id)
        if right_topic_table:
            q = q.with_(right_topic_table["query"], right_topic_table["alias"])
            right_table = AliasedQuery(right_topic_table["alias"])
        else:
            right_table = build_table_by_topic_id(right_topic_id)

        left_topic_id = join.topicId
        left_topic = get_topic_by_id(left_topic_id)
        left_topic_table = topic_space_filter(left_topic_id)
        if left_topic_table:
            left_table = AliasedQuery(left_topic_table["alias"])
        else:
            left_table = build_table_by_topic_id(left_topic_id)

        left_factor = get_factor(join.factorId, left_topic)
        left_field = Field(left_factor.name, None, left_table)

        right_factor = get_factor(join.secondaryFactorId, right_topic)
        right_field = Field(right_factor.name, None, right_table)

        if join.type == "inner" or join.type == "":
            join_type = JoinType.inner
        elif join.type == "left":
            join_type = JoinType.left
        elif join.type == "right":
            join_type = JoinType.right
        else:
            join_type = JoinType.inner

        q = q.join(right_table, join_type).on(left_field.eq(right_field))

    q = q.where(build_dataset_where(dataset.filters, topic_space_filter))
    if for_count:
        return q.select(fn.Count("*"))
    else:
        return q.select(
            *build_dataset_select_fields(dataset.columns, topic_space_filter))
    def write_factor():

        start = time.time()
        # create action status monitor
        status = ActionStatus()
        status.type = "write-factor"
        status.uid = action_context.get_pipeline_id()

        previous_data = action_context.previousOfTriggerData
        current_data = action_context.currentOfTriggerData

        action = action_context.action

        if action.topicId is not None:

            pipeline_topic = action_context.get_pipeline_context(
            ).pipelineTopic
            target_topic = get_topic_by_id(action.topicId)
            variables = get_variables(action_context)

            where_ = parse_parameter_joint(action.by, current_data, variables,
                                           pipeline_topic, target_topic)
            status.by = where_

            target_data = query_topic_data(where_, target_topic,
                                           action_context.get_current_user())

            target_factor = get_factor(action.factorId, target_topic)
            source_ = action.source
            arithmetic = action.arithmetic

            result = None
            current_value_ = check_and_convert_value_by_factor(
                target_factor, parse_parameter(source_, current_data,
                                               variables))
            if arithmetic is None or arithmetic == "none":  # mean AS IS
                result = {target_factor.name: current_value_}
            elif arithmetic == "sum":
                previous_value_ = check_and_convert_value_by_factor(
                    target_factor,
                    parse_parameter(source_, previous_data, variables))
                if previous_value_ is None:
                    previous_value_ = 0
                value_ = Decimal(current_value_) - Decimal(previous_value_)
                result = {target_factor.name: {"_sum": value_}}
            elif arithmetic == "count":
                if previous_data is None:
                    result = {target_factor.name: {"_count": 1}}
                else:
                    result = {target_factor.name: {"_count": 0}}
            elif arithmetic == "avg":
                result = {target_factor.name: {"_avg": current_value_}}

            updates_ = result
            trigger_pipeline_data_list = []
            if target_data is not None:
                if target_topic.type == "aggregate":
                    args = [
                        updates_, where_, target_topic,
                        action_context.get_current_user()
                    ]
                    retry_callback = (update_retry_callback, args)
                    recovery_callback = (update_recovery_callback, args)
                    execute_ = retry_template(retry_callback,
                                              recovery_callback, RetryPolicy())
                    result = execute_()
                    trigger_pipeline_data_list.append(result)
                else:
                    trigger_pipeline_data_list.append(
                        update_topic_data_one(
                            updates_, target_data,
                            action_context.get_pipeline_id(),
                            target_data[get_id_name_by_datasource(
                                data_source_container.get_data_source_by_id(
                                    target_topic.dataSourceId))], target_topic,
                            action_context.get_current_user()))
            else:
                raise Exception("can't insert data in write factor action ")

        status.updateCount = status.updateCount + 1
        elapsed_time = time.time() - start
        status.completeTime = elapsed_time
        return status, trigger_pipeline_data_list
def parse_parameter(parameter_: Parameter, instance, variables):
    if parameter_.kind == "topic":
        topic = get_topic_by_id(parameter_.topicId)
        topic_name = build_collection_name(topic.name)
        factor = get_factor(parameter_.factorId, topic)
        return cal_factor_value(instance, factor)
    elif parameter_.kind == 'constant':
        if parameter_.value is None:
            return None
        elif parameter_.value == '':
            return ''
        elif not parameter_.value:
            return None
        else:
            result = []
            it = parse_constant_expression(parameter_.value)
            for item in it:
                if item.startswith('{') and item.endswith('}'):
                    var_name = item.lstrip('{').right('}')
                    if var_name.startswith(AMP):
                        real_name = var_name.lstrip('&')
                        res = instance.get(real_name)
                        result.append(res)
                    elif FUNC in var_name:
                        res = get_variable_with_func_pattern(
                            var_name, variables)
                        result.append(res)
                    elif DOT in var_name:
                        res = get_variable_with_dot_pattern(
                            var_name, variables)
                        result.append(res)
                else:
                    result.append(item)

            return ''.join(result)
    elif parameter_.kind == 'computed':
        if parameter_.type == Operator.add:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = operator.add(
                        result, parse_parameter(item, instance, variables))
                else:
                    result = parse_parameter(item, instance, variables)
            return result
        elif parameter_.type == Operator.subtract:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = operator.sub(
                        result, parse_parameter(item, instance, variables))
                else:
                    result = parse_parameter(item, instance, variables)
            return result
        elif parameter_.type == Operator.multiply:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = operator.mul(
                        result, parse_parameter(item, instance, variables))
                else:
                    result = parse_parameter(item, instance, variables)
            return result
        elif parameter_.type == Operator.divide:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = operator.truediv(
                        result, parse_parameter(item, instance, variables))
                else:
                    result = parse_parameter(item, instance, variables)
            return result
        elif parameter_.type == Operator.modulus:
            result = None
            for item in parameter_.parameters:
                if result:
                    result = operator.mod(
                        result, parse_parameter(item, instance, variables))
                else:
                    result = parse_parameter(item, instance, variables)
            return result
        elif parameter_.type == "case-then":
            return parse_mapper_case_then(parameter_.parameters, instance,
                                          variables)
        else:
            raise Exception("operator is not supported")
def parse_parameter(parameter_: Parameter, instance, variables):
    if parameter_.kind == "topic":
        topic = get_topic_by_id(parameter_.topicId)
        topic_name = build_collection_name(topic.name)
        factor = get_factor(parameter_.factorId, topic)
        value_ = cal_factor_value(instance, factor)
        return check_and_convert_value_by_factor(factor, value_)
    elif parameter_.kind == 'constant':
        if parameter_.value is None:
            return None
        elif parameter_.value == '':
            return ''
        elif not parameter_.value:
            return None
        else:
            it = parse_constant_expression(parameter_.value)
            for item in it:
                if item.startswith('{') and item.endswith('}'):
                    var_name = item.lstrip('{').rstrip('}')
                    res = None
                    if var_name.startswith(AMP):
                        real_name = var_name.lstrip('&')
                        if real_name == "nextSeq":
                            res = get_surrogate_key()
                        else:
                            res = instance.get(real_name)
                    elif var_name == "snowflake":  # use nextSeq, prepare to remove in next version todo
                        res = get_surrogate_key()
                    elif FUNC in var_name:
                        res = get_variable_with_func_pattern(var_name, variables)
                    elif DOT in var_name:
                        res = get_variable_with_dot_pattern(var_name, variables)
                    else:
                        if var_name in variables:
                            res = variables[var_name]
                    return res
            return parameter_.value
    elif parameter_.kind == 'computed':
        if parameter_.type == Operator.add:
            result = None
            left = None
            for item in parameter_.parameters:
                if left is not None:
                    right = parse_parameter(item, instance, variables)
                    if right is None:
                        right = 0
                    elif isinstance(right, str):
                        if right.lstrip('-').isdigit():
                            right = Decimal(right)
                    result = operator.add(left, right)
                else:
                    left = parse_parameter(item, instance, variables)
                    if left is None:
                        left = 0
                    elif isinstance(left, str):
                        if left.lstrip('-').isdigit():
                            left = Decimal(left)
            return result
        elif parameter_.type == Operator.subtract:
            result = None
            left = None
            for item in parameter_.parameters:
                if left is not None:
                    right = parse_parameter(item, instance, variables)
                    if right is None:
                        right = 0
                    elif isinstance(right, str):
                        if right.lstrip('-').isdigit():
                            right = Decimal(right)
                    result = operator.sub(left, right)
                else:
                    left = parse_parameter(item, instance, variables)
                    if left is None:
                        left = 0
                    elif isinstance(left, str):
                        if left.lstrip('-').isdigit():
                            left = Decimal(left)
            return result
        elif parameter_.type == Operator.multiply:
            result = None
            left = None
            for item in parameter_.parameters:
                if left is not None:
                    right = parse_parameter(item, instance, variables)
                    if right is None:
                        right = 0
                    elif isinstance(right, str):
                        if right.lstrip('-').isdigit():
                            right = Decimal(right)
                    result = operator.mul(left, right)
                else:
                    left = parse_parameter(item, instance, variables)
                    if left is None:
                        left = 0
                    elif isinstance(left, str):
                        if left.lstrip('-').isdigit():
                            left = Decimal(left)
            return result
        elif parameter_.type == Operator.divide:
            result = None
            left = None
            for item in parameter_.parameters:
                if left is not None:
                    right = parse_parameter(item, instance, variables)
                    if right is None:
                        right = 0
                    elif isinstance(right, str):
                        if right.lstrip('-').isdigit():
                            right = Decimal(right)
                    result = operator.truediv(left, right)
                else:
                    left = parse_parameter(item, instance, variables)
                    if left is None:
                        left = 0
                    elif isinstance(left, str):
                        if left.lstrip('-').isdigit():
                            left = Decimal(left)
            return result
        elif parameter_.type == Operator.modulus:
            result = None
            left = None
            for item in parameter_.parameters:
                if left is not None:
                    right = parse_parameter(item, instance, variables)
                    if right is None:
                        right = 0
                    elif isinstance(right, str):
                        if right.lstrip('-').isdigit():
                            right = Decimal(right)
                    result = operator.mod(left, right)
                else:
                    left = parse_parameter(item, instance, variables)
                    if left is None:
                        left = 0
                    elif isinstance(left, str):
                        if left.lstrip('-').isdigit():
                            left = Decimal(left)
            return result
        elif parameter_.type == "year-of":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            if result is not None:
                return parsing_and_formatting(convert_datetime(result), YEAR)
            else:
                return result
        elif parameter_.type == "month-of":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            if result is not None:
                return parsing_and_formatting(convert_datetime(result), MONTH)
            else:
                return result
        elif parameter_.type == "week-of-year":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            return parsing_and_formatting(convert_datetime(result), WEEK_OF_YEAR)
        elif parameter_.type == "day-of-week":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            return parsing_and_formatting(convert_datetime(result), DAY_OF_WEEK)
        elif parameter_.type == "week-of-month":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            return parsing_and_formatting(convert_datetime(result), WEEK_OF_MONTH)
        elif parameter_.type == "quarter-of":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            return parsing_and_formatting(convert_datetime(result), QUARTER)
        elif parameter_.type == "half-year-of":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            return parsing_and_formatting(convert_datetime(result), HALF_YEAR)
        elif parameter_.type == "day-of-month":
            result = parse_parameter(parameter_.parameters[0], instance, variables)
            return parsing_and_formatting(convert_datetime(result), DAY_OF_MONTH)
        elif parameter_.type == "case-then":
            return parse_mapper_case_then(parameter_.parameters, instance, variables)
        else:
            raise Exception("operator is not supported")