Update of /cvsroot/monetdb/pathfinder/compiler/algebra
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv20677/compiler/algebra

Modified Files:
      Tag: PF_ROX
        builtins.c logical.c physical.c planner.c 
Log Message:
propagated changes of Friday May 30 2008 - Saturday May 31 2008
from the development trunk to the PF_ROX branch

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/05/30 - mayrm: compiler/algebra/builtins.c,1.97(Current_DailyBuild-31)
        compiler/algebra/logical.c,1.100(Current_DailyBuild-31)
        compiler/debug/logdebug.c,1.102(Current_DailyBuild-31)
        compiler/include/algebra.h,1.87(Current_DailyBuild-31)
        compiler/include/builtins.h,1.51(Current_DailyBuild-31)
        compiler/semantics/xquery_fo.c,1.162(Current_DailyBuild-31)
        compiler/sql/lalg2sql.brg,1.134(Current_DailyBuild-31)

Implementation for ``fn:node-name($arg as node()?) as xs:QName?'',
which forms the backbone of
  - fn:name (),
  - fn:local_name() and
  - fn:namespace_uri ().

doc_access-operator now has another accessor ``doc_QName'',
which supports access to the QName. ``doc_QName'' is not supported
by the MIL translation, yet.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/05/31 - stmane: compiler/algebra/physical.c,1.71(Current_DailyBuild-31)
        compiler/algebra/planner.c,1.64(Current_DailyBuild-31)
        compiler/algebra/opt/opt_complex.c,1.46(Current_DailyBuild-31)
        compiler/debug/physdebug.c,1.63(Current_DailyBuild-31)
propagated changes of Friday May 30 2008 - Saturday May 31 2008
from the XQuery_0-24 branch to the development trunk

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/05/30 - tsheyar:
        
compiler/debug/physdebug.c,1.62.2.1(XQuery_0-24,xrpcdemo_sync,Stable_DailyBuild-31)
-- Only print properties if we really have them (fixes a segfault).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/05/30 - tsheyar:
        compiler/algebra/physical.c,1.69.2.2(XQuery_0-24,Stable_DailyBuild-31)
-- doc_tbl is trivially sorted for inputs of cardinality 1.
   (This change avoids the planning of a physical sort operator.)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/05/30 - tsheyar:
        compiler/algebra/planner.c,1.62.2.2(XQuery_0-24,Stable_DailyBuild-31)
-- add missing physical implementation for the step_join operator.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/05/30 - tsheyar:
        
compiler/algebra/opt/opt_complex.c,1.45.2.1(XQuery_0-24,Stable_DailyBuild-31)
-- performance fix for step_joins.
   (Merge step_join pair implementing descendant-or-self::node()/child::___
    into a single step_join descendant::___.)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/05/31 - stmane: compiler/algebra/planner.c,1.62.2.3(XQuery_0-24)

fixed compilation: removed unused variable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


U physical.c
Index: physical.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/physical.c,v
retrieving revision 1.53.2.12
retrieving revision 1.53.2.13
diff -u -d -r1.53.2.12 -r1.53.2.13
--- physical.c  30 May 2008 12:36:38 -0000      1.53.2.12
+++ physical.c  31 May 2008 11:45:10 -0000      1.53.2.13
@@ -2604,6 +2604,10 @@
     for (unsigned int i = 0; i < PFord_set_count (n->orderings); i++)
         PFord_set_add (ret->orderings, PFord_set_at (n->orderings, i));
 
+    /* for single base tables the result is trivially sorted */
+    if (PFprop_card (n->prop) == 1)
+        PFord_set_add (ret->orderings, sortby (res));
+
     /* ---- doc_tbl: costs ---- */
     ret->cost = DEFAULT_COST + n->cost;
 

U planner.c
Index: planner.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/planner.c,v
retrieving revision 1.47.2.9
retrieving revision 1.47.2.10
diff -u -d -r1.47.2.9 -r1.47.2.10
--- planner.c   30 May 2008 12:36:44 -0000      1.47.2.9
+++ planner.c   31 May 2008 11:45:11 -0000      1.47.2.10
@@ -415,6 +415,57 @@
                               *(plan_t **) PFarray_at (R(n)->plans, s));
         }
 
