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

Modified Files:
      Tag: PF_ROX
        lalg2sql.brg sql.c sqlprint.c 
Log Message:
propagated changes of Wednesday Jan 30 2008 - Saturday Feb 09 2008
from the development trunk to the PF_ROX branch


Index: sql.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/sql/sql.c,v
retrieving revision 1.48
retrieving revision 1.48.2.1
diff -u -d -r1.48 -r1.48.2.1
--- sql.c       21 Jan 2008 14:30:50 -0000      1.48
+++ sql.c       9 Feb 2008 08:40:38 -0000       1.48.2.1
@@ -558,7 +558,7 @@
 
 
 
-/* .......... Union .......... */
+/* .......... Set operators .......... */
 
 /**
  * Create a SQL tree node representing the SQL
@@ -570,10 +570,6 @@
     return wire2 (sql_union, a, b);
 }
 
-
-
-/* .......... Difference .......... */
-
 /**
  * Create a SQL tree node representing the SQL
  * `EXCEPT ALL' operator.
@@ -584,7 +580,15 @@
     return wire2 (sql_diff, a, b);
 }
 
-
+/**
+ * Create a SQL tree node representing the SQL
+ * `INTERSECT ALL' operator.
+ */
+PFsql_t *
+PFsql_intersect (const PFsql_t *a, const PFsql_t *b)
+{
+    return wire2 (sql_intersect, a, b);
+}
 
 /* .......... Literal construction .......... */
 
@@ -968,6 +972,37 @@
     return wire1 (sql_sum, column);
 }
 
+/* ........... String Functions ........... */
+
+/**
+ * Construct a SQL tree  node representing
+ * the SQL length functions for strings
+ */
+PFsql_t *
+PFsql_str_length (const PFsql_t *a)
+{
+    return wire1 (sql_str_length, a);
+}
+
+/**
+ * Construct a SQL tree  node representing
+ * the SQL length functions for strings
+ */
+PFsql_t *
+PFsql_str_upper (const PFsql_t *a)
+{
+    return wire1 (sql_str_upper, a);
+}
+
+/**
+ * Construct a SQL tree  node representing
+ * the SQL length functions for strings
+ */
+PFsql_t *
+PFsql_str_lower (const PFsql_t *a)
+{
+    return wire1 (sql_str_lower, a);
+}
 
 
 /* .......... OLAP Functionality .......... */
@@ -1306,7 +1341,7 @@
             case sql_col_nameid:     return "nameid";
             case sql_col_value:      return "value";
             case sql_col_name:       return "name";
-            case sql_col_namespace:  return "namespace";  
+            case sql_col_ns_uri:     return "uri";  
             case sql_col_twig_pre:   return "twig_pre";
             case sql_col_iter:       return "iter";
             case sql_col_pos:        return "pos";

Index: lalg2sql.brg
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/sql/lalg2sql.brg,v
retrieving revision 1.108
retrieving revision 1.108.2.1
diff -u -d -r1.108 -r1.108.2.1
--- lalg2sql.brg        22 Jan 2008 11:04:33 -0000      1.108
+++ lalg2sql.brg        9 Feb 2008 08:40:36 -0000       1.108.2.1
@@ -475,6 +475,7 @@
 #define LEVEL_      column_name (special_col (sql_col_level))
 #define KIND_       column_name (special_col (sql_col_kind))
 #define NAME_       column_name (special_col (sql_col_name))
+#define NS_URI_     column_name (special_col (sql_col_ns_uri))
 #define GUIDE_      column_name (special_col (sql_col_guide))
 #define VALUE_      column_name (special_col (sql_col_value))
 #define TWIG_PRE_   column_name (special_col (sql_col_twig_pre))
@@ -488,7 +489,7 @@
 #define LEVEL(n)      ext_column_name (n, special_col (sql_col_level))
 #define KIND(n)       ext_column_name (n, special_col (sql_col_kind))
 #define NAME(n)       ext_column_name (n, special_col (sql_col_name))
