コード例 #1
0
    def validateSubtree(self, context: StatementContext):
        self.inputs[0].validateSubtree(context)
        self.inputs[1].validateSubtree(context)
        if self.cond is None:
            self.pairs = list()
            for i0, a0 in enumerate(self.inputs[0].type.attrs):
                if a0.name is None:
                    continue
                matches = [(i1, a1) for i1, a1 in enumerate(self.inputs[1].type.attrs)\
                           if a0.name == a1.name]
                if len(matches) > 1:
                    raise self.validationError('ambiguity in natural join: {} from the left input'
                                               ' matches multiple attributes on the right'\
                                               .format(a0.str_ref_only()))

                elif len(matches) == 1:
                    i1, a1 = matches[0]
                    try:
                        context.check.function_call(symbolic(sym.EQ), [a0.type, a1.type])
                    except TypeSysError as e:
                        raise self.validationError('natural join cannot equate {} and {}'\
                                                   .format(a0, a1))
                    self.pairs.append((i0, i1))
            if len(self.pairs) == 0:
                logger.warning('{}: no attributes with matching names found;'
                               ' natural join degnerates into cross product'.format(self))
            for i0, i1 in self.pairs:
                if any((j0, j1) for j0, j1 in self.pairs if j0 != i0 and j1 == i1):
                    raise self.validationError('ambiguity in natural join: {} from the right input'
                                               ' matches multiple attributes on the left'\
                                               .format(self.inputs[1].type.attrs[i1]\
                                                       .str_ref_only()))
            attrspecs = list()
            for a0 in self.inputs[0].type.attrs:
                attrspecs.append(a0)
            for i1, a1 in enumerate(self.inputs[1].type.attrs):
                if not any(i1 == i for _, i in self.pairs):
                    attrspecs.append(a1)
                    if any(a1.can_be_confused_with(a0) for a0 in self.inputs[0].type.attrs):
                        # this shouldn't happen under natural join rule, but oh well:
                        logger.warning('{}: attribute {} becomes confused with others'
                                       ' in the join output'\
                                       .format(self, a1.str_ref_only()))
            self.type = RelType(context.new_tmp(), attrspecs)
        else:
            self.cond.validateSubtree(context, self)
            if self.cond.type != ValType.BOOLEAN:
                raise self.validationError('join condition {} has type {}; boolean expected'\
                                           .format(self.cond, self.cond.type.value))
            for a0, a1 in itertools.product(self.inputs[0].type.attrs, self.inputs[1].type.attrs):
                if a0.can_be_confused_with(a1):
                    logger.warning('{}: attributes {} from the left input and {} from the right'
                                   ' become confused in the join output'\
                                   .format(self, a0.str_ref_only(), a1.str_ref_only()))
            self.type = RelType(context.new_tmp(),
                                self.inputs[0].type.attrs + self.inputs[1].type.attrs)
コード例 #2
0
ファイル: ast.py プロジェクト: rigers2001/radb
 def validateSubtree(self, context: StatementContext):
     self.inputs[0].validateSubtree(context)
     self.cond.validateSubtree(context, self)
     if self.cond.type != ValType.BOOLEAN:
         raise self.validationError('selection condition {} has type {}; boolean expected'\
                                    .format(self.cond, self.cond.type.value))
     self.type = RelType(context.new_tmp(), self.inputs[0].type.attrs)
コード例 #3
0
ファイル: ast.py プロジェクト: rigers2001/radb
 def validateSubtree(self, context: StatementContext):
     self.inputs[0].validateSubtree(context)
     if self.attrnames is not None:
         if len(self.attrnames) != len(self.inputs[0].type.attrs):
             raise self.validationError('renaming {} attribute(s) but the input has {}'\
                                        .format(len(self.attrnames),
                                                len(self.inputs[0].type.attrs)))
         if len(self.attrnames) != len(set(self.attrnames)):
             logger.warning('{}: duplicate attribute names when renaming: {}'\
                            .format(self, ', '.join(self.attrnames)))
     else:
         for a1, a2 in itertools.combinations(self.inputs[0].type.attrs, 2):
             if a1.name == a2.name and not a1.can_be_confused_with(a2):
                 logger.warning('{}: attributes {} and {} become confused after renaming'\
                                .format(self, a1.str_ref_only(), a2.str_ref_only()))
     attrspecs = list()
     if self.attrnames is not None:
         for name, attrspec in zip(self.attrnames,
                                   self.inputs[0].type.attrs):
             attrspecs.append(AttrSpec(self.relname, name, attrspec.type))
     else:
         for attrspec in self.inputs[0].type.attrs:
             attrspecs.append(
                 AttrSpec(self.relname, attrspec.name, attrspec.type))
     self.type = RelType(self.inputs[0].type.tmp,
                         attrspecs)  # don't create a new temp relation
