예제 #1
0
    def convertvalref(self, valueref):
        """Convert a Datalog value reference (a literal or a variable) to RA.
        Literals are passed through unchanged.  Variables are converted"""
        if self.match(valueref):
            pos = self.position(valueref)
            LOG.debug("convertvalref(match) self(%s), valueref(%s), pos(%s)", self, valueref, pos)  # noqa

            return expression.UnnamedAttributeRef(pos)
        else:
            # must be a join condition, and the other variable matches
            LOG.debug("convertvalref(not) self(%s), valueref(%s)", self, valueref)  # noqa
            return valueref
예제 #2
0
    def implicitconditions(self):
        """An iterator over implicit selection conditions derived from the
        datalog syntax. For example, A(X,X) implies position0 == position1,
        and A(X,4) implies position1 == 4"""
        # Check for implicit literal equality conditions, like A(X,"foo")
        for i, b in enumerate(self.valuerefs):
            if isinstance(b, expression.Literal):
                posref = expression.UnnamedAttributeRef(i)
                yield expression.EQ(posref, b)

        # Check for repeated variable conditions, like A(X,X)
        N = len(self.valuerefs)
        for i, x in enumerate(self.valuerefs):
            if isinstance(x, Var):
                for j in range(i + 1, N):
                    y = self.valuerefs[j]
                    if isinstance(y, Var):
                        # TODO: probably want to implement __eq__, but it makes
                        # Var objects unhashable
                        if x.var == y.var:
                            leftpos = expression.UnnamedAttributeRef(i)
                            rightpos = expression.UnnamedAttributeRef(j)
                            yield expression.EQ(leftpos, rightpos)
예제 #3
0
    def renameIDB(self, plan):
        """Rename the attributes of the plan to match the current rule. Used
        when chaining multiple rules."""
        term = self

        # Do we know the actual scheme? If it's recursive, we don't
        # So derive it from the rule head
        # Not really satisfied with this.
        try:
            sch = plan.scheme()
        except algebra.RecursionError:
            sch = Scheme([make_attr(i, r, term.name)
                          for i, r in enumerate(term.valuerefs)])

        oldscheme = [name for (name, _) in sch]
        termscheme = [expr for expr in term.valuerefs]

        if len(oldscheme) != len(termscheme):
            raise TypeError("Rule with head %s does not match Term %s" % (term.name, term))  # noqa

        pairs = zip(termscheme, oldscheme)

        # Merge the old and new schemes.  Use new where we can.
        def choosename(new, old):
            if isinstance(new, Var):
                # Then use this new var as the column name
                return new.var
            else:
                # It's an implicit selection condition, like R(x,3). In R's
                # schema, don't call the column name '3' (new), instead call it
                # whatever the column name was in the prior rule where R is the
                # head variable R (old).
                return old

        mappings = [(choosename(new, old), expression.UnnamedAttributeRef(i))
                    for i, (new, old) in enumerate(pairs)]

        # Use an apply operator to implement the renaming
        plan = algebra.Apply(mappings, plan)

        return plan
예제 #4
0
    def rewrite_node(sexpr):
        # Push unboxing into the state variables of distributed aggregates
        if isinstance(sexpr, expression.AggregateExpression):
            if sexpr.is_decomposable():
                ds = sexpr.get_decomposable_state()
                lsms = rewrite_statemods(ds.get_local_statemods(), from_args,
                                         base_offsets)  # noqa
                rsms = rewrite_statemods(ds.get_remote_statemods(), from_args,
                                         base_offsets)  # noqa

                if lsms or rsms:
                    sexpr.set_decomposable_state(
                        expression.DecomposableAggregateState(
                            ds.get_local_emitters(), lsms,
                            ds.get_remote_emitters(), rsms,
                            ds.get_finalizer()))
                return sexpr

        if not isinstance(sexpr, expression.DottedRef):
            return sexpr
        elif sexpr.table_alias not in from_args:
            raise NoSuchRelationException(sexpr.table_alias)
        else:
            op = from_args[sexpr.table_alias]
            scheme = op.scheme()

            debug_info = None
            if not sexpr.field:
                offset = 0
            elif isinstance(sexpr.field, int):
                if sexpr.field >= len(scheme):
                    raise ColumnIndexOutOfBounds(str(sexpr))
                offset = sexpr.field
            else:
                assert isinstance(sexpr.field, basestring)
                offset = scheme.getPosition(sexpr.field)
                debug_info = sexpr.field

            offset += base_offsets[sexpr.table_alias]
            return expression.UnnamedAttributeRef(offset, debug_info)
예제 #5
0
 def ascolumnlist(self):
     """Return a columnlist structure suitable for use with Project and
     ProjectingJoin. Currently a list of positional attribute references.
     May eventually be a scheme itself."""
     return [expression.UnnamedAttributeRef(i) for i in xrange(len(self))]
예제 #6
0
 def p_sexpr_index(p):
     'sexpr : DOLLAR INTEGER_LITERAL'
     p[0] = sexpr.UnnamedAttributeRef(p[2])
예제 #7
0
 def findvar(variable):
     var = variable.var
     if var not in scheme:
         msg = "Head variable %s does not appear in rule body: %s" % (var, self)  # noqa
         raise SyntaxError(msg)
     return expression.UnnamedAttributeRef(scheme.getPosition(var))