-#define NAMESPACE(n)  ext_column_name (n, special_col (sql_col_namespace))   
+#define NS_URI(n)     ext_column_name (n, special_col (sql_col_ns_uri))
 #define GUIDE(n)      ext_column_name (n, special_col (sql_col_guide))
 #define VALUE(n)      ext_column_name (n, special_col (sql_col_value))
 #define TWIG_PRE(n)   ext_column_name (n, special_col (sql_col_twig_pre))
@@ -496,6 +497,13 @@
 #define POS(n)        ext_column_name (n, special_col (sql_col_pos))
 #define MAX(n)        ext_column_name (n, special_col (sql_col_max))
 
+#define TRUE_STR       lit_str("true")
+#define FALSE_STR      lit_str("false")
+#define TRUE_DEC       lit_dec(1.0E0)
+#define FALSE_DEC      lit_dec(0.0E0)
+#define TRUE_INT       lit_int(1)
+#define FALSE_INT      lit_int(0)
+
 /**
  * Returns a new column name
  * (also storing its logical algebra name and its type).
@@ -697,7 +705,7 @@
         n = (n->kind == sql_column_name ||
              n->kind == sql_lit_int)?
             n:
-            case_ (when (n, lit_int (1)), else_ (lit_int (0)));
+            case_ (when (n, TRUE_INT), else_ (FALSE_INT));
 
     if (n->kind == sql_column_name)
     {
@@ -1294,7 +1302,7 @@
     if (name)
         where_list_add (WHERELIST(p), eq (NAME(step), name));
     if (namespace)
-        where_list_add (WHERELIST(p), eq (NAMESPACE(step), namespace));
+        where_list_add (WHERELIST(p), eq (NS_URI(step), namespace));
 }
 
 static void
@@ -1635,6 +1643,60 @@
         return frag_select (table_name (PF_SQL_TABLE_FRAG));
 }
 
+/**
+ * Cast from a boolean value 
+ */
+static PFsql_t *
+cast_from_bool (PFsql_t * expr, PFalg_simple_type_t res_ty)
+{
+    switch (res_ty) {
+        case aat_uA:  
+        case aat_str:
+            if (expr->kind == sql_column_name)
+                expr = eq (expr, TRUE_INT);
+            return case_ (when (expr,TRUE_STR),
+                          else_ (FALSE_STR));
+        case aat_dec:
+        case aat_dbl:
+            if (expr->kind != sql_column_name)
+                return case_ (when (expr, TRUE_DEC),
+                              else_ (FALSE_DEC));
+            else
+                return cast (expr, type (res_ty));
+        case aat_int:
+            if (expr->kind != sql_column_name)
+                return case_ (when (expr, TRUE_INT),
+                              else_ (FALSE_INT));
+            else
+                return expr;
+        default:
+            PFoops (OOPS_FATAL, "This cast from a boolean"
+                                " value is not allowed");
+    }
+    
+    return NULL; /* satisfy picky compilers */
+}
+
+/**
+ * A cast to boolean is has to provide a boolean expression.
+ */
+static PFsql_t *
+cast_to_bool (PFsql_t *expr, PFalg_simple_type_t ty)
+{
+    switch (ty) {
+        case aat_dec:
+        case aat_dbl:
+            return eq(expr, TRUE_DEC);
+        case aat_int:
+            return eq(expr, TRUE_INT);
+        default:
+            PFoops (OOPS_FATAL, "This cast to a boolean"
+                                " boolean value is not allowed");
+    }
+    
+    return NULL; /* satisfy picky compilers */
+}
+
 static PFsql_t *
 cast_ (PFsql_t * expr, PFalg_simple_type_t ty, PFalg_simple_type_t res_ty)
 {
@@ -1647,6 +1709,7 @@
     #define CHAR_TYPE(t)   ((t == aat_str) || \
                             (t == aat_uA))
     #define NUM_NOTEXPR(t) ((t == aat_int))
