コード例 #1
0
def condition_pattern(
    operators: Set[str],
    lhs_pattern: Pattern[Expression],
    rhs_pattern: Pattern[Expression],
    commutative: bool,
) -> Pattern[Expression]:
    """
    Matches a binary condition given the two operands and the valid
    operators. It also supports commutative conditions.
    """
    pattern: Pattern[Expression]
    if commutative:
        pattern = Or(
            [
                FunctionCallPattern(
                    Or([String(op) for op in operators]), (lhs_pattern, rhs_pattern)
                ),
                FunctionCallPattern(
                    Or([String(op) for op in operators]), (rhs_pattern, lhs_pattern)
                ),
            ]
        )
    else:
        pattern = FunctionCallPattern(
            Or([String(op) for op in operators]), (lhs_pattern, rhs_pattern)
        )
    return pattern
コード例 #2
0
ファイル: conditions.py プロジェクト: fpacifici/snuba
def __set_condition_pattern(lhs: Pattern[Expression],
                            operator: str) -> FunctionCallPattern:
    return FunctionCallPattern(
        String(operator),
        (
            Param("lhs", lhs),
            Param("tuple", FunctionCallPattern(String("tuple"), None)),
        ),
    )
コード例 #3
0
def build_match(
    col: str,
    ops: Sequence[str],
    param_type: Any,
    alias: Optional[str] = None,
    key: Optional[str] = None,
) -> Or[Expression]:
    # The IN condition has to be checked separately since each parameter
    # has to be checked individually.
    alias_match = AnyOptionalString() if alias is None else String(alias)
    pattern: Union[ColumnPattern, SubscriptableReferencePattern]
    if key is not None:
        pattern = SubscriptableReferencePattern(table_name=alias_match,
                                                column_name=String(col),
                                                key=String(key))
    else:
        pattern = ColumnPattern(table_name=alias_match,
                                column_name=String(col))

    column_match = Param("column", pattern)

    return Or([
        FunctionCallPattern(
            Or([String(op) for op in ops]),
            (column_match, Param("rhs", LiteralPattern(
                AnyPattern(param_type)))),
        ),
        FunctionCallPattern(
            String(ConditionFunctions.IN),
            (
                column_match,
                Param(
                    "rhs",
                    FunctionCallPattern(
                        Or([String("array"), String("tuple")]),
                        all_parameters=LiteralPattern(AnyPattern(param_type)),
                    ),
                ),
            ),
        ),
    ])
コード例 #4
0
logger = logging.getLogger(__name__)

EQ_CONDITION_PATTERN = condition_pattern(
    {ConditionFunctions.EQ},
    ColumnPattern(None, Param("lhs", Any(str))),
    LiteralPattern(Any(int)),
    commutative=True,
)

FULL_CONDITION_PATTERN = Or([
    EQ_CONDITION_PATTERN,
    FunctionCallPattern(
        String(ConditionFunctions.IN),
        (
            ColumnPattern(None, Param("lhs", Any(str))),
            FunctionCallPattern(Or([String("tuple"),
                                    String("array")]), None),
        ),
    ),
], )


def _check_expression(pattern: Pattern[Expression], expression: Expression,
                      column_name: str) -> bool:
    match = pattern.match(expression)
    return match is not None and match.optional_string("lhs") == column_name


class ProjectIdEnforcer(ConditionChecker):
    def get_id(self) -> str:
        return "project_id"
コード例 #5
0
ファイル: conditions.py プロジェクト: fpacifici/snuba
def is_not_in_condition(exp: Expression) -> bool:
    return __is_set_condition(exp, ConditionFunctions.NOT_IN)


def is_not_in_condition_pattern(
        lhs: Pattern[Expression]) -> FunctionCallPattern:
    return __set_condition_pattern(lhs, ConditionFunctions.NOT_IN)


def binary_condition(alias: Optional[str], function_name: str, lhs: Expression,
                     rhs: Expression) -> FunctionCall:
    return FunctionCall(alias, function_name, (lhs, rhs))


binary_condition_patterns = {
    op: FunctionCallPattern(String(op), (AnyExpression(), AnyExpression()))
    for op in BINARY_OPERATORS
}


def is_binary_condition(exp: Expression, operator: str) -> bool:
    if operator in binary_condition_patterns:
        return binary_condition_patterns[operator].match(exp) is not None

    return False


def unary_condition(alias: Optional[str], function_name: str,
                    operand: Expression) -> FunctionCall:
    return FunctionCall(alias, function_name, (operand, ))
コード例 #6
0
def is_not_in_condition(exp: Expression) -> bool:
    return __is_set_condition(exp, ConditionFunctions.NOT_IN)


def is_not_in_condition_pattern(
        lhs: Pattern[Expression]) -> FunctionCallPattern:
    return __set_condition_pattern(lhs, ConditionFunctions.NOT_IN)


def binary_condition(function_name: str, lhs: Expression,
                     rhs: Expression) -> FunctionCall:
    return FunctionCall(None, function_name, (lhs, rhs))


binary_condition_patterns = {
    op: FunctionCallPattern(String(op), (AnyExpression(), AnyExpression()))
    for op in BINARY_OPERATORS
}


def condition_pattern(
    operators: Set[str],
    lhs_pattern: Pattern[Expression],
    rhs_pattern: Pattern[Expression],
    commutative: bool,
) -> Pattern[Expression]:
    """
    Matches a binary condition given the two operands and the valid
    operators. It also supports commutative conditions.
    """
    pattern: Pattern[Expression]
コード例 #7
0
    KEY_COL_MAPPING_PARAM,
    KEY_MAPPING_PARAM,
    TABLE_MAPPING_PARAM,
    mapping_pattern,
)
from snuba.query.conditions import ConditionFunctions, condition_pattern
from snuba.query.expressions import Column, Expression, FunctionCall, Literal
from snuba.query.matchers import FunctionCall as FunctionCallPattern
from snuba.query.matchers import Literal as LiteralPattern
from snuba.query.matchers import String
from snuba.request.request_settings import RequestSettings

CONDITION_PATTERN = condition_pattern(
    {ConditionFunctions.EQ, ConditionFunctions.NEQ},
    FunctionCallPattern(
        String("ifNull"), (mapping_pattern, LiteralPattern(String(""))),
    ),
    LiteralPattern(String("")),
    commutative=False,
)


class EmptyTagConditionProcessor(QueryProcessor):
    """
    If queries have conditions of the form `ifNull(tags[key], '') =/!= ''` we can simplify this using
    the `has` function.
    """

    def process_query(self, query: Query, request_settings: RequestSettings) -> None:
        def process_condition(exp: Expression) -> Expression:
            result = CONDITION_PATTERN.match(exp)