Update of /cvsroot/monetdb/pathfinder/compiler/algebra/prop
In directory sfp-cvsdas-1.v30.ch3.sourceforge.com:/tmp/cvs-serv6600/algebra/prop

Modified Files:
        Makefile.ag prop_icol.c 
Added Files:
        prop_name_origin.c 
Log Message:
-- Introduced a new column-name-origin property that enhances the column names
   in the DOT generated algebra plans. If a column stems from a ref_tbl or a
   path step we now keep the original name throughout the plan.
   (Use pf-option -fN to print the mapping of original names.)

-- Make property usage a little bit more defensive. Instead of !PFprop_icol
   a new function PFprop_not_icol is introduced that copes correctly with
   missing property information.


Index: prop_icol.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/prop/prop_icol.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- prop_icol.c 7 Jan 2010 15:24:27 -0000       1.51
+++ prop_icol.c 17 Mar 2010 21:56:28 -0000      1.52
@@ -58,9 +58,9 @@
  * Test if @a col is in the list of icol columns in array @a icols
  */
 static bool
-icol_worker (PFalg_collist_t *icols, PFalg_col_t col)
+icol_worker (PFalg_collist_t *icols, PFalg_col_t col, bool exist)
 {
-    if (!icols) return false;
+    if (!icols) return !exist;
 
     for (unsigned int i = 0; i < clsize (icols); i++)
         if (col == clat (icols, i))
@@ -75,7 +75,16 @@
 bool
 PFprop_icol (const PFprop_t *prop, PFalg_col_t col)
 {
-    return icol_worker (prop->icols, col);
+    return icol_worker (prop->icols, col, true);
+}
+
+/**
+ * Test if @a col is *not* in the list of icol columns in container @a prop
+ */
+bool
+PFprop_not_icol (const PFprop_t *prop, PFalg_col_t col)
+{
+    return !icol_worker (prop->icols, col, false);
 }
 
 /**
@@ -85,7 +94,7 @@
 bool
 PFprop_icol_left (const PFprop_t *prop, PFalg_col_t col)
 {
-    return icol_worker (prop->l_icols, col);
+    return icol_worker (prop->l_icols, col, true);
 }
 
 /**
@@ -95,7 +104,7 @@
 bool
 PFprop_icol_right (const PFprop_t *prop, PFalg_col_t col)
 {
-    return icol_worker (prop->r_icols, col);
+    return icol_worker (prop->r_icols, col, true);
 }
 
 /*
@@ -149,7 +158,7 @@
 {
     assert (a);
 
-    if (!icol_worker (a, b))
+    if (!icol_worker (a, b, false))
         cladd (a) = b;
 }
 
@@ -167,7 +176,7 @@
 
     for (unsigned int i = 0; i < clsize (b); i++) {
         cur = clat (b, i);
-        if (!icol_worker (a, cur))
+        if (!icol_worker (a, cur, false))
             cladd (a) = cur;
     }
 }
@@ -196,7 +205,7 @@
 static bool
 in (PFalg_collist_t *a, PFalg_col_t b)
 {
-    return (icol_worker (a, b));
+    return (icol_worker (a, b, true));
 }
 
 /**

Index: Makefile.ag
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/algebra/prop/Makefile.ag,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- Makefile.ag 7 Jan 2010 15:24:27 -0000       1.20
+++ Makefile.ag 17 Mar 2010 21:56:28 -0000      1.21
@@ -46,6 +46,7 @@
                 prop_key.c \
                 prop_level.c \
                 prop_lineage.c \
+                prop_name_origin.c \
                 prop_ocol.c \
                 prop_ori_names.c \
                 prop_rec_delta.c \

--- NEW FILE: prop_name_origin.c ---
/**
 * @file
 *
 * Inference of name origin properties of logical algebra expressions.
 *
 * Copyright Notice:
 * -----------------
 *
 * The contents of this file are subject to the Pathfinder Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 * http://monetdb.cwi.nl/Legal/PathfinderLicense-1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is the Pathfinder system.
 *
 * The Original Code has initially been developed by the Database &
 * Information Systems Group at the University of Konstanz, Germany and
 * the Database Group at the Technische Universitaet Muenchen, Germany.
 * It is now maintained by the Database Systems Group at the Eberhard
 * Karls Universitaet Tuebingen, Germany.  Portions created by the
 * University of Konstanz, the Technische Universitaet Muenchen, and the
 * Universitaet Tuebingen are Copyright (C) 2000-2005 University of
 * Konstanz, (C) 2005-2008 Technische Universitaet Muenchen, and (C)
 * 2008-2009 Eberhard Karls Universitaet Tuebingen, respectively.  All
 * Rights Reserved.
 *
 * $Id: prop_name_origin.c,v 1.1 2010/03/17 21:56:28 tsheyar Exp $
 */

/* always include pf_config.h first! */
#include "pf_config.h"
#include "pathfinder.h"
#include <assert.h>

#include "properties.h"
#include "alg_dag.h"
#include "oops.h"
#include "mem.h"
#include <strings.h>

/* mnemonic column list accessors */
#include "alg_cl_mnemonic.h"

/* Easily access subtree-parts */
#include "child_mnemonic.h"

/**
 * Return the original name of column @a col (in container @a prop).
 */
char *
PFprop_name_origin (const PFprop_t *prop, PFalg_col_t col)
{
    assert (prop);

    if (!prop->name_origin)
        return NULL;

    for (unsigned int i = 0; i < PFarray_last (prop->name_origin); i++)
        if (col == ((name_origin_t *) PFarray_at (prop->name_origin, i))->col)
            return ((name_origin_t *) PFarray_at (prop->name_origin, i))->name;

    return NULL;
}

/**
 * Add for a column @a col the original name @a name.
 */
static void
add_name (PFprop_t *prop, PFalg_col_t col, char *name)
{
    assert (prop);
    assert (prop->name_origin);


#ifndef NDEBUG
    if (PFprop_name_origin (prop, col))
        PFoops (OOPS_FATAL,
                "name for column `%s' already declared (%s)",
                PFcol_str (col),
                PFprop_name_origin (prop, col));
#endif

    *(name_origin_t *) PFarray_add (prop->name_origin)
        = (name_origin_t) { .col = col, .name = name };
}

static void
copy (PFarray_t *base, PFarray_t *content)
{
    for (unsigned int i = 0; i < PFarray_last (content); i++)
        *(name_origin_t *) PFarray_add (base) =
            *(name_origin_t *) PFarray_at (content, i);
}

/**
 * Infer properties about the original names; worker for prop_infer().
 */
static void
infer_name_origin (PFla_op_t *n)
{
    /*
     * Several operators (at least) propagate original
     * to their output 1:1.
     */
    switch (n->kind) {

        case la_serialize_seq:
        case la_serialize_rel:
        case la_attach:
        case la_cross:
        case la_eqjoin:
        case la_thetajoin:
        case la_select:
        case la_pos_select:
        case la_distinct:
        case la_fun_1to1:
        case la_num_eq:
        case la_num_gt:
        case la_bool_and:
        case la_bool_or:
        case la_bool_not:
        case la_to:
        case la_rownum:
        case la_rowrank:
        case la_rank:
        case la_rowid:
        case la_type:
        case la_type_assert:
        case la_cast:
        case la_step_join:
        case la_guide_step_join:
        case la_doc_index_join:
        case la_doc_tbl:
        case la_doc_access:
        case la_docnode:
        case la_element:
        case la_attribute:
        case la_textnode:
        case la_comment:
        case la_processi:
        case la_content:
        case la_roots:
        case la_error:
        case la_trace_items:
        case la_proxy:
        case la_proxy_base:
        case la_dummy:

            /* propagate information from both input operators */
            for (unsigned int i = 0; i < PFLA_OP_MAXCHILD && n->child[i]; i++)
                copy (n->prop->name_origin, n->child[i]->prop->name_origin);
            break;

        default:
            break;
    }

    /*
     * Now consider more specific stuff from various rules.
     */
    switch (n->kind) {
        case la_ref_tbl:
            {
                PFarray_t   *fullname = PFarray (sizeof (char), 64);
                unsigned int len      = strlen (n->sem.ref_tbl.name) + 1;
                PFalg_col_t  col;
                char        *name;

                /* add the table name */
                PFarray_printf (fullname, "%s.", n->sem.ref_tbl.name);

                for (unsigned int i = 0; i < n->schema.count; i++) {
                    col  = n->schema.items[i].name;
                    name = *((char**) PFarray_at (n->sem.ref_tbl.tcols, i));

                    /* add the column name to the table name */
                    PFarray_printf (fullname, "%s", name);

                    add_name (n->prop, col, PFstrdup (fullname->base));

                    /* reset the column name */
                    PFarray_last (fullname) = len;
                }
            } break;

        case la_project:
            /*
             * projection does not affect properties, except for the
             * column name change.
             */
            for (unsigned int i = 0; i < n->sem.proj.count; i++) {
                char *name = PFprop_name_origin (L(n)->prop,
                                                 n->sem.proj.items[i].old);
                if (name)
                    add_name (n->prop, n->sem.proj.items[i].new, name);
            }
            break;

        case la_disjunion:
        case la_intersect:
            /*
             * add all columns that are constant in both input relations
             * and additionally both contain the same value
             */
            for (unsigned int i = 0; i < n->schema.count; i++) {
                PFalg_col_t col   = n->schema.items[i].name;
                char       *lname = PFprop_name_origin (L(n)->prop, col),
                           *rname = PFprop_name_origin (R(n)->prop, col);
                
                if (lname && rname && !strcmp (lname, rname))
                    add_name (n->prop, col, lname);
            }
            break;

        case la_semijoin:
        case la_difference:
            copy (n->prop->name_origin, L(n)->prop->name_origin);
            break;
            
        case la_aggr:
            for (unsigned int i = 0; i < n->sem.aggr.count; i++)
                if (n->sem.aggr.aggr[i].kind == alg_aggr_dist &&
                    PFprop_name_origin (L(n)->prop, n->sem.aggr.aggr[i].col))
                    add_name (n->prop,
                              n->sem.aggr.aggr[i].col,
                              PFprop_name_origin (L(n)->prop, 
                                                  n->sem.aggr.aggr[i].col));

            if (n->sem.aggr.part &&
                PFprop_name_origin (L(n)->prop, n->sem.aggr.part))
                add_name (
                        n->prop,
                        n->sem.aggr.part,
                        PFprop_name_origin (L(n)->prop, n->sem.aggr.part));
            break;

        case la_step:
        case la_guide_step:
            if (PFprop_name_origin (R(n)->prop, n->sem.step.iter))
                add_name (
                        n->prop,
                        n->sem.step.iter,
                        PFprop_name_origin (R(n)->prop, n->sem.step.iter));
            /* fall through */
        case la_step_join:
        case la_guide_step_join:
            {
                PFarray_t *name = PFarray (sizeof (char), 64);
                PFarray_printf (name, "%s(%s)",
                                PFalg_node_kind_str (n->sem.step.spec.kind),
                                (n->sem.step.spec.kind == node_kind_elem ||
                                 n->sem.step.spec.kind == node_kind_attr)
                                ?  PFqname_str (n->sem.step.spec.qname)
                                : "");
                                 
                add_name (n->prop,
                          n->sem.step.item_res,
                          PFstrdup (name->base));
            } break;

        case la_doc_index_join:
            add_name (n->prop, n->sem.doc_join.item_res, "node-id(index)");
            break;

        case la_doc_tbl:
            add_name (n->prop, n->sem.doc_tbl.res, "document-node()");
            break;

        case la_twig:
            switch (L(n)->kind) {
                case la_docnode:
                    if (PFprop_name_origin (L(n)->prop, L(n)->sem.docnode.iter))
                        add_name (
                                n->prop,
                                n->sem.iter_item.iter,
                                PFprop_name_origin (L(n)->prop,
                                                    L(n)->sem.docnode.iter));
                    break;

                case la_element:
                case la_textnode:
                case la_comment:
                    if (PFprop_name_origin (L(n)->prop, 
L(n)->sem.iter_item.iter))
                        add_name (
                                n->prop,
                                n->sem.iter_item.iter,
                                PFprop_name_origin (L(n)->prop,
                                                    L(n)->sem.iter_item.iter));
                    break;

                case la_attribute:
                case la_processi:
                    if (PFprop_name_origin (L(n)->prop,
                                      L(n)->sem.iter_item1_item2.iter))
                        add_name (n->prop,
                                  n->sem.iter_item.iter,
                                  PFprop_name_origin (
                                      L(n)->prop,
                                      L(n)->sem.iter_item1_item2.iter));
                    break;

                case la_content:
                    if (PFprop_name_origin (L(n)->prop,
                                      L(n)->sem.iter_pos_item.iter))
                        add_name (n->prop,
                                  n->sem.iter_item.iter,
                                  PFprop_name_origin (
                                      L(n)->prop,
                                      L(n)->sem.iter_pos_item.iter));
                    break;

                default:
                    break;
            }
            add_name (n->prop, n->sem.step.item, "node-id(transient)");
            break;

        case la_error:
        case la_nil:
        case la_cache:
        case la_trace:
        case la_trace_items:
        case la_trace_msg:
        case la_trace_map:
            /* we have no have properties */
            break;

        case la_rec_fix:
            /* get the constants of the overall result */
            copy (n->prop->constants, R(n)->prop->constants);
            break;

        case la_rec_param:
            /* recursion parameters do not have properties */
            break;

        case la_rec_arg:
            copy (n->prop->constants, R(n)->prop->constants);
            break;

        case la_rec_base:
            /* infer no properties of the seed */
            break;

        case la_fun_param:
            copy (n->prop->constants, L(n)->prop->constants);
            break;

        case la_serialize_seq:
        case la_serialize_rel:
        case la_side_effects:
        case la_lit_tbl:
        case la_empty_tbl:
        case la_attach:
        case la_cross:
        case la_eqjoin:
        case la_thetajoin:
        case la_select:
        case la_pos_select:
        case la_distinct:
        case la_fun_1to1:
        case la_num_eq:
        case la_num_gt:
        case la_bool_and:
        case la_bool_or:
        case la_bool_not:
        case la_to:
        case la_rownum:
        case la_rowrank:
        case la_rank:
        case la_rowid:
        case la_type:
        case la_type_assert:
        case la_cast:
        case la_doc_access:
        case la_fcns:
        case la_docnode:
        case la_element:
        case la_attribute:
        case la_textnode:
        case la_comment:
        case la_processi:
        case la_content:
        case la_merge_adjacent:
        case la_roots:
        case la_fragment:
        case la_frag_extract:
        case la_frag_union:
        case la_empty_frag:
        case la_fun_call:
        case la_fun_frag_param:
        case la_proxy:
        case la_proxy_base:
        case la_string_join:
        case la_dummy:

            break;

        case la_internal_op:
            PFoops (OOPS_FATAL,
                    "internal optimization operator is not allowed here");
    }
}

/* worker for PFprop_infer_name_origin */
static void
prop_infer (PFla_op_t *n)
{
    assert (n);

    /* nothing to do if we already visited that node */
    if (n->bit_dag)
        return;

    /* infer properties for children */
    for (unsigned int i = 0; i < PFLA_OP_MAXCHILD && n->child[i]; i++)
        prop_infer (n->child[i]);

    n->bit_dag = true;

    /* reset name origin property
       (reuse already existing lists if already available
        as this increases the performance of the compiler a lot) */
    if (n->prop->name_origin)
        PFarray_last (n->prop->name_origin) = 0;
    else
        /* prepare the property for 10 names */
        n->prop->name_origin = PFarray (sizeof (const_t), 10);

    /* infer information on original column names */
    infer_name_origin (n);
}

/**
 * Infer original name property for a DAG rooted in root
 */
void
PFprop_infer_name_origin (PFla_op_t *root) {
    prop_infer (root);
    PFla_dag_reset (root);
}

/* vim:set shiftwidth=4 expandtab: */


------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to