+    #define BOOL_TYPE(t)    (t == aat_bln)
 
     /* Since we handle untypedAtomic and Strings the same
      * way in SQL, its obvious we don't have to
@@ -1654,6 +1717,12 @@
      * and input type is a CHAR_TYPE */
     if (CHAR_TYPE(ty) && CHAR_TYPE(res_ty)) return expr;
 
+    if (BOOL_TYPE(ty))
+        return cast_from_bool (expr, res_ty);
+
+    if (BOOL_TYPE(res_ty))
+        return cast_to_bool (expr, ty);
+
     /* if we cast a numeric type to varchar we have to
        first cast it to CHAR and then to varchar */
     if (NUM_TYPE (ty) && CHAR_TYPE (res_ty))
@@ -1890,8 +1959,8 @@
                     if (entry.type == aat_bln)
                         colexpr = (colexpr->kind == sql_column_name)?
                                   colexpr:
-                                  case_ (when (colexpr, lit_int (1)),
-                                         else_ (lit_int (0)));
+                                  case_ (when (colexpr, TRUE_INT),
+                                         else_ (FALSE_INT));
                     
                     /* Generate a special column name DIST
                        that can be overloaded ... */
@@ -2910,12 +2979,11 @@
 
         /* Rel:    disjunion (Rel, Rel) */
         case 20:
+        /* Rel:    intersect (Rel, Rel) */
+        case 21:
         /* Rel:    difference (Rel, Rel) */
         case 22:
         {
-            /* FIXME: the translation won't work if the same operator
-               is referenced twice (as the left environment is
-               overwritten -- see joins) */
             PFsql_t * (*op) (const PFsql_t *, const PFsql_t *);
             PFsql_t *selectlist1 = NULL;
             PFsql_t *selectlist2 = NULL;
@@ -2986,11 +3054,13 @@
                     }
             }
 
