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

Modified Files:
        algebra.c algebra_cse.c core2alg.brg logical.c 
Log Message:
-- Implemented generic function application facility (for the logical algebra).

   Generic functions can now be implemented in the logical algebra using
   the following 4 operators:

   o la_fun_call:
     The head of a function call whose left child is the loop relation and the
     right child a function parameter list. The operator is prepared for a set
     of different kinds (e.g., xrpc and tijah), stores the function name and a
     pointer to an arbitrary context (for XRPC this is a reference to the core
     apply node).

   o la_fun_param:
     An item of the function parameter list refering to an algebra expression
     (left child) and to the rest of the function parameter list (right child).
     Its schema stores the names of all input columns. The order of columns
     in the schema is important!

   o la_fun_frag_param:
     An item of the function parameter list refering to a fragment (left child)
     and to the rest of the function parameter list (right child). It has a
     further position argument that indicates to which column of the next
     la_fun_param operator in the right child the fragment information refers
     to. This operator is only used if a column contains node references.

   o la_frag_extract:
     If a function call returns nodes a frag_extract operator sits on top of
     the la_fun_call operator to fix the fragment information needed by our
     compilation scheme. Similar to the la_fun_frag_param operator it stores
     the schema position of the item column it refers to.



Index: core2alg.brg
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/core2alg.brg,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- core2alg.brg        6 Dec 2007 08:42:12 -0000       1.58
+++ core2alg.brg        13 Dec 2007 13:08:14 -0000      1.59
@@ -154,6 +154,9 @@
 %term recursion          = 74 /**< "with $v seeded by..." expression */
 %term seed               = 75
 
+  /* Pathfinder extension: XRPC */
+%term xrpc               = 76 /**< XRPC calls: "execute at" */
+
 %%
 
 Query:              main (FunctionDecls, CoreExpr)              =   1 (10);
@@ -243,6 +246,7 @@
 TagName:            CoreExpr                                    = 401 (10);
 
 CoreExpr:           apply (FunctionArgs)                        =  60 (10);
+CoreExpr:           xrpc (CoreExpr, apply (FunctionArgs))       =  61 (10);
 
 FunctionArgs:       nil                                         = 500 (10);
 FunctionArgs:       arg (FunctionArg, FunctionArgs)             = 501 (10);
@@ -476,6 +480,9 @@
         /* CoreExpr:           apply (FunctionArgs) */
         case 60:
 
+        /* CoreExpr:           xrpc (CoreExpr, apply (FunctionArgs)) */
+        case 61:
+            
         /* FunctionArgs:       arg (FunctionArg, FunctionArgs) */
         case 501:
 
@@ -2179,6 +2186,126 @@
 
         } break;
 
