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