-            if (p->kind == la_disjunion)
-                op = PFsql_union;
-            else
-                op = PFsql_difference;
-
+            switch (p->kind) {
+                case la_disjunion:  op = PFsql_union;      break;
+                case la_difference: op = PFsql_difference; break;
+                case la_intersect:  op = PFsql_intersect;  break;
+                default: assert(!"set operator expected");
+            };
+                  
             /* dump the operator binding */
             execute (comment ("binding due to set operation"));
             execute (bind (table_def (newtable, columnlist),
@@ -3005,12 +3075,6 @@
             BOUND(p) = true;
         }   break;
 
-        /* Rel:    intersect (Rel, Rel) */
-        case 21:
-            /* FIXME: implementation is missing */
-            assert (!"missing");
-            break;
-
         /* Rel:    distinct (Rel) */
         case 23:
             /* copy all existing column, from, and where lists */
@@ -3051,8 +3115,15 @@
                 case alg_fun_num_divide:
                     res_expr = div (expr[0], expr[1]); break;
                 case alg_fun_fn_contains:
-                    /* FIXME: this only works with constant expr[1] */
-                    res_expr = like (expr[0], expr[1]); break;
+                    /* adding check for constant expression */
+                    if (!PFprop_const (L(p)->prop, att[1]) || 
+                        ty[1]         != aat_str           ||
+                        expr[1]->kind == sql_column_name)
+                        PFoops (OOPS_FATAL, "fn_contains works only with 
constant "
+                                            "string expressions");
+
+                    res_expr = like (expr[0], expr[1]);
+                    break;
                 /**< fn:ceiling */
                 case alg_fun_fn_ceiling:
                     res_expr = ceil (expr[0]); break;
@@ -3077,9 +3148,14 @@
                 /** string functions */
                 case alg_fun_fn_starts_with:
                 case alg_fun_fn_ends_with:
+                    assert (!"missing");
+                    break;
                 case alg_fun_fn_string_length:
+                    res_expr = str_length (expr[0]); break;
                 case alg_fun_fn_upper_case:
+                    res_expr = str_upper (expr[0]); break;
                 case alg_fun_fn_lower_case:
+                    res_expr = str_lower (expr[0]); break;
                 case alg_fun_fn_translate:
                 case alg_fun_fn_substring_before:
                 case alg_fun_fn_substring_after:
@@ -3308,6 +3384,8 @@
         case 38:
         /* Rel:    count (Rel) */
         case 39:
+        /* Rel:    all (Rel) */
+        case 42:
             /* Bind the input of the aggregate if the group by
                criterion is not a column reference. */
             if (p->sem.aggr.part &&
@@ -3326,8 +3404,8 @@
             PFalg_att_t att = p->sem.aggr.att,
                         part = p->sem.aggr.part,
                         res_att = p->sem.aggr.res;
-            PFalg_simple_type_t ty,
-                                part_ty,
+            PFalg_simple_type_t part_ty,
+                                ty = 0 /* dummy type */,
                                 res_ty = type_of (p, res_att);
             PFsql_t *expr = NULL,
                     *part_expr;
@@ -3379,6 +3457,18 @@
                 case la_avg:   expr = avg (expr); break;
                 case la_max:   expr = max (expr); break;
                 case la_min:   expr = min (expr); break;
+                /* with la_all we have to ensure that each
+                 * attribute att is true for all rows within
+                 * a group, since we express boolean values
+                 * as literal integers, MIN does the job */ 
+                case la_all:   assert (ty == aat_bln);
+                               expr = min (((expr)->kind == sql_column_name)?
+                                           expr:
+                                           case_(
+                                              when (expr,
+                                                    lit_int(1)),
+                                              else_ (lit_int (0))));
+                             break;
                 case la_sum:   expr = sum (expr); break;
                 case la_count: expr = count (star ()); break;
                 default: assert (0); break;
@@ -3559,12 +3649,6 @@
             assert (!"missing");
             break;
 
-        /* Rel:    all (Rel) */
-        case 42:
-            /* FIXME: implementation is missing */
-            assert (!"missing");
-            break;
-
         /* Rel:    string_join (Rel, Rel) */
         case 43:
         {
@@ -3580,11 +3664,18 @@
             col_env_add_full (COLMAP(p), iter, iter_ty,
                               col_env_lookup (COLMAP(L(p)), iter, iter_ty),
                               col_env_lookup_step (
-                                  COLMAP(L(p)), iter, iter_ty),
+                                  COLMAP(L(p)),
+                                  p->sem.string_join.iter,
+                                  type_of (p, p->sem.string_join.iter)),
                               col_env_lookup_step_leaf (
-                                  COLMAP(L(p)), iter, iter_ty));
+                                  COLMAP(L(p)),
+                                  p->sem.string_join.iter,
+                                  type_of (p, p->sem.string_join.iter)));
+                                      
             col_env_add (COLMAP(p), item, item_ty,
-                         col_env_lookup (COLMAP(L(p)), item, item_ty));
+                         col_env_lookup (COLMAP(L(p)),
+                                         p->sem.string_join.item,
+                                         type_of (p, 
p->sem.string_join.item)));
 
             /* copy fromlist */
             from_list_copy (FROMLIST(p), FROMLIST(L(p)));