+        /* CoreExpr:           xrpc (CoreExpr, apply (FunctionArgs)) */
+        case 61:
+        {   /* TOPDOWN*/
+            PFla_op_t     *param_list = PFla_nil (),
+                          *fun_call;
+            PFalg_schema_t schema;
+            PFarray_t     *old_env;
+            PFarray_t     *old_fun_args;
+            
+            /* prepare the standard in/output schema */
+            schema.count = 3;
+            schema.items = PFmalloc (schema.count *
+                                     sizeof (PFalg_schm_item_t));
+            schema.items[0].name = att_iter;
+            schema.items[0].type = aat_nat;
+            schema.items[1].name = att_pos;
+            schema.items[1].type = aat_nat;
+            schema.items[2].name = att_item;
+            /* Note: the item type has to be adjusted for each parameter */
+            schema.items[2].type = 0;
+            
+            PFty_t ty = p->type;
+
+            /* Collect the destinations */
+            reduce (kids[0], nts[0]);
+            
+            /*
+             * Function application:
+             *
+             * (1) Save current variable and function parameter environment.
+             * (2) Enter bindings for all variables in the function
+             *     signature to the variable environment.
+             * (3) Transform the function parameters
+             *     into an XRPC function call.
+             * (4) Restore variable and function parameter environment.
+             */
+
+            /* (1) Save current variable and function parameter environment
+               and create new ones. */
+            old_env = env;
+
+            env = PFarray (sizeof (PFla_env_t));
+
+            for (unsigned int i = 0; i < PFarray_last (old_env); i++)
+                *((PFla_env_t *) PFarray_add (env))
+                    = *((PFla_env_t *) PFarray_at (old_env, i));
+
+            old_fun_args = fun_args;
+
+            /* We will collect the argument values here */
+            fun_args = PFarray (sizeof (struct PFla_pair_t));
+
+            /* (2) Enter bindings for function parameters.
+             *     We do this by reducing our child nodes in a
+             *     top-down fashion.
+             */
+
+            /* Top-down processing puts all argument values into this array */
+            reduce (kids[1], nts[1]);
+
+            /* All function arguments are now in the array `fun_args'. */
+
+            /* (3) Transform the function parameters into an XRPC function
+             *     call.
+             */
+            
+            /* Create a linked list of parameters. */
+            for (unsigned int i = R(p)->sem.fun->arity; i > 0; i--) {
+                PFla_pair_t curr_arg
+                    = *(PFla_pair_t *) PFarray_at (fun_args, i-1);
+
+                /* adjust the item type */
+                schema.items[2].type = PFprop_type_of (curr_arg.rel, att_item);
+                /* create a new parameter */
+                param_list = fun_param (curr_arg.rel, param_list, schema);
+                
+                /* create a new fragment parameter if the parameter
+                   represents a sequence with nodes */
+                if (schema.items[2].type & aat_node)
+                    param_list = fun_frag_param (
+                                     PFla_set_to_la (curr_arg.frag),
+                                     param_list,
+                                     2 /* referencing column item */);
+            }
+
+            /* As the top-most argument add the XRPC destination strings */
+            schema.items[2].type = PFprop_type_of (A(L(p)).rel, att_item);
+            param_list = fun_param (A(L(p)).rel, param_list, schema);
+            
+            /* Collect all result types */
+            schema.items[2].type = PFalg_type (ty);
+
+            /* Construct the complete function call */
+            fun_call = fun_call (loop,                 /* loop relation */
+                                 param_list,           /* parameter list */
+                                 schema,               /* result schema */
+                                 alg_fun_call_xrpc,    /* function call kind */
+                                 R(p)->sem.fun->qname, /* function name */
+                                 R(p),                 /* context info */
+                                 att_iter,             /* loop column */
+                                 PFalg_type_occ (ty)); /* occurrence
+                                                          indicator */
+                
+            /* To correctly reference the fragment information of
+               resulting items of kind node we introduce an additional
+               frag_extract operator that refers to column item */
+            if (schema.items[2].type & aat_node)
+                A(p) = (struct  PFla_pair_t) {
+                         .rel = fun_call,
+                         .frag = PFla_set (frag_extract (fun_call, 2)) };
+            else
+                A(p) = (struct  PFla_pair_t) {
+                         .rel = fun_call,
+                         .frag = PFla_empty_set () };
+
+            /* (4) Restore variable and function parameter environments. */
+            env = old_env;
+            fun_args = old_fun_args;
+        } break;
+            
         /* FunctionArgs:       nil */
         case 500:
             break;

Index: algebra.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/algebra.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- algebra.c   29 Nov 2007 15:36:57 -0000      1.63
+++ algebra.c   13 Dec 2007 13:08:14 -0000      1.64
@@ -425,6 +425,7 @@
 #include "oops.h"
 #include "mem.h"
 #include "array.h"
+#include "subtyping.h"
 
 #include "algebra.h"
 
@@ -971,6 +972,79 @@
 }
 
 /**
+ * Print function call kind
+ */
+char *
+PFalg_fun_call_kind_str (PFalg_fun_call_t kind)
+{
+    switch (kind) {
+        case alg_fun_call_dft:          return "";
+        case alg_fun_call_xrpc:         return "XRPC";
+        case alg_fun_call_xrpc_helpers: return "XRPC helper";
+        case alg_fun_call_tijah:        return "Tijah";
+    }
+    return NULL;
+}
+
+/**
+ * Extract all possible algebra types from the XQuery type.
+ */
+PFalg_simple_type_t
+PFalg_type (PFty_t ty)
+{
+    PFalg_simple_type_t alg_ty = 0;
+    
+    ty = PFty_prime (PFty_defn (ty));
+    
+    if (!PFty_disjoint (ty, PFty_xs_integer ()))
+        alg_ty |= aat_int;
+    if (!PFty_disjoint (ty, PFty_xs_string ()))
+        alg_ty |= aat_str;
+    if (!PFty_disjoint (ty, PFty_xs_double ()))
+        alg_ty |= aat_dbl;
+    if (!PFty_disjoint (ty, PFty_xs_decimal ()))
+        alg_ty |= aat_dec;
+    if (!PFty_disjoint (ty, PFty_xs_boolean ()))
+        alg_ty |= aat_bln;
+    if (!PFty_disjoint (ty, PFty_xs_QName ()))
+        alg_ty |= aat_qname;
+    if (!PFty_disjoint (ty, PFty_untypedAtomic ()))
+        alg_ty |= aat_uA;
+    if (!PFty_disjoint (ty, PFty_xs_anyAttribute ()))
+        alg_ty |= aat_anode;
+    if (!PFty_disjoint (ty, PFty_xs_anyElement ()) ||
+        !PFty_disjoint (ty, PFty_doc (PFty_xs_anyNode ())) ||
+        !PFty_disjoint (ty, PFty_pi (NULL)) ||
+        !PFty_disjoint (ty, PFty_comm ()) ||
+        !PFty_disjoint (ty, PFty_text ()))
+        alg_ty |= aat_pnode;
+    if (!PFty_disjoint (ty, PFty_stmt ())) {
+        alg_ty |= aat_update;
+        alg_ty |= aat_node;
+        alg_ty |= aat_node1;
+        alg_ty |= aat_uA;
+        alg_ty |= aat_qname;
+    }
+    return alg_ty;
+}
+
+/**
+ * Extract occurrence indicator from the XQuery type.
+ */
+PFalg_occ_ind_t
+PFalg_type_occ (PFty_t ty)
+{
+    if (PFty_subtype (ty, PFty_item ()))
+        return alg_occ_exactly_one;
+    else if (PFty_subtype (ty, PFty_plus (PFty_item ())))
+        return alg_occ_one_or_more;
+    else if (PFty_subtype (ty, PFty_opt(PFty_item ())))
+        return alg_occ_zero_or_one;
+    else
+        return alg_occ_unknown;
+}
+
+/**
  * Print function name
  */
 char *

