Changeset: 5e512a237e01 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5e512a237e01 Modified Files: monetdb5/optimizer/opt_mergetable.c Branch: default Log Message:
merged with Jun2016 diffs (169 lines): diff --git a/monetdb5/optimizer/opt_mergetable.c b/monetdb5/optimizer/opt_mergetable.c --- a/monetdb5/optimizer/opt_mergetable.c +++ b/monetdb5/optimizer/opt_mergetable.c @@ -629,14 +629,61 @@ mat_join2(MalBlkPtr mb, InstrPtr p, matl mat_add(ml, r, mat_none, getFunctionId(p)); } +static int +subjoin_split(Client cntxt, InstrPtr p, int args) +{ + char *name; + int len, i, res = 0; + Symbol sym; + MalBlkPtr mb; + InstrPtr q; + + if (args <= 2) /* we asume there are no 2x1 joins! */ + return 1; + + len = strlen( getFunctionId(p) ); + name = GDKmalloc(len+3); + strncpy(name, getFunctionId(p), len-7); + strcpy(name+len-7, "subselect"); + + sym = findSymbol(cntxt->nspace, getModuleId(p), name); + assert(sym); + mb = sym->def; + + q = mb->stmt[0]; + for(i = q->retc; i<q->argc; i++ ) { + if (isaBatType(getArgType(mb,q,i))) + res++; + else + break; + } + return res-1; +} + +/* 1 or 2 mat lists: + * in case of one take the second half of the code + * in case of two we need to detect the list lengths. + * + * input is one list of arguments (just total length of mats) + */ static void -mat_join3(MalBlkPtr mb, InstrPtr p, matlist_t *ml, int m, int n, int o) +mat_joinNxM(Client cntxt, MalBlkPtr mb, InstrPtr p, matlist_t *ml, int args) { int tpe = getArgType(mb,p, 0), j,k, nr = 1; InstrPtr l = newInstruction(mb, ASSIGNsymbol); InstrPtr r = newInstruction(mb, ASSIGNsymbol); mat_t *mat = ml->v; + int *mats = (int*)GDKzalloc(sizeof(int) * args); + int nr_mats = 0, first = 0; + for(j=0;j<args;j++) { + mats[j] = is_a_mat(getArg(p,p->retc+j), ml); + if (mats[j] != -1) { + nr_mats++; + if (!first) + first = j; + } + } setModuleId(l,matRef); setFunctionId(l,packRef); getArg(l,0) = getArg(p,0); @@ -647,22 +694,27 @@ mat_join3(MalBlkPtr mb, InstrPtr p, matl //printf("# %s.%s(%d,%d)", getModuleId(p), getFunctionId(p), m, n); - assert(m>=0 || n>=0); - if (m >= 0 && n >= 0 && o >= 0) { - assert(mat[n].mi->argc == mat[o].mi->argc); - for(k=1; k<mat[m].mi->argc; k++) { - for (j=1; j<mat[n].mi->argc; j++) { + if (args == nr_mats) { + int mv1 = mats[0], i; + int mv2 = mats[args-1]; + int split = subjoin_split(cntxt, p, args); + int nr_mv1 = split, nr_mv2 = nr_mats-split; + + /* now detect split point */ + for(k=1; k<mat[mv1].mi->argc; k++) { + for (j=1; j<mat[mv2].mi->argc; j++) { InstrPtr q = copyInstruction(p); getArg(q,0) = newTmpVariable(mb, tpe); getArg(q,1) = newTmpVariable(mb, tpe); - getArg(q,2) = getArg(mat[m].mi,k); - getArg(q,3) = getArg(mat[n].mi,j); - getArg(q,4) = getArg(mat[o].mi,j); + for (i = 0; i < nr_mv1; i++ ) + getArg(q,q->retc+i) = getArg(mat[mats[i]].mi,k); + for (i = 0; i < nr_mv2; i++ ) + getArg(q,q->retc+split+i) = getArg(mat[mats[i]].mi,k); pushInstruction(mb,q); - propagatePartnr(ml, getArg(mat[m].mi, k), getArg(q,0), nr); - propagatePartnr(ml, getArg(mat[n].mi, j), getArg(q,1), nr); + propagatePartnr(ml, getArg(mat[mv1].mi, k), getArg(q,0), nr); + propagatePartnr(ml, getArg(mat[mv2].mi, j), getArg(q,1), nr); /* add result to mat */ l = pushArgument(mb,l,getArg(q,0)); @@ -671,23 +723,24 @@ mat_join3(MalBlkPtr mb, InstrPtr p, matl } } } else { - int mv = (m>=0)?m:n; - int av = (m<0); - int bv = (m>=0); + /* only one side + * mats from first..first+nr_mats + */ + int mv = mats[first]; for(k=1; k<mat[mv].mi->argc; k++) { InstrPtr q = copyInstruction(p); getArg(q,0) = newTmpVariable(mb, tpe); getArg(q,1) = newTmpVariable(mb, tpe); - getArg(q,p->retc+av) = getArg(mat[mv].mi, k); - if (o >= 0) - getArg(q,p->retc+2) = getArg(mat[o].mi, k); + for (j=0;j<nr_mats;j++) { + assert(mat[mats[first]].mi->argc == mat[mats[first+j]].mi->argc); + getArg(q,p->retc+first+j) = getArg(mat[mats[first+j]].mi, k); + } + propagatePartnr(ml, getArg(mat[mv].mi, k), getArg(q,(first!=0)), k); + propagatePartnr(ml, getArg(p, p->retc+(first)?nr_mats:0), getArg(q,(first==0)), k); pushInstruction(mb,q); - propagatePartnr(ml, getArg(mat[mv].mi, k), getArg(q,av), k); - propagatePartnr(ml, getArg(p, p->retc+bv), getArg(q,bv), k); - /* add result to mat */ l = pushArgument(mb, l, getArg(q,0)); r = pushArgument(mb, r, getArg(q,1)); @@ -1583,17 +1636,20 @@ OPTmergetableImplementation(Client cntxt } bats = nr_of_bats(mb, p); - /* (l,r) Join (L, R, ..) */ - if (match > 0 && isMatJoinOp(p) && p->argc >= 3 && p->retc == 2 && - match <= 3 && bats >= 2) { - m = is_a_mat(getArg(p,p->retc), &ml); - n = is_a_mat(getArg(p,p->retc+1), &ml); - o = is_a_mat(getArg(p,p->retc+2), &ml); - - if (bats == 3 && match >= 2) - mat_join3(mb, p, &ml, m, n, o); - else + /* (l,r) Join (L, R, ..) + * 2 -> (l,r) equi/theta joins (l,r) + * 3 -> (l,r) range-joins (l,r1,r2) + * NxM -> (l,r) filter-joins (l1,..,ln,r1,..,rm) + */ + if (match > 0 && isMatJoinOp(p) && + p->argc >= 3 && p->retc == 2 && bats >= 2) { + if (bats == 2) { + m = is_a_mat(getArg(p,p->retc), &ml); + n = is_a_mat(getArg(p,p->retc+1), &ml); mat_join2(mb, p, &ml, m, n); + } else { + mat_joinNxM(cntxt, mb, p, &ml, bats); + } actions++; continue; } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list