str MATpackValues(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { int i,*ret, type, first = 1; BAT *bn; (void) cntxt; type = getArgType(mb,p,first); bn = BATnew(TYPE_void, type, p->argc, TRANSIENT); if( bn == NULL) throw(MAL, "mat.pack", MAL_MALLOC_FAIL); if (ATOMvarsized(type)) { for(i = first; i < p->argc; i++) BUNappend(bn, stk->stk[getArg(p,i)].val.sval, TRUE); } else { for(i = first; i < p->argc; i++) BUNappend(bn, getArgReference(stk, p, i), TRUE); } BATsettrivprop(bn); BATderiveProps(bn,FALSE); ret= (int*) getArgReference(stk,p,0); BBPkeepref(*ret = bn->batCacheid); return MAL_SUCCEED; }
static BAT * MATproject_( BAT *map, BAT **bats, int len ) { BAT *res = NULL; if (ATOMstorage(bats[0]->ttype) <= TYPE_void) { /*error*/ } else if (ATOMvarsized(bats[0]->ttype)) { res = MATproject_var(map, bats, len); } else if (ATOMsize(bats[0]->ttype) == sizeof(bte)) { res = MATproject_bte(map, bats, len, bats[0]->ttype); } else if (ATOMsize(bats[0]->ttype) == sizeof(sht)) { res = MATproject_sht(map, bats, len, bats[0]->ttype); } else if (ATOMsize(bats[0]->ttype) == sizeof(int)) { res = MATproject_int(map, bats, len, bats[0]->ttype); } else if (ATOMsize(bats[0]->ttype) == sizeof(lng)) { res = MATproject_lng(map, bats, len, bats[0]->ttype); #ifdef HAVE_HGE } else if (ATOMsize(bats[0]->ttype) == sizeof(hge)) { res = MATproject_hge(map, bats, len, bats[0]->ttype); #endif } else { res = MATproject_any(map, bats, len); } if(res){ res->tsorted = 0; res->trevsorted = 0; res->T->nonil = MATnonil(bats, len); } return res; }
void GDKqsort_rev(void *h, void *t, const void *base, size_t n, int hs, int ts, int tpe) { struct qsort_t buf; assert(hs > 0); assert(ts >= 0); assert(tpe != TYPE_void); buf.hs = (unsigned int) hs; buf.ts = (unsigned int) ts; buf.cmp = BATatoms[tpe].atomCmp; buf.base = base; if (ATOMvarsized(tpe)) { assert(base != NULL); GDKqsort_impl_var_rev(&buf, h, t, n); return; } if (base) tpe = TYPE_str; /* we need the default case */ if (tpe != ATOMstorage(tpe) && ATOMnilptr(ATOMstorage(tpe)) == ATOMnilptr(tpe) && BATatoms[ATOMstorage(tpe)].atomCmp == BATatoms[tpe].atomCmp) tpe = ATOMstorage(tpe); switch (tpe) { case TYPE_bte: GDKqsort_impl_bte_rev(&buf, h, t, n); break; case TYPE_sht: GDKqsort_impl_sht_rev(&buf, h, t, n); break; case TYPE_int: GDKqsort_impl_int_rev(&buf, h, t, n); break; case TYPE_lng: GDKqsort_impl_lng_rev(&buf, h, t, n); break; #ifdef HAVE_HGE case TYPE_hge: GDKqsort_impl_hge_rev(&buf, h, t, n); break; #endif case TYPE_flt: GDKqsort_impl_flt_rev(&buf, h, t, n); break; case TYPE_dbl: GDKqsort_impl_dbl_rev(&buf, h, t, n); break; default: GDKqsort_impl_any_rev(&buf, h, t, n); break; } }
static str MATsort(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, int rev) { bat *res_id = (bat*) getArgReference(stk,pci,0); /* result sorted */ bat *map_id = (bat*) getArgReference(stk,pci,1); /* result map */ BAT *res = NULL, *map = NULL; /* rest of the args are sorted parts, (excluding sorted and map) */ BAT **bats = GDKzalloc(sizeof(BAT*) * pci->argc - 2); BUN pcnt = 0; int i, len = pci->argc-2; (void) cntxt; (void) mb; (void) stk; if( bats == NULL) throw(SQL, "mat.sortTail",MAL_MALLOC_FAIL); for (i=2; i<pci->argc; i++) { bat id = *(bat*) getArgReference(stk,pci,i); bats[i-2] = BATdescriptor(id); if (!bats[i-2]) goto error; pcnt += BATcount(bats[i-2]); } if (ATOMstorage(bats[0]->ttype) <= TYPE_void) { /*error*/ } else if (ATOMvarsized(bats[0]->ttype)) { res = MATsort_any(&map, bats, len, pcnt, rev); } else if (ATOMsize(bats[0]->ttype) == sizeof(bte)) { res = MATsort_bte(&map, bats, len, pcnt, rev); } else if (ATOMsize(bats[0]->ttype) == sizeof(sht)) { res = MATsort_sht(&map, bats, len, pcnt, rev); } else if (ATOMsize(bats[0]->ttype) == sizeof(int)) { res = MATsort_int(&map, bats, len, pcnt, rev); } else if (ATOMsize(bats[0]->ttype) == sizeof(lng)) { res = MATsort_lng(&map, bats, len, pcnt, rev); #ifdef HAVE_HGE } else if (ATOMsize(bats[0]->ttype) == sizeof(hge)) { res = MATsort_hge(&map, bats, len, pcnt, rev); #endif } else { res = MATsort_any(&map, bats, len, pcnt, rev); } if (res) { res->T->nonil = MATnonil(bats, len); if (rev) { res->trevsorted = 1; res->tsorted = res->batCount <= 1; } else { res->tsorted = 1; res->trevsorted = res->batCount <= 1; } } error: for (i=0; i<len && bats[i]; i++) BBPunfix(bats[i]->batCacheid); GDKfree(bats); if (map && res) { map->tsorted = 0; map->trevsorted = 0; BBPkeepref( *map_id = map->batCacheid); BBPkeepref( *res_id = res->batCacheid); return MAL_SUCCEED; } if (map) BBPunfix(map->batCacheid); throw(SQL, "mat.sortTail","Cannot access descriptor"); }
int OPTrecyclerImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { int i, j, cnt, tp, c, actions = 0, marks = 0, delta = 0; Lifespan span; InstrPtr *old, q; int limit, updstmt = 0; char *recycled; short app_sc = -1, in = 0; ValRecord cst; (void) cntxt; (void) stk; limit = mb->stop; old = mb->stmt; for (i = 1; i < limit; i++) { p = old[i]; if (getModuleId(p) == sqlRef && (getFunctionId(p) == affectedRowsRef || getFunctionId(p) == exportOperationRef || getFunctionId(p) == appendRef || getFunctionId(p) == updateRef || getFunctionId(p) == deleteRef)) updstmt = 1; } span = setLifespan(mb); if (span == NULL) return 0; /* watch out, newly created instructions may introduce new variables */ recycled = GDKzalloc(sizeof(char) * mb->vtop * 2); if (recycled == NULL) return 0; if (newMalBlkStmt(mb, mb->ssize) < 0) { GDKfree(recycled); return 0; } pushInstruction(mb, old[0]); mb->recid = recycleSeq++; /* create a handle for recycler */ (void) newFcnCall(mb, "recycle", "prelude"); in = 1; for (i = 1; i < limit; i++) { p = old[i]; if (hasSideEffects(p, TRUE) || isUpdateInstruction(p) || isUnsafeFunction(p)) { if (getModuleId(p) == recycleRef) { /*don't inline recycle instr. */ freeInstruction(p); continue; } pushInstruction(mb, p); /* update instructions are not recycled but monitored*/ if (isUpdateInstruction(p)) { if (getModuleId(p) == batRef && (getArgType(mb, p, 1) == TYPE_bat || isaBatType(getArgType(mb, p, 1)))) { recycled[getArg(p, 1)] = 0; q = newFcnCall(mb, "recycle", "reset"); pushArgument(mb, q, getArg(p, 1)); actions++; } if (getModuleId(p) == sqlRef) { if (getFunctionId(p) == appendRef) { if (app_sc >= 0) continue; else app_sc = getArg(p, 2); } VALset(&cst, TYPE_int, &delta); c = defConstant(mb, TYPE_int, &cst); q = newFcnCall(mb, "recycle", "reset"); pushArgument(mb, q, c); pushArgument(mb, q, getArg(p, 2)); pushArgument(mb, q, getArg(p, 3)); if (getFunctionId(p) == updateRef) pushArgument(mb, q, getArg(p, 4)); actions++; } } /* take care of SQL catalog update instructions */ if (getModuleId(p) == sqlRef && getFunctionId(p) == catalogRef) { tp = *(int *) getVarValue(mb, getArg(p, 1)); if (tp == 22 || tp == 25) { delta = 2; VALset(&cst, TYPE_int, &delta); c = defConstant(mb, TYPE_int, &cst); q = newFcnCall(mb, "recycle", "reset"); pushArgument(mb, q, c); pushArgument(mb, q, getArg(p, 2)); if (tp == 25) pushArgument(mb, q, getArg(p, 3)); actions++; } } continue; } if (p->token == ENDsymbol || p->barrier == RETURNsymbol) { if (in) { /* if (updstmt && app_sc >= 0) { q = newFcnCall(mb, "recycle", "reset"); pushArgument(mb, q, app_sc); pushArgument(mb, q, app_tbl); } */ (void) newFcnCall(mb, "recycle", "epilogue"); in = 0; } pushInstruction(mb, p); continue; } if (p->barrier && p->token != CMDcall) { /* never save a barrier unless it is a command and side-effect free */ pushInstruction(mb, p); continue; } /* don't change instructions in update statements */ if (updstmt) { pushInstruction(mb, p); continue; } /* skip simple assignments */ if (p->token == ASSIGNsymbol) { pushInstruction(mb, p); continue; } if (getModuleId(p) == octopusRef && (getFunctionId(p) == bindRef || getFunctionId(p) == bindidxRef)) { recycled[getArg(p, 0)] = 1; p->recycle = recycleMaxInterest; marks++; } /* During base table recycling skip marking instructions other than octopus.bind */ if (baseTableMode) { pushInstruction(mb, p); continue; } /* general rule: all arguments are constants or recycled, ignore C pointer arguments from mvc */ cnt = 0; for (j = p->retc; j < p->argc; j++) if (recycled[getArg(p, j)] || isVarConstant(mb, getArg(p, j)) || ignoreVar(mb, getArg(p, j))) cnt++; if (cnt == p->argc - p->retc) { OPTDEBUGrecycle { mnstr_printf(cntxt->fdout, "#recycle instruction\n"); printInstruction(cntxt->fdout, mb, 0, p, LIST_MAL_ALL); } marks++; p->recycle = recycleMaxInterest; /* this instruction is to be monitored */ for (j = 0; j < p->retc; j++) if (getLastUpdate(span, getArg(p, j)) == i) recycled[getArg(p, j)] = 1; } /* * The expected gain is largest if we can re-use selections * on the base tables in SQL. These, however, are marked as * uselect() calls, which only produce the oid head. * For cheap types we preselect using select() and re-map uselect() back * over this temporary. * For the time being for all possible selects encountered * are marked for re-use. */ /* take care of semantic driven recyling */ /* for selections check the bat argument only the range is often template parameter*/ if ((getFunctionId(p) == selectRef || getFunctionId(p) == antiuselectRef || getFunctionId(p) == likeselectRef || getFunctionId(p) == likeRef || getFunctionId(p) == thetaselectRef) && recycled[getArg(p, 1)]) { p->recycle = recycleMaxInterest; marks++; if (getLastUpdate(span, getArg(p, 0)) == i) recycled[getArg(p, 0)] = 1; } if ((getFunctionId(p) == uselectRef || getFunctionId(p) == thetauselectRef) && recycled[getArg(p, 1)]) { if (!ATOMvarsized(getGDKType(getArgType(mb, p, 2)))) { q = copyInstruction(p); getArg(q, 0) = newTmpVariable(mb, TYPE_any); if (getFunctionId(p) == uselectRef) setFunctionId(q, selectRef); else setFunctionId(q, thetaselectRef); q->recycle = recycleMaxInterest; marks++; recycled[getArg(q, 0)] = 1; pushInstruction(mb, q); getArg(p, 1) = getArg(q, 0); setFunctionId(p, projectRef); p->argc = 2; } p->recycle = recycleMaxInterest; marks++; if (getLastUpdate(span, getArg(p, 0)) == i) recycled[getArg(p, 0)] = 1; } if (getModuleId(p) == pcreRef) { if ((getFunctionId(p) == selectRef && recycled[getArg(p, 2)]) || (getFunctionId(p) == uselectRef && recycled[getArg(p, 2)])) { p->recycle = recycleMaxInterest; marks++; if (getLastUpdate(span, getArg(p, 0)) == i) recycled[getArg(p, 0)] = 1; } else if (getFunctionId(p) == likeuselectRef && recycled[getArg(p, 1)]) { q = copyInstruction(p); getArg(q, 0) = newTmpVariable(mb, TYPE_any); setFunctionId(q, likeselectRef); q->recycle = recycleMaxInterest; recycled[getArg(q, 0)] = 1; pushInstruction(mb, q); getArg(p, 1) = getArg(q, 0); setFunctionId(p, projectRef); setModuleId(p, algebraRef); p->argc = 2; p->recycle = recycleMaxInterest; marks += 2; if (getLastUpdate(span, getArg(p, 0)) == i) recycled[getArg(p, 0)] = 1; } } /* * The sql.bind instructions should be handled carefully * The delete and update BATs should not be recycled, * because they may lead to view dependencies that later interferes * with the transaction commits. */ /* enable recycling of delta-bats if (getModuleId(p) == sqlRef && (((getFunctionId(p) == bindRef || getFunctionId(p) == putName("bind_idxbat", 11)) && getVarConstant(mb, getArg(p, 5)).val.ival != 0) || getFunctionId(p) == binddbatRef)) { recycled[getArg(p, 0)] = 0; p->recycle = REC_NO_INTEREST; } */ /* * The sql.bind instructions should be handled carefully * The delete and update BATs should not be recycled, * because they may lead to view dependencies that later interferes * with the transaction commits. */ /* enable recycling of delta-bats if (getModuleId(p)== sqlRef && (((getFunctionId(p)==bindRef || getFunctionId(p) == putName("bind_idxbat",11)) && getVarConstant(mb, getArg(p,5)).val.ival != 0) || getFunctionId(p)== binddbatRef) ) { recycled[getArg(p,0)]=0; p->recycle = REC_NO_INTEREST; } */ pushInstruction(mb, p); }
str BKCreuseBAT(bat *ret, const bat *bid, const bat *did) { BAT *b, *d, *bn, *bs; oid oidx = 0, bidx, *o, *ol; gdk_return res; if ((b = BATdescriptor(*bid)) == NULL) { throw(MAL, "bat.reuse", RUNTIME_OBJECT_MISSING); } if ( b->htype != TYPE_void) { BBPunfix(b->batCacheid); throw(MAL, "bat.reuse", SEMANTIC_TYPE_MISMATCH); } if ((d = BATdescriptor(*did)) == NULL) { BBPunfix(b->batCacheid); throw(MAL, "bat.reuse", RUNTIME_OBJECT_MISSING); } bn= BATnew(b->htype, b->ttype, BATcount(b) - BATcount(d), TRANSIENT); if (bn == NULL) { BBPunfix(b->batCacheid); BBPunfix(d->batCacheid); throw(MAL, "bat.reuse", MAL_MALLOC_FAIL ); } res = BATsubsort(&bs, NULL, NULL, d, NULL, NULL, 0, 0); BBPunfix(d->batCacheid); if (res != GDK_SUCCEED) { BBPunfix(b->batCacheid); BBPunfix(bn->batCacheid); throw(MAL, "bat.reuse", MAL_MALLOC_FAIL ); } oidx = b->hseqbase; bidx = oidx + BATcount(b)-1; o = (oid*)Tloc(bs, BUNfirst(bs)); ol= (oid*)Tloc(bs, BUNlast(bs)); switch(ATOMstorage(b->ttype) ){ case TYPE_bte: reuseloop(bte); break; case TYPE_sht: reuseloop(sht); break; case TYPE_int: reuseloop(int); break; case TYPE_lng: reuseloop(lng); break; #ifdef HAVE_HGE case TYPE_hge: reuseloop(hge); break; #endif case TYPE_flt: reuseloop(flt); break; case TYPE_dbl: reuseloop(dbl); break; case TYPE_oid: reuseloop(oid); break; case TYPE_str: /* to be done based on its index width */ default: if (ATOMvarsized(bn->ttype)) { BUN p = BUNfirst(b); BUN q = BUNlast(b); BATiter bi = bat_iterator(b); for (;p<q; oidx++, p++) { if ( *o == oidx ){ while ( ol > o && ol[-1] == bidx) { bidx--; q--; ol--; } BUNappend(bn, BUNtail(bi, --q), FALSE); o += (o < ol); bidx--; } else { BUNappend(bn, BUNtail(bi, p), FALSE); } } } else { switch( b->T->width){ case 1:reuseloop(bte); break; case 2:reuseloop(sht); break; case 4:reuseloop(int); break; case 8:reuseloop(lng); break; #ifdef HAVE_HGE case 16:reuseloop(hge); break; #endif default: throw(MAL, "bat.shrink", "Illegal argument type"); } } } BATsetcount(bn, BATcount(b) - BATcount(bs)); BATseqbase(bn, b->hseqbase); bn->tsorted = 0; bn->trevsorted = 0; bn->tdense = 0; bn->tkey = b->tkey; if (!(bn->batDirty&2)) BATsetaccess(bn, BAT_READ); BBPunfix(b->batCacheid); BBPunfix(bs->batCacheid); BBPkeepref(*ret= bn->batCacheid); return MAL_SUCCEED; }
char * atom2string(sql_allocator *sa, atom *a) { char buf[BUFSIZ], *p = NULL; void *v; if (a->isnull) return sa_strdup(sa, "NULL"); switch (a->data.vtype) { #ifdef HAVE_HGE case TYPE_hge: { char *_buf = buf; int _bufsiz = BUFSIZ; hgeToStr(&_buf, &_bufsiz, &a->data.val.hval); break; } #endif case TYPE_lng: sprintf(buf, LLFMT, a->data.val.lval); break; case TYPE_wrd: sprintf(buf, SSZFMT, a->data.val.wval); break; case TYPE_oid: sprintf(buf, OIDFMT "@0", a->data.val.oval); break; case TYPE_int: sprintf(buf, "%d", a->data.val.ival); break; case TYPE_sht: sprintf(buf, "%d", a->data.val.shval); break; case TYPE_bte: sprintf(buf, "%d", a->data.val.btval); break; case TYPE_bit: if (a->data.val.btval) return sa_strdup(sa, "true"); return sa_strdup(sa, "false"); case TYPE_flt: sprintf(buf, "%f", a->data.val.fval); break; case TYPE_dbl: sprintf(buf, "%f", a->data.val.dval); break; case TYPE_str: if (a->data.val.sval) return sa_strdup(sa, a->data.val.sval); else sprintf(buf, "NULL"); break; default: v = &a->data.val.ival; if (ATOMvarsized(a->data.vtype)) v = a->data.val.pval; if (ATOMformat(a->data.vtype, v, &p) < 0) { snprintf(buf, BUFSIZ, "atom2string(TYPE_%d) not implemented", a->data.vtype); } else { char *r = sa_strdup(sa, p); _DELETE(p); return r; } } return sa_strdup(sa, buf); }