Index: algebra_cse.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/algebra_cse.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- algebra_cse.c       10 Dec 2007 15:09:59 -0000      1.61
+++ algebra_cse.c       13 Dec 2007 13:08:14 -0000      1.62
@@ -455,6 +455,10 @@
             return false;
             break;
 
+        case la_frag_extract:
+            return (a->sem.col_ref.pos == b->sem.col_ref.pos);
+            break;
+            
         case la_error:
             return false;
             break;
@@ -487,6 +491,15 @@
             return false;
             break;
 
+        case la_fun_call:
+        case la_fun_param:
+        case la_fun_frag_param:
+            /*
+             * we do neither split up nor merge function application
+             */
+            return false;
+            break;
+            
         case la_proxy:
         case la_proxy_base:
             /* we assume that we do not split up proxy nodes */

Index: logical.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/logical.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- logical.c   10 Dec 2007 15:10:00 -0000      1.70
+++ logical.c   13 Dec 2007 13:08:15 -0000      1.71
@@ -3325,6 +3325,21 @@
     return ret;
 }
 
+/** Constructor for a fragment extract operator
+    (to be used in combination with a function call) */
+PFla_op_t *
+PFla_frag_extract (const PFla_op_t *n, unsigned int col_pos)
+{
+    PFla_op_t *ret = la_op_wire1 (la_frag_extract, n);
+
+    /* allocate memory for the result schema */
+    ret->schema.count = 0;
+    ret->schema.items = NULL;
+
+    ret->sem.col_ref.pos = col_pos;
+
+    return ret;
+}
 
 /**
  * Create empty set of fragments. It signals that an algebra expression
@@ -3827,11 +3842,107 @@
 
 
 /**
+ * Constructor for the function application
+ */
+PFla_op_t *
+PFla_fun_call (const PFla_op_t *loop, const PFla_op_t *param_list,
+               PFalg_schema_t schema, PFalg_fun_call_t kind,
+               PFqname_t qname, void *ctx,
+               PFalg_att_t iter, PFalg_occ_ind_t occ_ind)
+{
+    PFla_op_t     *ret;
+    unsigned int   i;
+
+    assert (loop);
+    assert (param_list);
+
+    /* create new function application node */
+    ret = la_op_wire2 (la_fun_call, loop, param_list);
+
+    /* allocate memory for the result schema (= schema(n)) */
+    ret->schema.count = schema.count;
+
+    ret->schema.items
+        = PFmalloc (schema.count * sizeof (*(ret->schema.items)));
+
+    for (i = 0; i < schema.count; i++)
+        ret->schema.items[i] = schema.items[i];
+
+    /* insert semantic value */
+    ret->sem.fun_call.kind    = kind;
+    ret->sem.fun_call.qname   = qname;
+    ret->sem.fun_call.ctx     = ctx;
+    ret->sem.fun_call.iter    = iter;
+    ret->sem.fun_call.occ_ind = occ_ind;
+
+    return ret;
+}
+
+
+/**
+ * Constructor for a list item of a parameter list
+ * related to function application
+ */
+PFla_op_t *
+PFla_fun_param (const PFla_op_t *argument, const PFla_op_t *param_list,
+                PFalg_schema_t schema)
+{
+    PFla_op_t     *ret;
+    unsigned int   i;
+
+    assert (argument);
+    assert (param_list);
+
+    /* create new function application parameter node */
+    ret = la_op_wire2 (la_fun_param, argument, param_list);
+
+    /* allocate memory for the result schema (= schema(n)) */
+    ret->schema.count = schema.count;
+
+    ret->schema.items
+        = PFmalloc (schema.count * sizeof (*(ret->schema.items)));
+
+    for (i = 0; i < schema.count; i++)
+        ret->schema.items[i] = schema.items[i];
+
+    return ret;
+}
+
+
+/**
+ * Constructor for the fragment information of a list item
+ * of a parameter list related to function application
+ */
+PFla_op_t *
+PFla_fun_frag_param (const PFla_op_t *argument,
+                     const PFla_op_t *param_list,
+                     unsigned int col_pos)
+{
+    PFla_op_t     *ret;
+
+    assert (argument);
+    assert (param_list);
+
+    /* create new function application parameter node */
+    ret = la_op_wire2 (la_fun_frag_param, argument, param_list);
+
+    /* allocate memory for the result schema */
+    ret->schema.count = 0;
+    ret->schema.items = NULL;
+
+    ret->sem.col_ref.pos = col_pos;
+    
+    return ret;
+}
+
+
+/**
  * Constructor for a proxy operator with a single child
  */
