Changeset: e03af8e949f7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/e03af8e949f7 Added Files: sql/server/rel_proto_loader.c sql/server/rel_proto_loader.h Modified Files: sql/common/sql_types.c sql/server/CMakeLists.txt sql/server/rel_select.c sql/server/sql_parser.y Branch: odbc_loader Log Message:
initial steps to suppor proto(col) based loading diffs (269 lines): diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c --- a/sql/common/sql_types.c +++ b/sql/common/sql_types.c @@ -1711,8 +1711,8 @@ sqltypeinit( allocator *sa) f = sql_create_union(sa, "copyfrombinary", "", "", TRUE, SCALE_FIX, 0, TABLE, 3, STR, STR, INT); f->varres = 1; - /* file_loader */ - f = sql_create_union(sa, "file_loader", "", "", TRUE, SCALE_FIX, 0, TABLE, 1, STR); + f = sql_create_union(sa, "file_loader", "", "", TRUE, SCALE_FIX, 0, TABLE, 1, STR); /* file_loader */ + f = sql_create_union(sa, "proto_loader", "", "", TRUE, SCALE_FIX, 0, TABLE, 1, STR); /* proto_loader */ f->varres = 1; /* sys_update_schemas, sys_update_tables */ diff --git a/sql/server/CMakeLists.txt b/sql/server/CMakeLists.txt --- a/sql/server/CMakeLists.txt +++ b/sql/server/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(sqlserver STATIC) set(sqlserver_public_headers ${CMAKE_CURRENT_SOURCE_DIR}/sql_parser.h ${CMAKE_CURRENT_SOURCE_DIR}/rel_file_loader.h + ${CMAKE_CURRENT_SOURCE_DIR}/rel_proto_loader.h ${CMAKE_CURRENT_SOURCE_DIR}/sql_mvc.h) target_sources(sqlserver @@ -65,6 +66,7 @@ target_sources(sqlserver rel_xml.c rel_dump.c rel_file_loader.c + rel_proto_loader.c rel_dump.h rel_exp.h rel_rel.h rel_basetable.h rel_rewriter.h @@ -95,6 +97,7 @@ target_sources(sqlserver sql_tokens.h sql_partition.h rel_file_loader.h + rel_proto_loader.h ${BISON_sqlparser_OUTPUT_HEADER} ${BISON_sqlparser_OUTPUT_SOURCE} PUBLIC diff --git a/sql/server/rel_proto_loader.c b/sql/server/rel_proto_loader.c new file mode 100644 --- /dev/null +++ b/sql/server/rel_proto_loader.c @@ -0,0 +1,71 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2024 MonetDB Foundation; + * Copyright August 2008 - 2023 MonetDB B.V.; + * Copyright 1997 - July 2008 CWI. + */ + +#include "monetdb_config.h" +#include "rel_proto_loader.h" + +#define NR_PROTO_LOADERS 255 +static proto_loader_t proto_loaders[NR_PROTO_LOADERS] = { 0 }; + +void +pl_exit(void) +{ + for (int i = 0; i < NR_PROTO_LOADERS; i++) { + if (proto_loaders[i].name) + GDKfree(proto_loaders[i].name); + } +} + +void +pl_unregister(char *name) +{ + proto_loader_t *fl = pl_find(name); + if (fl) { + GDKfree(fl->name); + fl->name = NULL; + } +} + +int +pl_register(char *name, pl_add_types_fptr add_types, pl_load_fptr load) +{ + proto_loader_t *fl = pl_find(name); + if (fl) { + TRC_WARNING(SQL_TRANS,"proto_loader re-registering %s\n", name); + GDKfree(fl->name); + fl->name = NULL; + } + + for (int i = 0; i < NR_PROTO_LOADERS; i++) { + if (proto_loaders[i].name == NULL) { + proto_loaders[i].name = GDKstrdup(name); + proto_loaders[i].add_types = add_types; + proto_loaders[i].load = load; + return 0; + } + } + + /* all proto_loaders array locations are occupied */ + return -1; /* could not register proto_loader */ +} + +proto_loader_t* +pl_find(char *name) +{ + if (!name) + return NULL; + for (int i = 0; i < NR_PROTO_LOADERS; i++) { + if (proto_loaders[i].name && strcmp(proto_loaders[i].name, name) == 0) + return proto_loaders+i; + } + return NULL; +} diff --git a/sql/server/rel_proto_loader.h b/sql/server/rel_proto_loader.h new file mode 100644 --- /dev/null +++ b/sql/server/rel_proto_loader.h @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2024 MonetDB Foundation; + * Copyright August 2008 - 2023 MonetDB B.V.; + * Copyright 1997 - July 2008 CWI. + */ + +#ifndef _REL_PROTO_LOADER_H_ +#define _REL_PROTO_LOADER_H_ + +#include "sql_types.h" +#include "sql_mvc.h" + +typedef str (*pl_add_types_fptr)(mvc *sql, sql_subfunc *f, char *url, list *res_exps, char *name); +typedef void *(*pl_load_fptr)(void *be, sql_subfunc *f, char *url, sql_exp *topn); /* use void * as both return type and be + argument are unknown types at this layer */ + +typedef struct proto_loader_t { + char *name; + pl_add_types_fptr add_types; + pl_load_fptr load; +} proto_loader_t; + +sql_export int pl_register(char *name, pl_add_types_fptr add_types, pl_load_fptr pl_load); +sql_export void pl_unregister(char *name); +extern proto_loader_t* pl_find(char *name); + +extern void pl_exit(void); + +#endif /*_REL_PROTO_LOADER_H_*/ 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 @@ -28,6 +28,7 @@ #include "rel_unnest.h" #include "rel_sequence.h" #include "rel_file_loader.h" +#include "rel_proto_loader.h" #define VALUE_FUNC(f) (f->func->type == F_FUNC || f->func->type == F_FILT) #define check_card(card,f) ((card == card_none && !f->res) || (CARD_VALUE(card) && f->res && VALUE_FUNC(f)) || card == card_loader || (card == card_relation && f->func->type == F_UNION)) @@ -657,6 +658,69 @@ rel_file_loader(mvc *sql, list *exps, li return NULL; } +static char * +proto_loader_add_table_column_types(mvc *sql, sql_subfunc *f, list *exps, list *res_exps, char *tname) +{ + sql_exp *uri = exps->h->data; + if (!exp_is_atom(uri)) + return "URI missing"; + + atom *a = uri->l; + if (a->data.vtype != TYPE_str || !a->data.val.sval) + return "URI missing"; + + char *uristr = a->data.val.sval; + if (strcmp(uristr, "") == 0) + return "URI missing"; + + char *proto = uristr, *ep = strchr(uristr, ':'); + + if (ep) { + *ep = 0; + proto = mkLower(sa_strdup(sql->sa, proto)); + } + if (!proto) + return "URI protocol missing"; + + proto_loader_t *pl = pl_find(proto); + if (!pl) + return sa_message(sql->ta, "URI extension '%s' missing", proto?proto:""); + str err = pl->add_types(sql, f, uristr, res_exps, tname); + if (err) + return err; + sql_subtype *st = sql_bind_localtype("str"); + sql_exp *proto_exp = exp_atom(sql->sa, atom_string(sql->sa, st, proto)); + if (!proto_exp) + return MAL_MALLOC_FAIL; + append(exps, proto_exp); + return NULL; +} + +static sql_rel * +rel_proto_loader(mvc *sql, list *exps, list *tl, char *tname) +{ + sql_subfunc *f = NULL; + bool found = false; + + if ((f = bind_func_(sql, NULL, "proto_loader", tl, F_UNION, true, &found, false))) { + list *nexps = exps; + if (list_empty(tl) || f->func->vararg || (nexps = check_arguments_and_find_largest_any_type(sql, NULL, exps, f, 1, false))) { + list *res_exps = sa_list(sql->sa); + if (list_length(exps) == 1 && f && f->func->varres && strlen(f->func->mod) == 0 && strlen(f->func->imp) == 0) { + char *err = proto_loader_add_table_column_types(sql, f, nexps, res_exps, tname); + if (err) + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: proto_loader function failed '%s'", err); + } + sql_exp *e = exp_op(sql->sa, nexps, f); + sql_rel *rel = rel_table_func(sql->sa, NULL, e, res_exps, TABLE_PROD_FUNC); + if (rel) + rel = rel_project(sql->sa, rel, exps_alias(sql, res_exps)); + return rel; + } + } + return NULL; +} + sql_exp * find_table_function(mvc *sql, char *sname, char *fname, list *exps, list *tl, sql_ftype type) { @@ -767,7 +831,11 @@ rel_named_table_function(sql_query *quer else tname = make_label(sql->sa, ++sql->label); - if (!sname && strcmp(fname, "file_loader") == 0) { + if (!sname && strcmp(fname, "proto_loader") == 0) { + rel = rel_proto_loader(sql, exps, tl, tname); + if (!rel) + return NULL; + } else if (!sname && strcmp(fname, "file_loader") == 0) { rel = rel_file_loader(sql, exps, tl, tname); if (!rel) return NULL; diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -3709,9 +3709,12 @@ table_ref: $$ = _symbol_create_list(SQL_NAME, l); } | string opt_table_name { dlist *l = L(); dlist *f = L(); - append_list(f, append_string(L(), "file_loader")); + const char *s = $1; + if (s && s[0] == DIR_SEP) /* Only normal abolute file names */ + append_list(f, append_string(L(), "file_loader")); + else + append_list(f, append_string(L(), "proto_loader")); append_int(f, FALSE); /* ignore distinct */ - const char *s = $1; int len = UTF8_strlen(s); sql_subtype t; sql_find_subtype(&t, "char", len, 0); _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org