@@ -3919,19 +4010,16 @@
         /* Constr: doc_tbl (Rel) */
         case 70:
         {
-            PFalg_att_t iter = p->sem.doc_tbl.iter,
-                        item = p->sem.doc_tbl.item,
-                        item_res = p->sem.doc_tbl.item_res;
-            PFalg_simple_type_t iter_ty = type_of (p, iter),
-                                item_ty = type_of (L(p), item),
-                                item_res_ty = type_of (p, item_res);
-            PFsql_t *item_expr = col_env_lookup (COLMAP(L(p)), item, item_ty);
-            PFsql_aident_t doc_tbl;
+            PFalg_att_t         att    = p->sem.doc_tbl.att,
+                                res    = p->sem.doc_tbl.res;
+            PFalg_simple_type_t res_ty = type_of (p, res);
+            PFsql_t            *item_expr;
+            PFsql_aident_t      doc_tbl;
 
-            /* copy the existing frommap */
-            from_list_copy (FROMLIST(p), FROMLIST(L(p)));
-            /* copy the existing wheremap */
-            where_list_copy (WHERELIST(p), WHERELIST(L(p)));
+            /* copy all existing column, from, and where lists */
+            copy_cols_from_where (p, L(p));
+
+            item_expr = col_env_lookup (COLMAP(p), att, aat_str);
 
             /* throw away singleton relation */
             if (PFarray_last (FROMLIST(p)) == 1) {
@@ -3951,13 +4039,7 @@
                            alias (doc_tbl));
 
             /* add the output columns to the column map */
-            col_env_add_full (COLMAP(p), iter, iter_ty,
-                              col_env_lookup (COLMAP(L(p)), iter, iter_ty),
-                              col_env_lookup_step (
-                                  COLMAP(L(p)), iter, iter_ty),
-                              col_env_lookup_step_leaf (
-                                  COLMAP(L(p)), iter, iter_ty));
-            col_env_add_full (COLMAP(p), item_res, item_res_ty,
+            col_env_add_full (COLMAP(p), res, res_ty,
                               PRE(doc_tbl), doc_tbl, false);
 
             /* add the two checks to lookup the correct document */

Index: sqlprint.c
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/sql/sqlprint.c,v
retrieving revision 1.44
retrieving revision 1.44.4.1
diff -u -d -r1.44 -r1.44.4.1
--- sqlprint.c  11 Jan 2008 10:47:18 -0000      1.44
+++ sqlprint.c  9 Feb 2008 08:40:38 -0000       1.44.4.1
@@ -97,8 +97,9 @@
       [sql_alias_bind]        = "alias_bind",
       [sql_on]                = "on",
       [sql_left_outer_join]   = "left_outer_join",
-      [sql_union]             = "union",
-      [sql_diff]              = "diff",
+      [sql_union]             = "UNION ALL",
+      [sql_diff]              = "EXCEPT ALL",
+      [sql_intersect]         = "INTERSECT ALL",
       [sql_lit_int]           = "lit_int",
       [sql_lit_lng]           = "lit_lng",
       [sql_lit_dec]           = "lit_dec",
@@ -121,7 +122,7 @@
       [sql_between]           = "between",
       [sql_like]              = "like",
       [sql_in]                = "in",
-      [sql_stmt_list]          = "stmt_list",
+      [sql_stmt_list]         = "stmt_list",
       [sql_list_list]         = "list_list",
       [sql_not]               = "not",
       [sql_and]    /* used */ = "AND",
@@ -131,6 +132,9 @@
       [sql_sum]    /* used */ = "SUM",
       [sql_min]    /* used */ = "MIN",
       [sql_avg]    /* used */ = "AVG",
+      [sql_str_length]        = "LENGTH",
+      [sql_str_upper]         = "UPPER",
+      [sql_str_lower]         = "LOWER",
       [sql_over]              = "over",
       [sql_row_number]        = "ROW_NUMBER",
       [sql_dense_rank]        = "DENSE_RANK",
@@ -616,6 +620,14 @@
             PFprettyprintf(")");
             break;
 
+        case sql_str_length:
+        case sql_str_upper:
+        case sql_str_lower:
+            PFprettyprintf("%s (", ID[n->kind]);
+            print_statement (L(n));
+            PFprettyprintf(")");
+            break;
+
         case sql_cast:
             assert (R(n)->kind == sql_type);
 
@@ -935,20 +947,15 @@
             break;
 
         case sql_union:
-            print_fullselect (f, L(n), i);
-            indent (f, i);
-            fprintf (f, "UNION ALL");
-            indent (f, i);
-            print_fullselect (f, R(n), i);
-            break;
-            
         case sql_diff:
+        case sql_intersect:
             print_fullselect (f, L(n), i);
             indent (f, i);
-            fprintf (f, "EXCEPT ALL");
+            fprintf (f, "%s", ID[n->kind]);
             indent (f, i);
             print_fullselect (f, R(n), i);
             break;
+            
         case sql_alias_bind:
         case sql_tbl_name:
         case sql_schema_tbl_name:


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