示例#1
0
 def get_pattern(self):
     if self.pattern is None:
         self.pattern = astmatch.Or(
             astmatch.group('value', pgastmatch.Constant()),
             pgastmatch.TypeCast(
                 arg=astmatch.group('value', pgastmatch.Constant())))
     return self.pattern
示例#2
0
    def get_pattern(self) -> astmatch.MatchASTNode:
        if self.pattern is None:
            # Basic std::_is_exclusive(blah) expression
            pure_distinct_expr = irastmatch.FunctionCall(
                func_shortname=sn.QualName('std', '_is_exclusive'),
                args=[
                    irastmatch.CallArg(
                        expr=astmatch.group('expr', irastmatch.Base())
                    ),
                ],
            )

            possibly_wrapped_distinct_expr = irastmatch.SelectStmt(
                result=pure_distinct_expr
            )

            distinct_expr = astmatch.Or(
                pure_distinct_expr, possibly_wrapped_distinct_expr
            )

            # A logical conjunction of unique constraint expressions
            binop = irastmatch.OperatorCall(
                func_shortname=sn.QualName('std', 'AND'),
            )

            # Set expression with the above binop
            set_expr = irastmatch.Set(
                expr=astmatch.Or(
                    distinct_expr, binop
                )
            )

            # A unique constraint expression can be either one of the
            # three above
            constr_expr = astmatch.Or(
                distinct_expr, binop, set_expr
            )

            # Populate expression alternatives to complete recursive
            # pattern definition.
            binop.args = [irastmatch.CallArg(expr=constr_expr),
                          irastmatch.CallArg(expr=constr_expr)]

            self.pattern = constr_expr

        return self.pattern
示例#3
0
    def get_pattern(self):
        if self.pattern is None:
            tscol = astmatch.group(
                'column',
                pgastmatch.FuncCall(
                    name='setweight',
                    args=[
                        pgastmatch.FuncCall(
                            name='to_tsvector',
                            args=[
                                astmatch.group('language',
                                               pgastmatch.Constant()),
                                astmatch.Or(
                                    pgastmatch.FuncCall(
                                        name='coalesce',
                                        args=[
                                            astmatch.Or(
                                                astmatch.group(
                                                    'column_name',
                                                    pgastmatch.ColumnRef()),
                                                pgastmatch.
                                                TypeCast(arg=astmatch.group(
                                                    'column_name',
                                                    pgastmatch.ColumnRef()))),
                                            pgastmatch.Constant()
                                        ]),
                                    pgastmatch.TypeCast(
                                        arg=pgastmatch.FuncCall(
                                            name='coalesce',
                                            args=[
                                                astmatch.group(
                                                    'column_name',
                                                    pgastmatch.ColumnRef()),
                                                pgastmatch.Constant()
                                            ])))
                            ]),
                        astmatch.group('weight', pgastmatch.Constant())
                    ]))

            binop1 = pgastmatch.Expr(name='||', larg=tscol, rarg=tscol)

            binop1.left = astmatch.Or(tscol, binop1)

            self.pattern = astmatch.Or(tscol, binop1)

        return self.pattern
示例#4
0
class ASTMatchTests(unittest.TestCase):
    tree1 = tast.BinOp(left=tast.BinOp(
        left=tast.FunctionCall(name='test',
                               args=[
                                   tast.BinOp(left=tast.Constant(value=1),
                                              op='+',
                                              right=tast.Constant(value=2)),
                                   tast.Constant(value='test'),
                               ]),
        op='*',
        right=tast.BinOp(left=tast.Constant(value=1),
                         op='-',
                         right=tast.FunctionCall(name='test1'))),
                       op='-',
                       right=tast.Constant(value='value'))

    pat1 = tastmatch.BinOp(left=tastmatch.BinOp(
        left=tastmatch.FunctionCall(name='test',
                                    args=[
                                        tastmatch.BinOp(
                                            left=tastmatch.Constant(value=1),
                                            op='+',
                                            right=tastmatch.Constant(value=2)),
                                        tastmatch.Constant(value='test')
                                    ]),
        op='*',
        right=tastmatch.BinOp(left=tastmatch.Constant(value=1),
                              op='-',
                              right=tastmatch.FunctionCall(name='test1'))),
                           op='-',
                           right=tastmatch.Constant(value='value'))

    pat2 = tastmatch.Constant(value='test')

    pat3 = tastmatch.BinOp(left=tastmatch.BinOp(
        left=tastmatch.FunctionCall(
            name='test',
            args=[
                tastmatch.BinOp(left=match.group('important_constant',
                                                 tastmatch.Constant()),
                                op='+',
                                right=tastmatch.Constant()),
                tastmatch.Constant()
            ]),
        op='*',
        right=tastmatch.BinOp(left=tastmatch.Constant(),
                              op='-',
                              right=tastmatch.FunctionCall())),
                           op='-',
                           right=match.group('important_constant2',
                                             tastmatch.Constant()))

    binop = tastmatch.BinOp(op='+',
                            right=match.group('recursive',
                                              tastmatch.Constant()))

    binop.left = match.Or(binop, tastmatch.Constant())

    pat4 = match.Or(match.group('recursive', tastmatch.Constant()), binop)

    tree2 = tast.BinOp(
        left=tast.BinOp(
            left=tast.BinOp(
                left=tast.BinOp(
                    left=tast.Constant(value=1),
                    op='+',
                    right=tast.Constant(value=2),
                ),
                op='+',
                right=tast.Constant(value=3),
            ),
            op='+',
            right=tast.Constant(value=4),
        ),
        op='+',
        right=tast.Constant(value=5),
    )

    tree3 = tast.BinOp(
        left=tast.BinOp(
            left=tast.Constant(value=1),
            op='+',
            right=tast.Constant(value=2),
        ),
        op='-',
        right=tast.Constant(value=3),
    )

    tree4 = tast.Constant(value='one and only')

    def test_common_ast_match(self):
        assert match.match(self.pat1, self.tree1)
        assert not match.match(self.pat2, self.tree1)

        result = match.match(self.pat3, self.tree1)
        assert result.important_constant[0].node.value == 1
        assert result.important_constant2[0].node.value == 'value'

        result = match.match(self.pat4, self.tree2)
        assert sorted([c.node.value for c in result.recursive]) == [2, 3, 4, 5]

        # tree3 won't match because pat4 wants '+' op everywhere
        assert not match.match(self.pat4, self.tree3)

        # but the single constant matches just fine
        result = match.match(self.pat4, self.tree4)
        assert result and result.recursive[0].node.value == 'one and only'
示例#5
0
 def get_pattern(self):
     if self.pattern is None:
         self.pattern = pgastmatch.TypeCast(
             type_name=astmatch.group('value', pgastmatch.TypeName()))
     return self.pattern