コード例 #4
0
 def validateSubtree(self, context: StatementContext):
     self.inputs[0].validateSubtree(context)
     self.inputs[1].validateSubtree(context)
     for a0, a1 in itertools.product(self.inputs[0].type.attrs, self.inputs[1].type.attrs):
         if a0.can_be_confused_with(a1):
             logger.warning('{}: attributes {} from the left input and {} from the right'
                            ' become confused in the cross product output'\
                            .format(self, a0.str_ref_only(), a1.str_ref_only()))
     self.type = RelType(context.new_tmp(),
                         self.inputs[0].type.attrs + self.inputs[1].type.attrs)
コード例 #5
0
 def validateSubtree(self, context: StatementContext):
     # first check if this is a table in dbms:
     if context.db.table_exists(self.rel):
         attrspecs = [AttrSpec(self.rel, attr, type)\
                      for attr, type in context.db.describe(self.rel)]
         self.type = RelType(context.new_tmp(), attrspecs)
         self.view = None
         return
     # then check if this is a view defined in this session:
     view_def = context.views.raw_def(self.rel)
     if view_def is not None:
         self.view = RelExpr.from_view_def(view_def)
         self.view.validateSubtree(context)
         attrspecs = [AttrSpec(self.rel, attrspec.name, attrspec.type)\
                      for attrspec in self.view.type.attrs]
         self.type = RelType(self.view.type.tmp, attrspecs) # don't create a new temp relation
         return
     # reference is not found:
     raise self.validationError('relation {} does not exist'.format(self.rel))
コード例 #6
0
ファイル: ast.py プロジェクト: rigers2001/radb
 def validateSubtree(self, context: StatementContext):
     self.inputs[0].validateSubtree(context)
     output_attrspecs = list()
     for attr in self.attrs:
         attr.validateSubtree(context, self)
         if isinstance(attr, AttrRef):
             _, aidx = attr.internal_ref
             output_attrspecs.append(self.inputs[0].type.attrs[aidx])
         else:
             output_attrspecs.append(AttrSpec(None, None, attr.type))
     self.type = RelType(context.new_tmp(), output_attrspecs)
コード例 #7
0
 def validateSubtree(self, context: StatementContext):
     self.inputs[0].validateSubtree(context)
     self.inputs[1].validateSubtree(context)
     if len(self.inputs[0].type.attrs) != len(self.inputs[1].type.attrs):
         raise self.validationError('input relations to a set operation'
                                    ' do not have the same number of attributes')
     for i, (a0, a1) in enumerate(zip(self.inputs[0].type.attrs, self.inputs[1].type.attrs)):
         if a0.type != a1.type:
             raise self.validationError('input attributes at position {} have'
                                        ' different types: {} vs. {}'.format(i, a0, a1))
         if a0.name != a1.name:
             logger.warning('{}: input attributes at position {} have'
                            ' different names: {} vs. {}'.format(self, i,
                                                                 a0.str_ref_only(),
                                                                 a1.str_ref_only()))
     self.type = RelType(context.new_tmp(), self.inputs[0].type.attrs)
コード例 #8
0
ファイル: ast.py プロジェクト: pmfischer/radb
 def validateSubtree(self, context: StatementContext):
     self.inputs[0].validateSubtree(context)
     output_attrspecs = list()
     for groupby in self.groupbys:
         groupby.validateSubtree(context, self)
         if isinstance(groupby, AttrRef):
             _, aidx = groupby.internal_ref
             output_attrspecs.append(self.inputs[0].type.attrs[aidx])
         else:
             output_attrspecs.append(AttrSpec(None, None, groupby.type))
     for aggr in self.aggrs:
         aggr.validateSubtree(context, self, allow_aggr=True)
         aggr.checkSubtreeGroupInvariant(self)
         if isinstance(aggr, AttrRef):  # rare, but techincally possible
             _, aidx = groupby.internal_ref
             output_attrspecs.append(self.inputs[0].type.attrs[aidx])
         else:
             output_attrspecs.append(AttrSpec(None, None, aggr.type))
     self.type = RelType(context.new_tmp(), output_attrspecs)