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

Modified Files:
      Tag: M5XQ
        opt_mvd.c 
Log Message:
propagated changes of Friday Jun 12 2009 - Monday Jun 15 2009
from the development trunk to the M5XQ branch

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2009/06/12 - tsheyar: compiler/algebra/opt/opt_mvd.c,1.54
-- 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 opt_mvd.c
Index: opt_mvd.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/opt/opt_mvd.c,v
retrieving revision 1.50.2.3
retrieving revision 1.50.2.4
diff -u -d -r1.50.2.3 -r1.50.2.4
--- opt_mvd.c   20 May 2009 16:28:33 -0000      1.50.2.3
+++ opt_mvd.c   15 Jun 2009 12:45:16 -0000      1.50.2.4
@@ -258,38 +258,81 @@
 
 /* worker for aggregate operators */
 static bool
-modify_aggr (PFla_op_t *p,
-             PFla_op_kind_t kind)
+modify_aggr (PFla_op_t *p)
 {
     bool modified = false;
 
+    assert (p->kind == la_aggr);
+
     /* An expression that contains the partitioning column is
        independent of the aggregate. The translation thus moves the
        expression above the aggregate operator and removes its partitioning
        column. */
     if (is_cross (L(p)) &&
         p->sem.aggr.part) {
+        PFla_op_t *lp        = NULL,
+                  *rp        = NULL;
+        bool       all_left  = true,
+                   all_right = true;
+
+        /* check if all aggregate columns reside in one cross product
+           argument */
+        for (unsigned int i = 0; i < p->sem.aggr.count; i++) {
+            /* Some aggregates (such as count, sum, ...) are affected
+               by the cardinality of the input. For these aggregates
+               we would need to ensure the keyness of the part column.
+               As we don't have that information at hand we skip the
+               rewrite. */
+            switch (p->sem.aggr.aggr[i].kind) {
+                case alg_aggr_min:
+                case alg_aggr_max:
+                case alg_aggr_avg:
+                case alg_aggr_all:
+                    break;
+                default:
+                    return modified;
+            }
+
+            if (p->sem.aggr.aggr[i].kind != alg_aggr_count) {
+                if (!col_present (LL(p), p->sem.aggr.aggr[i].col))
+                    all_left &= false;
+                else if (!col_present (LR(p), p->sem.aggr.aggr[i].col))
+                    all_right &= false;
+            }
+        }
+
         if (col_present (LL(p), p->sem.aggr.part) &&
-            !col_present (LL(p), p->sem.aggr.col)) {
-            *p = *(cross_can (
-                      LL(p),
-                      aggr (kind,
-                            LR(p),
-                            p->sem.aggr.res,
-                            p->sem.aggr.col,
-                            col_NULL)));
-            modified = true;
+            !col_present (LR(p), p->sem.aggr.part) &&
+            all_right) {
+            lp = LL(p);
+            rp = LR(p);
         }
         /* if not present check the right operand */
         else if (col_present (LR(p), p->sem.aggr.part) &&
-                 !col_present (LR(p), p->sem.aggr.col)) {
-            *p = *(cross_can (
-                      LR(p),
-                      aggr (kind,
-                            LL(p),
-                            p->sem.aggr.res,
-                            p->sem.aggr.col,
-                            col_NULL)));
+                 !col_present (LL(p), p->sem.aggr.part) &&
+                 all_left) {
+            lp = LR(p);
+            rp = LL(p);
+        }
+
+        if (lp && rp) {
+            /* Invent a new constant partition column as we need
+               to ensure that aggregates on empty inputs return
+               an empty input. (The unpartitioned aggregate will
+               *always* return a single row.) */
+            PFalg_col_t const_part = PFcol_new (col_iter);
+
+            *p = *PFla_project_ (
+                      cross_can (
+                          distinct (
+                              project (lp, proj (p->sem.aggr.part,
+                                                 p->sem.aggr.part))),
+                          aggr (attach (rp, const_part, lit_nat (21)),
+                                const_part,
+                                p->sem.aggr.count,
+                                p->sem.aggr.aggr)),
+                      p->schema.count,
+                      PFalg_proj_create (p->schema));
             modified = true;
         }
     }
@@ -1035,46 +1078,8 @@
         }
         break;
 
-    case la_avg:
-        modified = modify_aggr (p, la_avg) || modified;
-        break;
-    case la_max:
-        modified = modify_aggr (p, la_max) || modified;
-        break;
-    case la_min:
-        modified = modify_aggr (p, la_min) || modified;
-        break;
-    case la_sum:
-        modified = modify_aggr (p, la_sum) || modified;
-        break;
-    case la_prod:
-        modified = modify_aggr (p, la_prod) || modified;
-        break;
-    case la_count:
-        /* An expression that contains the partitioning column is
-           independent of the aggregate. The translation thus moves the
-           expression above the aggregate operator and removes its partitioning
-           column. */
-        if (is_cross (L(p)) &&
-            p->sem.aggr.part) {
-            if (col_present (LL(p), p->sem.aggr.part)) {
-                *p = *(cross_can (
-                          LL(p),
-                          count (LR(p),
-                                 p->sem.aggr.res,
-                                 col_NULL)));
-                modified = true;
-            }
-            /* if not present it has to be in the right operand */
-            else {
-                *p = *(cross_can (
-                          LR(p),
-                          count (LL(p),
-                                 p->sem.aggr.res,
-                                 col_NULL)));
-                modified = true;
-            }
-        }
+    case la_aggr:
+        modified = modify_aggr (p) || modified;
         break;
 
     case la_rownum:
@@ -1322,64 +1327,6 @@
         }
         break;
 
-    case la_seqty1:
-        if (is_cross (L(p)) &&
-            p->sem.aggr.part) {
-            if (col_present (LL(p), p->sem.aggr.part) &&
-                !col_present (LL(p), p->sem.aggr.col)) {
-                *p = *(cross_can (
-                          LL(p),
-                          seqty1 (
-                              LR(p),
-                              p->sem.aggr.res,
-                              p->sem.aggr.col,
-                              col_NULL)));
-                modified = true;
-            }
-            /* if not present check the right operand */
-            else if (col_present (LR(p), p->sem.aggr.part) &&
-                     !col_present (LR(p), p->sem.aggr.col)) {
-                *p = *(cross_can (
-                          LR(p),
-                          seqty1 (
-                              LL(p),
-                              p->sem.aggr.res,
-                              p->sem.aggr.col,
-                              col_NULL)));
-                modified = true;
-            }
-        }
-        break;
-
-    case la_all:
-        if (is_cross (L(p)) &&
-            p->sem.aggr.part) {
-            if (col_present (LL(p), p->sem.aggr.part) &&
-                !col_present (LL(p), p->sem.aggr.col)) {
-                *p = *(cross_can (
-                          LL(p),
-                          all (
-                              LR(p),
-                              p->sem.aggr.res,
-                              p->sem.aggr.col,
-                              col_NULL)));
-                modified = true;
-            }
-            /* if not present check the right operand */
-            else if (col_present (LR(p), p->sem.aggr.part) &&
-                     !col_present (LR(p), p->sem.aggr.col)) {
-                *p = *(cross_can (
-                          LR(p),
-                          all (
-                              LL(p),
-                              p->sem.aggr.res,
-                              p->sem.aggr.col,
-                              col_NULL)));
-                modified = true;
-            }
-        }
-        break;
-
     case la_step:
         if (is_cross (R(p))) {
             if (col_present (RL(p), p->sem.step.item)) {


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