Changeset: bd6de4362cd0 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/bd6de4362cd0 Modified Files: clients/mapiclient/dump.c Branch: nested Log Message:
Work on dumping complex types. diffs (truncated from 426 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 @@ -491,6 +491,45 @@ bailout: return false; } +static bool +has_multiset(Mapi mid) +{ + MapiHdl hdl; + bool ret; + static int answer = -1; + + if (answer >= 0) + return answer; + + if ((hdl = mapi_query(mid, + "select id from sys._columns" + " where table_id = 2076" + " and name = 'multiset'")) == NULL || + mapi_error(mid)) + goto bailout; + ret = mapi_get_row_count(hdl) == 1; + while ((mapi_fetch_row(hdl)) != 0) { + if (mapi_error(mid)) + goto bailout; + } + if (mapi_error(mid)) + goto bailout; + mapi_close_handle(hdl); + answer = ret; + return ret; + +bailout: + if (hdl) { + if (mapi_result_error(hdl)) + mapi_explain_result(hdl, stderr); + else + mapi_explain_query(hdl, stderr); + mapi_close_handle(hdl); + } else + mapi_explain(mid, stderr); + return false; +} + static int dump_foreign_keys(Mapi mid, const char *schema, const char *tname, const char *tid, stream *sqlf) { @@ -795,9 +834,12 @@ toUpper(const char *s) size_t len = strlen(s); if (len >= sizeof(toupperbuf)) - return s; /* too long: it's not *that* important */ - for (i = 0; i < len; i++) - toupperbuf[i] = toupper((int)s[i]); + return NULL; /* too long */ + for (i = 0; i < len; i++) { + if (s[i] & 0x80 || isupper(s[i])) + return NULL; /* not all ASCII lower case */ + toupperbuf[i] = toupper(((unsigned char *) s)[i]); + } toupperbuf[i] = '\0'; return toupperbuf; } @@ -824,7 +866,7 @@ static const char *geomsubtypes[] = { }; static int -dump_type(Mapi mid, stream *sqlf, const char *c_type, const char *c_type_digits, const char *c_type_scale, bool hashge) +dump_type(Mapi mid, stream *sqlf, const char *c_type, const char *c_type_digits, const char *c_type_scale, int c_multiset, bool hashge) { int space = 0; @@ -939,21 +981,29 @@ dump_type(Mapi mid, stream *sqlf, const } else { mnstr_printf(sqlf, "GEOMETRY"); } - } else if (strcmp(c_type_digits, "0") == 0) { - space = mnstr_printf(sqlf, "%s", toUpper(c_type)); - } else if (strcmp(c_type_scale, "0") == 0) { - space = mnstr_printf(sqlf, "%s(%s)", - toUpper(c_type), c_type_digits); } else { - if (strcmp(c_type, "decimal") == 0) { - if (strcmp(c_type_digits, "39") == 0) - c_type_digits = "38"; - else if (!hashge && strcmp(c_type_digits, "19") == 0) - c_type_digits = "18"; + const char *s = toUpper(c_type); + if (s) + space = mnstr_printf(sqlf, "%s", s); + else + space = dquoted_print(sqlf, c_type, NULL); + if (strcmp(c_type_digits, "0") != 0) { + if (strcmp(c_type_scale, "0") == 0) { + space += mnstr_printf(sqlf, "(%s)", c_type_digits); + } else { + if (strcmp(c_type, "decimal") == 0) { + if (strcmp(c_type_digits, "39") == 0) + c_type_digits = "38"; + else if (!hashge && strcmp(c_type_digits, "19") == 0) + c_type_digits = "18"; + } + space += mnstr_printf(sqlf, "(%s,%s)", + c_type_digits, c_type_scale); + } } - space = mnstr_printf(sqlf, "%s(%s,%s)", - toUpper(c_type), c_type_digits, c_type_scale); } + if (c_multiset == 2) + space += mnstr_printf(sqlf, "[]"); return space; } @@ -997,10 +1047,15 @@ dump_column_definition(Mapi mid, stream "c.type_digits, " /* 2 */ "c.type_scale, " /* 3 */ "c.\"null\", " /* 4 */ - "c.number " /* 5 */ + "%s," /* 5 */ + "c.number " /* 6 */ "FROM sys._columns c " "WHERE c.table_id = %s " - "ORDER BY c.number", tid); + "%s" + "ORDER BY c.number", + has_multiset(mid) ? "c.multiset" : "cast(0 as tinyint)", + tid, + has_multiset(mid) ? "AND c.column_type = 0 " : ""); else snprintf(query, maxquerylen, "SELECT c.name, " /* 0 */ @@ -1008,7 +1063,8 @@ dump_column_definition(Mapi mid, stream "c.type_digits, " /* 2 */ "c.type_scale, " /* 3 */ "c.\"null\", " /* 4 */ - "c.number " /* 5 */ + "%s," /* 5 */ + "c.number " /* 6 */ "FROM sys._columns c, " "sys._tables t, " "sys.schemas s " @@ -1016,7 +1072,11 @@ dump_column_definition(Mapi mid, stream "AND t.name = '%s' " "AND t.schema_id = s.id " "AND s.name = '%s' " - "ORDER BY c.number", t, s); + "%s" + "ORDER BY c.number", + has_multiset(mid) ? "c.multiset" : "cast(0 as tinyint)", + t, s, + has_multiset(mid) ? "AND c.column_type = 0 " : ""); if ((hdl = mapi_query(mid, query)) == NULL || mapi_error(mid)) goto bailout; @@ -1028,6 +1088,7 @@ dump_column_definition(Mapi mid, stream char *c_type_digits = strdup(mapi_fetch_field(hdl, 2)); char *c_type_scale = strdup(mapi_fetch_field(hdl, 3)); const char *c_null = mapi_fetch_field(hdl, 4); + int c_multiset = atoi(mapi_fetch_field(hdl, 5)); int space; if (mapi_error(mid) || !c_type || !c_type_digits || !c_type_scale) { @@ -1071,7 +1132,7 @@ dump_column_definition(Mapi mid, stream if (c_type_digits == NULL) goto bailout; } - space = dump_type(mid, sqlf, c_type, c_type_digits, c_type_scale, hashge); + space = dump_type(mid, sqlf, c_type, c_type_digits, c_type_scale, c_multiset, hashge); if (strcmp(c_null, "false") == 0) { mnstr_printf(sqlf, "%*s NOT NULL", CAP(13 - space), ""); @@ -2032,6 +2093,7 @@ dump_table_storage(Mapi mid, const char snprintf(query, maxquerylen, "SELECT name, storage FROM sys._columns " "WHERE storage IS NOT NULL " + "AND storage NOT LIKE '!%%ms!_%%' ESCAPE '!' " "AND table_id = (SELECT id FROM sys._tables WHERE name = '%s' " "AND schema_id = (SELECT id FROM sys.schemas WHERE name = '%s'))", t, s); @@ -2406,10 +2468,12 @@ dump_function(Mapi mid, stream *sqlf, co ffunc = strdup(ffunc); query_len = snprintf(query, query_size, "SELECT a.name, a.type, a.type_digits, " - "a.type_scale, a.inout " + "a.type_scale, a.inout, %s " "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); + "ORDER BY a.inout DESC, a.number", + has_multiset(mid) ? "a.multiset" : "cast(0 as tinyint)", + fid); assert(query_len < (int) query_size); if (!ffunc || query_len < 0 || query_len >= (int) query_size) { free(ffunc); @@ -2445,6 +2509,7 @@ dump_function(Mapi mid, stream *sqlf, co char *adigs = mapi_fetch_field(hdl, 2); char *ascal = mapi_fetch_field(hdl, 3); const char *ainou = mapi_fetch_field(hdl, 4); + int multiset = atoi(mapi_fetch_field(hdl, 5)); if (strcmp(ainou, "0") == 0) { /* end of arguments */ @@ -2471,7 +2536,7 @@ dump_function(Mapi mid, stream *sqlf, co mnstr_printf(sqlf, "%s", sep); dquoted_print(sqlf, aname, " "); - dump_type(mid, sqlf, atype, adigs, ascal, hashge); + dump_type(mid, sqlf, atype, adigs, ascal, multiset, hashge); sep = ", "; free(atype); @@ -2487,6 +2552,7 @@ dump_function(Mapi mid, stream *sqlf, co char *atype = strdup(mapi_fetch_field(hdl, 1)); char *adigs = strdup(mapi_fetch_field(hdl, 2)); char *ascal = strdup(mapi_fetch_field(hdl, 3)); + int multiset = atoi(mapi_fetch_field(hdl, 5)); if (atype == NULL || adigs == NULL || ascal == NULL) { free(atype); @@ -2509,7 +2575,7 @@ dump_function(Mapi mid, stream *sqlf, co dquoted_print(sqlf, aname, " "); sep = ", "; } - dump_type(mid, sqlf, atype, adigs, ascal, hashge); + dump_type(mid, sqlf, atype, adigs, ascal, multiset, hashge); free(atype); free(adigs); @@ -2545,6 +2611,7 @@ dump_function(Mapi mid, stream *sqlf, co char *adigs = strdup(mapi_fetch_field(hdl, 2)); char *ascal = strdup(mapi_fetch_field(hdl, 3)); const char *ainou = mapi_fetch_field(hdl, 4); + int multiset = atoi(mapi_fetch_field(hdl, 5)); if (!atype || !adigs || !ascal) { free(atype); @@ -2562,7 +2629,7 @@ dump_function(Mapi mid, stream *sqlf, co break; } mnstr_printf(sqlf, "%s", sep); - dump_type(mid, sqlf, atype, adigs, ascal, hashge); + dump_type(mid, sqlf, atype, adigs, ascal, multiset, hashge); sep = ", "; free(atype); @@ -2715,10 +2782,35 @@ dump_database(Mapi mid, stream *sqlf, co { const char start_trx[] = "START TRANSACTION"; const char end[] = "ROLLBACK"; - const char types[] = + const char *types = + has_multiset(mid) ? "SELECT s.name, " "t.systemname, " - "t.sqlname " + "t.sqlname, " + "a.name, " + "a.type, " + "a.type_digits, " + "a.type_scale, " + "a.number, " + "a.multiset " + "FROM sys.types t " + "LEFT JOIN sys.schemas s ON s.id = t.schema_id " + "LEFT OUTER JOIN sys.args a ON t.id = a.func_id " + "WHERE t.eclass = 18 " + "AND (t.schema_id <> 2000 " + "OR (t.schema_id = 2000 " + "AND t.sqlname NOT IN ('geometrya','mbr','url','inet','json','uuid'))) " + "ORDER BY t.id, a.number" + : + "SELECT s.name, " + "t.systemname, " + "t.sqlname, " + "CAST(NULL AS VARCHAR(256)), " + "CAST(NULL AS VARCHAR(1024)), " + "CAST(NULL AS INTEGER), " + "CAST(NULL AS INTEGER), " + "CAST(NULL AS INTEGER), " + "CAST(0 AS TINYINT) " "FROM sys.types t LEFT JOIN sys.schemas s ON s.id = t.schema_id " "WHERE t.eclass = 18 " "AND (t.schema_id <> 2000 " @@ -2825,7 +2917,8 @@ dump_database(Mapi mid, stream *sqlf, co "AND p.privileges = pc.privilege_code_id " "AND p.grantable = go.id " "ORDER BY s.name, t.name, c.name, a.name, g.name, p.grantable"; - const char function_grants[] = + const char *function_grants = + has_multiset(mid) ? "SELECT f.id, " "s.name, " "f.name, " @@ -2834,6 +2927,45 @@ dump_database(Mapi mid, stream *sqlf, co "a.type_scale, " "a.inout, " "a.number, " _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org