Changeset 55


Ignore:
Timestamp:
May 23, 2009, 11:28:19 PM (11 years ago)
Author:
marchulsman
Message:

Field transformation, python interpreter,etc.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • container/container.py

    r54 r55  
    66import base_container
    77from multi_visitor import VisitorFactory,NF_ROBJ
    8 
    98
    109
     
    335334        return opcon.CrossJoinOpCon(self,other,"RIGHT JOIN")
    336335
    337     def go(self,*args,**kwds):
    338         tbl = args[0]
    339         sel = range(self.ncol,self.ncol + tbl.ncol)
    340         return opcon.SelectCon(opcon.CrossJoinOpCon(self,tbl),sel)
     336    def go(self,table):
     337        sel = range(self.ncol,self.ncol + table.ncol)
     338        return opcon.SelectCon(opcon.CrossJoinOpCon(self,table),sel)
    341339
    342340    def stack(self,other):
     
    401399                return r.data[0].copy()
    402400        else:
    403             res = numpy.array(r.data, dtype=object).T.view(xnumpy.XArray)
     401            res = numpy.array(tuple(r.data), dtype=object).T.view(xnumpy.XArray)
    404402            res.colnames = self._activefields.name
    405403            if(r.nrow == 1):
    406404                res.shape = (res.shape[1],)
    407    
    408405            return res
    409406   
     
    412409            if('_result' in self.__dict__):
    413410                if(not self._result.isvalid()):
    414                     query = self._invar.update['_query']
    415                     self._result  = query.execute(self)
     411                    qg_rewrite.e.update(self._query)
     412                    self._result  = qg_rewrite.e.execute(self._query)
    416413            else:
    417414                if('_query' not in self._invar.update):
    418                    
    419                     query = queryengine.Query()
    420                     self._invar.update['_query'] = query
     415                    self._query = qg_rewrite.e.create(self)
     416                    self._invar.update['_query'] = self._query
    421417                else:
    422                     query = self._invar.update['_query']
    423                 self._result = query.execute(self)
     418                    self._query = self._invar.update['_query']
     419                    qg_rewrite.e.update(self._query,self)
     420                self._result = qg_rewrite.e.execute(self._query)
    424421        except AttributeError,e:
    425422            traceback.print_exc()
     
    595592import itypes_py
    596593import capcon
     594import qg_rewrite
    597595
    598596fseqgen = utility.seqgen().next
  • container/itypes_py.py

    r54 r55  
    8585TA_LEASTONE = 4
    8686TA_FIX = 8
     87TA_PT = 16
    8788
    8889_tableattr = numpy.array([('type',         0, 0, 0, createType("uint16"),          0),\
    8990                           ('start_field',  0, 0, 0, createType("uint16"),          0),\
     91                           ('end_field',  0, 0, 0, createType("uint16"),          0),\
    9092                           ('source',       0, 0, 0, createType("uint16"),          0)],dtype=object).view(xnumpy.XArray)
    9193_tableattr_names = _tableattr[:,0]
  • container/opcon.py

    r54 r55  
    167167                self._fields = itypes_py.binop_type(sleft._activefields,rtype,operator)
    168168                self._actidx = numpy.arange(len(self._fields)).view(xnumpy.XArray)
    169                 self._table_attr = itypes_py.createTableAttr((itypes_py.TA_REDUCE,0,0))
     169                self._table_attr = itypes_py.createTableAttr((itypes_py.TA_REDUCE,0,len(self._actidx),0))
    170170                self._noFieldProps(sleft)
    171171            else:
     
    182182                       
    183183                self._noFieldProps(sleft,sright)
    184                 self._table_attr = itypes_py.createTableAttr((ta_left,0,0),(ta_right,0,1))
     184                self._table_attr = itypes_py.createTableAttr((ta_left,0,len(self._actidx),0),(ta_right,0,len(self._actidx),1))
    185185            self._invar.save(self)
    186186
     
    221221            self._fields.fieldnr = numpy.hstack((numpy.arange(len(left._fields)),numpy.arange(len(right._fields))))
    222222            self._actidx =  numpy.hstack((left._actidx, (right._actidx + len(left._fields))))
    223             self._table_attr = itypes_py.createTableAttr((itypes_py.TA_FLEX | itypes_py.TA_LEASTONE,0,0),(itypes_py.TA_FLEX | itypes_py.TA_LEASTONE,sleft.ncol,1))
     223            self._table_attr = itypes_py.createTableAttr(\
     224                              (itypes_py.TA_FLEX | itypes_py.TA_LEASTONE,0,left.ncol,0),\
     225                              (itypes_py.TA_FLEX | itypes_py.TA_LEASTONE,left.ncol,len(self._fields),1))
    224226           
    225227            if(operator == "LEFT JOIN"):
     
    259261class UpCon(MultiOpCon):
    260262    def __init__(self,source,left):
     263        self._source = [source]
    261264        if(source._invar.register(self)):
    262265            skip = True
     
    290293                #determine new active fields
    291294                idx = pfields[nfields].argsort()
    292                 self._actidx = nfields[idx]
     295                self._actidx = nfields[idx].view(xnumpy.XArray)
    293296
    294297                #remove current node
     
    325328
    326329class WhereCon(MultiOpCon):
    327     tbattr = itypes_py.createTableAttr((itypes_py.TA_FLEX,0,0),(itypes_py.TA_FIX,0,1))
     330    tbattr = itypes_py.createTableAttr((itypes_py.TA_FLEX,0,-1,0),(itypes_py.TA_FIX,0,0,1))
    328331    def __init__(self, source, row_constraint):
    329332        self._source = (source,row_constraint)
  • container/qg_rewrite.py

    r54 r55  
    33from qgraph import NodeVisitorFactory,QueryBase,Node
    44from base_container import QueryResult,ModificationSemaphore
     5
    56import traceback
    67import numpy
     8import xnumpy
    79import itypes_py
     10import opcon
    811
    912class Engine(object):
     
    1215        self.exec_pm = exec_pm
    1316
    14     def execute(self,root,vars={}):
     17    def create(self,root):
     18        query = Query(root)
    1519        try:
    16            if('_query' in root.__dict__):
    17                query = root._query
    18                query.update(root)
    19            else:
    20                query = Query(root)
    21                self.pre_pm.run(query)
    22                root._query = query
    23            return self.exec_pm.run(query)
    24                
     20            self.pre_pm.run(query)
     21        except Exception,e:
     22            print traceback.print_exc()
     23            raise e
     24        return query
     25
     26    def update(self,query,root):
     27        query.update(root)
     28
     29    def execute(self,query,vars={}):
     30        try:
     31          return self.exec_pm.run(query)
    2532        except Exception,e:
    2633            print traceback.print_exc()
     
    3239        node.target = []
    3340        return None
     41
     42#special root class, used as root for query graph
     43class Root(opcon.UnaryOpCon):
     44    pass
     45
     46#specialization of root node, reorders output
     47class ReorderRoot(Root):
     48    pass
    3449
    3550class Query(QueryBase):
     
    4257       self.pass_results = {}
    4358
     59       nroot =  Node(Root,source=[self.qg])
     60       self.qg.target.append(nroot)
     61       nroot.fields = self.qg.fields
     62       nroot.actidx = self.qg.actidx
     63       self.qg = nroot
     64
    4465   def __del__(self):
    4566       x = CycleBreakVisitor(self.params)
    4667       x.visit(self.qg)
    47 
    4868    #{{{
    4969   ############## Modifiable section ##################
     
    129149
    130150
    131 class PassManager(object):
     151class PassManager(object):#{{{
    132152    def __init__(self):
    133153        self.passes = []
     
    168188    def ready(cls,results):
    169189        return True
    170 
     190#}}}
    171191
    172192
    173193############### DEBUG VISITORS ######################
    174 class PrintNodeTreeVisitor(NodeVisitorFactory(),Pass):
     194class PrintNodeTreeVisitor(NodeVisitorFactory(),Pass):#{{{
    175195    tabs = 0
    176196    @classmethod
     
    200220
    201221    def visitparam(self,param):
    202         return '\t' * self.tabs + str(param)
    203 
    204 class DrawNodeTreeVisitor(NodeVisitorFactory(flags=F_CACHE),Pass):
     222        return '\t' * self.tabs + str(param) #}}}
     223class DrawNodeTreeVisitor(NodeVisitorFactory(flags=F_CACHE),Pass):#{{{
    205224    @classmethod
    206225    def run(cls,query):
     
    236255            self.graph.add_edge(s_id,id(node))
    237256           
    238         return id(node)
    239 
    240 class FieldTransformPass(NodeVisitorFactory(prefixes=('pass1',),flags=F_CACHE | NF_ROBJ),Pass):   
     257        return id(node)#}}}
     258class DrawFieldTreeVisitor(DrawNodeTreeVisitor):#{{{
     259    @classmethod
     260    def ready(cls,pass_results):
     261        return FieldTransformPass in pass_results
     262
     263    def visitnode(self,node):
     264        if(isinstance(node.obj,type)):
     265            name = node.obj.__name__
     266        else:
     267            name = str(node.obj)
     268
     269        in_trans = node.in_trans
     270        if(not node.actidx is None):
     271            fieldnames = node.fields.name[node.actidx]
     272        else:
     273            fieldnames = ["NO"]
     274        if(in_trans is None):
     275            lbl = "{" + name + "|{" + "|".join(fieldnames) + "}"
     276        else:
     277            lbl = "{{" +"|".join(map(str,in_trans)) +  "}|" + name + "|{" + "|".join(fieldnames) + "}"
     278
     279        if(not node.out_trans is None):
     280            lbl += "|" + str(node.out_trans)
     281        lbl += "}"
     282        lbl = lbl.replace(" ","\ ")
     283 
     284        self.graph.add_node(id(node),shape="record",label=lbl,rankdir="LR")
     285        for s in node.source:
     286            s_id = self.visit(s)
     287            self.graph.add_edge(s_id,id(node))
     288           
     289        return id(node)#}}}
     290       
     291
     292##############TRANSFORMATION PASSES#######################
     293class DependencyWalkPass(Pass):#{{{
     294    @classmethod
     295    def run(cls,query):
     296        cache = {}
     297        depqueue = deque([query.qg])
     298        deplist = []
     299        cidx = 0
     300        while(depqueue):
     301            x = depqueue.popleft()
     302            ltx = len(x.target)
     303            if(ltx > 1):
     304                if(x not in cache):
     305                    oldval = ltx
     306                    cache[x] = ltx - 1
     307                else:
     308                    oldval = cache[x]
     309                    cache[x] = oldval - 1
     310            else:
     311                oldval = 1
     312           
     313            if(oldval == 1): #all dependencies have been visited
     314                depqueue.extend([s for s in x.source if isinstance(s,Node)])
     315                deplist.append(x)
     316            cidx += 1
     317        return deplist#}}}
     318class FieldTransformPass(NodeVisitorFactory(prefixes=('pass1',),flags=F_CACHE | NF_ROBJ),Pass):    #{{{
     319
     320    @classmethod
     321    def ready(cls,pass_results):
     322        return DependencyWalkPass in pass_results
     323
    241324    @classmethod
    242325    def run(cls,query):
    243326        self = cls(query.params)
    244         self.fields = []
    245         self.cur_fields = set()
    246 
    247         #breadth first order
    248         bfo_nodes = []
    249         bfo_queue = deque([query.qg])
    250 
    251         root = query.qg
     327        depwalk = query.pass_results[DependencyWalkPass]
     328
     329        #pass 1: the fist pass walks along dependency chain
     330        #(all targets of a node first before it is visited itself)
     331        #In this pass we set for each  node the required output fields
     332        #these are stored in out_trans. Once a node is visited, the
     333        #contents are moved to the actidx field (actidx is not needed anymore
     334        #at that point).
     335        #Select and Up nodes are removed. The root node starts with
     336        #the active fields, and is changed in a reorderopcon if these
     337        #active fields occur multiple times or in a different order then
     338        #the field array indicates
     339        #For each other node, we walk through the table attribute array
     340        #this array indicates for a set of out-fields (indicated
     341        #by start and endfield), from which source they come, and how
     342        #the corresponding input-fields may be switched on/off.
     343        #TA_FLEX:   indicates that in-fields correspond directly to the
     344        #           out-fields, and may be switched off at will
     345        #TA_LEASTONE: is a flag, only to be used in combination with TA_FLEX
     346        #               it indicates that at least one in-field should still be
     347        #               used as input, even is no output is needed
     348        #TA_REDUCE: indicates that the input-fields in their active
     349        #           ordering (i.e. fields[actidx]) correspond directly
     350        #           to the output fields. If output fields are switched off,
     351        #           this may also be done for the corresponding input fields.
     352        #TA_FIX:    similar to TA_REDUCE, but in-fields may not be switched off.
     353        #TA_PT:     passthrough fields. Similar to TA_FLEX, but tHese fields are
     354        #directly copied from the input.
     355        depwalk = filter(self.pass1,depwalk) #filter on output of visit method
     356       
     357       
     358        #pass2: In the second pass we create transformations for input
     359        #and output. Input transformations are needed when the
     360        #out fields of the source node do not match with the expected
     361        #fields of this node, or when this node's function expects the
     362        #field in their active ordering (i.e. fields[actidx]).
     363        #output transformations are needed when we have passthrough fields
     364        #as well as results from an executed function. THey indicate how
     365        #the output fields should be obtained.
     366        #NOTE!!!!!!: to simplify the code, we assume that fields are
     367        #ordered as follows: passthrough fields from source 0 - source x (in order)
     368        # followed by result fields, followed by possible calculation fields
     369
     370        for n in depwalk[:0:-1]: #walk in reverse order (excluding root node)
     371            nout_trans = numpy.empty((len(n.source)+2,),dtype=object)
     372            if(n.table_attr is None):
     373                if(not numpy.all(n.actidx)):
     374                    nout_trans[0] = n.actidx
     375            else:
     376                for ta in n.table_attr:
     377                    tatype = ta.type
     378                    s = n.source[ta.source]
     379                    sfield = ta.start_field
     380                    efield = ta.end_field
     381                    if(efield == -1):
     382                        efield = sfield + len(s.fields)
     383   
     384                    if(tatype & itypes_py.TA_FLEX):
     385                        x = n.actidx[sfield:efield]
     386                        if(tatype & itypes_py.TA_LEASTONE):
     387                            if(not numpy.any(x)):
     388                                idx = numpy.where(s.actidx)[0][0]
     389                                n.in_trans[ta.source] = 0
     390                                n.out_trans[sfield + idx] = True
     391                        else:
     392                            morefield = s.actidx & ~x
     393                            if(numpy.any(morefield)):
     394                                tmp = numpy.zeros(s.actidx.shape,dtype="uint16")
     395                                tmp[s.actidx] = numpy.arange(sum(s.actidx),dtype="uint16")
     396                                n.in_trans[ta.source] = tmp[x]
     397                    elif(tatype & itypes_py.TA_PT):
     398                        ot = s.actidx
     399                        ot_len = sum(ot)
     400                        ufield = node.actidx[sfield:efield]
     401                        if(sum(ufield) == ot_len and numpy.all(yynumpy.less(cia[0:],cia[:-1]))):
     402                            idx = slice(None,None,None)
     403                        else:
     404                            tmp = numpy.zeros(ot.shape,dtype="uint16")
     405                            tmp[ot] = numpy.arange(ot_len,dtype="uint16")
     406                            idx = tmp[node.actidx[sfield:efield]]
     407                        nout_trans[sfield + 2] = idx
     408                    else: #TA_REDUCE or TA_FIX
     409                        ot = s.actidx
     410                        ot_len = sum(ot)
     411                        cia = n.in_trans[ta.source]
     412                        #no actidx needed if equal to selected out fields
     413                        #and same order
     414                        if(len(cia) == ot_len and numpy.all(numpy.less(cia[0:],cia[:-1]))):
     415                            n.in_trans[ta.source] = None
     416                        else:
     417                            tmp = numpy.zeros(ot.shape,dtype="uint16")
     418                            tmp[ot] = numpy.arange(ot_len,dtype="uint16")
     419                            n.in_trans[ta.source] = tmp[cia]
     420                if(all(n.in_trans == (None,))):
     421                    n.in_trans = None
     422               
     423                #set out_trans if needed
     424                ot_len = sum(n.out_trans)
     425                sel = n.out_trans & n.actidx
     426                if(sum(sel) < ot_len):
     427                    tmp = numpy.zeros(n.actidx.shape,dtype="uint16")
     428                    tmp[n.out_trans] = numpy.arange(ot_len,dtype="uint16")
     429                    nout_trans[0] = tmp[sel]
     430               
     431            #replace with final transformation
     432            if(numpy.all(nout_trans == [None])):
     433                n.out_trans = None
     434            else:
     435                n.out_trans = nout_trans
     436   
     437        #update to prevent invalidation
     438        query.pass_results[DependencyWalkPass] = depwalk
     439
     440        return depwalk
     441       
     442    def pass1node(self,node):
     443        if(not numpy.any(node.out_trans)):
     444            if(node.tmp): #check if field is required (TA_LEASTONE)
     445                node.out_trans[0] = True
     446            else:
     447                #no output: node should be removed?
     448                return True
     449
     450        #some reuse of variables going on:
     451        #actidx is not needed anymore in its original capacity
     452        #so we assign it a boolean vector with the out variables
     453        #expected by target nodes
     454        #out_trans is now reused to hold a similar sized boolean
     455        #vector which signifies what we expect the node function
     456        #to output
     457        node.actidx = node.out_trans.copy()
     458        if(node.table_attr is None):
     459            return True
     460     
     461        #node.in_trans = [None] * len(node.source)
     462        node.in_trans = numpy.empty((len(node.source),),dtype=object)
     463
     464        for ta in node.table_attr:
     465           tatype = ta.type
     466           s = node.source[ta.source]
     467           sfield = ta.start_field
     468           efield = ta.end_field
     469           if(efield == -1):
     470               efield = sfield + len(s.fields)
     471           if(s.out_trans is None):
     472               s.out_trans = numpy.zeros((len(s.fields),),dtype=bool)
     473
     474           if(tatype & itypes_py.TA_FLEX):
     475               s.out_trans |= node.out_trans[sfield:efield]
     476               if(tatype & itypes_py.TA_LEASTONE):
     477                    s.tmp = True #tmp variable indicating this node should at least
     478                                 #return one field
     479           elif(tatype & itypes_py.TA_REDUCE):
     480               nactidx = s.actidx[node.out_trans]
     481               s.out_trans[nactidx] = True
     482               node.in_trans[ta.source] = nactidx
     483           elif(tatype & itypes_py.TA_FIX):
     484               s.out_trans[s.actidx] = True
     485               node.in_trans[ta.source] = s.actidx
     486               node.out_trans[sfield:efield] = True
     487           elif(tatype & itypes_py.TA_PT):
     488               s.out_trans |= node.out_trans[sfield:efield]
     489               node.out_trans[sfield:efield] = False
     490           else:
     491               raise RuntimeError, "Unexpected table attribute type"
     492        return True
     493
     494    def pass1Root(self,root):
    252495        actidx = root.actidx
     496        #if last node reorders results, add reordercon which specializes in that
    253497        if(not numpy.all(numpy.less(actidx[:-1],actidx[1:]))):
    254             nroot = Node("ReorderCon",[query.qg])
    255             root.targets = [nroot]
    256             nroot.actidx = root.actidx
    257             nroot.fields = root.fields
    258             root = nroot
    259         root.out_trans = numpy.zeros((len(root.fields),),dtype=bool)
    260         root.out_trans[actidx] = True
    261        
    262         #pass1: field-handling (bfo-order)
    263         while(bfo_queue):
    264             x = bfo_queue.popleft()
    265             if(self.pass1(x)):
    266                bfo_nodes.append(x)
    267             bfo_queue.extend([s for s in x.source if isinstance(s,Node)])
    268        
    269 
    270         #pass2: adapt in_actidx to out_trans (renumbering field idx)
    271         for n in bfo_nodes:
    272             if(n.in_actidx is None):
    273                 continue
    274             for sidx,ia in enumerate(n.in_actidx):
    275                 if(not ia is None):
    276                     ot = n.source[sidx].out_trans
    277                     ot_len = sum(ot)
    278                     #no actidx needed if equal to selected out fields
    279                     #and same order
    280                     if(len(ia) == ot_len and numpy.all(numpy.less(ia[0:],ia[:-1]))):
    281                         n.in_actidx[sidx] = None
    282                     else:
    283                         tmp = numpy.zeros(ot.shape,dtype="uint16")
    284                         tmp[ot] = numpy.arange(ot_len,dtype="uint16")
    285                         n.in_actidx[sidx] = tmp[ia]
    286         return bfo_nodes
    287 
     498            root.obj = ReorderRoot
     499   
     500        #set out_trans for root node using its active fields (actidx)
     501        real_root = root.source[0]
     502        real_root.out_trans = numpy.zeros((len(root.fields),),dtype=bool)
     503        real_root.out_trans[actidx] = True
     504        return True
     505 
    288506    def pass1SelectCon(self,node):
    289507        s = node.source[0]
     
    320538        node.source = []
    321539        node.target = []
    322 
    323 
    324     def pass1node(self,node):
    325         if(sum(node.out_trans) == 0 or node.table_attr is None):
    326             return True
    327         node.in_actidx = [None] * len(node.source)
    328 
    329         for ta in node.table_attr:
    330            tatype = ta.type
    331            s = node.source[ta.source]
    332            sfield = ta.start_field
    333            if(s.out_trans is None):
    334                s.out_trans = numpy.zeros((len(s.fields),),dtype=bool)
    335 
    336            if(tatype & itypes_py.TA_FLEX):
    337                s.out_trans |= node.out_trans[sfield:(sfield + len(s.fields))]
    338                if(tatype & itypes_py.TA_LEASTONE):
    339                     if(not numpy.any(s.out_trans)):
    340                         s.out_trans[0] = True
    341            elif(tatype & itypes_py.TA_REDUCE):
    342                nactidx = s.actidx[node.out_trans]
    343                s.out_trans[nactidx] = True
    344                node.in_actidx[ta.source] = nactidx
    345            elif(tatype & itypes_py.TA_FIX):
    346                s.out_trans[s.actidx] = True
    347                node.in_actidx[ta.source] = s.actidx
    348            else:
    349               raise RuntimeError, "Unexpected table attribute type"
    350         return True
     540           
     541#}}}
     542
     543
     544
     545########### EXECUTION PASSES ####################
     546class PyExecutePass(NodeVisitorFactory(flags=F_CACHE),Pass):    #{{{
     547
     548    @classmethod
     549    def run(cls,query):
     550        self = cls(query.params)
     551        return self.visit(query.qg)
     552
     553    def visit(self,node):
     554        result = super(PyExecutePass,self).visit(node)
     555        if(isinstance(node,Node)):
     556            if(not node.out_trans is None):
     557                nres = []
     558                for i,otrans in enumerate(node.out_trans[2:]):
     559                    if(not otrans is None):
     560                        nres.append(res[i].data[otrans])
     561                if(node.out_trans[0] is None):
     562                    nres.append(result.data)
     563                else:
     564                    nres.append(result.data[node.out_trans[0]])
     565
     566                data=numpy.hstack(nres)
     567                return QueryResult(data=data,nrow=len(data[0]),ncol=len(data))
     568        return result
     569
     570    def visitsources(self,node):
     571        res = super(PyExecutePass,self).visitsources(node)
     572        if(not node.in_trans is None):
     573            inres = list(res)
     574            for i,a_idx in enumerate(node.in_trans):
     575                if(not a_idx is None):
     576                    odata = inres[i]
     577                    inres[i] = QueryResult(data=odata.data[a_idx],nrow=odata.nrow,ncol=len(a_idx))
     578            return tuple(inres)
     579        return res
     580
     581
     582    def visitWhereCon(self,node):
     583       (d,ri) = self.visitsources(node)
     584       if(isinstance(ri,QueryResult)):
     585          ri = ri.data[0]
     586       d.data = xnumpy.dimarray(tuple(column.dim1(ri) for column in d.data),object,1,1)
     587       d.nrow = len(d.data[0])
     588       return d
     589
     590
     591    def visitArithmeticOpCon(self,node):
     592        (lr,rr,operator) = self.visitsources(node)
     593        if(isinstance(rr,QueryResult)):
     594            if(lr.ncol == 1):
     595                ncol = rr.ncol
     596                data = xnumpy.dimarray(tuple(getattr(col,operator)(lr.data[0]) for col in rr.data),object,1,1)
     597            elif(rr.ncol == 1):
     598                ncol = lr.ncol
     599                data = xnumpy.dimarray(tuple(getattr(col,operator)(rr.data[0]) for col in lr.data),object,1,1)
     600            else:
     601                ncol = lr.ncol
     602                data = xnumpy.dimarray(tuple(getattr(coll,operator)(colr) for coll,colr in zip(lr.data,rr.data)),object,1,1)
     603            pass
     604        else:
     605            ncol = lr.ncol
     606            data = xnumpy.dimarray(tuple(getattr(col,operator)(rr) for col in lr.data),object,1,1)
     607
     608        return QueryResult(data,lr.nrow,ncol)
     609
     610    def visitSrcCon(self,node):
     611        (res,) = self.visitsources(node)
     612        return res
     613
     614    def visitRoot(self,node):
     615        (res,) = self.visitsources(node)
     616        return res
     617       
     618#}}}
    351619
    352620pe = PassManager()
     621pe.register(DependencyWalkPass)
    353622pe.register(FieldTransformPass)
    354 #pe.register(DrawNodeTreeVisitor)
     623#pe.register(DrawFieldTreeVisitor)
    355624pp = PassManager()
    356 pp.register(PrintNodeTreeVisitor)
     625pp.register(PyExecutePass)
    357626
    358627e = Engine(pe,pp)
     628
     629
  • container/srccon.py

    r46 r55  
     1from base_container import QueryResult,ModificationSemaphore
    12import container
    23import opcon
    34
    4 import queryengine
    55import itypes_py
    66import utility
     
    6262
    6363        if(not data is None):
    64             self._result = queryengine.QueryResult(data,len(data[0]),len(data))
     64            self._result = QueryResult(xnumpy.dimarray(data,object,1,1),len(data[0]),len(data))
    6565
    6666        if(not modifiable):
    6767            if(not data):
    68                 data = tuple(xnumpy.dimarray(tuple(),itypes_py.to_numpy(type)) for type in fields.type)
    69                 self._result = queryengine.QueryResult(data,0,0)
     68                data = xnumpy.dimarray((xnumpy.dimarray(tuple(),itypes_py.to_numpy(type)) for type in fields.type),object,1,1)
     69                self._result = QueryResult(data,0,0)
    7070            self._res = self._result
    7171            self._res.cacheable = True
     
    7373            self._set_props_class()
    7474        else:
    75             self.modify_check = queryengine.ModificationSemaphore(1)
     75            self.modify_check = ModificationSemaphore(1)
    7676            self._add_buffer = []
    7777            self.modify_sems = set([self.modify_check])
     
    229229                ncol = self.ncol
    230230                data = itypes_py.transpose(self._add_buffer)
    231                 data = tuple(xnumpy.dimarray(col,fieldtypes[i]) for i,col in enumerate(data))
    232                 r = queryengine.QueryResult(data, nrow, ncol)
     231                data = xnumpy.dimarray((xnumpy.dimarray(col,fieldtypes[i]) for i,col in enumerate(data)),object,1,1)
     232                r = QueryResult(data, nrow, ncol)
    233233                self._add_buffer = []
    234234                r.modify_check = self.modify_check
     
    240240                r = self._result
    241241                data = itypes_py.transpose(self._add_buffer);
    242                 r.data = tuple(utility.colappend(r.data[i], \
     242                r.data = xnumpy.dimarray((utility.colappend(r.data[i], \
    243243                    col) \
    244                     for i,col in enumerate(data))
     244                    for i,col in enumerate(data)),object,1,1)
    245245                r.nrow += len(self._add_buffer)
    246246                self._add_buffer = []
  • src/base_container.c

    r54 r55  
    171171
    172172   static char *kwlist[] = {"data","nrow","ncol",NULL};
    173    if(!PyArg_ParseTupleAndKeywords(args,kwds,"O!O!O!",kwlist,
    174             &PyTuple_Type,&data,&PyInt_Type,&nrow,&PyInt_Type,&ncol))
     173   if(!PyArg_ParseTupleAndKeywords(args,kwds,"OO!O!",kwlist,
     174            &data,&PyInt_Type,&nrow,&PyInt_Type,&ncol))
    175175      return -1;
     176
     177   if(!(PyArray_Check(data) && ((PyArrayObject*)data)->nd == 1))
     178   {
     179       PyErr_SetString(PyExc_TypeError, "Data objects should be a 1 dimensional array");
     180       return -1;
     181   }
    176182   tmp = self->data;
    177183   Py_INCREF(data);
     
    314320{
    315321    PyObject *tmp;
    316     if(!PyTuple_Check(value))
    317     {
    318         PyErr_SetString(PyExc_TypeError, "Data objects should be a tuple");
     322    if(!(PyArray_Check(value) && ((PyArrayObject*)value)->nd == 1))
     323    {
     324        PyErr_SetString(PyExc_TypeError, "Data objects should be a 1 dimensional array");
    319325        return -1;
    320326    }
     
    588594{
    589595    PyObject *tmp;
    590     if(!(PyArray_Check(value) && ((PyArrayObject*)value)->nd == 2))
    591     {
    592         PyErr_SetString(PyExc_TypeError, "Table attributes should be a two dimensional numpy object");
     596    if(!(value == Py_None || (PyArray_Check(value) && ((PyArrayObject*)value)->nd == 2)))
     597    {
     598        PyErr_SetString(PyExc_TypeError, "Table attributes should be None or a two dimensional numpy object");
    593599        return -1;
    594600    }
  • src/qgraph.c

    r54 r55  
    2020    PyObject * actidx;
    2121    PyObject * props;
    22 
    2322    PyObject * table_attr;
     23
     24    PyObject * tmp;
    2425    PyObject * in_trans;
    2526    PyObject * out_trans;
     
    314315}
    315316
     317static PyObject *
     318Node_getTmp(Node *self, void *closure)
     319{
     320    if(!self->in_actidx)
     321    {
     322        Py_INCREF(Py_None);
     323        self->in_actidx = Py_None;
     324    }
     325    Py_INCREF(self->in_actidx);
     326    return self->in_actidx;
     327}
     328static int
     329Node_setTmp(Node *self, PyObject *value, void *closure)
     330{
     331    PyObject *tmp;
     332    tmp = self->tmp;
     333    Py_INCREF(value);
     334    self->tmp = value;
     335    Py_XDECREF(tmp);
     336    return 0;
     337}
    316338static PyGetSetDef Node_getseters[] = {
    317339    {"obj",
     
    353375    {"in_actidx",
    354376     (getter)Node_getInActidx, (setter)Node_setInActidx,
    355      "Out field nr.",
     377     "which field to use from input.",
     378     NULL},
     379    {"tmp",
     380     (getter)Node_getTmp, (setter)Node_setTmp,
     381     "temporary variable used by query graph passes.",
    356382     NULL},
    357383    {NULL}  /* Sentinel */
     
    792818    return self->qg_node;
    793819}
     820static int
     821QGCreator_setQG(QGCreator *self, PyObject * value, void *closure)
     822{
     823    PyObject * tmp;
     824    tmp = self->qg_node;
     825    Py_INCREF(value);
     826    self->qg_node = value;
     827    Py_XDECREF(tmp);
     828    return 0;
     829}
    794830
    795831static PyObject *
     
    831867    Py_INCREF(value);
    832868    self->modifiables = value;
    833     Py_DECREF(tmp);
     869    Py_XDECREF(tmp);
    834870    return 0;
    835871}
     
    860896     NULL},
    861897    {"qg",
    862      (getter)QGCreator_getQG, NULL,
     898     (getter)QGCreator_getQG, (setter)QGCreator_setQG,
    863899     "Obtain root query graph node.",
    864900     NULL},
     
    12901326    Py_DECREF(curname);
    12911327    if(visit_method == NULL)
    1292         return Visitor_notfound(self,prefix,visited,flags);
     1328    {
     1329        PyErr_Clear();
     1330        if(visited->ob_type == &Node_Type)
     1331            return Visitor_notfound(self,prefix,visited,flags);
     1332        else
     1333        {
     1334           Py_INCREF(Py_None);
     1335           visit_method = Py_None;
     1336           return visit_method;
     1337        }
     1338    }
    12931339    else
    12941340        return visit_method;
     
    13001346    PyObject *visited;
    13011347    PyObject *source;
     1348    PyObject *prefix;
    13021349    Py_ssize_t arglength;
    13031350
     
    13281375    /* Obtain source objects of the node */
    13291376    source = ((Node *)visited)->source;
    1330    
     1377    prefix = PyTuple_GET_ITEM(closure,0);
    13311378    if(!PyList_Check(source) || PyList_Size(source) == 0)
    13321379        return PyTuple_New(0);
     
    13441391            /* Reuse or own args tuple */
    13451392            PyTuple_SET_ITEM(args,0,PyList_GET_ITEM(source,i));
    1346             resvisit = Visitor_visit((PyObject *)self,args,closure);
     1393            resvisit = PyObject_CallMethod((PyObject *)self,PyString_AsString(prefix),"O",args);
     1394            //resvisit = Visitor_visit((PyObject *)self,args,closure);
    13471395
    13481396            if(resvisit == NULL)
Note: See TracChangeset for help on using the changeset viewer.