Changeset: d0386497afd4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d0386497afd4
Modified Files:
        gdk/gdk_utils.c
        sql/server/rel_select.c
        sql/test/miscellaneous/Tests/simple_selects.sql
        sql/test/miscellaneous/Tests/simple_selects.stable.out
Branch: default
Log Message:

Merge with Nov2019


diffs (truncated from 552 to 300 lines):

diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -402,39 +402,76 @@ MT_init(void)
 # error "don't know how to get the amount of physical memory for your OS"
 #endif
 
-#ifndef WIN32
+#ifdef __linux__
        /* limit values to whatever cgroups gives us */
-       FILE *f;
-       /* limit of memory usage */
-       f = fopen("/sys/fs/cgroup/memory/memory.limit_in_bytes", "r");
-       if (f != NULL) {
-               uint64_t mem;
-               if (fscanf(f, "%" SCNu64, &mem) == 1
-                   && mem < (uint64_t) _MT_pagesize * _MT_npages) {
-                       _MT_npages = (size_t) (mem / _MT_pagesize);
+       FILE *fc;
+       fc = fopen("/proc/self/cgroup", "r");
+       if (fc != NULL) {
+               char buf[1024];
+               while (fgets(buf, (int) sizeof(buf), fc) != NULL) {
+                       char *p, *q;
+                       p = strchr(buf, ':');
+                       if (p == NULL)
+                               break;
+                       q = p + 1;
+                       p = strchr(q, ':');
+                       if (p == NULL)
+                               break;
+                       *p++ = 0;
+                       if (strstr(q, "memory") != NULL) {
+                               char pth[1024];
+                               FILE *f;
+                               q = strchr(p, '\n');
+                               if (q == NULL)
+                                       break;
+                               *q = 0;
+                               q = stpconcat(pth, "/sys/fs/cgroup/memory",
+                                             p, NULL);
+                               /* sometimes the path in
+                                * /proc/self/cgroup ends in "/" (or
+                                * actually, is "/"); in all other
+                                * cases add one */
+                               if (q[-1] != '/')
+                                       *q++ = '/';
+                               /* limit of memory usage */
+                               strcpy(q, "memory.limit_in_bytes");
+                               f = fopen(pth, "r");
+                               if (f != NULL) {
+                                       uint64_t mem;
+                                       if (fscanf(f, "%" SCNu64, &mem) == 1
+                                           && mem < (uint64_t) _MT_pagesize * 
_MT_npages) {
+                                               _MT_npages = (size_t) (mem / 
_MT_pagesize);
+                                       }
+                                       fclose(f);
+                               }
+                               /* soft limit of memory usage */
+                               strcpy(q, "memory.soft_limit_in_bytes");
+                               f = fopen(pth, "r");
+                               if (f != NULL) {
+                                       uint64_t mem;
+                                       if (fscanf(f, "%" SCNu64, &mem) == 1
+                                           && mem < (uint64_t) _MT_pagesize * 
_MT_npages) {
+                                               _MT_npages = (size_t) (mem / 
_MT_pagesize);
+                                       }
+                                       fclose(f);
+                               }
+                               /* limit of memory+swap usage
+                                * we use this as maximum virtual memory size */
+                               strcpy(q, "memory.memsw.limit_in_bytes");
+                               f = fopen(pth, "r");
+                               if (f != NULL) {
+                                       uint64_t mem;
+                                       if (fscanf(f, "%" SCNu64, &mem) == 1
+                                           && mem < (uint64_t) GDK_vm_maxsize) 
{
+                                               GDK_vm_maxsize = (size_t) mem;
+                                       }
+                                       fclose(f);
+                               }
+                               break;
+
+                       }
                }
-               fclose(f);
-       }
-       /* soft limit of memory usage */
-       f = fopen("/sys/fs/cgroup/memory/memory.soft_limit_in_bytes", "r");
-       if (f != NULL) {
-               uint64_t mem;
-               if (fscanf(f, "%" SCNu64, &mem) == 1
-                   && mem < (uint64_t) _MT_pagesize * _MT_npages) {
-                       _MT_npages = (size_t) (mem / _MT_pagesize);
-               }
-               fclose(f);
-       }
-       /* limit of memory+swap usage
-        * we use this as maximum virtual memory size */
-       f = fopen("/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes", "r");
-       if (f != NULL) {
-               uint64_t mem;
-               if (fscanf(f, "%" SCNu64, &mem) == 1
-                   && mem < (uint64_t) GDK_vm_maxsize) {
-                       GDK_vm_maxsize = (size_t) mem;
-               }
-               fclose(f);
+               fclose(fc);
        }
 #endif
 
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -3080,6 +3080,8 @@ rel_logical_exp(sql_query *query, sql_re
 
                        lr = rel_select_copy(sql->sa, lr, sa_list(sql->sa));
                        lr = rel_logical_exp(query, lr, lo, f);
+                       if (!lr)
+                               return NULL;
                        rr = rel_select_copy(sql->sa, rr, sa_list(sql->sa));
                        rr = rel_logical_exp(query, rr, ro, f);
                        if (lr && rr && lr->l == rr->l) {
@@ -3092,6 +3094,8 @@ rel_logical_exp(sql_query *query, sql_re
                        sql->pushdown = pushdown;
                } else {
                        lr = rel_logical_exp(query, lr, lo, f);
+                       if (!lr)
+                               return NULL;
                        rr = rel_logical_exp(query, rr, ro, f);
                }
 
@@ -6144,35 +6148,148 @@ rel_column_exp(sql_query *query, sql_rel
        return NULL;
 }
 
-static sql_rel *
-rel_simple_select(sql_query *query, sql_rel *rel, symbol *where, dlist 
*selection, int distinct)
+static sql_rel*
+rel_where_groupby_nodes(sql_query *query, sql_rel *rel, SelectNode *sn)
+{
+       mvc *sql = query->sql;
+
+       if (sn->where) {
+               rel = rel_logical_exp(query, rel, sn->where, sql_where);
+               if (!rel) {
+                       if (sql->errstr[0] == 0)
+                               return sql_error(sql, 02, SQLSTATE(42000) 
"Subquery result missing");
+                       return NULL;
+               }
+       }
+
+       if (rel && sn->groupby) {
+               list *gbe = rel_group_by(query, &rel, sn->groupby, 
sn->selection, sql_sel | sql_groupby);
+               if (!gbe)
+                       return NULL;
+               rel = rel_groupby(sql, rel, gbe);
+       }
+
+       if (rel && sn->having) {
+               /* having implies group by, ie if not supplied do a group by */
+               if (rel->op != op_groupby)
+                       rel = rel_groupby(sql, rel, NULL);
+       }
+
+       return rel;
+}
+
+static sql_rel*
+rel_having_limits_nodes(sql_query *query, sql_rel *rel, SelectNode *sn, 
exp_kind ek)
 {
        mvc *sql = query->sql;
-       dnode *n = 0;
        sql_rel *inner;
 
-       if (!selection)
+       if (sn->having) {
+               inner = rel->l;
+               assert(is_project(rel->op) && inner);
+       
+               if (inner && inner->op == op_groupby)
+                       set_processed(inner);
+               inner = rel_logical_exp(query, inner, sn->having, sql_having);
+
+               if (!inner)
+                       return NULL;
+               if (inner->exps && exps_card(inner->exps) > CARD_AGGR)
+                       return sql_error(sql, 02, SQLSTATE(42000) "SELECT: 
cannot compare sets with values, probably an aggregate function missing");
+               rel->l = inner;
+       }
+
+       if (rel && sn->distinct)
+               rel = rel_distinct(rel);
+
+       if (rel && sn->orderby) {
+               list *obe = NULL;
+
+               set_processed(rel);
+               rel = rel_orderby(sql, rel);
+               obe = rel_order_by(query, &rel, sn->orderby, sql_orderby);
+               if (!obe)
+                       return NULL;
+               rel->r = obe;
+       }
+       if (!rel)
+               return NULL;
+
+       if (sn->limit || sn->offset) {
+               sql_subtype *lng = sql_bind_localtype("lng");
+               list *exps = new_exp_list(sql->sa);
+
+               if (sn->limit) {
+                       sql_exp *l = rel_value_exp(query, NULL, sn->limit, 0, 
ek);
+
+                       if (!l || !(l=rel_check_type(sql, lng, NULL, l, 
type_equal)))
+                               return NULL;
+                       if ((ek.card != card_relation && sn->limit) &&
+                               (ek.card == card_value && sn->limit)) {
+                               sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(l));
+                               l = exp_aggr1(sql->sa, l, zero_or_one, 0, 0, 
CARD_ATOM, 0);
+                       }
+                       append(exps, l);
+               } else
+                       append(exps, NULL);
+               if (sn->offset) {
+                       sql_exp *o = rel_value_exp( query, NULL, sn->offset, 0, 
ek);
+                       if (!o || !(o=rel_check_type(sql, lng, NULL, o, 
type_equal)))
+                               return NULL;
+                       append(exps, o);
+               }
+               rel = rel_topn(sql->sa, rel, exps);
+       }
+
+       if (sn->sample) {
+               list *exps = new_exp_list(sql->sa);
+               dlist* sample_parameters = sn->sample->data.lval;
+               sql_exp *sample_size = rel_value_exp(query, NULL, 
sample_parameters->h->data.sym, 0, ek);
+               if (!sample_size)
+                       return NULL;
+               append(exps, sample_size);
+
+               if (sample_parameters->cnt == 2) {
+                       sql_exp *seed_value = rel_value_exp(query, NULL, 
sample_parameters->h->next->data.sym, 0, ek);
+                       if (!seed_value)
+                               return NULL;
+                       append(exps, seed_value);
+               }
+
+               rel = rel_sample(sql->sa, rel, exps);
+       }
+
+       if (rel)
+               set_processed(rel);
+       return rel;
+}
+
+static sql_rel *
+rel_simple_select(sql_query *query, sql_rel *rel, SelectNode *sn, exp_kind ek)
+{
+       mvc *sql = query->sql;
+       sql_rel *inner;
+
+       if (!sn->selection)
                return sql_error(sql, 02, SQLSTATE(42000) "SELECT: the 
selection or from part is missing");
-       if (where) {
-               sql_rel *r;
-
-               if(!rel)
-                       rel = rel_project(sql->sa, NULL, 
list_append(new_exp_list(sql->sa), exp_atom_bool(sql->sa, 1)));
-               r = rel_logical_exp(query, rel, where, sql_where);
-               if (!r)
-                       return NULL;
-               rel = r;
-       }
+
+       if ((sn->where || sn->groupby || sn->having) && !rel)
+               rel = rel_project(sql->sa, NULL, 
list_append(new_exp_list(sql->sa), exp_atom_bool(sql->sa, 1)));
+
+       rel = rel_where_groupby_nodes(query, rel, sn);
+       if (sql->session->status) /* rel might be NULL as input, so we have to 
check for the session status for errors */
+               return NULL;
+
        if (!rel || rel->op != op_project || !list_empty(rel->exps))
                rel = rel_project(sql->sa, rel, new_exp_list(sql->sa));
        inner = rel;
-       for (n = selection->h; n; n = n->next ) {
+       for (dnode *n = sn->selection->h; n; n = n->next) {
                /* Here we could get real column expressions (including single
                 * atoms) but also table results. Therefore we try both
                 * rel_column_exp and rel_table_exp.
                 */
                sql_rel *o_inner = inner;
-               list *te = NULL, *pre_prj = rel_projections(sql, o_inner, NULL, 
1, 1);
+               list *te = NULL, *pre_prj = rel_projections(sql, o_inner, NULL, 
1, 1);
                sql_exp *ce = rel_column_exp(query, &inner, n->data.sym, 
sql_sel);
 
                if (inner != o_inner) {  /* relation got rewritten */
@@ -6194,7 +6311,7 @@ rel_simple_select(sql_query *query, sql_
                        rel = inner;
                        continue;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to