Update of /cvsroot/monetdb/pathfinder/compiler/sql
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv6069/compiler/sql
Modified Files:
Tag: M5XQ
lalg2sql.brg
Log Message:
re-aligned with development trunk:
files
compiler/algebra/opt/opt_algebra_cse.c
compiler/algebra/opt/opt_thetajoin.c
compiler/sql/lalg2sql.brg
appeared to differ in the M5XQ branch from the development trunk
although they have not been modified in the M5XQ branch;
most probably some propagation of changes from the development
trunk to the M5XQ branch went wrong unnoticedly ...
Index: lalg2sql.brg
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/sql/lalg2sql.brg,v
retrieving revision 1.158.2.3
retrieving revision 1.158.2.4
diff -u -d -r1.158.2.3 -r1.158.2.4
--- lalg2sql.brg 20 Jun 2009 09:49:07 -0000 1.158.2.3
+++ lalg2sql.brg 20 Jun 2009 10:17:24 -0000 1.158.2.4
@@ -383,7 +383,6 @@
#define TLEVEL(p) ((p)->sql_ann->twig_level)
/* serialization report */
#define SER_REPORT(p) ((p)->sql_ann->ser_report)
-#define RANK_MAP(p) ((p)->sql_ann->rank_map)
/* check if sql_statement is a literal */
#define IS_LITERAL(s) (s->kind == sql_lit_int \
@@ -936,8 +935,7 @@
ret->content_size = NULL;
ret->ser_report = ser_no;
ret->ser_list1 = NULL;
- ret->ser_list2 = NULL;
- ret->rank_map = NULL;
+ ret->bind = true;
return ret;
}
@@ -1874,17 +1872,19 @@
}
/**
- * The rank mapping stores the order of a rank operator
- * associated with its result name. (Rank operators that are
- * recorded in this structure occur between a twig node
- * and the serialize node and are collected for the special
- * serialization report (SER_REPORT).
+ * Check if a column @a b appears in list @a a.
*/
-struct rank_map_t {
- PFalg_col_t name;
- PFarray_t *sort_list;
-};
-typedef struct rank_map_t rank_map_t;
+static bool
+clin (PFalg_collist_t *a, PFalg_col_t b)
+{
+ if (!a) return false;
+
+ for (unsigned int i = 0; i < clsize (a); i++)
+ if (b == clat (a, i))
+ return true;
+
+ return false;
+}
/**
* Reduce function. This is the core of this source file, containing
@@ -2057,8 +2057,23 @@
/* The order criterion consists of the column pos. */
if (rule == 1 || rule == 2) {
orderby = col_env_lookup (COLMAP(query), pos, pos_ty);
- orderby = IS_LITERAL(orderby)
- ? NULL : sortkey_list (sortkey_item (orderby, true));
+
+ /* transform the order by statement into a sortkey list */
+
+ /* unfold the sorting criteria of a numbering operator */
+ if (orderby->kind == sql_over &&
+ R(orderby)->kind == sql_wnd_clause &&
+ RR(orderby)->kind == sql_order_by) {
+ assert (L(orderby)->kind == sql_row_number ||
+ L(orderby)->kind == sql_dense_rank);
+ assert (!RL(orderby));
+ /* orderby may become an empty list (aka. NULL) */
+ orderby = RRL(orderby);
+ }
+ else if (IS_LITERAL(orderby))
+ orderby = NULL;
+ else
+ orderby = sortkey_list (sortkey_item (orderby, true));
}
/* The order is represented by the order list of a rank operator.
Transform the list of order columns into a SQL ORDER BY list. */
@@ -2196,28 +2211,6 @@
assert (twig != PF_SQL_ALIAS_UNBOUND);
- if (RANK_MAP(query) &&
- PFarray_last (RANK_MAP(query)) >= 1) {
- PFarray_t *list;
- PFsql_t *sort_item;
- rank_map_t *rank_map;
- /* ignore dummy orderby */
- orderby = NULL;
-
- rank_map = *(rank_map_t **)
- PFarray_at (RANK_MAP(query), 0);
-
- assert (rank_map->name == p->sem.ser_seq.pos);
- assert (rank_map->sort_list);
-
- list = rank_map->sort_list;
- for (int i = PFarray_last (list) - 1;
- i >= 0;
- i--) {
- sort_item = *(PFsql_t **) PFarray_at (list, i);
- orderby = sortkey_list (sort_item, orderby);
- }
- }
/* add minor ordering to ensure that subtrees
of the twig nodes are ordered correctly */
orderby = sortkey_list (PRE(twig), orderby);
@@ -2489,36 +2482,82 @@
/* Query: serialize_rel (nil, Rel) */
case 7:
{
- PFla_op_t *query = R(p);
+ PFla_op_t *query = R(p);
+
+ PFalg_col_t iter = p->sem.ser_rel.iter,
+ pos = p->sem.ser_rel.pos;
+ PFalg_simple_type_t iter_ty = type_of (p, iter),
+ pos_ty = type_of (p, pos);
+ PFsql_t *orderby,
+ *orderbyITER,
+ *orderbyPOS,
+ *selectlist = NULL;
+
+ /* transform the ITER order by statement into a sortkey list */
+ orderby = col_env_lookup (COLMAP(query), iter, iter_ty);
- PFalg_col_t iter = p->sem.ser_rel.iter;
- PFalg_simple_type_t iter_ty = type_of (p, p->sem.ser_rel.iter);
+ /* unfold the sorting criteria of a numbering operator */
+ if (orderby->kind == sql_over &&
+ R(orderby)->kind == sql_wnd_clause &&
+ RR(orderby)->kind == sql_order_by) {
+ assert (L(orderby)->kind == sql_row_number ||
+ L(orderby)->kind == sql_dense_rank);
+ assert (!RL(orderby));
+ /* orderby may become an empty list (aka. NULL) */
+ orderby = RRL(orderby);
+ }
+ else if (IS_LITERAL(orderby))
+ orderby = NULL;
+ else
+ orderby = sortkey_list (sortkey_item (orderby, true));
- PFalg_col_t pos = p->sem.ser_rel.pos;
- PFalg_simple_type_t pos_ty = type_of (p, p->sem.ser_rel.pos);
+ orderbyITER = orderby;
- PFsql_t* orderbyITER = col_env_lookup (COLMAP(query),
- iter, iter_ty);
- PFsql_t* orderbyPOS = col_env_lookup (COLMAP(query), pos, pos_ty);
+ /* transform the POS order by statement into a sortkey list */
+ orderby = col_env_lookup (COLMAP(query), pos, pos_ty);
- /* check if pos and iter column are literals */
- orderbyITER = IS_LITERAL(orderbyITER)?NULL:orderbyITER;
- orderbyPOS = IS_LITERAL(orderbyPOS)?NULL:orderbyPOS;
+ /* unfold the sorting criteria of a numbering operator */
+ if (orderby->kind == sql_over &&
+ R(orderby)->kind == sql_wnd_clause &&
+ RR(orderby)->kind == sql_order_by) {
+ assert (L(orderby)->kind == sql_row_number ||
+ L(orderby)->kind == sql_dense_rank);
+ assert (!RL(orderby));
+ /* orderby may become an empty list (aka. NULL) */
+ orderby = RRL(orderby);
+ }
+ else if (IS_LITERAL(orderby))
+ orderby = NULL;
+ else
+ orderby = sortkey_list (sortkey_item (orderby, true));
- PFsql_t* orderby = NULL;
+ orderbyPOS = orderby;
- /* we don't have to use literals in our order by criterion */
- if(orderbyITER && orderbyPOS)
- orderby = sortkey_list (sortkey_item (orderbyITER, true),
- sortkey_item (orderbyPOS, true));
+ orderby = NULL;
+ /* combine ITER and POS orders */
+ if (orderbyITER && orderbyPOS)
+ orderby = sortkey_list (orderbyITER, orderbyPOS);
else if(orderbyPOS)
- orderby = sortkey_list (sortkey_item (orderbyPOS, true));
+ orderby = orderbyPOS;
else if(orderbyITER)
- orderby = sortkey_list (sortkey_item (orderbyITER, true));
+ orderby = orderbyITER;
+ /* Only include iter and item information in the result. */
+ for (unsigned int i = 0; i < PFarray_last (COLMAP(query)); i++) {
+ sql_column_env_t entry = col_env_at (COLMAP(query), i);
+ if (clin (p->sem.ser_rel.items, entry.col) ||
+ p->sem.ser_rel.iter == entry.col)
+ /* add the sql operation to the select list */
+ selectlist = select_list (
+ transform_expression (
+ entry.expression,
+ COLUMN_NAME (entry.col, entry.type)),
+ selectlist);
+ }
+
/* call a helper function that does the 'real' job */
PFsql_t* final_query = PFsql_select (false,
- transform_selectlist (COLMAP(query)),
+ selectlist,
transform_frommap (query),
transform_wheremap (query),
orderby,
@@ -4018,9 +4057,25 @@
/* generate the aggregation */
switch (p->sem.aggr.aggr[i].kind) {
case alg_aggr_dist:
- /* extend group by list */
- groupbylist = column_list (groupbylist, expr);
- break;
+ {
+ bool found = false;
+ /* Try to find the column col in the rank order list.
*/
+ if (rule == 36) {
+ PFord_ordering_t sortby = L(p)->sem.sort.sortby;
+ unsigned int i;
+ for (i = 0; i < PFord_count (sortby); i++)
+ if (PFord_order_col_at (sortby, i) == col) {
+ found = true;
+ break;
+ }
+ }
+ /* In case the column did not exist in
+ the column list already ... */
+ if (!found)
+ /* ... extend the group by list. */
+ groupbylist = column_list (groupbylist, expr);
+ } break;
+
case alg_aggr_min: expr = min_ (expr); break;
case alg_aggr_max: expr = max_ (expr); break;
case alg_aggr_all:
@@ -4417,6 +4472,7 @@
eq (COL (strjoin_alias, txt_pos),
COL (interm_alias, txt_pos)));
} break;
+
/* Rel: rownum (Rel) */
case 50:
{
@@ -4462,8 +4518,12 @@
partlist,
orderby)));
- bind = true;
- execute (comment ("binding due to rownum operator"));
+ /* Use the information collected in decide_numbering_bind()
+ to decide whether we need to bind the numbering operator. */
+ if (p->sql_ann->bind) {
+ bind = true;
+ execute (comment ("binding due to rownum operator"));
+ }
} break;
/* Rel: rowrank (Rel) */
@@ -4474,54 +4534,27 @@
/* copy all existing column, from, and where lists */
copy_cols_from_where (p, L(p));
- if (SER_REPORT(p) == ser_yes) {
- /* Ignore the result of the rank operator in the normal
- translation process and only add it to the special
- rank map environment. */
- PFord_ordering_t sortby = p->sem.sort.sortby;
-
- unsigned int i, j, k;
- PFalg_col_t ord;
- PFarray_t *srtbylist = PFarray (sizeof (PFsql_t *), 10);
- bool asc, cols_added;
- rank_map_t *rank_map;
-
-
-
- PFsql_t *expr;
- PFalg_simple_type_t expr_ty;
-
+ /* Normal translation of rank operator (using a DENSE_RANK
+ operator). */
+ PFord_ordering_t sortby = p->sem.sort.sortby;
+ PFsql_t *srtbylist = NULL;
+ PFalg_col_t ord;
+ bool asc;
+ PFsql_t* expr = NULL;
+ PFalg_simple_type_t expr_ty;
- for (i = 0; i < PFord_count (sortby); i++) {
- ord = PFord_order_col_at (sortby, i);
- asc = PFord_order_dir_at (sortby, i) == DIR_ASC;
+ /* collect all sorting criteria */
+ for (int i = PFord_count (sortby) - 1; i >= 0; i--) {
+ ord = PFord_order_col_at (sortby, i);
+ asc = PFord_order_dir_at (sortby, i) == DIR_ASC;
- expr_ty = type_of (L(p), ord);
- expr = col_env_lookup (COLMAP(L(p)),
- ord,
- expr_ty);
+ expr_ty = type_of (L(p), ord);
+ expr = col_env_lookup (COLMAP(L(p)),
+ ord,
+ expr_ty);
- cols_added = false;
- if (RANK_MAP(L(p)))
- for (j = 0; j < PFarray_last (RANK_MAP(L(p))); j++) {
- rank_map = *(rank_map_t **)
- PFarray_at (RANK_MAP(L(p)), j);
- if (rank_map->name == ord) {
- /* copy all sort criteria of the rank mapping
*/
- for (k = 0;
- k < PFarray_last(rank_map->sort_list);
- k++)
- *(PFsql_t **) PFarray_add (srtbylist)
- = *(PFsql_t **) PFarray_at (
-
rank_map->sort_list,
- k);
- cols_added = true;
- break;
- }
- }
- if (!cols_added)
- *(PFsql_t **) PFarray_add (srtbylist)
- = sortkey_item (
+ srtbylist = sortkey_list (
+ sortkey_item (
/* different handling of boolean
types as search criterion */
(expr->kind == sql_column_name ||
@@ -4529,64 +4562,19 @@
expr_ty != aat_bln)
? expr
: case_ (when (expr, TRUE_INT),
- else_ (FALSE_INT)),
- asc);
- }
-
- /* initialize rankmap */
- if (!RANK_MAP(p))
- RANK_MAP(p) = PFarray (sizeof (rank_map_t *), 2);
-
- /* add new entry to the rank map */
- rank_map = PFmalloc (sizeof (rank_map_t));
- *rank_map = (rank_map_t) { .name = p->sem.sort.res,
- .sort_list = srtbylist };
- *(rank_map_t **) PFarray_add (RANK_MAP(p)) = rank_map;
-
- /* add a dummy for the rank operator */
- col_env_add (COLMAP(p),
- p->sem.sort.res,
- aat_nat,
- lit_int(0));
- } else {
- /* Normal translation of rank operator (using a DENSE_RANK
- operator). */
- PFord_ordering_t sortby = p->sem.sort.sortby;
- PFsql_t *srtbylist = NULL;
- PFalg_col_t ord;
- bool asc;
- PFsql_t* expr = NULL;
- PFalg_simple_type_t expr_ty;
-
- /* collect all sorting criteria */
- for (int i = PFord_count (sortby) - 1; i >= 0; i--) {
- ord = PFord_order_col_at (sortby, i);
- asc = PFord_order_dir_at (sortby, i) == DIR_ASC;
-
- expr_ty = type_of (L(p), ord);
- expr = col_env_lookup (COLMAP(L(p)),
- ord,
- expr_ty);
-
- srtbylist = sortkey_list (
- sortkey_item (
- /* different handling of boolean
- types as search criterion */
- (expr->kind == sql_column_name ||
- expr->kind == sql_lit_int ||
- expr_ty != aat_bln)
- ? expr
- : case_ (when (expr, TRUE_INT),
- else_ (FALSE_INT)),
- asc),
- srtbylist);
- }
- col_env_add (COLMAP(p),
- p->sem.sort.res,
- aat_nat,
- over (dense_rank (),
- window_clause (NULL, order_by
(srtbylist))));
+ else_ (FALSE_INT)),
+ asc),
+ srtbylist);
+ }
+ col_env_add (COLMAP(p),
+ p->sem.sort.res,
+ aat_nat,
+ over (dense_rank (),
+ window_clause (NULL, order_by (srtbylist))));
+ /* Use the information collected in decide_numbering_bind()
+ to decide whether we need to bind the numbering operator. */
+ if (p->sql_ann->bind) {
bind = true;
execute (comment ("binding due to rank operator"));
}
@@ -4603,8 +4591,12 @@
over (row_number (),
window_clause (NULL, NULL)));
- bind = true;
- execute (comment ("binding due to rowid operator"));
+ /* Use the information collected in decide_numbering_bind()
+ to decide whether we need to bind the numbering operator. */
+ if (p->sql_ann->bind) {
+ bind = true;
+ execute (comment ("binding due to rowid operator"));
+ }
break;
/* Rel: step (Frag, Rel) */
@@ -5628,71 +5620,6 @@
break;
}
- /* Just copy the rankmaps to another operator */
-#define COPY_RANK_MAP(dest,src) \
- do { \
- unsigned int i; \
- if (RANK_MAP(src)) { \
- if (!RANK_MAP(dest)) \
- RANK_MAP(dest) = PFarray ( \
- sizeof (rank_map_t *), \
- PFarray_last (RANK_MAP(src))); \
- for (i = 0; i < PFarray_last (RANK_MAP(src)); i++) \
- *(rank_map_t **) PFarray_add (RANK_MAP(dest)) \
- = *(rank_map_t **) PFarray_at (RANK_MAP(src), i); \
- } \
- } while (0)
-
- /* propagate the special rank mapping information */
- switch (p->kind) {
- case la_project:
- {
- unsigned int i, j;
-
- COPY_RANK_MAP(p, L(p));
-
- if (RANK_MAP(p))
- /* Adjust the names and remove a rank mapping
- if it is not referenced anymore. */
- for (i = 0; i < PFarray_last (RANK_MAP(p)); i++) {
- for (j = 0; j < p->sem.proj.count; j++)
- if ((*(rank_map_t **) PFarray_at (RANK_MAP(p),
i))->name
- == p->sem.proj.items[j].old) {
- (*(rank_map_t **) PFarray_at (RANK_MAP(p),
i))->name
- = p->sem.proj.items[j].new;
- break;
- }
-
- if (j == p->sem.proj.count) {
- *(rank_map_t **) PFarray_at (RANK_MAP(p), i)
- = *(rank_map_t **) PFarray_top (RANK_MAP(p));
- PFarray_del (RANK_MAP(p));
- i--;
- }
- }
- } break;
-
- case la_attach:
- case la_rank:
- COPY_RANK_MAP(p, L(p));
- break;
-
- case la_step_join:
- case la_guide_step_join:
- case la_doc_access:
- COPY_RANK_MAP(p, R(p));
- break;
-
- case la_eqjoin:
- case la_thetajoin:
- COPY_RANK_MAP(p, L(p));
- COPY_RANK_MAP(p, R(p));
- break;
-
- default:
- break;
- }
-
/* BINDING: execute the statement at the end
if the node is dirty, and bind it to a new SQL variable.
The strategy behind this late binding is to merge
@@ -5749,6 +5676,183 @@
}
/**
+ * Check if a column name is used by an operator.
+ */
+static bool
+col_used (PFla_op_t * p, PFalg_col_t col)
+{
+ switch (p->kind) {
+ case la_attach:
+ case la_project:
+ case la_rowid:
+ return false;
+
+ case la_fun_1to1:
+ for (unsigned int i = 0; i < clsize (p->sem.fun_1to1.refs); i++)
+ if (clat (p->sem.fun_1to1.refs, i) == col)
+ return true;
+
+ return false;
+
+ case la_num_eq:
+ case la_num_gt:
+ case la_bool_and:
+ case la_bool_or:
+ return col == p->sem.binary.col1 || col == p->sem.binary.col2;
+
+ case la_bool_not:
+ return col == p->sem.unary.col;
+
+ case la_rownum:
+ case la_rowrank:
+ case la_rank:
+ if (p->sem.sort.part &&
+ p->sem.sort.part == col)
+ return true;
+
+ for (unsigned int i = 0; i < PFord_count (p->sem.sort.sortby); i++)
+ if (PFord_order_col_at (p->sem.sort.sortby, i) == col)
+ return true;
+
+ return false;
+
+ case la_type:
+ case la_cast:
+ return col == p->sem.type.col;
+
+ default:
+ break;
+ }
+ return true;
+}
+
+/* mapping structure that records the numbering operator
+ together with its (possibly update) column name */
+struct num_map_t
+{
+ PFalg_col_t col;
+ PFla_op_t *op;
+};
+typedef struct num_map_t num_map_t;
+
+/**
+ * Worker for decide_numbering_bind adding numbering operators
+ * to the operator list @a num_map. Furthermore all numbering
+ * operators that are used in an operator are removed from the
+ * list again.
+ */
+static void
+collect_numberings (PFla_op_t *p, PFarray_t *num_map)
+{
+ /* avoid inconsistencies */
+ if (REFCTR (p) > 1)
+ return;
+
+ /* only analyze operators that don't change the cardinality */
+ switch (p->kind) {
+ case la_project:
+ case la_attach:
+ 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_rownum:
+ case la_rowrank:
+ case la_rank:
+ case la_rowid:
+ case la_type:
+ case la_cast:
+ break;
+
+ default:
+ return;
+ }
+
+ /* collect the numbering operators in the subplan */
+ collect_numberings (L(p), num_map);
+
+ switch (p->kind) {
+ case la_project:
+ /* update the column names of the numbering operators */
+ for (unsigned int i = 0; i < PFarray_last (num_map); i++)
+ for (unsigned int j = 0; j < p->sem.proj.count; j++)
+ if ((*(num_map_t *) PFarray_at (num_map, i)).col
+ == p->sem.proj.items[j].old) {
+ (*(num_map_t *) PFarray_at (num_map, i)).col
+ = p->sem.proj.items[j].new;
+ break;
+ }
+ break;
+
+ case la_rowid:
+ /* Add the numbering operator. */
+ *(num_map_t *) PFarray_add (num_map)
+ = (num_map_t) { .col = p->sem.rowid.res, .op = p };
+ break;
+
+ case la_rownum:
+ case la_rowrank:
+ case la_rank:
+ /* Add the numbering operators.
+ Avoid partitioned variants as we don't know how to
+ fix the order by list for partitioned operators. */
+ if (!p->sem.sort.part)
+ *(num_map_t *) PFarray_add (num_map)
+ = (num_map_t) { .col = p->sem.sort.res, .op = p };
+ /* fall through */
+
+ default:
+ {
+ /* remove numbering operators whose output is used anywhere */
+ PFalg_col_t col;
+ unsigned int i = 0;
+ while (i < PFarray_last (num_map)) {
+ col = (*(num_map_t *) PFarray_at (num_map, i)).col;
+ if (col_used (p, col)) {
+ *(num_map_t *) PFarray_at (num_map, i)
+ = *(num_map_t *) PFarray_top (num_map);
+ PFarray_del (num_map);
+ }
+ else
+ i++;
+ }
+ } break;
+ }
+}
+
+/**
+ * Change the default behavior to always bind numbering
+ * operators.
+ *
+ * This is done by analysing whether numbering operators are
+ * used before the serialization or not. In case they
+ * are unused we can avoid the binding and cope with it
+ * in the serialization operators.
+ */
+static void
+decide_numbering_bind (PFla_op_t *p)
+{
+ PFarray_t *num_map;
+
+ assert (p->kind == la_serialize_seq ||
+ p->kind == la_serialize_rel);
+
+ num_map = PFarray (sizeof (num_map_t), 3);
+
+ /* Collect all numbering operators that are
+ only used by the serialize operators. */
+ collect_numberings (R(p), num_map);
+
+ /* All numbering operators that are in the list are not used
+ before the serialization operator and thus don't need to be
+ bound immediately. */
+ for (unsigned int i = 0; i < PFarray_last (num_map); i++)
+ (*(num_map_t *) PFarray_at (num_map, i)).op->sql_ann->bind = false;
+}
+
+/**
* Collect a list of the logical operators of all
* referenced fragments.
*
@@ -5814,26 +5918,9 @@
|| ((p)->kind == la_thetajoin))
/* item list */
#define ITEM_LIST(p) ((p)->sql_ann->ser_list1)
-/* rank list */
-#define RANK_LIST(p) ((p)->sql_ann->ser_list2)
-
-/**
- * Check if a column @a b appears in list @a a.
- */
-static bool
-clin (PFalg_collist_t *a, PFalg_col_t b)
-{
- if (!a) return false;
-
- for (unsigned int i = 0; i < clsize (a); i++)
- if (b == clat (a, i))
- return true;
-
- return false;
-}
static void
-ser_info_worker (PFla_op_t *p, PFarray_t *twigs, PFarray_t *ranks)
+ser_info_worker (PFla_op_t *p, PFarray_t *twigs)
{
assert (p);
assert (twigs);
@@ -5870,7 +5957,7 @@
/* DAG walk */
for (unsigned int i = 0; i < PFLA_OP_MAXCHILD && p->child[i]; i++) {
- ser_info_worker (p->child[i], twigs, ranks);
+ ser_info_worker (p->child[i], twigs);
status = MIN(status, SER_REPORT(p->child[i]));
}
@@ -5901,47 +5988,35 @@
assert (!"Serialization report status unknown");
}
- /* maintain item and rank information */
+ /* maintain item information */
switch (p->kind) {
case la_project:
{
PFalg_col_t old, new;
if (ITEM_LIST(L(p)))
ITEM_LIST(p) = PFalg_collist (clsize (ITEM_LIST(L(p))));
- if (RANK_LIST(L(p)))
- RANK_LIST(p) = PFalg_collist (clsize (RANK_LIST(L(p))));
/* projection has the ability to omit and change names */
for (unsigned int i = 0; i < p->sem.proj.count; i++) {
old = p->sem.proj.items[i].old;
new = p->sem.proj.items[i].new;
if (clin (ITEM_LIST(L(p)), old)) cladd (ITEM_LIST(p)) = new;
- if (clin (RANK_LIST(L(p)), old)) cladd (RANK_LIST(p)) = new;
}
} break;
case la_rank:
ITEM_LIST(p) = ITEM_LIST(L(p));
-
- if (RANK_LIST(L(p)))
- RANK_LIST(p) = PFalg_collist_copy (RANK_LIST(L(p)));
- else
- RANK_LIST(p) = PFalg_collist (1);
-
- cladd (RANK_LIST(p)) = p->sem.sort.res;
break;
case la_roots:
case la_attach:
ITEM_LIST(p) = ITEM_LIST(L(p));
- RANK_LIST(p) = RANK_LIST(L(p));
break;
case la_step_join:
case la_guide_step_join:
case la_doc_access:
ITEM_LIST(p) = ITEM_LIST(R(p));
- RANK_LIST(p) = RANK_LIST(R(p));
break;
case la_eqjoin:
@@ -5954,15 +6029,6 @@
ITEM_LIST(p) = ITEM_LIST(L(p));
else
ITEM_LIST(p) = ITEM_LIST(R(p));
-
- if (RANK_LIST(L(p)) && RANK_LIST(R(p)))
- RANK_LIST(p) = PFalg_collist_concat (
- PFalg_collist_copy (RANK_LIST(L(p))),
- RANK_LIST(R(p)));
- else if (RANK_LIST(L(p)))
- RANK_LIST(p) = RANK_LIST(L(p));
- else
- RANK_LIST(p) = RANK_LIST(R(p));
break;
default:
@@ -5983,8 +6049,7 @@
case la_step_join:
case la_guide_step:
case la_guide_step_join:
- if (clin (ITEM_LIST(p), p->sem.step.item) ||
- clin (RANK_LIST(p), p->sem.step.item)) {
+ if (clin (ITEM_LIST(p), p->sem.step.item)) {
SER_REPORT(p) = ser_no;
return;
}
@@ -5992,8 +6057,7 @@
break;
case la_doc_access:
- if (clin (ITEM_LIST(p), p->sem.doc_access.col) ||
- clin (RANK_LIST(p), p->sem.doc_access.col)) {
+ if (clin (ITEM_LIST(p), p->sem.doc_access.col)) {
SER_REPORT(p) = ser_no;
return;
}
@@ -6015,17 +6079,13 @@
}
}
- /* add the rank to the ranks list */
- *(PFla_op_t **) PFarray_add (ranks) = p;
-
- SER_REPORT(p) = ser_tc;
+ /* check if we bind the rank operator or not */
+ SER_REPORT(p) = p->sql_ann->bind ? ser_no: ser_tc;
} break;
case la_eqjoin:
if (clin (ITEM_LIST(p), p->sem.eqjoin.col1) ||
- clin (ITEM_LIST(p), p->sem.eqjoin.col2) ||
- clin (RANK_LIST(p), p->sem.eqjoin.col1) ||
- clin (RANK_LIST(p), p->sem.eqjoin.col2)) {
+ clin (ITEM_LIST(p), p->sem.eqjoin.col2)) {
SER_REPORT(p) = ser_no;
return;
}
@@ -6035,9 +6095,7 @@
case la_thetajoin:
for (unsigned int i = 0; i < p->sem.thetajoin.count; i++)
if (clin (ITEM_LIST(p), p->sem.thetajoin.pred[i].left) ||
- clin (ITEM_LIST(p), p->sem.thetajoin.pred[i].right) ||
- clin (RANK_LIST(p), p->sem.thetajoin.pred[i].left) ||
- clin (RANK_LIST(p), p->sem.thetajoin.pred[i].right)) {
+ clin (ITEM_LIST(p), p->sem.thetajoin.pred[i].right)) {
SER_REPORT(p) = ser_no;
return;
}
@@ -6055,9 +6113,8 @@
static void
infer_ser_info (PFla_op_t * p)
{
- PFarray_t *twigs = PFarray (sizeof (PFla_op_t*), 2),
- *ranks;
- bool twig_only = false;
+ PFarray_t *twigs = PFarray (sizeof (PFla_op_t*), 2);
+ bool twig_only = false;
assert (p->kind == la_serialize_seq);
@@ -6067,11 +6124,8 @@
if (!twig_only)
return;
- /* prepare a list for the rank operators */
- ranks = PFarray (sizeof(PFla_op_t*), 2);
-
/* infer the serialization info */
- ser_info_worker (R(p), twigs, ranks);
+ ser_info_worker (R(p), twigs);
/* the serialize operator either contains yes or no */
SER_REPORT(p) = (SER_REPORT(R(p)) != ser_no) ? ser_yes : ser_no;
@@ -6087,16 +6141,6 @@
assert (twig->kind == la_twig);
SER_REPORT(twig) = ser_yes;
}
-
- /* in a second step assign to all collected rank operators
- ser_yes to store its result in a special rank mapping
- environment. */
- for (unsigned int i = 0; i < PFarray_last (ranks); i++) {
- PFla_op_t *rank = *(PFla_op_t **) PFarray_at (ranks, i);
- assert (rank);
- assert (rank->kind == la_rank);
- SER_REPORT(rank) = ser_yes;
- }
}
/**
@@ -6205,14 +6249,22 @@
label (n);
PFla_dag_reset (n);
- /* check if serialize returns a node* */
- PFalg_simple_type_t ser_ty = PFprop_type_of (n, n->sem.ser_seq.item);
- /* check if ser_ty has no other type */
- if ((ser_ty & aat_node) && !(ser_ty & ~aat_node)) {
- /* infer the serialization information */
- infer_ser_info (n);
-
- PFla_dag_reset (n);
+ /* Decide for all numbering operators (rownum, rank, rowrank, rowid)
+ whether they need to be bound immediately or at the next binding. */
+ decide_numbering_bind (n);
+
+ /* The following checks introduce additional annotations that allow the SQL
+ code generation to generate more efficient code for queries that result
+ in new XML fragments. */
+ if (n->kind == la_serialize_seq) {
+ /* check if serialize returns a node* */
+ PFalg_simple_type_t ser_ty = PFprop_type_of (n, n->sem.ser_seq.item);
+ /* check if ser_ty has no other type */
+ if ((ser_ty & aat_node) && !(ser_ty & ~aat_node)) {
+ /* infer the serialization information */
+ infer_ser_info (n);
+ PFla_dag_reset (n);
+ }
}
/* Assign the delta-pre, level, and size value for node constructors */
------------------------------------------------------------------------------
Are you an open source citizen? Join us for the Open Source Bridge conference!
Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250.
Need another reason to go? 24-hour hacker lounge. Register today!
http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins