Changeset: 61b74f07c79f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/61b74f07c79f
Modified Files:
sql/backends/monet5/rel_bin.c
Branch: pp_hashjoin
Log Message:
merged
diffs (262 lines):
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -4819,6 +4819,111 @@ rel2bin_inter(backend *be, sql_rel *rel,
}
static stmt *
+sub_topn(backend *be, stmt *sub, stmt **Psub, sql_rel *topn, list *oexps, stmt
*l, int distinct)
+{
+ stmt *psub = Psub?*Psub:NULL;
+ node *n;
+ list *npl = sa_list(be->mvc->sa), *pl =
psub?psub->op4.lval:sub->op4.lval;
+ /* distinct, topn returns at least N (unique groups) */
+ stmt *limit = NULL, *lpiv = NULL, *lgid = NULL;
+ int nr_obe = list_length(oexps);
+
+ /* check for partition columns */
+ stmt *grp = NULL, *ext = NULL, *cnt = NULL;
+ for (n=oexps->h; n; n = n->next, nr_obe--) {
+ sql_exp *gbe = n->data;
+ bool last = (!n->next ||
!is_partitioning((sql_exp*)n->next->data));
+
+ if (!topn->grouped || !is_partitioning(gbe))
+ break;
+ /* create group by */
+ stmt *gbcol = exp_bin(be, gbe, sub, NULL, NULL, NULL, NULL,
NULL, 0, 0, 0);
+ if (!gbcol)
+ gbcol = exp_bin(be, gbe, psub, NULL, NULL, NULL, NULL,
NULL, 0, 0, 0);
+
+ if (!gbcol) {
+ assert(be->mvc->session->status == -10); /* Stack
overflow errors shouldn't terminate the server */
+ return NULL;
+ }
+ if (!gbcol->nrcols)
+ gbcol = stmt_const(be, bin_find_smallest_column(be,
sub), gbcol);
+ stmt *groupby = stmt_group(be, gbcol, grp, ext, cnt, last);
+ grp = stmt_result(be, groupby, 0);
+ ext = stmt_result(be, groupby, 1);
+ cnt = stmt_result(be, groupby, 2);
+ gbcol = stmt_alias(be, gbcol, gbe->alias.label,
exp_find_rel_name(gbe), exp_name(gbe));
+ }
+
+ if (grp)
+ lgid = grp;
+ for (; n; n = n->next, nr_obe--) {
+ sql_exp *orderbycole = n->data;
+
+ stmt *orderbycolstmt = exp_bin(be, orderbycole, sub, psub,
NULL, NULL, NULL, NULL, 0, 0, 0);
+
+ if (!orderbycolstmt)
+ return NULL;
+
+ /* handle constants */
+ if (orderbycolstmt->nrcols == 0 && n->next) /* no need to sort
on constant */
+ continue;
+ orderbycolstmt = column(be, orderbycolstmt);
+ if (!limit) { /* topn based on a single column */
+ limit = stmt_limit(be, orderbycolstmt, NULL, grp,
stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole),
nulls_last(orderbycole), nr_obe, 1);
+ } else { /* topn based on 2 columns */
+ limit = stmt_limit(be, orderbycolstmt, lpiv, lgid,
stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole),
nulls_last(orderbycole), nr_obe, 1);
+ }
+ if (!limit)
+ return NULL;
+ lpiv = limit;
+ if (!grp && nr_obe > 1) {
+ lpiv = stmt_result(be, limit, 0);
+ lgid = stmt_result(be, limit, 1);
+ if (lpiv == NULL || lgid == NULL)
+ return NULL;
+ }
+ }
+ if (!lpiv) {
+ stmt *orderbycolstmt = pl->h->data;
+
+ if (!orderbycolstmt)
+ return NULL;
+
+ orderbycolstmt = column(be, orderbycolstmt);
+ limit = stmt_limit(be, orderbycolstmt, NULL, grp,
stmt_atom_lng(be, 0), l, distinct, 0, 0, nr_obe, 1);
+ lpiv = limit;
+ if (!lpiv)
+ return NULL;
+ }
+
+ limit = lpiv;
+ if (!limit) /* partition/order by cols fully overlap */
+ limit = stmt_limit(be, pl->h->data, NULL, grp,
stmt_atom_lng(be, 0), l, 0,0,0,0,1);
+ if (limit && grp)
+ limit = stmt_project(be, stmt_selectnonil(be, limit, NULL),
limit);
+ stmt *s;
+ if (psub) {
+ for (n=pl->h ; n; n = n->next) {
+ stmt *os = n->data;
+ list_append(npl, s=stmt_project(be, limit, column(be,
os)));
+ s->label = os->label;
+ }
+ *Psub = stmt_list(be, npl);
+ }
+
+ /* also rebuild sub as multiple orderby expressions may use the sub
table (ie aren't part of the result columns) */
+ pl = sub->op4.lval;
+ npl = sa_list(be->mvc->sa);
+ for (n=pl->h ; n; n = n->next) {
+ stmt *os = n->data;
+ list_append(npl, s = stmt_project(be, limit, column(be, os)));
+ s->label = os->label;
+ }
+ sub = stmt_list(be, npl);
+ return sub;
+}
+
+static stmt *
rel2bin_project(backend *be, sql_rel *rel, list *refs, sql_rel *topn)
{
mvc *sql = be->mvc;
@@ -4906,104 +5011,8 @@ rel2bin_project(backend *be, sql_rel *re
if both order by and distinct: then get first order by col
do topn on it. Project all again! Then rest
*/
- if (topn && rel->r) {
- list *oexps = rel->r, *npl = sa_list(sql->sa);
- /* distinct, topn returns at least N (unique groups) */
- int distinct = need_distinct(rel);
- stmt *limit = NULL, *lpiv = NULL, *lgid = NULL;
- int nr_obe = list_length(oexps);
-
- /* check for partition columns */
- stmt *grp = NULL, *ext = NULL, *cnt = NULL;
- for (n=oexps->h; n; n = n->next, nr_obe--) {
- sql_exp *gbe = n->data;
- bool last = (!n->next ||
!is_partitioning((sql_exp*)n->next->data));
-
- if (!topn->grouped || !is_partitioning(gbe))
- break;
- /* create group by */
- stmt *gbcol = exp_bin(be, gbe, sub, NULL, NULL, NULL,
NULL, NULL, 0, 0, 0);
- if (!gbcol)
- gbcol = exp_bin(be, gbe, psub, NULL, NULL,
NULL, NULL, NULL, 0, 0, 0);
-
- if (!gbcol) {
- assert(sql->session->status == -10); /* Stack
overflow errors shouldn't terminate the server */
- return NULL;
- }
- if (!gbcol->nrcols)
- gbcol = stmt_const(be,
bin_find_smallest_column(be, sub), gbcol);
- stmt *groupby = stmt_group(be, gbcol, grp, ext, cnt,
last);
- grp = stmt_result(be, groupby, 0);
- ext = stmt_result(be, groupby, 1);
- cnt = stmt_result(be, groupby, 2);
- gbcol = stmt_alias(be, gbcol, gbe->alias.label,
exp_find_rel_name(gbe), exp_name(gbe));
- }
-
- if (grp)
- lgid = grp;
- for (; n; n = n->next, nr_obe--) {
- sql_exp *orderbycole = n->data;
-
- stmt *orderbycolstmt = exp_bin(be, orderbycole, sub,
psub, NULL, NULL, NULL, NULL, 0, 0, 0);
-
- if (!orderbycolstmt)
- return NULL;
-
- /* handle constants */
- if (orderbycolstmt->nrcols == 0 && n->next) /* no need
to sort on constant */
- continue;
- orderbycolstmt = column(be, orderbycolstmt);
- if (!limit) { /* topn based on a single column */
- limit = stmt_limit(be, orderbycolstmt, NULL,
grp, stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole),
nulls_last(orderbycole), nr_obe, 1);
- } else { /* topn based on 2 columns */
- limit = stmt_limit(be, orderbycolstmt, lpiv,
lgid, stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole),
nulls_last(orderbycole), nr_obe, 1);
- }
- if (!limit)
- return NULL;
- lpiv = limit;
- if (!grp && nr_obe > 1) {
- lpiv = stmt_result(be, limit, 0);
- lgid = stmt_result(be, limit, 1);
- if (lpiv == NULL || lgid == NULL)
- return NULL;
- }
- }
- if (!lpiv) {
- stmt *orderbycolstmt = pl->h->data;
-
- if (!orderbycolstmt)
- return NULL;
-
- orderbycolstmt = column(be, orderbycolstmt);
- limit = stmt_limit(be, orderbycolstmt, NULL, grp,
stmt_atom_lng(be, 0), l, distinct, 0, 0, nr_obe, 1);
- lpiv = limit;
- if (!lpiv)
- return NULL;
- }
-
- limit = lpiv;
- if (!limit) /* partition/order by cols fully overlap */
- limit = stmt_limit(be, pl->h->data, NULL, grp,
stmt_atom_lng(be, 0), l, 0,0,0,0,1);
- if (limit && grp)
- limit = stmt_project(be, stmt_selectnonil(be, limit,
NULL), limit);
- stmt *s;
- for (n=pl->h ; n; n = n->next) {
- stmt *os = n->data;
- list_append(npl, s=stmt_project(be, limit, column(be,
os)));
- s->label = os->label;
- }
- psub = stmt_list(be, npl);
-
- /* also rebuild sub as multiple orderby expressions may use the
sub table (ie aren't part of the result columns) */
- pl = sub->op4.lval;
- npl = sa_list(sql->sa);
- for (n=pl->h ; n; n = n->next) {
- stmt *os = n->data;
- list_append(npl, s = stmt_project(be, limit, column(be,
os)));
- s->label = os->label;
- }
- sub = stmt_list(be, npl);
- }
+ if (topn && rel->r)
+ sub = sub_topn(be, sub, &psub, topn, rel->r, l,
need_distinct(rel));
if (need_distinct(rel)) {
stmt *distinct = NULL;
psub = rel2bin_distinct(be, psub, &distinct);
@@ -5356,6 +5365,8 @@ assert(0);
sub = refs_find_rel(refs, rl);
if (!sub)
sub = rel2bin_project(be, rl, refs,
rel);
+ else if (rl->r) /* handle topn */
+ sub = sub_topn(be, sub, NULL, rel,
rl->r, l, need_distinct(rl));
} else
sub = rel2bin_project(be, rl, refs, rel);
if (rel->grouped && rl->r && has_partitioning(rl->r))
@@ -5382,15 +5393,15 @@ assert(0);
sc = column(be, sc);
stmt *glimit = NULL;
- stmt *il = l, *io = o;
if (pp) {
+ stmt *il = l, *io = o;
io = stmt_atom_lng(be, 0);
il = all;
limit = stmt_limit_partitioned(be, sc /*stmt_alias(be,
sc, sc->label, tname, cname)*/, NULL, NULL, io, il);
glimit = stmt_result(be, limit, 0);
limit = stmt_result(be, limit, 1);
} else {
- limit = stmt_limit(be, sc, NULL, NULL, io, il,
0,0,0,0,0);
+ limit = stmt_limit(be, sc, NULL, NULL, o, l, 0,0,0,0,0);
}
for ( ; n; n = n->next) {
diff --git
a/sql/test/BugTracker-2021/Tests/serializable-snapshot.Bug-7200.SQL.py
b/sql/test/BugTracker-2021/Tests/serializable-snapshot.Bug-7200.SQL.py
--- a/sql/test/BugTracker-2021/Tests/serializable-snapshot.Bug-7200.SQL.py
+++ b/sql/test/BugTracker-2021/Tests/serializable-snapshot.Bug-7200.SQL.py
@@ -33,7 +33,8 @@ thread1.join()
thread2.join()
cursor1.execute("SELECT COUNT(*), COUNT(DISTINCT k), SUM(k) from T;")
-if cursor1.fetchall() != [(MAX_ITERATIONS, MAX_ITERATIONS, EXPECTED_SUM)]:
+res = cursor1.fetchall()
+if res != [(MAX_ITERATIONS, MAX_ITERATIONS, EXPECTED_SUM)]:
sys.stderr.write("[(%d,%d,%d)] expected, [(%d,%d,%d)] received" %
(MAX_ITERATIONS, MAX_ITERATIONS, EXPECTED_SUM, res[0][0], res[0][1], res[0][2]))
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]