+    /* generate a semijoin */
+    if (L(n)->schema.count == 1 &&
+        L(n)->kind == la_distinct) {
+        PFalg_proj_t *proj = PFmalloc (n->schema.count * sizeof 
(PFalg_proj_t));
+
+        /* create the above projection list */
+        for (unsigned int i = 0; i < n->schema.count; i++) {
+            PFalg_att_t cur = n->schema.items[i].name;
+            if (cur != n->sem.eqjoin.att1)
+                proj[i] = PFalg_proj (cur, cur);
+            else
+                proj[i] = PFalg_proj (cur, n->sem.eqjoin.att2);
+        }
+        
+        for (unsigned int l = 0; l < PFarray_last (R(n)->plans); l++)
+            for (unsigned int r = 0; r < PFarray_last (LL(n)->plans); r++)
+                add_plan (ret,
+                          project (
+                              semijoin (
+                                  n->sem.eqjoin.att2,
+                                  n->sem.eqjoin.att1,
+                                  *(plan_t **) PFarray_at (R(n)->plans, l),
+                                  *(plan_t **) PFarray_at (LL(n)->plans, r)),
+                              n->schema.count, proj));
+    }
+    
+    /* generate a semijoin */
+    if (R(n)->schema.count == 1 &&
+        R(n)->kind == la_distinct) {
+        PFalg_proj_t *proj = PFmalloc (n->schema.count * sizeof 
(PFalg_proj_t));
+
+        /* create the above projection list */
+        for (unsigned int i = 0; i < n->schema.count; i++) {
+            PFalg_att_t cur = n->schema.items[i].name;
+            if (cur != n->sem.eqjoin.att2)
+                proj[i] = PFalg_proj (cur, cur);
+            else
+                proj[i] = PFalg_proj (cur, n->sem.eqjoin.att1);
+        }
+        
+        for (unsigned int l = 0; l < PFarray_last (L(n)->plans); l++)
+            for (unsigned int r = 0; r < PFarray_last (RL(n)->plans); r++)
+                add_plan (ret,
+                          project (
+                              semijoin (n->sem.eqjoin.att1,
+                                  n->sem.eqjoin.att2,
+                                  *(plan_t **) PFarray_at (L(n)->plans, l),
+                                  *(plan_t **) PFarray_at (RL(n)->plans, r)),
+                              n->schema.count, proj));
+    }
+    
     return ret;
 }
 
@@ -1466,7 +1517,7 @@
 
 /**
  * Create physical plan for the path step operator (XPath location
- * steps). Uses helper functions plan_scj_XXX.
+ * steps).
  */
 static PFplanlist_t *
 plan_step (const PFla_op_t *n)
