예제 #1
0
class RelationVisitor(QueryVisitor):
    '''
    will record all relation definitions and create them
    '''
    
    def __init__(self, joinBuilder, alu):
        '''
        @param joinBuilder: a visitor that has to be also visiting the AST.
        @type joinBuilder: JoinBuilder
        @param alu: the ALU to be used to operate
        @type alu: ALU
        '''
        super(RelationVisitor, self).__init__()
        self._logic = LogicBuilder(alu)
        self._join  = joinBuilder
        self._expr  = ExpressionEvalBuilder(alu)
        self._alu   = alu
        
        self._log = logging.getLogger(__name__+'.'+self.__class__.__name__)
        
        self._actualRelationName = None
        self._actualSelection    = None
        self._actualProjection   = None
        self._actualSource       = None
        self._actualInputs       = None
        self._active             = False
        self._exprStack          = None  # a stack on which projection are pushed.
        self._logicFound         = False # have we traversed any logic since last reset.
        
        self._relations = dict()
        self._inserts   = list()
        self._log.info('init')
        
    def getRelations(self):
        '''
        returns all relations that have been found while traversing
        '''
        return self._relations
    
    def getInserts(self):
        '''
        returns all inserts that have been seen while traversing.
        '''
        return self._inserts
    
    def enterTableCreation(self, name):
        self._active             = True
        self._actualRelationName = name
        self._actualSelection    = None
        self._actualProjection   = None
        self._actualSource       = None
    
    def leaveTableCreation(self):
        self._active             = False
        if self._actualRelationName is None:
            raise InternalError('rel name is None')
        if self._definedRelation is None:
            raise InternalError('select without a source')
        
        relation = TableOperator()
        self._definedRelation.addListener(relation)
        self._relations[self._actualRelationName] = relation
        for (name, rel) in self._actualInputs:
            relation.addSource(name, rel)
        self._actualRelationName = None
        self._actualInputs = list()

    def enterInsertStmt(self):
        self._active             = True
        self._actualRelationName = None
        
    def leaveInsertStmt(self):
        self._active             = False
        if self._actualRelationName is None:
            raise InternalError('rel name is None')
        if self._definedRelation is None:
            raise InternalError()
        
        relation = TableOperator()
        self._definedRelation.addListener(relation)
        self._inserts.append((self._actualRelationName,relation))
        for (name, rel) in self._actualInputs:
            relation.addSource(name, rel)
        self._actualRelationName = None
        self._actualInputs = list()

    def setTargetRelation(self, name):
        if not self._active: return
        self._actualRelationName = name
    
    def enterSelectStmt(self):
        if not self._active: return

        self._actualSelection    = None
        self._actualProjection   = None
        self._actualSource       = None
        self._definedRelation    = None
    
    def leaveSelectStmt(self):
        if not self._active: return

        relation = self._actualSource
        if self._actualSelection is not None:
            relation.addListener(self._actualSelection)
            relation = self._actualSelection
        if self._actualProjection is not None:
            relation.addListener(self._actualProjection)
            relation = self._actualProjection

        self._definedRelation = relation
        
        self._actualSelection    = None
        self._actualProjection   = None
        self._actualSource       = None
    
    def leaveSourceRelation(self):
        if not self._active: return
        self._actualSource = self._join.getResult()
        self._actualInputs = []
        for (name, rel) in self._join.getInputRelations():
            self._actualInputs.append((name, rel))

    def enterSelection(self):
        if not self._active: return
        self._actualSelection = None
        self._logicFound = False
    
    def leaveSelection(self):
        if not self._active: return
        if not self._logicFound: return
        tmp = SelectionOperator()
        tmp.init(self._logic.getResult())
        self._actualSelection = tmp
    
    def enterProjection(self, distinct):
        if self._actualProjection is None:
            self._actualProjection = ProjectionOperator(self._alu)
            self._actualProjection.setDistinct(distinct)
    
    def leaveProjection(self):
        if self._actualProjection is None:
            # no projections defined
            return
        if  self._actualProjection.isFullProjection():
            self._actualProjection = None

    def enterRename(self):
        pass
        
    def leaveRename(self):
        path = self._exprStack[0]
        expr = self._exprStack[1]
        self._exprStack = None
        self._actualProjection.addProjection(path, expr)

    def acceptLogic(self, logic):
        if not self._active: return
        self._logicFound = True
        logic.walk(self._logic)
    
    def acceptExpression(self, expr):
        if self._actualProjection is None: return
        if self._exprStack is None:
            self._exprStack = list()
            self._exprStack.append(expr)
        else:
            expr.walk(self._expr)
            self._exprStack.append(self._expr.getResult())
예제 #2
0
 def enterProjection(self, distinct):
     if self._actualProjection is None:
         self._actualProjection = ProjectionOperator(self._alu)
         self._actualProjection.setDistinct(distinct)