Changeset: de3e25f4be59 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=de3e25f4be59 Modified Files: geom/monetdb5/geom.mx monetdb5/mal/mal_interpreter.c monetdb5/modules/kernel/calc.c.mx monetdb5/modules/kernel/calc.h.mx monetdb5/modules/kernel/calc.mal.mx monetdb5/optimizer/opt_mitosis.c sql/backends/monet5/sql.mx sql/backends/monet5/sql_gencode.c Branch: headless Log Message:
Merge with default branch. diffs (truncated from 4391 to 300 lines): diff --git a/clients/ChangeLog.Dec2011 b/clients/ChangeLog.Dec2011 --- a/clients/ChangeLog.Dec2011 +++ b/clients/ChangeLog.Dec2011 @@ -1,6 +1,17 @@ # ChangeLog file for clients # This file is updated with Maddlog +* Wed Nov 2 2011 Sjoerd Mullender <[email protected]> +- ODBC: Improved internal query for SQLSpecialColumns. Before, the query + returned all columns taking part in a PRIMARY KEY *and* all columns + taking part in a UNIQUE constraint. Now it returns only one or the + other set. + +* Fri Oct 28 2011 Sjoerd Mullender <[email protected]> +- ODBC: The database name is now used as the catalog name throughout. + Functions that return a catalog name return the database name, and + functions that match on catalog name match it with the database name. + * Mon Oct 24 2011 Sjoerd Mullender <[email protected]> - ODBC: Implemented an easier way to create a log file of interactions with the ODBC driver. You can now add a connection attribute diff --git a/clients/mapiclient/stethoscope.c b/clients/mapiclient/stethoscope.c --- a/clients/mapiclient/stethoscope.c +++ b/clients/mapiclient/stethoscope.c @@ -391,14 +391,9 @@ main(int argc, char **argv) portnr = atol(optarg); break; case 'h': - if (strcmp(long_options[option_index].name, "help") == 0) { - usage(); - break; - } - if (strcmp(long_options[option_index].name, "host") == 0) { - host = optarg; - break; - } + host = optarg; + break; + case '?': default: usage(); exit(0); diff --git a/clients/odbc/driver/ODBCUtil.c b/clients/odbc/driver/ODBCUtil.c --- a/clients/odbc/driver/ODBCUtil.c +++ b/clients/odbc/driver/ODBCUtil.c @@ -371,6 +371,98 @@ ODBCTranslateSQL(const SQLCHAR *query, s return nquery; } +char * +ODBCParseOA(const char *tab, const char *col, const char *arg, size_t len) +{ + size_t i; + char *res; + const char *s; + + /* count length, counting ' and \ double */ + for (i = 0, s = arg; s < arg + len; i++, s++) { + if (*s == '\'' || *s == '\\') + i++; + } + i += strlen(tab) + strlen(col) + 10; /* ""."" = '' */ + res = malloc(i + 1); + snprintf(res, i, "\"%s\".\"%s\" = '", tab, col); + for (i = strlen(res), s = arg; s < arg + len; s++) { + if (*s == '\'' || *s == '\\') + res[i++] = *s; + res[i++] = *s; + } + res[i++] = '\''; + res[i] = 0; + return res; +} + +char * +ODBCParsePV(const char *tab, const char *col, const char *arg, size_t len) +{ + size_t i; + char *res; + const char *s; + + /* count length, counting ' and \ double */ + for (i = 0, s = arg; s < arg + len; i++, s++) { + if (*s == '\'' || *s == '\\') + i++; + } + i += strlen(tab) + strlen(col) + 25; /* ""."" like '' escape '\\' */ + res = malloc(i + 1); + snprintf(res, i, "\"%s\".\"%s\" like '", tab, col); + for (i = strlen(res), s = arg; s < arg + len; s++) { + if (*s == '\'' || *s == '\\') + res[i++] = *s; + res[i++] = *s; + } + for (s = "' escape '\\\\'"; *s; s++) + res[i++] = *s; + res[i] = 0; + return res; +} + +char * +ODBCParseID(const char *tab, const char *col, const char *arg, size_t len) +{ + size_t i; + char *res; + const char *s; + int fold = 1; + + while (len > 0 && (arg[--len] == ' ' || arg[len] == '\t')) + ; + len++; + if (len >= 2 && *arg == '"' && arg[len - 1] == '"') { + arg++; + len -= 2; + fold = 0; + } + + for (i = 0, s = arg; s < arg + len; i++, s++) { + if (*s == '\'' || *s == '\\') + i++; + } + i += strlen(tab) + strlen(col) + 10; /* ""."" = '' */ + if (fold) + i += 14; /* 2 times upper() */ + res = malloc(i + 1); + if (fold) + snprintf(res, i, "upper(\"%s\".\"%s\") = upper('", tab, col); + else + snprintf(res, i, "\"%s\".\"%s\" = '", tab, col); + for (i = strlen(res); len != 0; len--, arg++) { + if (*arg == '\'' || *arg == '\\') + res[i++] = *arg; + res[i++] = *arg; + } + res[i++] = '\''; + if (fold) + res[i++] = ')'; + res[i] = 0; + return res; +} + struct sql_types ODBC_sql_types[] = { {SQL_CHAR, SQL_CHAR, 0, 0, UNAFFECTED, 1, UNAFFECTED, 0, SQL_FALSE}, {SQL_VARCHAR, SQL_VARCHAR, 0, 0, UNAFFECTED, 1, UNAFFECTED, 0, SQL_FALSE}, diff --git a/clients/odbc/driver/ODBCUtil.h b/clients/odbc/driver/ODBCUtil.h --- a/clients/odbc/driver/ODBCUtil.h +++ b/clients/odbc/driver/ODBCUtil.h @@ -144,6 +144,10 @@ extern char *ODBCutf82wchar(const SQLCHA } while (0) #endif /* WITH_WCHAR */ +char *ODBCParseOA(const char *tab, const char *col, const char *arg, size_t len); +char *ODBCParsePV(const char *tab, const char *col, const char *arg, size_t len); +char *ODBCParseID(const char *tab, const char *col, const char *arg, size_t len); + /* SQL_DESC_CONCISE_TYPE, SQL_DESC_DATETIME_INTERVAL_CODE, and * SQL_DESC_TYPE are interdependent and setting one affects the other. * Also, setting them affect other fields. This is all encoded in diff --git a/clients/odbc/driver/SQLColumnPrivileges.c b/clients/odbc/driver/SQLColumnPrivileges.c --- a/clients/odbc/driver/SQLColumnPrivileges.c +++ b/clients/odbc/driver/SQLColumnPrivileges.c @@ -54,6 +54,7 @@ SQLColumnPrivileges_(ODBCStmt *stmt, RETCODE rc; char *query = NULL; char *query_end = NULL; + char *cat = NULL, *sch = NULL, *tab = NULL, *col = NULL; fixODBCstring(CatalogName, NameLength1, SQLSMALLINT , addStmtError, stmt, return SQL_ERROR); @@ -72,8 +73,54 @@ SQLColumnPrivileges_(ODBCStmt *stmt, (int) NameLength4, (char *) ColumnName); #endif + if (stmt->Dbc->sql_attr_metadata_id == SQL_FALSE) { + if (NameLength1 > 0) { + cat = ODBCParseOA("e", "value", + (const char *) CatalogName, + (size_t) NameLength1); + } + if (NameLength2 > 0) { + sch = ODBCParseOA("s", "name", + (const char *) SchemaName, + (size_t) NameLength2); + } + if (NameLength3 > 0) { + tab = ODBCParseOA("t", "name", + (const char *) TableName, + (size_t) NameLength3); + } + if (NameLength4 > 0) { + col = ODBCParsePV("c", "name", + (const char *) ColumnName, + (size_t) NameLength4); + } + } else { + if (NameLength1 > 0) { + cat = ODBCParseID("e", "value", + (const char *) CatalogName, + (size_t) NameLength1); + } + if (NameLength2 > 0) { + sch = ODBCParseID("s", "name", + (const char *) SchemaName, + (size_t) NameLength2); + } + if (NameLength3 > 0) { + tab = ODBCParseID("t", "name", + (const char *) TableName, + (size_t) NameLength3); + } + if (NameLength4 > 0) { + col = ODBCParseID("c", "name", + (const char *) ColumnName, + (size_t) NameLength4); + } + } + /* construct the query now */ - query = malloc(1200 + NameLength2 + NameLength3 + NameLength4); + query = malloc(1200 + (cat ? strlen(cat) : 0) + + (sch ? strlen(sch) : 0) + (tab ? strlen(tab) : 0) + + (col ? strlen(col) : 0)); query_end = query; /* SQLColumnPrivileges returns a table with the following columns: @@ -87,139 +134,78 @@ SQLColumnPrivileges_(ODBCStmt *stmt, is_grantable VARCHAR */ - sprintf(query_end, - "select cast(null as varchar(128)) as \"table_cat\"," - " \"s\".\"name\" as \"table_schem\"," - " \"t\".\"name\" as \"table_name\"," - " \"c\".\"name\" as \"column_name\"," - " case \"a\".\"id\"" - " when \"s\".\"owner\" then '_SYSTEM'" - " else \"g\".\"name\"" - " end as \"grantor\"," - " case \"a\".\"name\"" - " when 'public' then 'PUBLIC'" - " else \"a\".\"name\"" - " end as \"grantee\"," - " case \"p\".\"privileges\"" - " when 1 then 'SELECT'" - " when 2 then 'UPDATE'" - " when 4 then 'INSERT'" - " when 8 then 'DELETE'" - " when 16 then 'EXECUTE'" - " when 32 then 'GRANT'" - " end as \"privilege\"," - " case \"p\".\"grantable\"" - " when 1 then 'YES'" - " when 0 then 'NO'" - " end as \"is_grantable\" " - "from \"sys\".\"schemas\" \"s\"," - " \"sys\".\"_tables\" \"t\"," - " \"sys\".\"_columns\" \"c\"," - " \"sys\".\"auths\" \"a\"," - " \"sys\".\"privileges\" \"p\"," - " \"sys\".\"auths\" \"g\" " - "where \"p\".\"obj_id\" = \"c\".\"id\" and" - " \"c\".\"table_id\" = \"t\".\"id\" and" - " \"p\".\"auth_id\" = \"a\".\"id\" and" - " \"t\".\"schema_id\" = \"s\".\"id\" and" - " \"t\".\"system\" = false and" - " \"p\".\"grantor\" = \"g\".\"id\""); + strcpy(query_end, + "select \"e\".\"value\" as \"table_cat\"," + " \"s\".\"name\" as \"table_schem\"," + " \"t\".\"name\" as \"table_name\"," + " \"c\".\"name\" as \"column_name\"," + " case \"a\".\"id\"" + " when \"s\".\"owner\" then '_SYSTEM'" + " else \"g\".\"name\"" + " end as \"grantor\"," + " case \"a\".\"name\"" + " when 'public' then 'PUBLIC'" + " else \"a\".\"name\"" + " end as \"grantee\"," + " case \"p\".\"privileges\"" + " when 1 then 'SELECT'" + " when 2 then 'UPDATE'" + " when 4 then 'INSERT'" + " when 8 then 'DELETE'" + " when 16 then 'EXECUTE'" + " when 32 then 'GRANT'" + " end as \"privilege\"," + " case \"p\".\"grantable\"" + " when 1 then 'YES'" + " when 0 then 'NO'" + " end as \"is_grantable\" " + "from \"sys\".\"schemas\" \"s\"," + " \"sys\".\"_tables\" \"t\"," + " \"sys\".\"_columns\" \"c\"," + " \"sys\".\"auths\" \"a\"," + " \"sys\".\"privileges\" \"p\"," + " \"sys\".\"auths\" \"g\"," + " \"sys\".\"env\"() \"e\" " + "where \"p\".\"obj_id\" = \"c\".\"id\" and" + " \"c\".\"table_id\" = \"t\".\"id\" and" _______________________________________________ Checkin-list mailing list [email protected] http://mail.monetdb.org/mailman/listinfo/checkin-list
