Changeset: 1d49a0a775ee for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1d49a0a775ee Modified Files: ChangeLog clients/mapiclient/mhelp.c sql/server/rel_psm.c sql/server/rel_select.c sql/server/rel_select.h sql/server/rel_semantic.c sql/server/rel_updates.c sql/server/sql_parser.y sql/server/sql_tokens.h Branch: default Log Message:
Removed support for LOADER FUNCTION. diffs (truncated from 491 to 300 lines): diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ # ChangeLog file for devel # This file is updated with Maddlog +* Mon Jun 22 2026 Sjoerd Mullender <[email protected]> +- Removed support for LOADER FUNCTION. Since Python UDFs are not + supported anymore, the loader functions can also not be supported + anymore. It is no longer possible to create LOADER functions, nor is + it possible to use them. Upgrading to this version will succeed if + such functions exist. Use this query to find all affected functions: + `SELECT s.name, f.name FROM sys.functions f JOIN sys.schemas s ON s.id + = f.schema_id WHERE f.type = 7;`. These functions can then be dropped + manually using `DROP LOADER FUNCTION ...;`. + * Fri Jun 19 2026 Sjoerd Mullender <[email protected]> - Removed embedded Python support. It is no longer possible to use user-defined functions which are written in Python (i.e. using `CREATE diff --git a/clients/mapiclient/mhelp.c b/clients/mapiclient/mhelp.c --- a/clients/mapiclient/mhelp.c +++ b/clients/mapiclient/mhelp.c @@ -141,11 +141,6 @@ SQLhelp sqlhelp1[] = { " [NULL [AS] string] [BEST EFFORT]\n", "nrofrecords,qname,column_list,headerlist,separators", "See also https://www.monetdb.org/documentation/user-guide/sql-manual/data-loading/copy-from/"}, - {"COPY LOADER", - "Copy into using a user supplied parsing function", - "COPY LOADER INTO qname FROM qname '(' [ scalar_expression ... ] ')'", - "qname,scalar_expression", - "See also https://www.monetdb.org/documentation/user-guide/sql-manual/data-loading/loader-functions/"}, {"CREATE AGGREGATE", "Create a user-defined aggregate function.", "CREATE [ OR REPLACE ] AGGREGATE [ FUNCTION ] qname '(' { '*' | [ param [',' ...]] } ')'\n" @@ -224,7 +219,6 @@ SQLhelp sqlhelp1[] = { {"CREATE TABLE", "Create a new table", "CREATE TABLE [ IF NOT EXISTS ] qname table_source [STORAGE ident string]\n" - "CREATE TABLE [ IF NOT EXISTS ] qname FROM LOADER function_ref\n" "CREATE [ LOCAL | GLOBAL ] { TEMPORARY | TEMP } TABLE [ IF NOT EXISTS ] qname table_source [on_commit]", "table_source,on_commit,function_ref", "See also https://www.monetdb.org/documentation/user-guide/sql-manual/data-definition/table-definition/"}, @@ -243,7 +237,6 @@ SQLhelp sqlhelp1[] = { {"CREATE UNLOGGED TABLE", "Create a new unlogged table", "CREATE UNLOGGED TABLE [ IF NOT EXISTS ] qname table_source [STORAGE ident string]\n" - "CREATE UNLOGGED TABLE [ IF NOT EXISTS ] qname FROM LOADER function_ref\n" "CREATE UNLOGGED TABLE [ IF NOT EXISTS ] qname table_source [on_commit]", "table_source,on_commit,function_ref", "See also https://www.monetdb.org/documentation/user-guide/sql-manual/data-definition/table-definition/"}, @@ -688,7 +681,7 @@ SQLhelp sqlhelp2[] = { NULL}, {"function_type", NULL, - "{ FUNCTION | PROCEDURE | { { AGGREGATE | FILTER | LOADER | WINDOW } [ FUNCTION ] } }", + "{ FUNCTION | PROCEDURE | { { AGGREGATE | FILTER | WINDOW } [ FUNCTION ] } }", NULL, NULL}, {"generated_column", diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c --- a/sql/server/rel_psm.c +++ b/sql/server/rel_psm.c @@ -1529,34 +1529,6 @@ drop_trigger(mvc *sql, dlist *qname, int return rel_drop_trigger(sql, tr->t?tr->t->s->base.name:NULL, tname, if_exists); } -static sql_rel* -create_table_from_loader(sql_query *query, dlist *qname, symbol *fcall) -{ - mvc *sql = query->sql; - sql_schema *s = cur_schema(sql); - char *sname = qname_schema(qname); - char *tname = qname_schema_object(qname); - sql_subfunc *loader = NULL; - sql_rel *rel = NULL; - sql_table *t = NULL; - - if (sname && !(s = mvc_bind_schema(sql, sname))) - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(3F000) "CREATE TABLE FROM LOADER: no such schema '%s'", sname); - if ((t = mvc_bind_table(sql, s, tname))) - return sql_error(sql, 02, SQLSTATE(42S01) "CREATE TABLE FROM LOADER: name '%s' already in use", tname); - if (!mvc_schema_privs(sql, s)) - return sql_error(sql, 02, SQLSTATE(42000) "CREATE TABLE FROM LOADER: insufficient privileges for user '%s' in schema '%s'", get_string_global_var(sql, "current_user"), s->base.name); - - rel = rel_loader_function(query, fcall, new_exp_list(sql->sa), &loader); - if (!rel || !loader) - return NULL; - - loader->sname = s ? ma_strdup(sql->sa, s->base.name) : NULL; - loader->tname = tname ? ma_strdup(sql->sa, tname) : NULL; - - return rel; -} - static list * rel_paramlist( sql_query *query, symbol *nop) { @@ -1637,18 +1609,6 @@ rel_psm(sql_query *query, symbol *s) } else ret = rel_psm_stmt(sql->sa, rel_psm_call(query, s->data.sym)); break; - case SQL_CREATE_TABLE_LOADER: - { - dlist *l = s->data.lval; - dlist *qname = l->h->data.lval; - symbol *sym = l->h->next->data.sym; - - ret = create_table_from_loader(query, qname, sym); - if (ret == NULL) - return NULL; - ret = rel_psm_stmt(sql->sa, exp_rel(sql, ret)); - sql->type = Q_SCHEMA; - } break; case SQL_CREATE_TRIGGER: { dlist *l = s->data.lval; 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 @@ -6588,81 +6588,3 @@ schema_selects(sql_query *query, sql_sch sql->session->schema = os; return res; } - -sql_rel * -rel_loader_function(sql_query *query, symbol* fcall, list *fexps, sql_subfunc **loader_function) -{ - mvc *sql = query->sql; - sql_rel *sq = NULL; - dnode *l = fcall->data.lval->h; - char *sname = qname_schema(l->data.lval); - char *fname = qname_schema_object(l->data.lval); - - list *tl = sa_list(sql->sa); - list *exps = sa_list(sql->sa); - if (l->next) - l = l->next; /* skip distinct */ - if (l->next) { /* table call with subquery */ - if (l->next->type == type_symbol || l->next->type == type_list) { - int count = 0; - symbol *subquery = NULL; - dnode *n = NULL; - - if (l->next->type == type_symbol) - n = l->next; - else - n = l->next->data.lval?l->next->data.lval->h:NULL; - - for (dnode *m = n; m; m = m->next) { - if (m->type == type_symbol && m->data.sym->token == SQL_SELECT) - subquery = m->data.sym; - count++; - } - if (subquery && count > 1) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: The input for the loader function '%s' must be either a single sub query, or a list of values", fname); - - if (subquery) { - exp_kind ek = { type_value, card_relation, TRUE }; - if (!(sq = rel_subquery(query, subquery, ek))) - return NULL; - } else { - exp_kind ek = { type_value, card_column, TRUE }; - list *exps = sa_list(sql->sa); - for ( ; n; n = n->next) { - sql_exp *e = rel_value_exp(query, NULL, n->data.sym, sql_sel | sql_from, ek); - - if (!e) - return NULL; - append(exps, e); - } - sq = rel_project(sql->sa, NULL, exps); - } - } - if (!sq) - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such loader function %s%s%s'%s'", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname); - for (node *en = sq->exps->h; en; en = en->next) { - sql_exp *e = en->data; - - append(exps, e = exp_ref(sql, e)); - append(tl, exp_subtype(e)); - } - } - - sql_exp *e = NULL; - if (!(e = find_table_function(sql, sname, fname, exps, tl, F_LOADER))) - return NULL; - sql_subfunc *sf = e->f; - if (sq) { - for (node *n = sq->exps->h, *m = sf->func->ops->h ; n && m ; n = n->next, m = m->next) { - sql_exp *e = (sql_exp*) n->data; - sql_arg *a = (sql_arg*) m->data; - if (!exp_subtype(e) && rel_set_type_param(sql, &(a->type), sq, e, 0) < 0) - return NULL; - } - } - - if (loader_function) - *loader_function = sf; - - return rel_table_func(sql->sa, sq, e, fexps, (sq)?TABLE_FROM_RELATION:TABLE_PROD_FUNC); -} diff --git a/sql/server/rel_select.h b/sql/server/rel_select.h --- a/sql/server/rel_select.h +++ b/sql/server/rel_select.h @@ -31,7 +31,6 @@ extern sql_exp *rel_nop_(mvc *sql, sql_r extern sql_rel *rel_with_query(sql_query *query, symbol *q); extern sql_rel *table_ref(sql_query *query, symbol *tableref, int lateral, list *refs); extern sql_exp *find_table_function(mvc *sql, char *sname, char *fname, list *exps, list *tl, sql_ftype type); -extern sql_rel *rel_loader_function(sql_query* query, symbol* s, list *fexps, sql_subfunc **loader_function); extern list *check_arguments_and_find_largest_any_type(mvc *sql, sql_rel *rel, list *exps, sql_subfunc *sf, int maybe_zero_or_one, bool internal /*or second compile */); extern sql_rel *rel_reduce_on_column_privileges(mvc *sql, sql_rel *rel, sql_table *t); diff --git a/sql/server/rel_semantic.c b/sql/server/rel_semantic.c --- a/sql/server/rel_semantic.c +++ b/sql/server/rel_semantic.c @@ -169,8 +169,6 @@ rel_semantic(sql_query *query, symbol *s case SQL_CALL: case SQL_SET: - case SQL_CREATE_TABLE_LOADER: - case SQL_CREATE_TRIGGER: case SQL_DROP_TRIGGER: @@ -186,7 +184,6 @@ rel_semantic(sql_query *query, symbol *s case SQL_COPYINTO: case SQL_BINCOPYFROM: case SQL_BINCOPYINTO: - case SQL_COPYLOADER: return rel_updates(query, s); case SQL_WITH: 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 @@ -1548,20 +1548,6 @@ table_column_types(allocator *sa, sql_ta return types; } -static list * -table_column_names_and_defaults(allocator *sa, sql_table *t) -{ - node *n; - list *types = sa_list(sa); - - if (ol_first_node(t->columns)) for (n = ol_first_node(t->columns); n; n = n->next) { - sql_column *c = n->data; - append(types, &c->base.name); - append(types, c->def); - } - return types; -} - static sql_rel * rel_import(mvc *sql, sql_table *t, const char *tsep, const char *rsep, const char *ssep, const char *ns, const char *filename, lng nr, lng offset, int best_effort, dlist *fwf_widths, int onclient, int escape, const char* decsep, const char *decskip) { @@ -1937,47 +1923,6 @@ bincopyfrom(sql_query *query, dlist *qna } static sql_rel * -copyfromloader(sql_query *query, dlist *qname, symbol *fcall) -{ - mvc *sql = query->sql; - char *sname = qname_schema(qname); - char *tname = qname_schema_object(qname); - sql_subfunc *loader = NULL; - sql_rel *rel = NULL; - sql_table *t; - list *mts; - - if (!copy_allowed(sql, 1)) - return sql_error(sql, 02, SQLSTATE(42000) "COPY LOADER INTO: insufficient privileges: " - "COPY LOADER INTO requires database administrator rights"); - t = find_table_or_view_on_scope(sql, NULL, sname, tname, "COPY INTO", false); - //TODO the COPY LOADER INTO should return an insert relation (instead of ddl) to handle partitioned tables properly - if (insert_allowed(sql, t, tname, "COPY LOADER INTO", "copy loader into") == NULL) - return NULL; - if (isPartitionedByColumnTable(t) || isPartitionedByExpressionTable(t)) - return sql_error(sql, 02, SQLSTATE(42000) "COPY LOADER INTO: not possible for partitioned tables at the moment"); - if ((mts = partition_find_mergetables(sql, t))) { - for (node *n = mts->h ; n ; n = n->next) { - sql_part *pt = n->data; - - if ((isPartitionedByColumnTable(pt->t) || isPartitionedByExpressionTable(pt->t))) - return sql_error(sql, 02, SQLSTATE(42000) "COPY LOADER INTO: not possible for tables child of partitioned tables at the moment"); - } - } - - rel = rel_loader_function(query, fcall, new_exp_list(sql->sa), &loader); - if (!rel || !loader) - return NULL; - - loader->sname = t->s ? ma_strdup(sql->sa, t->s->base.name) : NULL; - loader->tname = tname ? ma_strdup(sql->sa, tname) : NULL; - loader->coltypes = table_column_types(sql->sa, t); - loader->colnames = table_column_names_and_defaults(sql->sa, t); - - return rel; -} _______________________________________________ checkin-list mailing list -- [email protected] To unsubscribe send an email to [email protected]
