Changeset: 044af24979f9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=044af24979f9
Modified Files:
        monetdb5/modules/mal/mal_weld.c
        monetdb5/optimizer/opt_weld.c
Branch: mal-weld
Log Message:

bat[:str] support for group.* and algebra.projection

Most of tpch01.sql now works in weld


diffs (truncated from 335 to 300 lines):

diff --git a/monetdb5/modules/mal/mal_weld.c b/monetdb5/modules/mal/mal_weld.c
--- a/monetdb5/modules/mal/mal_weld.c
+++ b/monetdb5/modules/mal/mal_weld.c
@@ -75,6 +75,17 @@ static str getWeldType(int type) {
                return NULL;
 }
 
+static str getWeldUTypeFromWidth(int width) {
+       if (width == 1)
+               return "u8";
+       else if (width == 2)
+               return "u16";
+       else if (width == 4)
+               return "u32";
+       else
+               return "u64";
+}
+
 static void getOrSetStructMember(char **addr, int type, void *value, int op) {
        if (type == TYPE_bte) {
                getOrSetStructMemberImpl(addr, char, value, op);
@@ -147,7 +158,7 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS
        (void)cntxt;
        (void)mb;
        weldState *wstate = *getArgReference_ptr(stk, pci, pci->retc);
-       int i, inputLen = 0, inputMaxLen = 0, outputLen = 0, outputMaxLen = 0;
+       int i, j, inputLen = 0, inputMaxLen = 0, outputLen = 0, outputMaxLen = 
0;
        str inputStmt = NULL, outputStmt = NULL;
 
        /* Build the input stmt, e.g.: |v13:i32, v50:vec[i8], v50hseqbase:i64| 
*/
@@ -157,9 +168,17 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS
                        inputStmt = realloc(inputStmt, inputMaxLen * 
sizeof(char));
                }
                int type = getArgType(mb, pci, i);
-               if (isaBatType(type)) {
+               if (isaBatType(type) && getBatType(type) != TYPE_str) {
                        inputLen += sprintf(inputStmt + inputLen, " 
v%d:vec[%s], v%dhseqbase:i64,",
                                                                getArg(pci, i), 
getWeldType(getBatType(type)), getArg(pci, i));
+               } else if (isaBatType(type) && getBatType(type) == TYPE_str) {
+                       bat bid = *getArgReference_bat(stk, pci, i);
+                       BAT *b = BATdescriptor(bid);
+                       if (b == NULL) throw(MAL, "weld.run", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+                       inputLen += sprintf(inputStmt + inputLen,
+                                                               " v%d:vec[%s], 
v%dhseqbase:i64, v%dstr:vec[i8], v%dstroffset:i64,",
+                                                               getArg(pci, i), 
getWeldUTypeFromWidth(b->twidth), getArg(pci, i),
+                                                               getArg(pci, i), 
getArg(pci, i));
                } else {
                        inputLen +=
                                sprintf(inputStmt + inputLen, " v%d:%s,", 
getArg(pci, i), getWeldType(type));
@@ -184,7 +203,12 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS
                        outputMaxLen += STR_SIZE_INC;
                        outputStmt = realloc(outputStmt, outputMaxLen * 
sizeof(char));
                }
+               int type = getArgType(mb, pci, i);
                outputLen += sprintf(outputStmt + outputLen, " v%d,", 
getArg(pci, i));
+               if (isaBatType(type) && getBatType(type) == TYPE_str) {
+                       /* Also return the string column base ptr */
+                       outputLen += sprintf(outputStmt + outputLen, " 
v%dstr,", getArg(pci, i));
+               }
        }
 
        outputStmt[0] = '{';
@@ -210,11 +234,11 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS
        }
 
        /* Prepare the input for Weld. We're building an array that has the 
layout of a struct */
-       /* Max possible size is when we only have bats, so we have 1 ptr for 
the array,
-        * 1 lng for the size and 1 lng for hseqbase. The extra 10 * 
sizeof(double) are for the
-        * constants */
-       char *inputStruct =
-               malloc((pci->argc - pci->retc) * (sizeof(void *) + 2 * 
sizeof(lng)) + 10 * sizeof(double));
+       /* Max possible size is when we only have string bats: 2 ptrs for theap 
and tvheap and 4 lngs
+        * for batCount, hseqbase, stroffset and tvheap->size.
+        * The extra 10 * sizeof(double) are for the constants */
+       char *inputStruct = malloc((pci->argc - pci->retc) * (2 * sizeof(void 
*) + 3 * sizeof(lng)) +
+                                                          10 * sizeof(double));
        char *inputPtr = inputStruct;
        for (i = pci->retc + 1; i < pci->argc; i++) { /* skip wstate on 
pci->retc */
                int type = getArgType(mb, pci, i);
@@ -222,10 +246,15 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS
                        bat bid = *getArgReference_bat(stk, pci, i);
                        BAT *b = BATdescriptor(bid);
                        if (b == NULL) throw(MAL, "weld.run", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
-                       /* TODO handle string colums */
                        getOrSetStructMember(&inputPtr, TYPE_ptr, 
&b->theap.base, OP_SET);
                        getOrSetStructMember(&inputPtr, TYPE_lng, &b->batCount, 
OP_SET);
                        getOrSetStructMember(&inputPtr, TYPE_lng, &b->hseqbase, 
OP_SET);
+                       if (getBatType(type) == TYPE_str) {
+                               getOrSetStructMember(&inputPtr, TYPE_str, 
&b->tvheap->base, OP_SET);
+                               getOrSetStructMember(&inputPtr, TYPE_lng, 
&b->tvheap->size, OP_SET);
+                               lng offset = b->twidth <= 2 ? GDK_VAROFFSET : 0;
+                               getOrSetStructMember(&inputPtr, TYPE_lng, 
&offset, OP_SET);
+                       }
                } else {
                        getOrSetStructMember(&inputPtr, type, 
getArgReference(stk, pci, i), OP_SET);
                        if (type == TYPE_str) {
@@ -255,7 +284,6 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS
                int type = getArgType(mb, pci, i);
                if (isaBatType(type)) {
                        BAT *b = COLnew(0, getBatType(type), 0, TRANSIENT);
-                       /* TODO handle string columns */
                        getOrSetStructMember(&outputStruct, TYPE_ptr, 
&b->theap.base, OP_GET);
                        getOrSetStructMember(&outputStruct, TYPE_lng, 
&b->batCount, OP_GET);
                        b->theap.free = b->batCount << b->tshift;
@@ -264,6 +292,30 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS
                        b->theap.storage = STORE_CMEM;
                        /* TODO check if the sorted props are important for the 
rest of the execution */
                        b->tsorted = b->trevsorted = 0;
+                       if (getBatType(type) == TYPE_str) {
+                               char *base;
+                               long size;
+                               getOrSetStructMember(&outputStruct, TYPE_str, 
&base, OP_GET);
+                               getOrSetStructMember(&outputStruct, TYPE_lng, 
&size, OP_GET);
+                               /* Find the matching vheap from the input bats 
*/
+                               for (j = pci->retc; j < pci->argc; j++) {
+                                       int inputType = getArgType(mb, pci, j);
+                                       if (isaBatType(inputType) && 
getBatType(inputType) == TYPE_str) {
+                                               bat inid = 
*getArgReference_bat(stk, pci, j);
+                                               BAT *in = BATdescriptor(inid);
+                                               if (in == NULL) throw(MAL, 
"weld.run", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+                                               if (in->tvheap->base == base) {
+                                                       
BBPshare(in->tvheap->parentid);
+                                                       b->tvheap = in->tvheap;
+                                                       b->ttype = in->ttype;
+                                                       b->twidth = in->twidth;
+                                                       b->tshift = in->tshift;
+                                                       b->tvarsized = 1;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
                        BBPkeepref(b->batCacheid);
                        *getArgReference_bat(stk, pci, i) = b->batCacheid;
                } else {
@@ -344,16 +396,22 @@ WeldAlgebraProjection(Client cntxt, MalB
        bat leftBat = *getArgReference_bat(stk, pci, 1);           /* might 
have value */
        int right = getArg(pci, 2);                                             
           /* bat[:any_1] */
        weldState *wstate = *getArgReference_ptr(stk, pci, 3); /* has value */
-       str any_1 = getWeldType(getBatType(getArgType(mb, pci, 0)));
        char weldStmt[STR_SIZE_INC];
        sprintf(weldStmt, "\
        let v%d = result( \
-               for (%s, appender[%s], |b: appender[%s], i: i64, oid: i64| \
+               for (%s, appender[?], |b, i, oid| \
                        merge(b, lookup(v%d, oid - v%dhseqbase)) \
                ) \
        ); \
        let v%dhseqbase = 0L;",
-       ret, getWeldCandList(left, leftBat), any_1, any_1, right, right, ret);
+       ret, getWeldCandList(left, leftBat), right, right, ret);
+       if (getBatType(getArgType(mb, pci, 0)) == TYPE_str) {
+               /* any_1 = str */
+               sprintf(weldStmt + strlen(weldStmt), "\
+               let v%dstr = v%dstr;\
+               let v%dstroffset = v%dstroffset;",
+               ret, right, ret, right);
+       }
        appendWeldStmt(wstate, weldStmt);
        return MAL_SUCCEED;
 }
@@ -487,8 +545,7 @@ WeldBatcalcBinary(MalBlkPtr mb, MalStkPt
        int rightType = getArgType(mb, pci, 2);
        str any_1 = getWeldType(getBatType(getArgType(mb, pci, 0)));
 
-       /* TODO Weld doesn't yet accept mismatching types for binary ops */
-       if (leftType != rightType) {
+       if (getBatType(leftType) != getBatType(rightType)) {
                throw(MAL, malfunc, PROGRAM_NYI);
        }
 
@@ -509,40 +566,40 @@ WeldBatcalcBinary(MalBlkPtr mb, MalStkPt
 
                sprintf(weldStmt, "\
                let v%d = result( \
-                       for (%s, appender[%s], |b: appender[%s], i: i64, oid: 
i64| \
+                       for (%s, appender[%s], |b, i, oid| \
                                merge(b, %s %s %s) \
                        ) \
                ); \
                let v%dhseqbase = 0L;",
-               ret, getWeldCandList(sid, s), any_1, any_1, leftStmt, op, 
rightStmt, ret);
+               ret, getWeldCandList(sid, s), any_1, leftStmt, op, rightStmt, 
ret);
        } else {
                if (isaBatType(leftType) && isaBatType(rightType)) {
                        sprintf(weldStmt, "\
                        let v%d = result( \
-                               for (zip(v%d, v%d), appender[%s], |b: 
appender[%s], i: i64, x: {%s, %s}| \
+                               for (zip(v%d, v%d), appender[%s], |b , i, x| \
                                        merge(b, x.$0 %s x.$1) \
                                ) \
                        ); \
                        let v%dhseqbase = 0L;",
-                       ret, left, right, any_1, any_1, any_1, any_1, op, ret);
+                       ret, left, right, any_1, op, ret);
                } else if (isaBatType(leftType)) {
                        sprintf(weldStmt, "\
                        let v%d = result( \
-                               for (v%d, |b: appender[%s], i: i64, x: %s| \
+                               for (v%d, appender[%s], |b, i, x| \
                                        merge(b, x %s v%d) \
                                ) \
                        ); \
                        let v%dhseqbase = 0L;",
-                       ret, left, any_1, any_1, op, right, ret);
+                       ret, left, any_1, op, right, ret);
                } else if (isaBatType(rightType)) {
                        sprintf(weldStmt, "\
                        let v%d = result( \
-                               for (v%d, |b: appender[%s], i: i64, x: %s| \
+                               for (v%d, appender[%s], |b, i, x| \
                                        merge(b, v%d %s x) \
                                ) \
                        ); \
                        let v%dhseqbase = 0L;",
-                       ret, right, any_1, any_1, right, op, ret);
+                       ret, right, any_1, left, op, ret);
                }
        }
        appendWeldStmt(wstate, weldStmt);
@@ -594,34 +651,50 @@ WeldGroup(Client cntxt, MalBlkPtr mb, Ma
        InstrPtr dep = pci;
        char zipStmt[STR_SIZE_INC] = {'\0'};
        char dictTypeStmt[STR_SIZE_INC] = {'\0'};
+       char dictKeyStmt[STR_SIZE_INC] = {'\0'};
+       char structMember[64];
        int count = 0;
        while (dep != NULL) {
-               ++count;
                int col = getArg(dep, 3);
                int colType = getBatType(getArgType(mb, dep, 3));
-               sprintf(zipStmt + strlen(zipStmt), "v%d,", col);
-               sprintf(dictTypeStmt + strlen(dictTypeStmt), " %s,", 
getWeldType(colType));
                if (dep->argc == 6) {
                        int oldGrps = getArg(dep, 4);
                        dep = wstate->groupDeps[oldGrps];
                } else {
                        dep = NULL;
                }
+               sprintf(zipStmt + strlen(zipStmt), "v%d,", col);
+               sprintf(dictTypeStmt + strlen(dictTypeStmt), " %s,", 
getWeldType(colType));
+               if (count > 0 || dep != NULL) {
+                       sprintf(structMember, ".$%d", count);
+               } else {
+                       structMember[0] = '\0';
+               }
+               if (getBatType(colType) == TYPE_str) {
+                       sprintf(dictKeyStmt + strlen(dictKeyStmt),
+                                       " strslice(v%dstr, i64(n%s) + 
v%dstroffset),", col, structMember, col);
+               } else {
+                       sprintf(dictKeyStmt + strlen(dictKeyStmt), " n%s,", 
structMember);
+               }
+               ++count;
        }
        /* Replace the last comma */
        zipStmt[strlen(zipStmt) - 1] = '\0';
        if (count == 1) {
                dictTypeStmt[strlen(dictTypeStmt) - 1] = '\0';
+               dictKeyStmt[strlen(dictKeyStmt) -1] = '\0';
        } else {
                dictTypeStmt[0] = '{';
                dictTypeStmt[strlen(dictTypeStmt) - 1] = '}';
+               dictKeyStmt[0] = '{';
+               dictKeyStmt[strlen(dictKeyStmt) -1] = '}';
        }
 
        char weldStmt[STR_SIZE_INC * 2];
        sprintf(weldStmt, "\
        let groupHash = result( \
                for(zip(%s), dictmerger[%s, i64, min], |b, i, n| \
-                       merge(b, {n, i}) \
+                       merge(b, {%s, i}) \
                ) \
        ); \
        let groupHashVec = tovec(groupHash); \
@@ -636,7 +709,7 @@ WeldGroup(Client cntxt, MalBlkPtr mb, Ma
                ) \
        ); \
        let idsAndCounts = for(zip(%s), {appender[i64], vecmerger[i64, 
+](empty)}, |b, i, n| \
-               let groupId = lookup(groupIdsDict, n); \
+               let groupId = lookup(groupIdsDict, %s); \
                {merge(b.$0, groupId), merge(b.$1, {groupId, 1L})} \
        ); \
        let v%d = result(idsAndCounts.$0); \
@@ -649,7 +722,8 @@ WeldGroup(Client cntxt, MalBlkPtr mb, Ma
                ) \
        ); \
        let v%dhseqbase = 0;",
-       zipStmt, dictTypeStmt, dictTypeStmt, zipStmt, groups, groups, histo, 
histo, extents, extents);
+       zipStmt, dictTypeStmt, dictKeyStmt, dictTypeStmt, zipStmt, dictKeyStmt, 
groups, groups, histo, histo,
+       extents, extents);
        appendWeldStmt(wstate, weldStmt);
        return MAL_SUCCEED;
 }
diff --git a/monetdb5/optimizer/opt_weld.c b/monetdb5/optimizer/opt_weld.c
--- a/monetdb5/optimizer/opt_weld.c
+++ b/monetdb5/optimizer/opt_weld.c
@@ -62,8 +62,16 @@ static void initWeldInstrs(void) {
        addWeldInstr(groupRef, subgroupdoneRef, weldGroupRef);                  
         /* group.subgroupdone */
 }
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to