@@ -1523,6 +1574,343 @@
 }
 
 /**
+ * Create physical plan for the path step join operator.
+ *
+ * This is only a fallback solution for rewrites that return step_joins
+ * instead of path steps.
+ *
+ * step_join:   |
+ *             pi_schema(n+item_res)
+ *              |
+ *             |X|_2=1
+ *     ________/ \________
+ *    /                   \
+ *  step_2,item_res       |
+ *   |                    |
+ *  pi_2:1,item_res:item  |
+ *    \________   ________/
+ *             \ /
+ *              #_1
+ *              |
+ */
+static PFplanlist_t *
+plan_step_join (const PFla_op_t *n)
+{
+    /* some assertions */
+    assert (n); assert (n->kind == la_step_join);
+    assert (R(n)); assert (R(n)->plans);
+
+    PFalg_att_t   item_res  = n->sem.step.item_res,
+                  item      = n->sem.step.item,
+                  iter,
+                  iter2;
+    PFalg_att_t   used_cols = 0;
+    unsigned int  count     = n->schema.count,
+                  count_in  = 2;
+    PFalg_proj_t *proj      = PFmalloc (count * sizeof (PFalg_proj_t)),
+                 *proj_in   = PFmalloc (count_in * sizeof (PFalg_proj_t));
+    PFplanlist_t *ret       = new_planlist ();
+    PFpa_op_t    *plan,
+                 *mark;
+
+    /* create the above projection list */
+    for (unsigned int i = 0; i < n->schema.count; i++)
+        proj[i] = PFalg_proj (n->schema.items[i].name,
+                              n->schema.items[i].name);
+
+    /* get ourselves two new attribute name
+       (for creating keys using mark and joining back) */
+    for (unsigned int i = 0; i < n->schema.count; i++)
+        used_cols |= n->schema.items[i].name;
+
+    iter  = PFalg_ori_name (PFalg_unq_name (att_iter, 0), ~used_cols);
+    used_cols |= iter;
+    iter2 = PFalg_ori_name (PFalg_unq_name (att_iter, 0), ~used_cols);
+
+    /* create the inner projection list */
+    proj_in[0] = PFalg_proj (iter2, iter);
+    proj_in[1] = PFalg_proj (item_res, item);
+
+    /* create the translation for every input plan */
+    for (unsigned int i = 0; i < PFarray_last (R(n)->plans); i++) {
+        plan = *(plan_t **) PFarray_at (R(n)->plans, i);
+        mark = mark (plan, iter);
+
+        add_plan (ret,
+                  project (
+                      leftjoin (
+                          iter,
+                          iter2,
+                          mark,
+                          llscjoin (
+                              project (
+                                  mark,
+                                  count_in,
+                                  proj_in),
+                              n->sem.step.spec,
+                              sortby (iter2, item_res),
+                              sortby (iter2, item_res),
+                              iter2,
+                              item_res)),
+                      count,
+                      proj));
+    }
+
+    return ret;
+}
+
+/**
+ * Create physical plan for the path step operator
+ * based on step join operator as input.
+ *
+ * As no iter information is available a constant iter
+ * is added.
+ */
+static PFplanlist_t *
+plan_step_join_to_step (const PFla_op_t *n)
+{
+    PFalg_att_t   item_out  = n->sem.proj.items[0].new,
+                  item_res  = n->sem.proj.items[0].old,
+                  item,
+                  iter,
+                  used_cols = 0;
+    PFalg_proj_t *proj_out  = PFmalloc (sizeof (PFalg_proj_t)),
+                 *proj_in   = PFmalloc (sizeof (PFalg_proj_t));
+    PFplanlist_t *ret       = new_planlist (),
+                 *sorted    = new_planlist ();
+    PFpa_op_t    *plan;
+    
+    /* some assertions */
+    assert (n); assert (n->kind == la_project);
+    assert (L(n)); assert (L(n)->kind == la_step_join);
+    assert (LR(n)->plans);
+
+    assert (n->schema.count == 1);
+    assert (L(n)->kind == la_step_join);
+    assert (item_res == L(n)->sem.step.item_res);
+    assert (PFprop_key (L(n)->prop, L(n)->sem.step.item_res) ||
+            PFprop_set (L(n)->prop));
+
+    /* find a free iter value */
+    item      = L(n)->sem.step.item;
+    used_cols = item_res | item;
+    iter      = PFalg_ori_name (PFalg_unq_name (att_iter, 0), ~used_cols);
+    
+    proj_out[0].new = item_out;
+    proj_out[0].old = item;
+    proj_in[0].new  = item;
+    proj_in[0].old  = item;
+    
+    for (unsigned int i = 0; i < PFarray_last (LR(n)->plans); i++)
+        add_plans (sorted,
+                   ensure_ordering (
+                       *(plan_t **) PFarray_at (LR(n)->plans, i),
+                       sortby (item)));
+
+    /* create the translation for every input plan */
+    for (unsigned int i = 0; i < PFarray_last (sorted); i++) {
+        plan = *(plan_t **) PFarray_at (sorted, i);
+        /* add plan in item|iter output order */
+        add_plan (ret,
+                  project (
+                      llscjoin (
+                          attach (
+                              project (plan, 1, proj_in),
+                              iter,
+                              lit_nat (1)),
+                          L(n)->sem.step.spec,
+                          sortby (item, iter),
+                          sortby (item, iter),
+                          iter,
+                          item),
+                      1, proj_out));
+    }
+
+    return ret;
+}
+
+/**
+ * Create physical plan for the path step operator
+ * based on step join operator as input.
+ *
+ * only the iter column is needed as output.
+ */
+static PFplanlist_t *
+plan_step_join_to_step_check (const PFla_op_t *n)
+{
+    PFalg_att_t   iter_out  = n->sem.proj.items[0].new,
+                  iter      = n->sem.proj.items[0].old,
+                  item_res,
+                  item;
+    PFalg_proj_t *proj_out  = PFmalloc (sizeof (PFalg_proj_t)),
+                 *proj_in   = PFmalloc (2 * sizeof (PFalg_proj_t));
+    PFplanlist_t *ret       = new_planlist ();
+    PFpa_op_t    *plan;
+    
+    /* some assertions */
+    assert (n); assert (n->kind == la_project);
+    assert (L(n)); assert (L(n)->kind == la_step_join);
+    assert (LR(n)->plans);
+
+    assert (n->schema.count == 1);
+    assert (L(n)->kind == la_step_join);
+    assert (PFprop_type_of (n, n->sem.proj.items[0].new) == aat_nat);
+    assert (PFprop_key (L(n)->prop, L(n)->sem.step.item_res) ||
+            PFprop_set (L(n)->prop));
+
+    item_res = L(n)->sem.step.item_res;
+    item     = L(n)->sem.step.item;
+    
+    proj_out[0].new = iter_out;
+    proj_out[0].old = iter;
+    proj_in[0].new  = iter;
+    proj_in[0].old  = iter;
+    proj_in[1].new  = item;
+    proj_in[1].old  = item;
+    
+    /*
+     * Loop-lifted staircase join can handle two different orderings
+     * for input and output: iter|item or item|iter. In the invocation
+     * of the staircase join operators in MIL, this information is
+     * encoded in a single integer value.
+     */
+    const PFord_ordering_t in[2]
+        = { sortby (iter, item), sortby (item, iter) };
+    const PFord_ordering_t out[2]
+        = { sortby (iter, item), sortby (item, iter) };
+
+    /* consider the two possible input orderings */
+    for (unsigned short i = 0; i < 2; i++) {
+
+        PFplanlist_t *ordered = new_planlist ();
+
+        /* sort all plans according to this input ordering */
+        for (unsigned int j = 0; j < PFarray_last (LR(n)->plans); j++) {
+            add_plans (ordered,
+                       ensure_ordering (
+                           *(plan_t **) PFarray_at (LR(n)->plans, j),
+                           in[i]));
+        }
+
+        /* generate plans for each input and each output ordering */
+
+        for (unsigned int k = 0; k < PFarray_last (ordered); k++)
+            for (unsigned short o = 0; o < 2; o++) {
+                plan = *(plan_t **) PFarray_at (ordered, k);
+                add_plan (ret,
+                          project (
+                              llscjoin (
+                                  project (plan, 2, proj_in),
+                                  L(n)->sem.step.spec,
+                                  in[i],
+                                  out[o],
+                                  iter,
+                                  item),
+                              1, proj_out));
+            }
+    }
+
+    return ret;
+}
+
+/**
+ * Create physical plan for the path step operator
+ * based on step join operator as input.
+ *
+ * Two-column scenario where an iter_nat|item_node relation
+ * is fed in.
+ */
+static PFplanlist_t *
+plan_step_join_to_llstep (const PFla_op_t *n)
+{
+    PFalg_att_t   item_out,
+                  item_res,
+                  item,
+                  iter_out,
+                  iter;
+    PFalg_proj_t *proj_in   = PFmalloc (2 * sizeof (PFalg_proj_t));
+    PFplanlist_t *ret       = new_planlist ();
+    PFpa_op_t    *plan;
+    
+    /* some assertions */
+    assert (n); assert (n->kind == la_project);
+    assert (L(n)); assert (L(n)->kind == la_step_join);
+    assert (LR(n)->plans);
+
+    assert (n->schema.count == 2);
+    assert (L(n)->kind == la_step_join);
+    assert (PFprop_key (L(n)->prop, L(n)->sem.step.item_res) ||
+            PFprop_set (L(n)->prop));
+
+    item_res = L(n)->sem.step.item_res;
+    item     = L(n)->sem.step.item;
+    
+    if (n->sem.proj.items[0].old == item_res &&
+        PFprop_type_of (n, n->sem.proj.items[1].new) == aat_nat) {
+        item_out = n->sem.proj.items[0].new;
+        iter_out = n->sem.proj.items[1].new;
+        iter     = n->sem.proj.items[1].old;
+    }
+    else if (n->sem.proj.items[1].old == item_res &&
+             PFprop_type_of (n, n->sem.proj.items[0].new) == aat_nat) {
+        item_out = n->sem.proj.items[1].new;
+        iter_out = n->sem.proj.items[0].new;
+        iter     = n->sem.proj.items[0].old;
+    }
+    else
+        return ret;
+        
+    proj_in[0].new = iter_out;
+    proj_in[0].old = iter;
+    proj_in[1].new = item_out;
+    proj_in[1].old = item;
+    
+    /*
+     * Loop-lifted staircase join can handle two different orderings
+     * for input and output: iter|item or item|iter. In the invocation
+     * of the staircase join operators in MIL, this information is
+     * encoded in a single integer value.
+     */
+    const PFord_ordering_t in_in[2]
+        = { sortby (iter, item), sortby (item, iter) };
+    const PFord_ordering_t in[2]
+        = { sortby (iter_out, item_out), sortby (item_out, iter_out) };
+    const PFord_ordering_t out[2]
+        = { sortby (iter_out, item_out), sortby (item_out, iter_out) };
+
+    /* consider the two possible input orderings */
+    for (unsigned short i = 0; i < 2; i++) {
+
+        PFplanlist_t *ordered = new_planlist ();
+
+        /* sort all plans according to this input ordering */
+        for (unsigned int j = 0; j < PFarray_last (LR(n)->plans); j++) {
+            add_plans (ordered,
+                       ensure_ordering (
+                           *(plan_t **) PFarray_at (LR(n)->plans, j),
+                           in_in[i]));
+        }
+
+        /* generate plans for each input and each output ordering */
+
+        for (unsigned int k = 0; k < PFarray_last (ordered); k++)
+            for (unsigned short o = 0; o < 2; o++) {
+                plan = *(plan_t **) PFarray_at (ordered, k);
+                add_plan (ret,
+                          llscjoin (
+                              project (plan, 2, proj_in),
+                              L(n)->sem.step.spec,
+                              in[i],
+                              out[o],
+                              iter_out,
+                              item_out));
+            }
+    }
+
+    return ret;
+}
+
+/**
  * Generate physical plan for document table access.
  *
  * @note
@@ -2715,6 +3103,29 @@
                                           PFla_distinct (n)));
                 }
             }
+            
+            if (n->schema.count == 1 &&
+                L(n)->kind == la_step_join &&
+                n->sem.proj.items[0].old == L(n)->sem.step.item_res &&
+                (PFprop_key (L(n)->prop, L(n)->sem.step.item_res) ||
+                 PFprop_set (L(n)->prop))) {
+                add_plans (plans, plan_step_join_to_step (n));
+            }
+            
+            if (n->schema.count == 1 &&
+                L(n)->kind == la_step_join &&
+                PFprop_type_of (n, n->sem.proj.items[0].new) == aat_nat &&
+                (PFprop_key (L(n)->prop, L(n)->sem.step.item_res) ||
+                 PFprop_set (L(n)->prop))) {
+                add_plans (plans, plan_step_join_to_step_check (n));
+            }
+            
+            if (n->schema.count == 2 &&
+                L(n)->kind == la_step_join &&
+                (PFprop_key (L(n)->prop, L(n)->sem.step.item_res) ||
+                 PFprop_set (L(n)->prop))) {
+                add_plans (plans, plan_step_join_to_llstep (n));
+            }
             break;
 
         case la_select:         plans = plan_select (n);       break;
@@ -2754,6 +3165,20 @@
                     add_plans (plans, plan_unique_thetajoin (n));
                 }
             }
+            
+            if (n->schema.count == 2 &&
+                L(n)->kind == la_project &&
+                LL(n)->kind == la_step_join &&
+                /* check for an iter column ... */
+                (PFprop_type_of (n, n->schema.items[0].name) == aat_nat ||
+                 PFprop_type_of (n, n->schema.items[1].name) == aat_nat) &&
+                /* ... and the correct item column */
+                (L(n)->sem.proj.items[0].old == LL(n)->sem.step.item_res ||
+                 L(n)->sem.proj.items[1].old == LL(n)->sem.step.item_res)) {
+                /* tests above are sufficient as the step_join result
+                   can never be of type nat */
+                add_plans (plans, plan_step_join_to_llstep (L(n)));
+            }
             break;
 
         case la_fun_1to1:       plans = plan_fun_1to1 (n);     break;
