コード例 #1
0
def prop_filter_json_extract(
        prop: Property,
        idx: int,
        prepend: str = "",
        prop_var: str = "properties") -> Tuple[str, Dict[str, Any]]:
    operator = prop.operator
    if operator == "is_not":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND NOT (trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s)) = %(v{prepend}_{idx})s)"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "icontains":
        value = "%{}%".format(prop.value)
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): value
        }
        return (
            "AND trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s)) LIKE %(v{prepend}_{idx})s"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "not_icontains":
        value = "%{}%".format(prop.value)
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): value
        }
        return (
            "AND NOT (trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s)) LIKE %(v{prepend}_{idx})s)"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "regex":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND match(trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s)), %(v{prepend}_{idx})s)"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "not_regex":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND NOT match(trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s)), %(v{prepend}_{idx})s)"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "is_set":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND JSONHas({prop_var}, %(k{prepend}_{idx})s)".format(
                idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "is_not_set":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND (isNull(trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s))) OR NOT JSONHas({prop_var}, %(k{prepend}_{idx})s))"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "gt":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND toInt64OrNull(replaceRegexpAll(visitParamExtractRaw({prop_var}, %(k{prepend}_{idx})s), ' ', '')) > %(v{prepend}_{idx})s"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "lt":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND toInt64OrNull(replaceRegexpAll(visitParamExtractRaw({prop_var}, %(k{prepend}_{idx})s), ' ', '')) < %(v{prepend}_{idx})s"
            .format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    else:
        if is_int(prop.value):
            clause = "AND JSONExtractInt({prop_var}, %(k{prepend}_{idx})s) = %(v{prepend}_{idx})s"
        elif is_json(prop.value):
            clause = "AND replaceRegexpAll(visitParamExtractRaw({prop_var}, %(k{prepend}_{idx})s),' ', '') = replaceRegexpAll(toString(%(v{prepend}_{idx})s),' ', '')"
        else:
            clause = "AND trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s)) = %(v{prepend}_{idx})s"

        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            clause.format(idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
コード例 #2
0
def prop_filter_json_extract(
        prop: Property,
        idx: int,
        prepend: str = "",
        prop_var: str = "properties",
        allow_denormalized_props: bool = False) -> Tuple[str, Dict[str, Any]]:
    # Once all queries are migrated over we can get rid of allow_denormalized_props
    is_denormalized = prop.key.lower(
    ) in settings.CLICKHOUSE_DENORMALIZED_PROPERTIES and allow_denormalized_props
    json_extract = "trim(BOTH '\"' FROM JSONExtractRaw({prop_var}, %(k{prepend}_{idx})s))".format(
        idx=idx, prepend=prepend, prop_var=prop_var)
    denormalized = "properties_{}".format(prop.key.lower())
    operator = prop.operator
    if operator == "is_not":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND NOT ({left} = %(v{prepend}_{idx})s)".format(
                idx=idx,
                prepend=prepend,
                left=denormalized if is_denormalized else json_extract),
            params,
        )
    elif operator == "icontains":
        value = "%{}%".format(prop.value)
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): value
        }
        return (
            "AND {left} LIKE %(v{prepend}_{idx})s".format(
                idx=idx,
                prepend=prepend,
                left=denormalized if is_denormalized else json_extract),
            params,
        )
    elif operator == "not_icontains":
        value = "%{}%".format(prop.value)
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): value
        }
        return (
            "AND NOT ({left} LIKE %(v{prepend}_{idx})s)".format(
                idx=idx,
                prepend=prepend,
                left=denormalized if is_denormalized else json_extract),
            params,
        )
    elif operator == "regex":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND match({left}, %(v{prepend}_{idx})s)".format(
                idx=idx,
                prepend=prepend,
                left=denormalized if is_denormalized else json_extract),
            params,
        )
    elif operator == "not_regex":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND NOT match({left}, %(v{prepend}_{idx})s)".format(
                idx=idx,
                prepend=prepend,
                left=denormalized if is_denormalized else json_extract),
            params,
        )
    elif operator == "is_set":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        if is_denormalized:
            return (
                "AND NOT isNull({left})".format(left=denormalized),
                params,
            )
        return (
            "AND JSONHas({prop_var}, %(k{prepend}_{idx})s)".format(
                idx=idx, prepend=prepend, prop_var=prop_var),
            params,
        )
    elif operator == "is_not_set":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        if is_denormalized:
            return (
                "AND isNull({left})".format(left=denormalized),
                params,
            )
        return (
            "AND (isNull({left}) OR NOT JSONHas({prop_var}, %(k{prepend}_{idx})s))"
            .format(idx=idx,
                    prepend=prepend,
                    prop_var=prop_var,
                    left=json_extract),
            params,
        )
    elif operator == "gt":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND toInt64OrNull(replaceRegexpAll({left}, ' ', '')) > %(v{prepend}_{idx})s"
            .format(
                idx=idx,
                prepend=prepend,
                left=denormalized if is_denormalized else
                "visitParamExtractRaw({prop_var}, %(k{prepend}_{idx})s)".
                format(
                    idx=idx,
                    prepend=prepend,
                    prop_var=prop_var,
                ),
            ),
            params,
        )
    elif operator == "lt":
        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            "AND toInt64OrNull(replaceRegexpAll({left}, ' ', '')) < %(v{prepend}_{idx})s"
            .format(
                idx=idx,
                prepend=prepend,
                left=denormalized if is_denormalized else
                "visitParamExtractRaw({prop_var}, %(k{prepend}_{idx})s)".
                format(
                    idx=idx,
                    prepend=prepend,
                    prop_var=prop_var,
                ),
            ),
            params,
        )
    else:
        if is_int(prop.value) and not is_denormalized:
            clause = "AND JSONExtractInt({prop_var}, %(k{prepend}_{idx})s) = %(v{prepend}_{idx})s"
        elif is_int(prop.value) and is_denormalized:
            clause = "AND toInt64OrNull({left}) = %(v{prepend}_{idx})s"
        elif is_json(prop.value) and not is_denormalized:
            clause = "AND replaceRegexpAll(visitParamExtractRaw({prop_var}, %(k{prepend}_{idx})s),' ', '') = replaceRegexpAll(toString(%(v{prepend}_{idx})s),' ', '')"
        else:
            clause = "AND {left} = %(v{prepend}_{idx})s"

        params = {
            "k{}_{}".format(prepend, idx): prop.key,
            "v{}_{}".format(prepend, idx): prop.value
        }
        return (
            clause.format(
                left=denormalized if is_denormalized else json_extract,
                idx=idx,
                prepend=prepend,
                prop_var=prop_var),
            params,
        )