Update of /cvsroot/monetdb/pathfinder/runtime
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv31233

Modified Files:
      Tag: xquery-decomposition
        rt_projection.mx 
Log Message:
added code to add xrpc:id attribute.
but we have decided to not to add this attribute to projected xrpc
fragments, so commit code before removing them.



Index: rt_projection.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/Attic/rt_projection.mx,v
retrieving revision 1.1.2.10
retrieving revision 1.1.2.11
diff -u -d -r1.1.2.10 -r1.1.2.11
--- rt_projection.mx    4 Mar 2008 17:34:04 -0000       1.1.2.10
+++ rt_projection.mx    7 Mar 2008 16:05:45 -0000       1.1.2.11
@@ -69,6 +69,7 @@
 #include "pf_config.h"
 #include "pf_support.h" /* for PF_SIBLING_PROBES and speculate_skip() */
 #include "shredder.h" /* for XML_DEPTH_MAX */
+#include "xrpc_common.h" /* for XRPC_NS */
 #include "rt_projection.h"
 
 #define USED 0
@@ -111,6 +112,29 @@
     oid *off;
 } stack;
 
+/* Concatenate two strings, separated with ':'.
+ * Results goes into 'res', '\0' terminated */
+static INLINE char *
+strs_concat(str str1, str str2)
+{
+    int i = 0, j = 0;
+    int len1 = strlen(str1), len2 = strlen(str2);
+    char *res = NULL;
+
+    if(!(res = GDKmalloc(len1 + len2 + 2))){
+        GDKerror("strs_concat: failed to malloc 'res'\n");
+        return NULL;
+    } else {
+        for(i = 0, j = 0; j < len1; i++, j++)
+            res[i] = str1[j];
+        res[i++] = '|';
+        for(j = 0; j < len2; i++, j++)
+            res[i] = str2[j];
+        res[i] = '\0';
+    }
+    return res;
+}
+
 static INLINE oid 
 skipholes(oid pre, unsigned int *pre_size) {
     while(pre_size[pre] & (1<<31)) 
@@ -167,6 +191,31 @@
     return newContID;
 }
 
+static INLINE oid
+getAttrOwner_(oid attr, oid nnid, oid *attr_own, oid *pre_nid)
+{
+    oid i, owner = attr_own[attr];
+
+    /* find pre of this nid in pre_nid for updatable document */
+    for(i = 0; i < nnid && pre_nid; i++) {
+        if(pre_nid[i] == owner) {
+            return i;
+        }
+    }
+    return owner;
+}
+
+static INLINE oid
+getAttrOwner(oid attr, BAT *attr_own_bat, BAT *pre_nid_bat)
+{
+    oid *pre_nid = NULL, *attr_own = NULL;
+
+    pre_nid = (oid*) Tloc(pre_nid_bat, BUNfirst(pre_nid_bat)); /* can be NULL! 
*/
+    attr_own = (oid*) Tloc(attr_own_bat, BUNfirst(attr_own_bat));
+
+    return getAttrOwner_(attr, BATcount(attr_own_bat), attr_own, pre_nid);
+}
+
 /* delete the contID-th BUN of WS[0 t/m batIDmax]
  * Returns: GDK_SUCCEED or GDK_FAIL
  */
@@ -188,12 +237,12 @@
         if(wsbun == BUN_NONE) {
             GDKerror("rmContainer: NOT FOUND WS["OIDFMT"], "
                     "WS might have been corrupted.\n", i);
-            ret = GDK_FAIL;
+            assert(0);
         }
         if( !(wsbat = BATdescriptor(*(bat*)Tloc(ws,wsbun))) ) {
             GDKerror("rmContainer: FETCH BATBAT for WS["OIDFMT"] "
                     "FAILED, WS might have been corrupted\n", i);
-            ret = GDK_FAIL;
+            assert(0);
         }
         bi = bat_iterator(wsbat);
         BUNfndVOID(bun, bi, (ptr)&contID);
@@ -201,14 +250,14 @@
             GDKerror("rmContainer: NOT FOUND WS["OIDFMT"]["OIDFMT"], "
                     "WS might have been corrupted\n", i, contID);
             BBPunfix(BBPcacheid(wsbat));
