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 -- [email protected]
To unsubscribe send an email to [email protected]