-PFla_op_t *PFla_proxy (const PFla_op_t *n, unsigned int kind,
-                       PFla_op_t *ref, PFla_op_t *base,
-                       PFalg_attlist_t new_cols, PFalg_attlist_t req_cols)
+PFla_op_t *
+PFla_proxy (const PFla_op_t *n, unsigned int kind,
+            PFla_op_t *ref, PFla_op_t *base,
+            PFalg_attlist_t new_cols, PFalg_attlist_t req_cols)
 {
     return PFla_proxy2 (n, kind, ref, base, NULL, new_cols, req_cols);
 }
@@ -3840,9 +3951,10 @@
 /**
  * Constructor for a proxy operator with a two children
  */
-PFla_op_t *PFla_proxy2 (const PFla_op_t *n, unsigned int kind,
-                       PFla_op_t *ref, PFla_op_t *base1, PFla_op_t *base2,
-                       PFalg_attlist_t new_cols, PFalg_attlist_t req_cols)
+PFla_op_t *
+PFla_proxy2 (const PFla_op_t *n, unsigned int kind,
+             PFla_op_t *ref, PFla_op_t *base1, PFla_op_t *base2,
+             PFalg_attlist_t new_cols, PFalg_attlist_t req_cols)
 {
     PFla_op_t     *ret;
     unsigned int   i;
@@ -3889,7 +4001,8 @@
 /**
  * Constructor for a proxy base operator
  */
-PFla_op_t *PFla_proxy_base (const PFla_op_t *n)
+PFla_op_t *
+PFla_proxy_base (const PFla_op_t *n)
 {
     PFla_op_t *ret = la_op_wire1 (la_proxy_base, n);
 
@@ -3945,6 +4058,10 @@
  * The @a left and @a right arguments are its new children.
  * Each algebra node has at most 2 children, so the left children
  * can even be misused as document.
+ *
+ * This function does not care about XQuery semantics and also
+ * duplicates operators whose semantics change this way (e.g., node
+ * constructors).
  */
 PFla_op_t *
 PFla_op_duplicate (PFla_op_t *n, PFla_op_t *left, PFla_op_t *right)
@@ -4254,6 +4371,9 @@
         case la_fragment:
             return PFla_fragment (left);
 
+        case la_frag_extract:
+            return PFla_frag_extract (left, n->sem.col_ref.pos);
+
         case la_frag_union:
             return PFla_frag_union (left, right);
 
@@ -4287,6 +4407,23 @@
                                    n->sem.trace_map.inner,
                                    n->sem.trace_map.outer);
 
+        case la_fun_call:
+            return PFla_fun_call (left, right,
+                                  n->schema,
+                                  n->sem.fun_call.kind,
+                                  n->sem.fun_call.qname,
+                                  n->sem.fun_call.ctx,
+                                  n->sem.fun_call.iter,
+                                  n->sem.fun_call.occ_ind);
+
+        case la_fun_param:
+            return PFla_fun_param (left, right,
+                                   n->schema);
+                                   
+        case la_fun_frag_param:
+            return PFla_fun_frag_param (left, right,
+                                        n->sem.col_ref.pos);
+                                   
         case la_string_join:
             return PFla_fn_string_join (
                        left, right,


-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to