-            ret = GDK_FAIL;
+            assert(0);
         }
         if(BUNdelete(wsbat, bun, FALSE) == BUN_NONE) {
             GDKerror("rmContainer: failed to delete "OIDFMT"-th BUN of "
                     "WS["OIDFMT"], WS might have been corrupted\n",
                     contID, i);
             BBPunfix(BBPcacheid(wsbat));
-            ret = GDK_FAIL;
+            assert(0);
         }
         BBPunfix(BBPcacheid(wsbat));
     }
@@ -231,60 +280,167 @@
         BAT *pre_level,
         BAT *pre_prop,
         BAT *pre_kind,
-        BAT *pre_nid)
+        BAT *pre_nid,
+        BAT *qn_prefix_uri_loc,
+        BAT *qn_uri_loc,
+        BAT *qn_prefix,
+        BAT *qn_uri,
+        BAT *qn_loc,
+        BAT *prop_val,
+        BAT *attr_own,
+        BAT *attr_qn,
+        BAT *attr_prop)
 {
     BAT *wsbat= NULL;
     BUN wsbun = BUN_NONE, bun = BUN_NONE;
     BATiter wsbi, bi;
     oid off = MAP_PID;
     bat batid = 0;
-    
+
     assert(ws != NULL && pre_size != NULL && pre_level != NULL &&
             pre_prop != NULL && pre_kind != NULL && pre_nid != NULL);
-    assert(contIDnew > contIDfrom);
+    ERRORcheck(contIDnew <= contIDfrom,
+            "cp2Container: contIDnew MUST be larger than contIDfrom\n");
+    ERRORcheck(!( (qn_prefix_uri_loc && qn_uri_loc && qn_prefix && qn_uri && 
qn_loc &&
+                   prop_val && attr_own && attr_qn && attr_prop) ||
+                  (!qn_prefix_uri_loc && !qn_uri_loc && !qn_prefix && !qn_uri 
&& !qn_loc &&
+                   !prop_val && !attr_own && !attr_qn && !attr_prop) ),
+            "cp2Container: attribute related BATs MUST be all given, or all 
not");
     
     wsbi = bat_iterator(ws);
-    for(off = MAP_PID; off <= ATTR_OWN_SHARED; off++){
-        BUNfndVOID(wsbun, wsbi, (ptr)&off);
-        if(wsbun == BUN_NONE) {
-            GDKerror("cp2Container: NOT FOUND WS["OIDFMT"]\n", off);
-            rmContainer(ws, (off -1), contIDnew);
-            return GDK_FAIL;
-        }
-        if( !(wsbat = BATdescriptor(*(bat*)Tloc(ws,wsbun))) ) {
-            GDKerror("cp2Container: FETCH BATBAT for WS["OIDFMT"] "
-                    "FAILED\n", off);
-            rmContainer(ws, (off -1), contIDnew);
-            return -1;
-        }
-        bi = bat_iterator(wsbat);
-        if(MAP_PID < off && off < NID_RID) { /* copy 
PRE_SIZE|LEVEL|PROP|KIND|NID */
-            if(off == PRE_SIZE)  batid = BBPcacheid(pre_size);
-            if(off == PRE_LEVEL) batid = BBPcacheid(pre_level);
-            if(off == PRE_PROP)  batid = BBPcacheid(pre_prop);
-            if(off == PRE_KIND)  batid = BBPcacheid(pre_kind);
-            if(off == PRE_NID)   batid = BBPcacheid(pre_nid);
-        } else { /* copy other ws BATs */
-            BUNfndVOID(bun, bi, (ptr)&contIDfrom);
-            if(bun == BUN_NONE) {
-                GDKerror("cp2Container: NOT FOUND WS["OIDFMT"]["OIDFMT"]\n",
-                        off, contIDfrom);
+    if(qn_prefix_uri_loc) {
+        for(off = MAP_PID; off <= ATTR_OWN_SHARED; off++){
+            BUNfndVOID(wsbun, wsbi, (ptr)&off);
+            if(wsbun == BUN_NONE) {
+                GDKerror("cp2Container: NOT FOUND WS["OIDFMT"]\n", off);
+                rmContainer(ws, (off -1), contIDnew);
+                return GDK_FAIL;
+            }
+            if( !(wsbat = BATdescriptor(*(bat*)Tloc(ws,wsbun))) ) {
+                GDKerror("cp2Container: FETCH BATBAT for WS["OIDFMT"] "
+                        "FAILED\n", off);
+                rmContainer(ws, (off -1), contIDnew);
+                return GDK_FAIL;
+            }
+            bi = bat_iterator(wsbat);
+            switch(off){
+                case PRE_SIZE:
+                    batid = BBPcacheid(pre_size);
+                    break;
+                case PRE_LEVEL:
+                    batid = BBPcacheid(pre_level);
+                    break;
+                case PRE_PROP:
+                    batid = BBPcacheid(pre_prop);
+                    break;
+                case PRE_KIND:
+                    batid = BBPcacheid(pre_kind);
+                    break;
+                case PRE_NID:
+                    batid = BBPcacheid(pre_nid);
+                    break;
+                case QN_PREFIX_URI_LOC:
+                    batid = BBPcacheid(qn_prefix_uri_loc);
+                    break;
+                case QN_URI_LOC:
+                    batid = BBPcacheid(qn_uri_loc);
+                    break;
+                case QN_PREFIX:
+                    batid = BBPcacheid(qn_prefix);
+                    break;
+                case QN_URI:
+                    batid = BBPcacheid(qn_uri);
+                    break;
+                case QN_LOC:
+                    batid = BBPcacheid(qn_loc);
+                    break;
+                case PROP_VAL:
+                    batid = BBPcacheid(prop_val);
+                    break;
+                case ATTR_OWN:
+                    batid = BBPcacheid(attr_own);
+                    break;
+                case ATTR_QN:
+                    batid = BBPcacheid(attr_qn);
+                    break;
+                case ATTR_PROP:
+                    batid = BBPcacheid(attr_prop);
+                    break;
+                default: /* copy other ws BATs */
+                    BUNfndVOID(bun, bi, (ptr)&contIDfrom);
+                    if(bun == BUN_NONE) {
+                        GDKerror("cp2Container: NOT FOUND 
WS["OIDFMT"]["OIDFMT"]\n",
+                                off, contIDfrom);
+                        BBPunfix(BBPcacheid(wsbat));
+                        rmContainer(ws, (off -1), contIDnew);
+                        return GDK_FAIL;
+                    }
+                    batid = *(bat*)BUNtail(bi, bun);
+                    break;
+            }
+            if(!BUNappend(wsbat, &batid, FALSE)){
+                GDKerror("cp2Container: BUNappend(ws["OIDFMT"], %d) failed\n",
+                        off, batid);
                 BBPunfix(BBPcacheid(wsbat));
                 rmContainer(ws, (off -1), contIDnew);
                 return GDK_FAIL;
             }
-            batid = *(bat*)BUNtail(bi, bun);
+            BBPunfix(BBPcacheid(wsbat));
         }
-        if(BUNappend(wsbat, &batid, FALSE) == NULL){
-            GDKerror("cp2Container: BUNappend(ws["OIDFMT"], %d) failed\n",
-                    off, batid);
+    } else {
+        for(off = MAP_PID; off <= ATTR_OWN_SHARED; off++){
+            BUNfndVOID(wsbun, wsbi, (ptr)&off);
+            if(wsbun == BUN_NONE) {
+                GDKerror("cp2Container: NOT FOUND WS["OIDFMT"]\n", off);
+                rmContainer(ws, (off -1), contIDnew);
+                return GDK_FAIL;
+            }
+            if( !(wsbat = BATdescriptor(*(bat*)Tloc(ws,wsbun))) ) {
+                GDKerror("cp2Container: FETCH BATBAT for WS["OIDFMT"] "
+                        "FAILED\n", off);
+                rmContainer(ws, (off -1), contIDnew);
+                return -1;
+            }
+            bi = bat_iterator(wsbat);
+            switch(off){
+                case PRE_SIZE:
+                    batid = BBPcacheid(pre_size);
+                    break;
+                case PRE_LEVEL:
+                    batid = BBPcacheid(pre_level);
+                    break;
+                case PRE_PROP:
+                    batid = BBPcacheid(pre_prop);
+                    break;
+                case PRE_KIND:
+                    batid = BBPcacheid(pre_kind);
+                    break;
+                case PRE_NID:
+                    batid = BBPcacheid(pre_nid);
+                    break;
+                default: /* copy other ws BATs */
+                    BUNfndVOID(bun, bi, (ptr)&contIDfrom);
+                    if(bun == BUN_NONE) {
+                        GDKerror("cp2Container: NOT FOUND 
WS["OIDFMT"]["OIDFMT"]\n",
+                                off, contIDfrom);
+                        BBPunfix(BBPcacheid(wsbat));
+                        rmContainer(ws, (off -1), contIDnew);
+                        return GDK_FAIL;
+                    }
+                    batid = *(bat*)BUNtail(bi, bun);
+                    break;
+            }
+            if(!BUNappend(wsbat, &batid, FALSE)){
+                GDKerror("cp2Container: BUNappend(ws["OIDFMT"], %d) failed\n",
+                        off, batid);
+                BBPunfix(BBPcacheid(wsbat));
+                rmContainer(ws, (off -1), contIDnew);
+                return GDK_FAIL;
+            }
             BBPunfix(BBPcacheid(wsbat));
-            rmContainer(ws, (off -1), contIDnew);
-            return GDK_FAIL;
         }
-            
-        BBPunfix(BBPcacheid(wsbat));
     }
+    
     return GDK_SUCCEED;
 }
 
@@ -454,15 +610,8 @@
         if(XTRACT_KIND(rkinds[i]) == ATTR) {
             hasAttr = TRUE;
             attr = ritems[i]; /* offset of this attribute in attr_* tables */
-            owner = attr_own[attr]; /* nid of attr's parent */
-            /* find pre of this nid in pre_nid for updatable document */
-            for(j = 0; j < nnid && pre_nid; j++){
-                if(pre_nid[j] == owner) {
-                    owner = j;
-                    break;
-                }
-            }
-            if(BUNappend(ctx_uitem, (ptr)&owner, FALSE) == NULL){
+            owner = getAttrOwner_(attr, nnid, attr_own, pre_nid);
+            if(!BUNappend(ctx_uitem, (ptr)&owner, FALSE)){
                 GDKerror("getProjectionCtx: BUNappend(ctx_uitem, "OIDFMT") 
failed\n",
                         ritems[i]);
                 BBPreclaim(ctx_uitem); BBPreclaim(ctx_ritem);
@@ -472,7 +621,7 @@
             }
         } else {
             /* append this returned node to ctx_ritem */
-            if(BUNappend(ctx_ritem, (ptr)&ritems[i], FALSE) == NULL){
+            if(!BUNappend(ctx_ritem, (ptr)&ritems[i], FALSE)){
                 GDKerror("getProjectionCtx: BUNappend(ctx_ritem, "OIDFMT") 
failed\n",
                         ritems[i]);
                 BBPreclaim(ctx_uitem); BBPreclaim(ctx_ritem);
@@ -504,7 +653,7 @@
                     break;
                 }
             }
-            if(BUNreplace(ctx_uitem, (ptr)&i, (ptr)&owner, FALSE) == NULL) {
+            if(!BUNreplace(ctx_uitem, (ptr)&i, (ptr)&owner, FALSE)) {
                 GDKerror("getProjectionCtx: BUNreplace(ctx_uitem, "OIDFMT", 
"OIDFMT") failed\n",
                         i, owner);
                 BBPreclaim(ctx_uitem); BBPreclaim(ctx_ritem);
@@ -707,29 +856,29 @@
                 if(stk.off[i] == oid_nil){ /* not written to output yet */
                     stk.off[i] = BATcount(res[0]);
                     newsize = stk.depth - i - 1 + inc; /* nodes above me on 
stack and size of ctx->pre[cur] */
-                    if(BUNappend(res[0], (ptr)&newsize, FALSE) == NULL){
+                    if(!BUNappend(res[0], (ptr)&newsize, FALSE)){
                         GDKerror("getProjectedNodes: append to res[0] 
failed\n");
                         goto getpnodes_failed;
                     }
-                    if(BUNappend(res[1], (ptr)&pre_level[stk.pre[i]], FALSE) 
== NULL){
+                    if(!BUNappend(res[1], (ptr)&pre_level[stk.pre[i]], FALSE)){
                         GDKerror("getProjectedNodes: append to res[1] 
failed\n");
                         goto getpnodes_failed;
                     }
-                    if(BUNappend(res[2], (ptr)&pre_prop[stk.pre[i]], FALSE) == 
NULL){
+                    if(!BUNappend(res[2], (ptr)&pre_prop[stk.pre[i]], FALSE)){
                         GDKerror("getProjectedNodes: append to res[2] 
failed\n");
                         goto getpnodes_failed;
                     }
-                    if(BUNappend(res[3], (ptr)&pre_kind[stk.pre[i]], FALSE) == 
NULL){
+                    if(!BUNappend(res[3], (ptr)&pre_kind[stk.pre[i]], FALSE)){
                         GDKerror("getProjectedNodes: append to res[3] 
failed\n");
                         goto getpnodes_failed;
                     }
                     if(pre_nid){
-                        if(BUNappend(res[4], (ptr)&pre_nid[stk.pre[i]], FALSE) 
== NULL){
+                        if(!BUNappend(res[4], (ptr)&pre_nid[stk.pre[i]], 
FALSE)){
                             GDKerror("getProjectedNodes: append to res[4] 
failed\n");
                             goto getpnodes_failed;
                         }
                     } else {
-                        if(BUNappend(res[4], (ptr)&stk.pre[i], FALSE) == NULL){
+                        if(!BUNappend(res[4], (ptr)&stk.pre[i], FALSE)){
                             GDKerror("getProjectedNodes: append to res[4] 
failed\n");
                             goto getpnodes_failed;
                         }
@@ -744,29 +893,29 @@
             if(ctx->knd[cur] == USED){
                 /* copy context node */
                 newsize = 0;
-                if(BUNappend(res[0], (ptr)&newsize, FALSE) == NULL){
+                if(!BUNappend(res[0], (ptr)&newsize, FALSE)){
                     GDKerror("getProjectedNodes: append to res[0] failed\n");
                     goto getpnodes_failed;
                 }
-                if(BUNappend(res[1], (ptr)&pre_level[pre], FALSE) == NULL){
+                if(!BUNappend(res[1], (ptr)&pre_level[pre], FALSE)){
                     GDKerror("getProjectedNodes: append to res[1] failed\n");
                     goto getpnodes_failed;
                 }
-                if(BUNappend(res[2], (ptr)&pre_prop[pre], FALSE) == NULL){
+                if(!BUNappend(res[2], (ptr)&pre_prop[pre], FALSE)){
                     GDKerror("getProjectedNodes: append to res[2] failed\n");
                     goto getpnodes_failed;
                 }
-                if(BUNappend(res[3], (ptr)&pre_kind[pre], FALSE) == NULL){
+                if(!BUNappend(res[3], (ptr)&pre_kind[pre], FALSE)){
                     GDKerror("getProjectedNodes: append to res[3] failed\n");
                     goto getpnodes_failed;
                 }
                 if(pre_nid) {
-                    if(BUNappend(res[4], (ptr)&pre_nid[pre], FALSE) == NULL){
+                    if(!BUNappend(res[4], (ptr)&pre_nid[pre], FALSE)){
                         GDKerror("getProjectedNodes: append to res[4] 
failed\n");
                         goto getpnodes_failed;
                     }
                 } else {
-                    if(BUNappend(res[4], (ptr)&pre, FALSE) == NULL){
+                    if(!BUNappend(res[4], (ptr)&pre, FALSE)){
                         GDKerror("getProjectedNodes: append to res[4] 
failed\n");
                         goto getpnodes_failed;
                     }
@@ -784,29 +933,29 @@
             } else {
                 /* copy context node with all its descendants */
                 for (i = ctx->pre[cur]; i <= ctx->pre[cur] + 
pre_size[ctx->pre[cur]]; i++){
-                    if(BUNappend(res[0], (ptr)&pre_size[i], FALSE) == NULL){
+                    if(!BUNappend(res[0], (ptr)&pre_size[i], FALSE)){
                         GDKerror("getProjectedNodes: append to res[0] 
failed\n");
                         goto getpnodes_failed;
                     }
-                    if(BUNappend(res[1], (ptr)&pre_level[i], FALSE) == NULL){
+                    if(!BUNappend(res[1], (ptr)&pre_level[i], FALSE)){
                         GDKerror("getProjectedNodes: append to res[1] 
failed\n");
                         goto getpnodes_failed;
                     }
-                    if(BUNappend(res[2], (ptr)&pre_prop[i], FALSE) == NULL){
+                    if(!BUNappend(res[2], (ptr)&pre_prop[i], FALSE)){
                         GDKerror("getProjectedNodes: append to res[2] 
failed\n");
                         goto getpnodes_failed;
                     }
-                    if(BUNappend(res[3], (ptr)&pre_kind[i], FALSE) == NULL){
+                    if(!BUNappend(res[3], (ptr)&pre_kind[i], FALSE)){
                         GDKerror("getProjectedNodes: append to res[3] 
failed\n");
                         goto getpnodes_failed;
                     }
                     if(pre_nid) {
-                        if(BUNappend(res[4], (ptr)&pre_nid[i], FALSE) == NULL){
+                        if(!BUNappend(res[4], (ptr)&pre_nid[i], FALSE)){
                             GDKerror("getProjectedNodes: append to res[4] 
failed\n");
                             goto getpnodes_failed;
                         }
                     } else {
-                        if(BUNappend(res[4], (ptr)&i, FALSE) == NULL){
+                        if(!BUNappend(res[4], (ptr)&i, FALSE)){
                             GDKerror("getProjectedNodes: append to res[4] 
failed\n");
                             goto getpnodes_failed;
                         }
@@ -872,6 +1021,143 @@
     return NULL;
 }
 
+static BAT**
+addXrpcIDs(
+        int contID,
+        BAT *ws,
+        BAT *referred_item,
+        BAT *referred_kind)
+{
+    oid i = oid_nil, j = oid_nil, qn = oid_nil, prop = oid_nil;
+    oid *ritems_old = NULL, *ritems= NULL;
+    char *pul = NULL, *ul = NULL, val[64];
+    unsigned int *rkinds = NULL;
+    unsigned int nrefd = 0;
+    BAT **res = NULL, *tmp_bat = NULL, *pre_nid = NULL;
+
+    assert(ws && referred_item && referred_kind);
+
+    if(!(res = GDKmalloc(9 * sizeof(BAT *)))){
+        GDKerror("addXrpcIDs: failed to malloc 'res'\n");
+        goto addids_failed;
+    }
+    /* copy QN_PREFIX_URI_LOC|URI_LOC|PREF|URI|LOC */
+    for(i = QN_PREFIX_URI_LOC, j = 0; i < PROP_TEXT; i++, j++){
+        if(!(tmp_bat = getBatFromContainer(ws, i, contID)))
+            goto addids_failed;
+        res[j] = BATcopy(tmp_bat, BAThtype(tmp_bat), BATttype(tmp_bat), TRUE);
+        BBPunfix(BBPcacheid(tmp_bat));
+        if(!res[j]){
+            GDKerror("addXrpcIDs: failed to copy WS["OIDFMT"][%d]\n", contID);
+            goto addids_failed;
+        }
+    }
+
+    if(!(tmp_bat = getBatFromContainer(ws, PROP_VAL, contID)))
+        goto addids_failed;
+    res[j] = BATcopy(tmp_bat, BAThtype(tmp_bat), BATttype(tmp_bat), TRUE);
+    BBPunfix(BBPcacheid(tmp_bat));
+    if(!res[j++]){
+        GDKerror("addXrpcIDs: failed to copy WS[PROP_VAL][%d]\n", contID);
+        goto addids_failed;
+    }
+
+    /* copy ATTR_OWN|QN|PROP */
+    for(i = ATTR_OWN; i < QN_NID; i++, j++){
+        if(!(tmp_bat = getBatFromContainer(ws, i, contID)))
+            goto addids_failed;
+        res[j] = BATcopy(tmp_bat, BAThtype(tmp_bat), BATttype(tmp_bat), TRUE);
+        BBPunfix(BBPcacheid(tmp_bat));
+        if(!res[j]){
+            GDKerror("addXrpcIDs: failed to copy WS["OIDFMT"][%d]\n", contID);
+            goto addids_failed;
+        }
+    }
+
+    nrefd = BATcount(referred_item); 
+    if(!(ritems = GDKmalloc(nrefd * sizeof(oid)))) {
+        GDKerror("addXrpcIDs: failed to malloc 'ritems'\n");
+        goto addids_failed;
+    }
+    ritems_old = (oid*) Tloc(referred_item, BUNfirst(referred_item));
+    rkinds = (unsigned int*) Tloc(referred_kind, BUNfirst(referred_kind));
+    if(!(pre_nid = getBatFromContainer(ws, PRE_NID, contID)))
+        goto addids_failed;
+    for(i = 0; i < nrefd; i++){
+        if((int)XTRACT_CONT(rkinds[i]) != contID) {
+            GDKerror("addXrpcIDs: referred_item["OIDFMT"] has contID %d, 
expected %d\n",
+                    XTRACT_CONT(rkinds[i]), contID);
+            goto addids_failed;
+        }
+        if(XTRACT_KIND(rkinds[i]) == ATTR)
+            /* overwrite an attribute node with its owner, no need to
+             * update the kind, will not be used. */
+            ritems[i] = getAttrOwner(ritems_old[i], res[6], pre_nid);
+        else
+            ritems[i] = ritems_old[i]; 
+    }
+
+    for(i = 0; i < nrefd; i++){
+        if(!(ul = strs_concat(XRPC_NS, "id")))
+            goto addids_failed;
+        if(!(pul = strs_concat("xrpc", ul)))
+            goto addids_failed;
+
+        qn = BATcount(res[0]);
+        prop = BATcount(res[5]);
+        snprintf(val, 64, "d%d:n"OIDFMT, contID, ritems[i]);
+
+        if(!BUNappend(res[0], pul, FALSE)) { /* QN_PREFIX_URI_LOC */
+            GDKerror("addXrpcIDs: failed to append %s to res[0] 
(QN_PREFIX_URI_LOC)\n", pul);
+            goto addids_failed;
+        }
+        if(!BUNappend(res[1], ul, FALSE)) { /* QN_URI_LOC */
+            GDKerror("addXrpcIDs: failed to append %s to res[1] 
(QN_URI_LOC)\n", ul);
+            goto addids_failed;
+        }
+        if(!BUNappend(res[2], "xrpc", FALSE)) { /* QN_PREFIX */
+            GDKerror("addXrpcIDs: failed to append \"xrpc\" to res[2] 
(QN_PREFIX)\n");
+            goto addids_failed;
+        }
+        if(!BUNappend(res[3], XRPC_NS, FALSE)) { /* QN_URI */
+            GDKerror("addXrpcIDs: failed to append %s to res[3] (QN_URI)\n", 
XRPC_NS);
+            goto addids_failed;
+        }
+        if(!BUNappend(res[4], "id", FALSE)) { /* QN_LOC */
+            GDKerror("addXrpcIDs: failed to append \"id\" to res[4] (QN_LOC) 
\n");
+            goto addids_failed;
+        }
+        if(!BUNappend(res[5], val, FALSE)) { /* PROP_VAL */
+            GDKerror("addXrpcIDs: failed to append \"%s\" to res[5] 
(PROP_VAL)\n", val);
+            goto addids_failed;
+        }
+        if(!BUNappend(res[6], (ptr)&(ritems[i]), FALSE)){ /* ATTR_OWN */
+            GDKerror("addXrpcIDs: failed to append \"%s\" to res[6] 
(ATTR_OWN)\n", val);
+            goto addids_failed;
+        }
+        if(!BUNappend(res[7], (ptr)&qn, FALSE)){ /* ATTR_QN */
+            GDKerror("addXrpcIDs: failed to append \"%s\" to res[7] 
(ATTR_QN)\n", val);
+            goto addids_failed;
+        }
+        if(!BUNappend(res[8], (ptr)&prop, FALSE)){ /* ATTR_PROP */
+            GDKerror("addXrpcIDs: failed to append \"%s\" to res[8] 
(ATTR_PROP)\n", val);
+            goto addids_failed;
+        }
+    }
+
+    GDKfree(ritems);
+    BBPunfix(BBPcacheid(pre_nid));
+    return res;
+
+addids_failed:
+    if(ritems) GDKfree(ritems);
+    for(i = 0; i < 9; i++)
+        if(res[i]) BBPreclaim(res[i]);
+    if(res) GDKfree(res);
+    if(pre_nid) BBPunfix(BBPcacheid(pre_nid));
+    return NULL;
+}
+
 int runtime_doc_projection2stream(
         str options,
         stream *out,
@@ -888,7 +1174,7 @@
         BAT *str_values)
 {
     int status = GDK_FAIL;
-    BAT **res_bats, *tmp_bats[5];
+    BAT **res_bats, **attr_bats;
     BAT *print_item = NULL, *print_kind = NULL;
     int i = 0, contID = int_nil, contIDnew = int_nil, kind = int_nil;
     oid pre = 0;
@@ -896,20 +1182,12 @@
     pcontext *ctx = NULL;
 
     (void) options;
-    (void)referred_kind;
-    (void)dec_values;
+    (void) dec_values;
 
     errCheck(out, ws, used_item, used_kind,
             returned_item, returned_kind, referred_item, referred_kind,
             int_values, dbl_values, dec_values, str_values);
 
-    if(referred_item) {
-        printmode = "xml-noheader-noroot";
-        /* TODO: add xrpc:id attribute to referred_item -s */
-    }
-
-    for(i = 0; i < 5; i++) tmp_bats[i] = NULL;
-
     if( (contID = getContID(used_kind, returned_kind)) < 0 )
         return status;
     
@@ -936,12 +1214,36 @@
         GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);
         return status;
     }
-    if(cp2Container(ws, contID, contIDnew, res_bats[0], res_bats[1],
-                res_bats[2], res_bats[3], res_bats[4]) == GDK_FAIL) {
-        GDKerror("runtime_doc_projection2stream: cp2Container failed\n");
-        for(i = 0; i < 5; i++) BBPreclaim(res_bats[i]);
-        GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);
-        return status;
+
+    /* Add xrpc:id attribute to referred_item -s */
+    if(referred_item) {
+        printmode = "xml-noheader-noroot";
+        if(!(attr_bats = addXrpcIDs(contID, ws, referred_item, 
referred_kind))){
+            GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);
+            for(i = 0; i < 5; i++) BBPreclaim(res_bats[i]);
+            return status;
+        }
+
+        if(cp2Container(ws, contID, contIDnew, res_bats[0], res_bats[1],
+                    res_bats[2], res_bats[3], res_bats[4],
+                    attr_bats[0], attr_bats[1], attr_bats[2],
+                    attr_bats[3], attr_bats[4], attr_bats[5],
+                    attr_bats[6], attr_bats[7], attr_bats[8]) == GDK_FAIL) {
+            GDKerror("runtime_doc_projection2stream: cp2Container failed\n");
+            for(i = 0; i < 5; i++) BBPreclaim(res_bats[i]);
+            for(i = 0; i < 9; i++) BBPreclaim(attr_bats[i]);
+            GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);
+            return status;
+        }
+    } else {
+        if(cp2Container(ws, contID, contIDnew, res_bats[0], res_bats[1],
+                    res_bats[2], res_bats[3], res_bats[4], 
+                    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == 
GDK_FAIL) {
+            GDKerror("runtime_doc_projection2stream: cp2Container failed\n");
+            for(i = 0; i < 5; i++) BBPreclaim(res_bats[i]);
+            GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);
+            return status;
+        }
     }
 
     /* serialize projected nodes to file */
@@ -951,6 +1253,7 @@
         GDKerror("runtime_doc_projection: failed to create 'print_item' 
BAT\n");
         rmContainer(ws, ATTR_PROP, contIDnew);
         for(i = 0; i < 5; i++) BBPreclaim(res_bats[i]);
+        if(attr_bats) for(i = 0; i < 9; i++) BBPreclaim(attr_bats[i]);
         GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);
         return status;
     }
@@ -959,6 +1262,7 @@
         GDKerror("runtime_doc_projection: failed to create 'print_kind' 
BAT\n");
         rmContainer(ws, ATTR_PROP, contIDnew);
         for(i = 0; i < 5; i++) BBPreclaim(res_bats[i]);
+        if(attr_bats) for(i = 0; i < 9; i++) BBPreclaim(attr_bats[i]);
         GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);
         BBPreclaim(print_item);
         return status;
@@ -974,7 +1278,7 @@
         GDKerror("runtime_doc_projection: failed to materialize projected 
document to disk\n");
 
     /* remove the new container from ws */
-    status = rmContainer(ws, ATTR_PROP, contIDnew);
+    rmContainer(ws, ATTR_OWN_SHARED, contIDnew);
     for(i = 0; i < 5; i++) {
         /* it seems that the batrefs are increamented by
          * xquery_print_result_driver
@@ -983,6 +1287,13 @@
                 BBPunfix(BBPcacheid(res_bats[i]));
         BBPreclaim(res_bats[i]);
     }
+    if(attr_bats) {
+        for(i = 0; i < 9; i++) {
+            if(BBP_refs(BBPcacheid(attr_bats[i])) > 1)
+                BBPunfix(BBPcacheid(attr_bats[i]));
+            BBPreclaim(attr_bats[i]);
+        }
+    }
     BBPreclaim(print_item);
     BBPreclaim(print_kind);
     GDKfree(ctx->pre); GDKfree(ctx->knd); GDKfree(ctx);


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to