@@ -2787,6 +3212,7 @@
         case la_all:            plans = plan_aggr (pa_all, n);    break;
                                                                   
         case la_step:           plans = plan_step (n);            break;
+        case la_step_join:      plans = plan_step_join (n);       break;
         case la_doc_tbl:        plans = plan_doc_tbl (n);         break;
 
         /* case doc_index_join */
@@ -2988,6 +3414,8 @@
             break;
 
         default:
+            /* add check to avoid a segfault if there is no plan */
+            if (PFarray_last (plans) > 0)
         {
             PFord_ordering_t ord = PFordering ();
             PFord_set_t orderings = PFord_set ();

U logical.c
Index: logical.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/logical.c,v
retrieving revision 1.78.2.10
retrieving revision 1.78.2.11
diff -u -d -r1.78.2.10 -r1.78.2.11
--- logical.c   30 May 2008 12:36:34 -0000      1.78.2.10
+++ logical.c   31 May 2008 11:45:09 -0000      1.78.2.11
@@ -3022,7 +3022,12 @@
         ret->schema.items[i] = n->schema.items[i];
 
     ret->schema.items[i]
-        = (struct PFalg_schm_item_t) { .type = aat_str, .name = res };
+        = (struct PFalg_schm_item_t) {
+                               .type = (doc_col != doc_qname)
+                                               ? aat_str
+                                               : aat_qname,
+                               .name = res
+                       };
 
     ret->sem.doc_access.res = res;
     ret->sem.doc_access.att = col;

U builtins.c
Index: builtins.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/builtins.c,v
retrieving revision 1.75.2.9
retrieving revision 1.75.2.10
diff -u -d -r1.75.2.9 -r1.75.2.10
--- builtins.c  30 May 2008 12:36:28 -0000      1.75.2.9
+++ builtins.c  31 May 2008 11:45:07 -0000      1.75.2.10
@@ -344,6 +344,169 @@
 /* ------------ */
 /* 2. ACCESSORS */
 /* ------------ */
+
+/* ----------------- */
+/* 2.1. fn:node-name */
+/* ----------------- */
+
+/* The fn:node-name function returns an expanded for 
+ * node kinds that can have names.
+ * Among them obviously elements and attributes. 
+ */
+
+static struct PFla_pair_t
+fn_bui_node_name (struct PFla_pair_t
+                    (*nodes)
+                    (const PFla_op_t *, bool, PFla_pair_t *args),
+                  const PFla_op_t *loop,
+                  bool ordering,
+                  struct PFla_pair_t *args)
+{
+    PFla_op_t *qnames = project (
+                            doc_access (
+                                PFla_set_to_la (args[0].frag),
+                                nodes (loop, ordering, args).rel,
+                                att_res, att_item, doc_qname),
+                            proj (att_iter, att_iter),
+                            proj (att_pos, att_pos),
+                            proj (att_item, att_res));
+
+    return (struct PFla_pair_t) {
+                    .rel = qnames,
+                    .frag = PFla_empty_set ()
+                };
+}
+
+static struct PFla_pair_t
+fn_bui_node_name_attr_ (const PFla_op_t* loop,
+                        bool ordering,
+                        struct PFla_pair_t *args)
+{
+    (void)ordering; (void)loop;
+    return args[0];
+}
+
+static struct PFla_pair_t
+fn_bui_node_name_elem_ (const PFla_op_t *loop,
+                        bool ordering,
+                        struct PFla_pair_t *args)
+{
+    (void)ordering; (void)loop;
+    return args[0];
+}
+
+/* filter attributes only */
+static struct PFla_pair_t
+fn_bui_node_name_attr_filter (const PFla_op_t* loop,
+                              bool ordering,
+                              struct PFla_pair_t *args)
+{
+    (void)loop; (void)ordering;
+    
+    PFla_op_t *attributes = NULL;
+    PFalg_step_spec_t self_attr_spec;
+    self_attr_spec.axis = alg_self;
+    self_attr_spec.kind = node_kind_attr;
+    
+    /* just find every attribute  */
+    self_attr_spec.qname = PFqname (PFns_wild, NULL); 
+    
+    attributes = attach (
+                    PFla_step_simple (
+                        PFla_set_to_la (args[0].frag),
+                        project (args[0].rel,
+                                 proj (att_iter, att_iter),
+                                 proj (att_item, att_item)),
+                        self_attr_spec,
+                        att_iter, att_item, att_item),
+                    att_pos, lit_int(1));
+
+    return (struct PFla_pair_t) {
+                    .rel = attributes,
+                    .frag = args[0].frag
+                };
+}
+
+/* filter elements only */
+static struct PFla_pair_t
+fn_bui_node_name_element_filter (const PFla_op_t* loop,
+                                 bool ordering,
+                                 struct PFla_pair_t *args)
+{
+    (void)loop; (void)ordering;
+    
+    PFla_op_t *elements = NULL;
+    PFalg_step_spec_t self_elem_spec;
+    self_elem_spec.axis = alg_self;
+    self_elem_spec.kind = node_kind_elem; 
+    
+    /* just find every element */
+    self_elem_spec.qname = PFqname (PFns_wild, NULL);
+    
+    elements = attach (
+                    PFla_step_simple (
+                        PFla_set_to_la (args[0].frag),
+                        project (args[0].rel,
+                                 proj (att_iter, att_iter),
+                                 proj (att_item, att_item)),
+                        self_elem_spec,
+                        att_iter, att_item, att_item),
+                        att_pos, lit_int(1));
+                                
+    return (struct PFla_pair_t) {
+                    .rel = elements,
+                    .frag = args[0].frag
+                };
+}
+
+static struct PFla_pair_t
+fn_bui_node_name_node_ (const PFla_op_t *loop,
+                        bool ordering,
+                        struct PFla_pair_t *args)
+{
+    PFla_op_t *union_ = disjunion (
+                            fn_bui_node_name_attr_filter (loop,
+                                                          ordering,
+                                                          args).rel,
+                            fn_bui_node_name_element_filter (loop,
+                                                             ordering,
+                                                             args).rel);
+                                                    
+    return (struct PFla_pair_t) {
+                .rel  = union_,
+                .frag = args[0].frag
+            };
+}
+
+/* node-name for attributes */
+struct PFla_pair_t
+PFfn_bui_node_name_attr (const PFla_op_t *loop,
+                         bool ordering,
+                         struct PFla_pair_t *args)
+{
+    return fn_bui_node_name (fn_bui_node_name_attr_, loop, ordering, args);
+}
+
+/* node-name for elements */
+struct PFla_pair_t 
+PFfn_bui_node_name_elem (const PFla_op_t *loop,
+                         bool ordering,
+                         struct PFla_pair_t *args)
+{
+    return fn_bui_node_name (fn_bui_node_name_elem_, loop, ordering, args);
+}
+
+/* node-name for general nodes */
+struct PFla_pair_t
+PFfn_bui_node_name_node (const PFla_op_t *loop,
+                         bool ordering,
+                         struct PFla_pair_t *args)
+{
+    return fn_bui_node_name (fn_bui_node_name_node_, loop, ordering, args);
+}
+
+
+
 /* -------------- */
 /* 2.3. fn:string */
 /* -------------- */


-------------------------------------------------------------------------
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