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

Modified Files:
      Tag: XQuery_0-24
        opt_const.c 
Log Message:
-- Fixing bug #1981827:
   It is incorrect to rewrite a grouped aggregate into an ungrouped one
   without taking the cardinality (and thus the loop relation) into account.

   Out of nowhere (no row) something (a row) pops up...   


U opt_const.c
Index: opt_const.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/opt/opt_const.c,v
retrieving revision 1.32
retrieving revision 1.32.2.1
diff -u -d -r1.32 -r1.32.2.1
--- opt_const.c 21 May 2008 10:52:07 -0000      1.32
+++ opt_const.c 2 Jun 2008 16:32:42 -0000       1.32.2.1
@@ -455,37 +455,45 @@
                and replace it by an unpartitioned count */
             if (p->schema.count == 1 &&
                 L(p)->kind == la_project &&
-                L(L(p))->kind == la_count &&
-                PFprop_const (L(L(p))->prop, L(L(p))->sem.aggr.part) &&
+                LL(p)->kind == la_count &&
+                PFprop_const (LL(p)->prop, LL(p)->sem.aggr.part) &&
+                L(p)->sem.proj.items[0].old == LL(p)->sem.aggr.res &&
                 R(p)->kind == la_project &&
-                L(R(p))->kind == la_attach &&
-                L(R(p))->sem.attach.value.type == aat_int &&
-                L(R(p))->sem.attach.value.val.int_ == 0 &&
-                L(L(R(p)))->kind == la_difference &&
-                R(L(L(R(p))))->kind == la_project &&
-                R(L(L(R(p))))->sem.proj.items[0].new ==
-                L(L(p))->sem.aggr.part &&
-                L(R(L(L(R(p))))) == L(L(p))) {
+                RL(p)->kind == la_attach &&
+                R(p)->sem.proj.items[0].old == RL(p)->sem.attach.res &&
+                RL(p)->sem.attach.value.type == aat_int &&
+                RL(p)->sem.attach.value.val.int_ == 0 &&
+                RLL(p)->kind == la_difference &&
+                RLLR(p)->kind == la_project &&
+                RLLR(p)->sem.proj.items[0].old ==
+                LL(p)->sem.aggr.part &&
+                L(RLLR(p)) == LL(p)) {
 
                 /* check that the values in the loop are constant
                    and provide the same value */
-                assert (PFprop_const (L(L(L(R(p))))->prop,
-                                      L(L(p))->sem.aggr.part));
+                assert (PFprop_const (RLLL(p)->prop,
+                                      LL(p)->sem.aggr.part));
                 assert (
                     PFalg_atom_comparable (
-                        PFprop_const_val (L(L(L(R(p))))->prop,
-                                          L(L(p))->sem.aggr.part),
-                        PFprop_const_val (L(L(p))->prop,
-                                          L(L(p))->sem.aggr.part)) &&
+                        PFprop_const_val (RLLL(p)->prop,
+                                          RLLR(p)->sem.proj.items[0].new),
+                        PFprop_const_val (LL(p)->prop,
+                                          LL(p)->sem.aggr.part)) &&
                     !PFalg_atom_cmp (
-                        PFprop_const_val (L(L(L(R(p))))->prop,
-                                          L(L(p))->sem.aggr.part),
-                        PFprop_const_val (L(L(p))->prop,
-                                          L(L(p))->sem.aggr.part)));
+                        PFprop_const_val (RLLL(p)->prop,
+                                          RLLR(p)->sem.proj.items[0].new),
+                        PFprop_const_val (LL(p)->prop,
+                                          LL(p)->sem.aggr.part)));
 
-                *p = *PFla_count (L(L(L(p))),
-                                  p->schema.items[0].name,
-                                  att_NULL);
+                /* To avoid creating more results than allowed (1 instead
+                   of 0) we have to make sure that we take the cardinality
+                   of the loop relation into account. */
+                *p = *project (cross (RLLL(p), /* loop */
+                                      PFla_count (LLL(p),
+                                                  R(p)->sem.proj.items[0].old,
+                                                  att_NULL)),
+                               proj (R(p)->sem.proj.items[0].new,
+                                     R(p)->sem.proj.items[0].old));
                 break;
             }
             break;
@@ -659,6 +667,11 @@
             /* some optimization opportunities for
                aggregate operators arise if 'att' is constant */
             if (PFprop_const_left (p->prop, p->sem.aggr.att)) {
+
+#if 0 /* We are not allowed to create an unpartitioned aggregate
+         as an empty loop relation might result in a single line
+         result otherwise. */
+         
                 /* if partitioning column is constant as well
                    replace aggregate by a new literal table
                    with one row containing 'att' and 'part' */
@@ -677,6 +690,7 @@
                    constant we can replace the aggregate by a
                    distinct operator (value in 'att' stays the same). */
                 else if (p->sem.aggr.part)
+#endif
                     *p = *PFla_distinct (
                               PFla_project (
                                   L(p),
@@ -684,6 +698,7 @@
                                               p->sem.aggr.att),
                                   PFalg_proj (p->sem.aggr.part,
                                               p->sem.aggr.part)));
+#if 0
                 /* replace aggregate by a new literal table
                    containining a single record with the result of
                    aggregate operator. */
@@ -693,6 +708,7 @@
                                             PFprop_const_val_left (
                                                 p->prop,
                                                 p->sem.aggr.att)));
+#endif
             }
             break;
 
@@ -704,6 +720,10 @@
                                                           p->sem.aggr.att));
             }
 
+#if 0 /* We are not allowed to create an unpartitioned aggregate
+         as an empty loop relation might result in a single line
+         result otherwise. */
+         
             /* if partitiong attribute is constant remove it
                and attach it after the operator */
             if (p->sem.aggr.part &&
@@ -739,6 +759,7 @@
                 *p = *ret;
                 SEEN(p) = true;
             }
+#endif
             break;
 
         case la_rownum:


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