Changeset: 55908093c060 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=55908093c060 Added Files: sql/test/rename/Tests/rename11.py sql/test/rename/Tests/rename11.stable.err sql/test/rename/Tests/rename11.stable.out Modified Files: buildtools/selinux/monetdb.te clients/mapilib/mapi.c sql/server/rel_updates.c sql/storage/bat/bat_storage.c sql/storage/bat/bat_storage.h sql/storage/bat/bat_utils.c sql/storage/bat/bat_utils.h sql/storage/store.c sql/test/BugTracker-2019/Tests/slow-inner-join.Bug-6737.sql sql/test/BugTracker-2019/Tests/slow-inner-join.Bug-6737.stable.out sql/test/rename/Tests/All Branch: default Log Message:
Merge with Apr2019 branch. diffs (truncated from 1285 to 300 lines): diff --git a/buildtools/selinux/monetdb.te b/buildtools/selinux/monetdb.te --- a/buildtools/selinux/monetdb.te +++ b/buildtools/selinux/monetdb.te @@ -1,4 +1,4 @@ -policy_module(monetdb, 0.5) +policy_module(monetdb, 0.6) # The above line declares that this file is a SELinux policy file. Its # name is monetdb, so the file should be saved as monetdb.te @@ -8,12 +8,14 @@ require { type tmp_t; type var_t; type user_home_t; + type unconfined_service_t; # for EPEL 7 + type proc_t; # for EPEL 7 class dir { read }; class fd { use }; class fifo_file { getattr read write }; class file { entrypoint execute getattr manage_file_perms map open read }; class netlink_selinux_socket create_socket_perms; - class process { rlimitinh siginh signal sigterm sigkill transition }; + class process { rlimitinh siginh signal sigchld sigterm sigkill transition }; class tcp_socket create_stream_socket_perms; class udp_socket create_stream_socket_perms; class unix_dgram_socket create_socket_perms; @@ -41,6 +43,10 @@ type_transition monetdbd_t mserver5_exec # monetdbd must be allowed to kill the server it started allow monetdbd_t mserver5_t:process { sigterm sigkill }; +# on EPEL 7 we need these as well +allow mserver5_t monetdbd_t:process sigchld; +allow monetdbd_t unconfined_service_t:process signal; +allow mserver5_t proc_t:file { open read getattr }; # read /proc/meminfo # declare a type for the systemd unit file (monetdbd.service) type monetdbd_unit_file_t; @@ -123,6 +129,9 @@ manage_sock_files_pattern(mserver5_t, ms allow mserver5_t monetdbd_t:fifo_file { read write getattr }; allow mserver5_t monetdbd_t:unix_stream_socket { read write getopt shutdown }; allow mserver5_t var_t:dir { read }; +# we want to be able to read some cgroup files +fs_search_cgroup_dirs(mserver5_t); +fs_read_cgroup_files(mserver5_t); allow monetdbd_t var_t:dir { read }; gen_tunable(mserver5_can_read_home, false) tunable_policy(`mserver5_can_read_home', ` diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c --- a/clients/mapilib/mapi.c +++ b/clients/mapilib/mapi.c @@ -2483,6 +2483,24 @@ mapi_reconnect(Mapi mid) return mapi_setError(mid, errbuf, "mapi_reconnect", MERROR); } #endif + /* compare our own address with that of our peer and + * if they are the same, we were connected to our own + * socket, so then we can't use this connection */ + union { + struct sockaddr s; + struct sockaddr_in i; + } myaddr, praddr; + socklen_t myaddrlen, praddrlen; + myaddrlen = (socklen_t) sizeof(myaddr); + praddrlen = (socklen_t) sizeof(praddr); + if (getsockname(s, &myaddr.s, &myaddrlen) == 0 && + getpeername(s, &praddr.s, &praddrlen) == 0 && + myaddr.i.sin_addr.s_addr == praddr.i.sin_addr.s_addr && + myaddr.i.sin_port == praddr.i.sin_port) { + closesocket(s); + return mapi_setError(mid, "connected to self", + "mapi_reconnect", MERROR); + } } mid->to = socket_wstream(s, "Mapi client write"); @@ -2989,6 +3007,7 @@ close_connection(Mapi mid) close_stream(mid->from); mid->from = 0; } + mid->redircnt = 0; mapi_log_record(mid, "Connection closed\n"); } diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c --- a/sql/server/rel_updates.c +++ b/sql/server/rel_updates.c @@ -1403,7 +1403,7 @@ extern sql_rel *rel_list(sql_allocator * static sql_rel * validate_merge_update_delete(mvc *sql, sql_table *t, str alias, sql_rel *joined_table, tokens upd_token, - sql_rel *upd_del, sql_rel *bt, sql_rel *join_rel) + sql_rel *upd_del, sql_rel *bt, sql_rel *extra_selection) { char buf[BUFSIZ]; sql_exp *aggr, *bigger, *ex; @@ -1415,7 +1415,7 @@ validate_merge_update_delete(mvc *sql, s assert(upd_token == SQL_UPDATE || upd_token == SQL_DELETE); - groupby = rel_groupby(sql, rel_dup(join_rel), NULL); //aggregate by all column and count (distinct values) + groupby = rel_groupby(sql, rel_dup(extra_selection), NULL); //aggregate by all column and count (distinct values) groupby->r = rel_projections(sql, bt, NULL, 1, 0); aggr = exp_aggr(sql->sa, NULL, cf, 0, 0, groupby->card, 0); (void) rel_groupby_add_aggr(sql, groupby, aggr); @@ -1454,7 +1454,8 @@ merge_into_table(sql_query *query, dlist char *sname = qname_schema(qname), *tname = qname_table(qname), *alias_name; sql_schema *s = NULL; sql_table *t = NULL; - sql_rel *bt, *joined, *join_rel = NULL, *extra_project = NULL, *insert = NULL, *upd_del = NULL, *res = NULL; + sql_rel *bt, *joined, *join_rel = NULL, *extra_project, *insert = NULL, *upd_del = NULL, *res = NULL, *extra_select; + sql_exp *nils, *project_first; int processed = 0; assert(tref && search_cond && merge_list); @@ -1500,79 +1501,108 @@ merge_into_table(sql_query *query, dlist action = dl->h->next->data.sym; sts = action->data.lval; - if(opt_search) + if (opt_search) return sql_error(sql, 02, SQLSTATE(42000) "MERGE: search condition not yet supported"); - if(token == SQL_MERGE_MATCH) { + if (token == SQL_MERGE_MATCH) { tokens uptdel = action->token; - sql_exp *e; - if((processed & MERGE_UPDATE_DELETE) == MERGE_UPDATE_DELETE) + if ((processed & MERGE_UPDATE_DELETE) == MERGE_UPDATE_DELETE) return sql_error(sql, 02, SQLSTATE(42000) "MERGE: only one WHEN MATCHED clause is allowed"); processed |= MERGE_UPDATE_DELETE; - if(uptdel == SQL_UPDATE) { - if(!update_allowed(sql, t, tname, "MERGE", "update", 0)) + if (uptdel == SQL_UPDATE) { + if (!update_allowed(sql, t, tname, "MERGE", "update", 0)) return NULL; - if((processed & MERGE_INSERT) == MERGE_INSERT) - joined = rel_dup(joined); + if ((processed & MERGE_INSERT) == MERGE_INSERT) { + join_rel = rel_dup(join_rel); + } else { + join_rel = rel_crossproduct(sql->sa, joined, bt, op_left); + if (!(join_rel = rel_logical_exp(query, join_rel, search_cond, sql_where))) + return NULL; + set_processed(join_rel); + } - join_rel = rel_crossproduct(sql->sa, bt, joined, op_join); - join_rel = rel_logical_exp(query, join_rel, search_cond, sql_where); - if (!join_rel) - return NULL; - set_processed(join_rel); - + //project columns of both bt and joined + oid extra_project = rel_project(sql->sa, join_rel, rel_projections(sql, bt, NULL, 1, 0)); extra_project->exps = list_merge(extra_project->exps, rel_projections(sql, joined, NULL, 1, 0), (fdup)NULL); - e = exp_column(sql->sa, alias_name, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1); - append(extra_project->exps, e); + list_append(extra_project->exps, exp_column(sql->sa, alias_name, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1)); + + //select bt values which are not null (they had a match in the join) + project_first = extra_project->exps->h->next->data; // this expression must come from bt!! + project_first = exp_ref(sql->sa, project_first); + nils = rel_unop_(query, extra_project, project_first, NULL, "isnull", card_value); + extra_select = rel_select(sql->sa, extra_project, exp_compare(sql->sa, nils, exp_atom_bool(sql->sa, 1), cmp_notequal)); - upd_del = update_generate_assignments(query, t, extra_project, bt, sts->h->data.lval, "MERGE"); - } else if(uptdel == SQL_DELETE) { + //the update statement requires a projection on the right side + extra_project = rel_project(sql->sa, extra_select, rel_projections(sql, bt, NULL, 1, 0)); + extra_project->exps = list_merge(extra_project->exps, rel_projections(sql, joined, NULL, 1, 0), (fdup)NULL); + list_append(extra_project->exps, + exp_column(sql->sa, alias_name, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1)); + upd_del = update_generate_assignments(query, t, extra_project, rel_dup(bt), sts->h->data.lval, "MERGE"); + } else if (uptdel == SQL_DELETE) { if (!update_allowed(sql, t, tname, "MERGE", "delete", 1)) return NULL; - if((processed & MERGE_INSERT) == MERGE_INSERT) - joined = rel_dup(joined); + if ((processed & MERGE_INSERT) == MERGE_INSERT) { + join_rel = rel_dup(join_rel); + } else { + join_rel = rel_crossproduct(sql->sa, joined, bt, op_left); + if (!(join_rel = rel_logical_exp(query, join_rel, search_cond, sql_where))) + return NULL; + set_processed(join_rel); + } - join_rel = rel_crossproduct(sql->sa, bt, joined, op_join); - join_rel = rel_logical_exp(query, join_rel, search_cond, sql_where); - if (!join_rel) - return NULL; - set_processed(join_rel); + //project columns of bt + oid + extra_project = rel_project(sql->sa, join_rel, rel_projections(sql, bt, NULL, 1, 0)); + list_append(extra_project->exps, exp_column(sql->sa, alias_name, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1)); - e = exp_column(sql->sa, alias_name, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1); - extra_project = rel_project(sql->sa, join_rel, append(new_exp_list(sql->sa), e)); + //select bt values which are not null (they had a match in the join) + project_first = extra_project->exps->h->next->data; // this expression must come from bt!! + project_first = exp_ref(sql->sa, project_first); + nils = rel_unop_(query, extra_project, project_first, NULL, "isnull", card_value); + extra_select = rel_select(sql->sa, extra_project, exp_compare(sql->sa, nils, exp_atom_bool(sql->sa, 1), cmp_notequal)); - upd_del = rel_delete(sql->sa, bt, extra_project); + //the delete statement requires a projection on the right side, which will be the oid values + extra_project = rel_project(sql->sa, extra_select, list_append(new_exp_list(sql->sa), + exp_column(sql->sa, alias_name, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1))); + upd_del = rel_delete(sql->sa, rel_dup(bt), extra_project); } else { assert(0); } - if(!upd_del || !(upd_del = validate_merge_update_delete(sql, t, alias, joined, uptdel, upd_del, bt, join_rel))) + if (!upd_del || !(upd_del = validate_merge_update_delete(sql, t, alias, joined, uptdel, upd_del, bt, extra_select))) return NULL; - } else if(token == SQL_MERGE_NO_MATCH) { - if((processed & MERGE_INSERT) == MERGE_INSERT) + } else if (token == SQL_MERGE_NO_MATCH) { + if ((processed & MERGE_INSERT) == MERGE_INSERT) return sql_error(sql, 02, SQLSTATE(42000) "MERGE: only one WHEN NOT MATCHED clause is allowed"); processed |= MERGE_INSERT; assert(action->token == SQL_INSERT); if (!insert_allowed(sql, t, tname, "MERGE", "insert")) return NULL; - if((processed & MERGE_UPDATE_DELETE) == MERGE_UPDATE_DELETE) - joined = rel_dup(joined); + if ((processed & MERGE_UPDATE_DELETE) == MERGE_UPDATE_DELETE) { + join_rel = rel_dup(join_rel); + } else { + join_rel = rel_crossproduct(sql->sa, joined, bt, op_left); + if (!(join_rel = rel_logical_exp(query, join_rel, search_cond, sql_where))) + return NULL; + set_processed(join_rel); + } - join_rel = rel_crossproduct(sql->sa, joined, bt, op_left); - join_rel = rel_logical_exp(query, join_rel, search_cond, sql_where); - if (!join_rel) + //project columns of both + extra_project = rel_project(sql->sa, join_rel, rel_projections(sql, bt, NULL, 1, 0)); + extra_project->exps = list_merge(extra_project->exps, rel_projections(sql, joined, NULL, 1, 0), (fdup)NULL); + + //select bt values which are null (they didn't have match in the join) + project_first = extra_project->exps->h->next->data; // this expression must come from bt!! + project_first = exp_ref(sql->sa, project_first); + nils = rel_unop_(query, extra_project, project_first, NULL, "isnull", card_value); + extra_select = rel_select(sql->sa, extra_project, exp_compare(sql->sa, nils, exp_atom_bool(sql->sa, 1), cmp_equal)); + + //project only values from the joined relation + extra_project = rel_project(sql->sa, extra_select, rel_projections(sql, joined, NULL, 1, 0)); + if (!(insert = merge_generate_inserts(query, t, extra_project, sts->h->data.lval, sts->h->next->data.sym))) return NULL; - join_rel->op = op_anti; - set_processed(join_rel); - - insert = merge_generate_inserts(query, t, join_rel, sts->h->data.lval, sts->h->next->data.sym); - if(!insert) - return NULL; - insert = rel_insert(query, rel_dup(bt), insert); - if(!insert) + if (!(insert = rel_insert(query, rel_dup(bt), insert))) return NULL; } else { assert(0); @@ -2207,7 +2237,7 @@ rel_updates(sql_query *query, symbol *s) { dlist *l = s->data.lval; - ret = copyfrom(query, + ret = copyfrom(query, l->h->data.lval, l->h->next->data.lval, l->h->next->next->data.lval, diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c --- a/sql/storage/bat/bat_storage.c +++ b/sql/storage/bat/bat_storage.c @@ -506,6 +506,7 @@ dup_delta(sql_trans *tr, sql_delta *obat bat->cnt = obat->cnt; bat->ucnt = obat->ucnt; bat->wtime = obat->wtime; + bat->cleared = obat->cleared; bat->name = _STRDUP(obat->name); if(!bat->name) @@ -787,6 +788,7 @@ dup_dbat( sql_trans *tr, sql_dbat *obat, bat->cnt = obat->cnt; bat->dname = _STRDUP(obat->dname); bat->wtime = obat->wtime; + bat->cleared = obat->cleared; if(!bat->dname) return LOG_ERR; if (bat->dbid) { @@ -1949,6 +1951,7 @@ clear_delta(sql_trans *tr, sql_delta *ba if (b) bat_destroy(b); } + bat->cleared = 1; bat->ibase = 0; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list