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

Reply via email to