Update of /cvsroot/monetdb/pathfinder/compiler/algebra
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv11514/algebra

Modified Files:
        algebra.c algebra_cse.c builtins.c core2alg.brg logical.c 
        physical.c planner.c 
Log Message:
-- Replaced aggregate operators count, min, max, avg, sum, prod, seqty1,
   and all in the algebra by a single aggregate operator ``aggr'' 
   that can handle multiple aggregates. The aggregate entries 
   are of kind count, min, max, avg, sum, prod, seqty1, all, and dist. 

-- Added new aggregate kind ``dist'' that allows to represent group by
   columns that functionally depend on the partitioning criterion
   in the result of the grouping aggregate.

-- Added rewrite that merges aggregates.                                        
                                             
                                                                                
                                             
-- Added rewrite that removes superfluous aggregates.                           
                                             
                                                                                
                                             
-- Added rewrite that pushes a rank operator through an aggregate.              
                                             
                                                                                
                                             
-- Extended the XML import to cope with the old                                 
                                             
   as well as the new representation of aggregates.                             
                                             


U core2alg.brg
Index: core2alg.brg
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/core2alg.brg,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -d -r1.90 -r1.91
--- core2alg.brg        7 May 2009 14:22:53 -0000       1.90
+++ core2alg.brg        12 Jun 2009 13:06:09 -0000      1.91
@@ -3514,7 +3514,9 @@
 static PFla_op_t *
 type_test (PFty_t ty, PFla_pair_t e, PFla_op_t *loop)
 {
-    PFla_op_t *itemty;
+    PFalg_aggr_t aggr_item;
+    PFla_op_t   *itemty,
+                *aggr;
 
     /*
      * Collect algebra expression with schema (iter,pos,itemty)
@@ -3653,6 +3655,10 @@
      * Second part is the test for the occurence indicator.
      */
 
+    /* build a seqty1 aggregate */
+    aggr_item = PFalg_aggr (alg_aggr_seqty1, col_subty, col_itemty);
+    aggr      = aggr (itemty, col_iter, 1, &aggr_item);
+
     /*
      * Ocurrence indicator `1' (exactly one item).
      *
@@ -3673,7 +3679,7 @@
     if (PFty_subtype (ty, PFty_item ()))
         return
             disjunion (
-                seqty1 (itemty, col_subty, col_itemty, col_iter),
+                aggr,
                 attach (
                     difference (
                         loop,
@@ -3694,13 +3700,16 @@
     if (PFty_subtype (ty, PFty_opt (PFty_item ())))
         return
             disjunion (
-                seqty1 (itemty, col_subty, col_itemty, col_iter),
+                aggr,
                 attach (
                     difference (
                         loop,
                         project (itemty, proj (col_iter, col_iter))),
                     col_subty, lit_bln (true)));
 
+    /* turn the seqty1 aggregate into an all aggregate */
+    aggr->sem.aggr.aggr[0].kind = alg_aggr_all;
+
     /*
      * Ocurrence indicator `+' (one or more items).
      *
@@ -3721,7 +3730,7 @@
     if (PFty_subtype (ty, PFty_plus (PFty_item ())))
         return
             disjunion (
-                all (itemty, col_subty, col_itemty, col_iter),
+                aggr,
                 attach (
                     difference (
                         loop,
@@ -3742,7 +3751,7 @@
     if (PFty_subtype (ty, PFty_star (PFty_item ())))
         return
             disjunion (
-                all (itemty, col_subty, col_itemty, col_iter),
+                aggr,
                 attach (
                     difference (
                         loop,

U algebra.c
Index: algebra.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/algebra.c,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -d -r1.107 -r1.108
--- algebra.c   7 May 2009 14:22:35 -0000       1.107
+++ algebra.c   12 Jun 2009 13:06:04 -0000      1.108
@@ -1257,6 +1257,36 @@
 }
 
 /**
+ * Print aggregate kind
+ */
+char *
+PFalg_aggr_kind_str (PFalg_aggr_kind_t kind)
+{
+    switch (kind) {
+        case alg_aggr_dist:    return "distinct";
+        case alg_aggr_count:   return "count";
+        case alg_aggr_min:     return "min";
+        case alg_aggr_max:     return "max";
+        case alg_aggr_avg:     return "avg";
+        case alg_aggr_sum:     return "sum";
+        case alg_aggr_seqty1:  return "seqty1";
+        case alg_aggr_all:     return "all";
+        case alg_aggr_prod:    return "prod";
+    }
+    PFoops (OOPS_FATAL, "unknown aggregate kind (%i)", kind);
+    return NULL;
+}
+
+/**
+ * Construct an aggregate entry.
+ */
+PFalg_aggr_t
+PFalg_aggr (PFalg_aggr_kind_t kind, PFalg_col_t res, PFalg_col_t col)
+{
+    return (PFalg_aggr_t) { .kind = kind, .res = res, .col = col };
+}
+
+/**
  * Construct a predicate.
  */
 PFalg_sel_t PFalg_sel (PFalg_comp_t comp,

U physical.c
Index: physical.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/physical.c,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -d -r1.93 -r1.94
--- physical.c  20 May 2009 16:00:44 -0000      1.93
+++ physical.c  12 Jun 2009 13:06:10 -0000      1.94
@@ -2278,114 +2278,53 @@
 }
 
 /**
- * Count: Count function operator. Does neither benefit from
- * any existing ordering, nor does it provide/preserve any input
- * ordering.
- */
-PFpa_op_t *
-PFpa_count (const PFpa_op_t *n, PFalg_col_t res, PFalg_col_t part)
-{
-    PFpa_op_t *ret = wire1 (pa_count, n);
-
-    ret->sem.count.res  = res;
-    ret->sem.count.part = part;
-    ret->sem.count.loop = col_NULL;
-
-    /* allocate memory for the result schema */
-    ret->schema.count = part ? 2 : 1;
-    ret->schema.items
-        = PFmalloc (ret->schema.count * sizeof (*(ret->schema.items)));
-
-    if (part) {
-        unsigned int i;
-        for (i = 0; i < n->schema.count; i++)
-
-            if (n->schema.items[i].name == part) {
-                ret->schema.items[0] = n->schema.items[i];
-                break;
-            }
-
-#ifndef NDEBUG
-        if (i == n->schema.count)
-            PFoops (OOPS_FATAL,
-                    "HashCount: unable to find partitioning column `%s'",
-                    PFcol_str (part));
-#endif
-    }
-
-    ret->schema.items[ret->schema.count - 1]
-        = (PFalg_schm_item_t) { .name = res, .type = aat_int };
-
-    /* ---- HashCount: orderings ---- */
-    /* HashCount does not provide any orderings. */
-
-    /* ---- HashCount: costs ---- */
-    ret->cost = AGGR_COST + n->cost;
-
-    return ret;
-}
-
-/**
  * Aggr: Aggregation function operator. Does neither benefit from
  * any existing ordering, nor does it provide/preserve any input
  * ordering.
  */
 PFpa_op_t *
-PFpa_aggr (PFpa_op_kind_t kind, const PFpa_op_t *n,
-           PFalg_col_t res, PFalg_col_t col, PFalg_col_t part)
+PFpa_aggr (const PFpa_op_t *n, PFalg_col_t part,
+           unsigned int count, PFalg_aggr_t *aggr)
 {
-    PFpa_op_t *ret = wire1 (kind, n);
+    PFpa_op_t    *ret = wire1 (pa_aggr, n);
     unsigned int  i;
-#ifndef NDEBUG
-    bool          c1 = false;
-    bool          c2 = false;
-#endif
-
-    ret->sem.aggr.res  = res;
-    ret->sem.aggr.col = col;
-    ret->sem.aggr.part = part;
 
     /* set number of schema items in the result schema
-     * (partitioning column plus result column)
+     * (result columns plus partitioning column)
      */
-    ret->schema.count = part ? 2 : 1;
+    ret->schema.count = count + (part ? 1 : 0);
 
-    ret->schema.items
-        = PFmalloc (ret->schema.count * sizeof (*(ret->schema.items)));
+    ret->schema.items = PFmalloc (ret->schema.count *
+                                  sizeof (*(ret->schema.items)));
 
-    /* verify that columns 'col' and 'part' are columns of n
-     * and include them into the result schema
-     */
-    for (i = 0; i < n->schema.count; i++) {
-        if (col == n->schema.items[i].name) {
-            ret->schema.items[0] = n->schema.items[i];
-            ret->schema.items[0].name = res;
-#ifndef NDEBUG
-            c1 = true;
-#endif
+    /* insert semantic value (aggregates) into the result */
+    ret->sem.aggr.part  = part;
+    ret->sem.aggr.count = count;
+    ret->sem.aggr.aggr  = PFmalloc (count * sizeof (PFalg_aggr_t));
+
+    for (i = 0; i < count; i++) {
+        PFalg_col_t col = aggr[i].col;
+        if (col) {
+            if (!check_col (n, col))
+                PFoops (OOPS_FATAL,
+                        "column `%s' referenced in aggregate not found",
+                        PFcol_str (col));
+            ret->schema.items[i].type = type_of (n, col);
         }
-        if (part && part == n->schema.items[i].name) {
-            ret->schema.items[1] = n->schema.items[i];
-#ifndef NDEBUG
-            c2 = true;
-#endif
+        else {
+            ret->schema.items[i].type = aat_int;
         }
+        ret->sem.aggr.aggr[i] = aggr[i];
+        ret->schema.items[i].name = aggr[i].res;
+    }
+    if (part) {
+        if (!check_col (n, part))
+            PFoops (OOPS_FATAL,
+                    "column `%s' referenced in aggregate not found",
+                    PFcol_str (part));
+        ret->schema.items[count].name = part;
+        ret->schema.items[count].type = type_of (n, part);
     }
-
-#ifndef NDEBUG
-    /* did we find column 'col'? */
-    if (!c1)
-        PFoops (OOPS_FATAL,
-                "column `%s' referenced in aggregation function not found",
-                PFcol_str (col));
-
-    /* did we find column 'part'? */
-    if (part && !c2)
-        PFoops (OOPS_FATAL,
-                "partitioning column `%s' referenced in aggregation "
-                "function not found",
-                PFcol_str (part));
-#endif
 
     /* ---- Aggr: orderings ---- */
     /* Aggr does not provide any orderings. */

U planner.c
Index: planner.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/planner.c,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -d -r1.85 -r1.86
--- planner.c   20 May 2009 16:00:44 -0000      1.85
+++ planner.c   12 Jun 2009 13:06:10 -0000      1.86
@@ -1517,26 +1517,23 @@
 }
 
 /**
- * Generate physical plan for logical aggregation operators
- * (avg, max, min, sum).
+ * Generate physical plan for logical aggregation operators.
  */
 static PFplanlist_t *
-plan_aggr (PFpa_op_kind_t kind, const PFla_op_t *n)
+plan_aggr (const PFla_op_t *n)
 {
     PFplanlist_t  *ret  = new_planlist ();
 
     assert (n);
-    assert (n->kind == la_avg || n->kind == la_max
-            || n->kind == la_min || n->kind == la_sum || n->kind == la_prod
-            || n->kind == la_seqty1 || n->kind == la_all);
     assert (L(n)); assert (L(n)->plans);
 
     /* consider each plan in n */
     for (unsigned int i = 0; i < PFarray_last (L(n)->plans); i++)
         add_plan (ret,
-                  aggr (kind,
-                        *(plan_t **) PFarray_at (L(n)->plans, i),
-                        n->sem.aggr.res, n->sem.aggr.col, n->sem.aggr.part));
+                  aggr (*(plan_t **) PFarray_at (L(n)->plans, i),
+                        n->sem.aggr.part,
+                        n->sem.aggr.count,
+                        n->sem.aggr.aggr));
 
     return ret;
 }
@@ -1566,10 +1563,12 @@
     op = L(n);
 
     if (op->kind == la_project &&
-        L(op)->kind == la_count &&
+        L(op)->kind == la_aggr &&
+        L(op)->sem.aggr.count == 1 &&
+        L(op)->sem.aggr.aggr[0].kind == alg_aggr_count &&
         L(op)->sem.aggr.part) {
         part_col = L(op)->sem.aggr.part;
-        res_col  = L(op)->sem.aggr.res;
+        res_col  = L(op)->sem.aggr.aggr[0].res;
         if (part_col == op->sem.proj.items[0].old &&
             res_col  == op->sem.proj.items[1].old) {
             new_part_col = op->sem.proj.items[0].new;
@@ -1583,12 +1582,14 @@
         }
         count_op = L(op);
     }
-    else if (op->kind == la_count &&
+    else if (op->kind == la_aggr &&
+             op->sem.aggr.count == 1 &&
+             op->sem.aggr.aggr[0].kind == alg_aggr_count &&
              op->sem.aggr.part) {
         part_col     = L(op)->sem.aggr.part;
-        res_col      = L(op)->sem.aggr.res;
+        res_col      = L(op)->sem.aggr.aggr[0].res;
         new_part_col = L(op)->sem.aggr.part;
-        new_res_col  = L(op)->sem.aggr.res;
+        new_res_col  = L(op)->sem.aggr.aggr[0].res;
         count_op = op;
     }
     else
@@ -1620,7 +1621,7 @@
 
     if (op->kind != la_difference ||
         R(op)->kind != la_project ||
-        RL(op)->kind != la_count ||
+        RL(op)->kind != la_aggr ||
         count_op != RL(op) ||
         op->schema.count != 1 ||
         R(op)->sem.proj.items[0].old != part_col)
@@ -1652,32 +1653,6 @@
 }
 
 /**
- * Generate physical plan for the logical `Count' operator.
- *
- * Currently we only provide HashCount, which neither benefits from
- * any input ordering, nor does it guarantee any output ordering.
- *
- * FIXME:
- *   Is there a means to implement an order-aware Count operator
- *   in MonetDB?
- */
-static PFplanlist_t *
-plan_count (const PFla_op_t *n)
-{
-    PFplanlist_t  *ret  = new_planlist ();
-
-    assert (n); assert (n->kind == la_count);
-    assert (L(n)); assert (L(n)->plans);
-
-    /* consider each plan in n */
-    for (unsigned int i = 0; i < PFarray_last (L(n)->plans); i++)
-        add_plan (ret,
-                  count (*(plan_t **) PFarray_at (L(n)->plans, i),
-                         n->sem.aggr.res, n->sem.aggr.part));
-    return ret;
-}
-
-/**
  * Generate physical plans for the logical `rownum' operator.
  *
  * The logical `rownum' operator is a rather complex operator.  In
@@ -3623,12 +3598,7 @@
         case la_bool_not:
                                 plans = plan_unary (n);           break;
         case la_to:             plans = plan_to (n);              break;
-        case la_count:          plans = plan_count (n);           break;
-        case la_avg:            plans = plan_aggr (pa_avg, n);    break;
-        case la_max:            plans = plan_aggr (pa_max, n);    break;
-        case la_min:            plans = plan_aggr (pa_min, n);    break;
-        case la_sum:            plans = plan_aggr (pa_sum, n);    break;
-        case la_prod:           plans = plan_aggr (pa_prod, n);   break;
+        case la_aggr:           plans = plan_aggr (n);            break;
 
         case la_rownum:         plans = plan_rownum (n);          break;
         case la_rowrank:
@@ -3641,8 +3611,6 @@
         case la_type:           plans = plan_type (n);            break;
         case la_type_assert:    plans = plan_type_assert (n);     break;
         case la_cast:           plans = plan_cast (n);            break;
-        case la_seqty1:         plans = plan_aggr (pa_seqty1, n); break;
-        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;

U algebra_cse.c
Index: algebra_cse.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/algebra_cse.c,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- algebra_cse.c       28 May 2009 16:34:58 -0000      1.84
+++ algebra_cse.c       12 Jun 2009 13:06:06 -0000      1.85
@@ -370,22 +370,16 @@
                     && a->sem.unary.res == b->sem.unary.res);
             break;
 
-        case la_avg:
-        case la_max:
-        case la_min:
-        case la_sum:
-        case la_prod:
-        case la_count:
-        case la_seqty1:
-        case la_all:
-            if (a->sem.aggr.col != b->sem.aggr.col
-                || a->sem.aggr.res != b->sem.aggr.res)
+        case la_aggr:
+            if (a->sem.aggr.count != b->sem.aggr.count ||
+                a->sem.aggr.part  != b->sem.aggr.part)
                 return false;
 
-            /* either both aggregates are partitioned or none */
-            /* partitioning column must be equal (if available) */
-            if (a->sem.aggr.part != b->sem.aggr.part)
-                return false;
+            for (unsigned int i = 0; i < a->sem.aggr.count; i++)
+                if (a->sem.aggr.aggr[i].kind != b->sem.aggr.aggr[i].kind ||
+                    a->sem.aggr.aggr[i].res  != b->sem.aggr.aggr[i].res  ||
+                    a->sem.aggr.aggr[i].col  != b->sem.aggr.aggr[i].col)
+                    return false;
 
             return true;
 

U logical.c
Index: logical.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/logical.c,v
retrieving revision 1.125
retrieving revision 1.126
diff -u -d -r1.125 -r1.126
--- logical.c   14 May 2009 19:33:22 -0000      1.125
+++ logical.c   12 Jun 2009 13:06:09 -0000      1.126
@@ -2157,119 +2157,73 @@
 
 
 /**
- * Constructor for operators forming the application of a
- * (partitioned) aggregation function (sum, min, max and avg) on a column.
+ * Constructor for aggregate operator that builds @a count number
+ * of aggregates in parallel (based on the same partitioning column
+ * @a part). Every attribute is of the kind count, sum, min, max, avg,
+ * seqty1, all, prod, or dist.
  *
- * The values of column @a col are used by the aggregation functaion.
- * The partitioning (group by) column is represented by @a part.
- * The result is stored in column @a res.
+ *
+ * The `seqty1' aggregate is particularly crafted to test the occurrence
+ * indicator ``exactly one'' (`1'). It groups its argument according
+ * to the column @a part. For each partition it will look at the
+ * value column @a col. If there is exactly one tuple for the
+ * partition, and if the value of @a col is @c true for this tuple,
+ * the result for this partition will be @c true. In all other cases
+ * (There is more than one tuple, or the single tuple contains @c false
+ * in @a col.) the result for this partition will be @c false.
+ *
+ * The `all' aggregate looks into a group of tuples (by partitioning
+ * column @a part), and returns @c true for this group iff all
+ * values in column @a col for this group are @c true.
+ *
+ * The `dist' aggregate can be used only for columns that functionally
+ * dependent on the partitioning column (and could be replaced by min or max).
  */
 PFla_op_t *
-PFla_aggr (PFla_op_kind_t kind, const PFla_op_t *n, PFalg_col_t res,
-           PFalg_col_t col, PFalg_col_t part)
+PFla_aggr (const PFla_op_t *n, PFalg_col_t part,
+           unsigned int count, PFalg_aggr_t *aggr)
 {
-    /* build a new aggr node */
-    PFla_op_t    *ret = la_op_wire1 (kind, n);
+    /* build a new aggregate node */
+    PFla_op_t    *ret = la_op_wire1 (la_aggr, n);
     unsigned int  i;
-    bool          c1 = false;
-    bool          c2 = false;
 
     /* set number of schema items in the result schema
-     * (partitioning column plus result column)
+     * (result columns plus partitioning column)
      */
-    ret->schema.count = part ? 2 : 1;
+    ret->schema.count = count + (part ? 1 : 0);
 
-    ret->schema.items
-        = PFmalloc (ret->schema.count * sizeof (*(ret->schema.items)));
+    ret->schema.items = PFmalloc (ret->schema.count *
+                                  sizeof (*(ret->schema.items)));
 
+    /* insert semantic value (aggregates) into the result */
+    ret->sem.aggr.part  = part;
+    ret->sem.aggr.count = count;
+    ret->sem.aggr.aggr  = PFmalloc (count * sizeof (PFalg_aggr_t));
 
-    /* verify that columns 'col' and 'part' are columns of n
-     * and include them into the result schema
-     */
-    for (i = 0; i < n->schema.count; i++) {
-        if (col == n->schema.items[i].name) {
-            ret->schema.items[0] = n->schema.items[i];
-            ret->schema.items[0].name = res;
-            c1 = true;
+    for (i = 0; i < count; i++) {
+        PFalg_col_t col = aggr[i].col;
+        if (col) {
+            if (!PFprop_ocol (n, col))
+                PFoops (OOPS_FATAL,
+                        "column `%s' referenced in aggregate not found",
+                        PFcol_str (col));
+            ret->schema.items[i].type = PFprop_type_of (n, col);
         }
-        if (part && part == n->schema.items[i].name) {
-            ret->schema.items[1] = n->schema.items[i];
-            c2 = true;
+        else {
+            ret->schema.items[i].type = aat_int;
         }
+        ret->sem.aggr.aggr[i] = aggr[i];
+        ret->schema.items[i].name = aggr[i].res;
     }
-
-    /* did we find column 'col'? */
-    if (!c1)
-        PFoops (OOPS_FATAL,
-                "column `%s' referenced in aggregation function not found",
-                PFcol_str (col));
-
-    /* did we find column 'part'? */
-    if (part && !c2)
-        PFoops (OOPS_FATAL,
-                "partitioning column `%s' referenced in aggregation "
-                "function not found",
-                PFcol_str (part));
-
-    /* insert semantic value (result (aggregated) column, partitioning
-     * column(s), and result column) into the result
-     */
-    ret->sem.aggr.col = col;
-    ret->sem.aggr.part = part;
-    ret->sem.aggr.res = res;
-
-    return ret;
-}
-
-
-/**
- * Constructor for (partitioned) row counting operators.
- *
- * Counts all rows with identical values in column @a part (which holds
- * the partitioning or group by column). The result is stored in
- * column @a res.
- */
-PFla_op_t *
-PFla_count (const PFla_op_t *n, PFalg_col_t res, PFalg_col_t part)
-{
-    PFla_op_t    *ret = la_op_wire1 (la_count, n);
-    unsigned int  i;
-
-    /* set number of schema items in the result schema
-     * (partitioning column plus result column)
-     */
-    ret->schema.count = part ? 2 : 1;
-
-    ret->schema.items
-        = PFmalloc (ret->schema.count * sizeof (*(ret->schema.items)));
-
-    /* copy the partitioning column */
     if (part) {
-        for (i = 0; i < n->schema.count; i++)
-            if (n->schema.items[i].name == part) {
-                ret->schema.items[1] = n->schema.items[i];
-                break;
-            }
-
-        /* did we find column 'part'? */
-        if (i >= n->schema.count)
+        if (!PFprop_ocol (n, part))
             PFoops (OOPS_FATAL,
-                    "partitioning column %s referenced in count operator "
-                    "not found", PFcol_str (part));
+                    "column `%s' referenced in aggregate not found",
+                    PFcol_str (part));
+        ret->schema.items[count].name = part;
+        ret->schema.items[count].type = PFprop_type_of (n, part);
     }
 
-    /* insert result column into schema */
-    ret->schema.items[0].name = res;
-    ret->schema.items[0].type = aat_int;
-
-    /* insert semantic value (partitioning and result column) into
-     * the result
-     */
-    ret->sem.aggr.part = part;
-    ret->sem.aggr.res  = res;
-    ret->sem.aggr.col  = col_NULL; /* don't use col field */
-
-
     return ret;
 }
 
@@ -2636,46 +2590,6 @@
 }
 
 /**
- * Constructor for algebra `seqty1' operator.
- *
- * This operator is particularly crafted to test the occurrence
- * indicator ``exactly one'' (`1'). It groups its argument according
- * to the column @a part. For each partition it will look at the
- * value column @a col. If there is exactly one tuple for the
- * partition, and if the value of @a col is @c true for this tuple,
- * the result for this partition will be @c true. In all other cases
- * (There is more than one tuple, or the single tuple contains @c false
- * in @a col.) the result for this partition will be @c false.
- */
-PFla_op_t *
-PFla_seqty1 (const PFla_op_t *n,
-             PFalg_col_t res, PFalg_col_t col, PFalg_col_t part)
-{
-    assert (PFprop_type_of (n, col) == aat_bln);
-    return PFla_aggr (la_seqty1, n, res, col, part);
-}
-
-
-/**
- * Construction operator for algebra `all' operator.
- *
- * The `all' operator looks into a group of tuples (by partitioning
- * column @a part), and returns @c true for this group iff all
- * values in column @a col for this group are @c true.
- *
- * This operator is used, e.g., to back the occurence indicators `+'
- * and `*'.
- */
-PFla_op_t *
-PFla_all (const PFla_op_t *n,
-          PFalg_col_t res, PFalg_col_t col, PFalg_col_t part)
-{
-    assert (PFprop_type_of (n, col) == aat_bln);
-    return PFla_aggr (la_all, n, res, col, part);
-}
-
-
-/**
  * Path step operator.
  *
  * Each such step operator corresponds to the evaluation of an XPath
@@ -4363,20 +4277,11 @@
                             n->sem.binary.col1,
                             n->sem.binary.col2);
 
-        case la_avg:
-        case la_max:
-        case la_min:
-        case la_sum:
-        case la_prod:
-            return PFla_aggr (n->kind, left,
-                              n->sem.aggr.res,
-                              n->sem.aggr.col,
-                              n->sem.aggr.part);
-
-        case la_count:
-            return PFla_count (left,
-                               n->sem.aggr.res,
-                               n->sem.aggr.part);
+        case la_aggr:
+            return PFla_aggr (left,
+                              n->sem.aggr.part,
+                              n->sem.aggr.count,
+                              n->sem.aggr.aggr);
 
         case la_rownum:
             return PFla_rownum (left,
@@ -4416,18 +4321,6 @@
                               n->sem.type.col,
                               n->sem.type.ty);
 
-        case la_seqty1:
-            return PFla_seqty1 (left,
-                                n->sem.aggr.res,
-                                n->sem.aggr.col,
-                                n->sem.aggr.part);
-
-        case la_all:
-            return PFla_all (left,
-                             n->sem.aggr.res,
-                             n->sem.aggr.col,
-                             n->sem.aggr.part);
-
         case la_step:
             return PFla_step (left, right,
                               n->sem.step.spec,

U builtins.c
Index: builtins.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/builtins.c,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -d -r1.124 -r1.125
--- builtins.c  20 May 2009 16:08:32 -0000      1.124
+++ builtins.c  12 Jun 2009 13:06:07 -0000      1.125
@@ -344,6 +344,24 @@
         .frag = PFla_empty_set () };
 }
 
+/* ----------------------------------------------- */
+/* Helper Function to Translate Simple Aggregates  */
+/* ----------------------------------------------- */
+
+/**
+ * Construct a simple aggregate.
+ */
+static PFla_op_t *
+simple_aggr (const PFla_op_t *n,
+             PFalg_col_t part,
+             PFalg_aggr_kind_t kind,
+             PFalg_col_t res,
+             PFalg_col_t col)
+{
+    PFalg_aggr_t aggr = PFalg_aggr (kind, res, col);
+    return PFla_aggr (n, part, 1, &aggr);
+}
+
 /* ------------ */
 /* 2. ACCESSORS */
 /* ------------ */
@@ -4814,10 +4832,13 @@
 {
     PFla_op_t *count = select_ (
                            not (eq (attach (
-                                        count (
+                                        simple_aggr (
                                             project (args[0].rel,
                                                      proj (col_iter, 
col_iter)),
-                                            col_item, col_iter),
+                                            col_iter,
+                                            alg_aggr_count,
+                                            col_item,
+                                            col_NULL),
                                         col_item1, lit_int (1)),
                                     col_item2, col_item1, col_item),
                                 col_res, col_item2),
@@ -4851,9 +4872,13 @@
                       PFla_op_t **side_effects,
                       struct PFla_pair_t *args)
 {
-    PFla_op_t *count = count (project (args[0].rel,
-                                       proj (col_iter, col_iter)),
-                              col_item, col_iter);
+    PFla_op_t *count = simple_aggr (
+                           project (args[0].rel,
+                                    proj (col_iter, col_iter)),
+                           alg_aggr_count,
+                           col_iter,
+                           col_item,
+                           col_NULL);
 
     char *err_string = "err:FORG0003, fn:exactly-one called with "
                        "a sequence containing more than one item.";
@@ -5041,9 +5066,13 @@
 {
     (void) ordering; (void) side_effects;
 
-    PFla_op_t *count = count (project (args[0].rel,
-                                       proj (col_iter, col_iter)),
-                              col_item, col_iter);
+    PFla_op_t *count = simple_aggr (
+                           project (args[0].rel,
+                                    proj (col_iter, col_iter)),
+                           col_iter,
+                           alg_aggr_count,
+                           col_item,
+                           col_NULL);
 
     return (struct PFla_pair_t) {
         .rel = attach (
@@ -5071,7 +5100,7 @@
  *                                ()
  */
 static struct PFla_pair_t
-fn_aggr (PFalg_simple_type_t t, PFla_op_kind_t kind,
+fn_aggr (PFalg_simple_type_t t, PFalg_aggr_kind_t kind,
          const PFla_op_t *loop,
          bool ordering,
          PFla_op_t **side_effects,
@@ -5080,11 +5109,14 @@
     (void) loop; (void) ordering; (void) side_effects;
 
     return (struct PFla_pair_t) {
-        .rel = attach(aggr (kind,
-                            project (cast(args[0].rel, col_cast, col_item, t),
-                                     proj (col_iter, col_iter),
-                                     proj (col_item, col_cast)),
-                            col_item, col_item, col_iter),
+        .rel = attach(simple_aggr (
+                          project (cast(args[0].rel, col_cast, col_item, t),
+                                   proj (col_iter, col_iter),
+                                   proj (col_item, col_cast)),
+                          col_iter,
+                          kind,
+                          col_item,
+                          col_item),
                       col_pos, lit_nat (1)),
         .frag = PFla_empty_set () };
 }
@@ -5098,7 +5130,7 @@
               PFla_op_t **side_effects,
               struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_dbl, la_avg, loop, ordering, side_effects, args);
+    return fn_aggr(aat_dbl, alg_aggr_avg, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5110,7 +5142,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_str, la_max, loop, ordering, side_effects, args);
+    return fn_aggr(aat_str, alg_aggr_max, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5122,7 +5154,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_int, la_max, loop, ordering, side_effects, args);
+    return fn_aggr(aat_int, alg_aggr_max, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5134,7 +5166,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_dec, la_max, loop, ordering, side_effects, args);
+    return fn_aggr(aat_dec, alg_aggr_max, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5146,7 +5178,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_dbl, la_max, loop, ordering, side_effects, args);
+    return fn_aggr(aat_dbl, alg_aggr_max, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5158,7 +5190,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_str, la_min, loop, ordering, side_effects, args);
+    return fn_aggr(aat_str, alg_aggr_min, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5170,7 +5202,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_int, la_min, loop, ordering, side_effects, args);
+    return fn_aggr(aat_int, alg_aggr_min, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5182,7 +5214,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_dec, la_min, loop, ordering, side_effects, args);
+    return fn_aggr(aat_dec, alg_aggr_min, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5194,7 +5226,7 @@
                   PFla_op_t **side_effects,
                   struct PFla_pair_t *args)
 {
-    return fn_aggr(aat_dbl, la_min, loop, ordering, side_effects, args);
+    return fn_aggr(aat_dbl, alg_aggr_min, loop, ordering, side_effects, args);
 }
 
 /**
@@ -5221,11 +5253,14 @@
 {
     (void) ordering; (void) side_effects;
 
-    PFla_op_t *sum = aggr (la_sum,
-                           project (cast(args[0].rel, col_cast, col_item, t),
-                                   proj (col_iter, col_iter),
-                                   proj (col_item, col_cast)),
-                           col_item, col_item, col_iter);
+    PFla_op_t *sum = simple_aggr (
+                         project (cast(args[0].rel, col_cast, col_item, t),
+                                 proj (col_iter, col_iter),
+                                 proj (col_item, col_cast)),
+                         col_iter,
+                         alg_aggr_sum,
+                         col_item,
+                         col_item);
 
     return (struct PFla_pair_t) {
         .rel = attach (
@@ -5249,11 +5284,14 @@
 {
     (void) ordering; (void) side_effects;
 
-    PFla_op_t *prod = aggr (la_prod,
-                           project (cast(args[0].rel, col_cast, col_item, t),
-                                   proj (col_iter, col_iter),
-                                   proj (col_item, col_cast)),
-                           col_item, col_item, col_iter);
+    PFla_op_t *prod = simple_aggr (
+                          project (cast(args[0].rel, col_cast, col_item, t),
+                                  proj (col_iter, col_iter),
+                                  proj (col_item, col_cast)),
+                          col_iter,
+                          alg_aggr_prod,
+                          col_item,
+                          col_item);
 
     return (struct PFla_pair_t) {
         .rel = attach (
@@ -5345,11 +5383,14 @@
 {
     (void) ordering; (void) side_effects;
 
-    PFla_op_t *sum = aggr (la_sum,
-                           project (cast (args[0].rel, col_cast, col_item, t),
-                                    proj (col_iter, col_iter),
-                                    proj (col_item, col_cast)),
-                           col_item, col_item, col_iter);
+    PFla_op_t *sum = simple_aggr (
+                         project (cast (args[0].rel, col_cast, col_item, t),
+                                  proj (col_iter, col_iter),
+                                  proj (col_item, col_cast)),
+                         col_iter,
+                         alg_aggr_sum,
+                         col_item,
+                         col_item);
 
     return (struct PFla_pair_t) {
         .rel = attach (


------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to