Changeset: c709820aef3f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c709820aef3f
Modified Files:
clients/mapiclient/dump.c
Branch: Jul2017
Log Message:
Dump foreign language functions.
diffs (truncated from 332 to 300 lines):
diff --git a/clients/mapiclient/dump.c b/clients/mapiclient/dump.c
--- a/clients/mapiclient/dump.c
+++ b/clients/mapiclient/dump.c
@@ -1220,72 +1220,209 @@ dump_table(Mapi mid, char *schema, char
return rc;
}
+static int
+dump_function(Mapi mid, stream *toConsole, const char *sname, const char
*fname, int hashge)
+{
+ MapiHdl hdl;
+ size_t qlen = 200 + strlen(sname) + strlen(fname);
+ char *query = malloc(qlen);
+ const char *sep;
+ char *fid, *ffunc;
+ int flang, ftype;
+
+ snprintf(query, qlen, "select f.id, f.func, f.language, f.type from
sys.functions f, sys.schemas s where f.schema_id = s.id and s.name = '%s' and
f.name = '%s'", sname, fname);
+ hdl = mapi_query(mid, query);
+ if (mapi_fetch_row(hdl) == 0) {
+ free(query);
+ mapi_close_handle(hdl);
+ return 0; /* no such function, apparently */
+ }
+ fid = mapi_fetch_field(hdl, 0);
+ ffunc = mapi_fetch_field(hdl, 1);
+ flang = atoi(mapi_fetch_field(hdl, 2));
+ ftype = atoi(mapi_fetch_field(hdl, 3));
+ if (flang == 1 || flang == 2) {
+ /* all information is stored in the func column */
+ mnstr_printf(toConsole, "%s\n", ffunc);
+ mapi_close_handle(hdl);
+ return 0;
+ }
+ mnstr_printf(toConsole, "CREATE ");
+ switch (ftype) {
+ case 1: /* scalar function */
+ case 5: /* table returning function */
+ mnstr_printf(toConsole, "FUNCTION");
+ break;
+ case 2:
+ mnstr_printf(toConsole, "PROCEDURE");
+ break;
+ case 3:
+ mnstr_printf(toConsole, "AGGREGATE");
+ break;
+ case 4:
+ mnstr_printf(toConsole, "FILTER FUNCTION");
+ break;
+ case 7:
+ mnstr_printf(toConsole, "LOADER");
+ break;
+ default:
+ /* shouldn't happen (6 is F_ANALYTIC, but no syntax to
+ * create, or values are not defined) */
+ free(query);
+ mapi_close_handle(hdl);
+ return -1;
+ }
+ ffunc = strdup(ffunc);
+ mnstr_printf(toConsole, " ");
+ quoted_print(toConsole, sname, 0);
+ mnstr_printf(toConsole, ".");
+ quoted_print(toConsole, fname, 0);
+ mnstr_printf(toConsole, "(");
+ snprintf(query, qlen, "select a.name, a.type, a.type_digits,
a.type_scale, a.inout from sys.args a, sys.functions f where a.func_id = f.id
and f.id = %s order by a.inout desc, a.number", fid);
+ mapi_close_handle(hdl);
+ hdl = mapi_query(mid, query);
+ free(query);
+ sep = "";
+ while (mapi_fetch_row(hdl) != 0) {
+ char *aname = mapi_fetch_field(hdl, 0);
+ char *atype = mapi_fetch_field(hdl, 1);
+ char *adigs = mapi_fetch_field(hdl, 2);
+ char *ascal = mapi_fetch_field(hdl, 3);
+ char *ainou = mapi_fetch_field(hdl, 4);
+
+ if (strcmp(ainou, "0") == 0) {
+ /* end of arguments */
+ break;
+ }
+
+ mnstr_printf(toConsole, "%s", sep);
+ quoted_print(toConsole, aname, 0);
+ mnstr_printf(toConsole, " ");
+ dump_type(mid, toConsole, atype, adigs, ascal, hashge);
+ sep = ", ";
+ }
+ mnstr_printf(toConsole, ")");
+ if (ftype == 1 || ftype == 3 || ftype == 5) {
+ sep = "TABLE (";
+ mnstr_printf(toConsole, " RETURNS ");
+ do {
+ char *aname = mapi_fetch_field(hdl, 0);
+ char *atype = mapi_fetch_field(hdl, 1);
+ char *adigs = mapi_fetch_field(hdl, 2);
+ char *ascal = mapi_fetch_field(hdl, 3);
+
+ assert(strcmp(mapi_fetch_field(hdl, 4), "0") == 0);
+ if (ftype == 5) {
+ mnstr_printf(toConsole, "%s", sep);
+ quoted_print(toConsole, aname, 0);
+ mnstr_printf(toConsole, " ");
+ sep = ", ";
+ }
+ dump_type(mid, toConsole, atype, adigs, ascal, hashge);
+ } while (mapi_fetch_row(hdl) != 0);
+ }
+ mapi_close_handle(hdl);
+ mnstr_printf(toConsole, " LANGUAGE ");
+ switch (flang) {
+ case 3:
+ mnstr_printf(toConsole, "R");
+ break;
+ case 4:
+ mnstr_printf(toConsole, "C");
+ break;
+ case 5:
+ mnstr_printf(toConsole, "J");
+ break;
+ case 6:
+ mnstr_printf(toConsole, "PYTHON");
+ break;
+ case 7:
+ mnstr_printf(toConsole, "PYTHON_MAP");
+ break;
+ case 8:
+ mnstr_printf(toConsole, "PYTHON2");
+ break;
+ case 9:
+ mnstr_printf(toConsole, "PYTHON2_MAP");
+ break;
+ case 10:
+ mnstr_printf(toConsole, "PYTHON3");
+ break;
+ case 11:
+ mnstr_printf(toConsole, "PYTHON3_MAP");
+ break;
+ default: /* unknown language */
+ free(ffunc);
+ return -1;
+ }
+ mnstr_printf(toConsole, "\n%s\n", ffunc);
+ free(ffunc);
+ return 0;
+}
+
int
dump_functions(Mapi mid, stream *toConsole, const char *sname, const char
*fname)
{
const char functions[] =
- "SELECT f.func "
+ "SELECT s.name, f.name "
"FROM sys.schemas s, "
"sys.functions f "
- "WHERE f.language BETWEEN 1 AND 2 AND "
- "s.id = f.schema_id "
- "%s%s"
- "%s%s%s%s%s%s"
+ "WHERE s.id = f.schema_id AND "
+ "f.id NOT IN (SELECT function_id FROM
sys.systemfunctions) "
+ "%s%s%s"
"ORDER BY f.func";
MapiHdl hdl;
char *q;
size_t l;
- char dumpSystem;
- char *schema = NULL;
+ int hashge = has_hugeint(mid);
- if (sname == NULL) {
- if (fname == NULL) {
- schema = NULL;
- } else if ((schema = strchr(fname, '.')) != NULL) {
- size_t len = schema - fname;
+ if (fname != NULL) {
+ /* dump a single function */
+ int rc;
+ char *schema = NULL;
+
+ if (sname == NULL) {
+ /* no schema given, so figure it out */
+ if ((schema = strchr(fname, '.')) != NULL) {
+ size_t len = schema - fname;
- schema = malloc(len + 1);
- strncpy(schema, fname, len);
- schema[len] = 0;
- fname += len + 1;
- } else if ((schema = get_schema(mid)) == NULL) {
- return 1;
+ schema = malloc(len + 1);
+ strncpy(schema, fname, len);
+ schema[len] = 0;
+ fname += len + 1;
+ } else if ((schema = get_schema(mid)) == NULL) {
+ return 1;
+ }
+ sname = schema;
}
- sname = schema;
+ rc = dump_function(mid, toConsole, sname, fname, hashge);
+ if (schema)
+ free(schema);
+ return rc;
}
- dumpSystem = sname && fname;
-
l = sizeof(functions) + (sname ? strlen(sname) : 0) + 100;
q = malloc(l);
snprintf(q, l, functions,
- dumpSystem ? "" : "AND f.id ",
- dumpSystem ? "" : "NOT IN (SELECT function_id FROM
sys.systemfunctions) ",
sname ? "AND s.name = '" : "",
sname ? sname : "",
- sname ? "' " : "",
- fname ? "AND f.name = '" : "",
- fname ? fname : "",
- fname ? "' " : "");
+ sname ? "' " : "");
hdl = mapi_query(mid, q);
free(q);
if (hdl == NULL || mapi_error(mid))
goto bailout;
while (!mnstr_errnr(toConsole) && mapi_fetch_row(hdl) != 0) {
- char *query = mapi_fetch_field(hdl, 0);
+ sname = mapi_fetch_field(hdl, 0);
+ fname = mapi_fetch_field(hdl, 1);
- mnstr_printf(toConsole, "%s\n", query);
+ dump_function(mid, toConsole, sname, fname, hashge);
}
if (mapi_error(mid))
goto bailout;
- if (schema)
- free(schema);
mapi_close_handle(hdl);
return mnstr_errnr(toConsole) != 0;
bailout:
- if (schema)
- free(schema);
if (hdl) {
if (mapi_result_error(hdl))
mapi_explain_result(hdl, stderr);
@@ -1450,10 +1587,12 @@ dump_database(Mapi mid, stream *toConsol
/* we must dump views, functions and triggers in order of
* creation since they can refer to each other */
const char *views_functions_triggers =
- "WITH vft AS ("
+ "WITH vft (sname, name, id, query, type) AS ("
"SELECT s.name AS sname, "
+ "t.name AS name, "
"t.id AS id, "
- "t.query AS query "
+ "t.query AS query, "
+ "'view' AS type "
"FROM sys.schemas s, "
"sys._tables t "
"WHERE t.type = 1 AND "
@@ -1462,29 +1601,33 @@ dump_database(Mapi mid, stream *toConsol
"s.name <> 'tmp' "
"UNION "
"SELECT s.name AS sname, "
+ "f.name AS name, "
"f.id AS id, "
- "f.func AS query "
+ "f.func AS query, "
+ "'function' AS type "
"FROM sys.schemas s, "
"sys.functions f "
- "WHERE f.language < 3 AND "
- "s.id = f.schema_id "
+ "WHERE s.id = f.schema_id "
"AND f.id NOT IN (SELECT function_id FROM
sys.systemfunctions) "
"UNION "
"SELECT s.name AS sname, "
+ "tr.name AS name, "
"tr.id AS id, "
- "tr.\"statement\" AS query "
+ "tr.\"statement\" AS query, "
+ "'trigger' AS type "
"FROM sys.triggers tr, "
"sys.schemas s, "
"sys._tables t "
"WHERE s.id = t.schema_id AND "
"t.id = tr.table_id"
") "
- "SELECT sname, query FROM vft ORDER BY id";
+ "SELECT sname, name, query, type FROM vft ORDER BY id";
char *sname = NULL;
char *curschema = NULL;
MapiHdl hdl;
int create_hash_func = 0;
int rc = 0;
+ int hashge;
/* start a transaction for the dump */
if (!describe)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list