Changeset: fea48a097a74 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fea48a097a74
Modified Files:
        clients/ChangeLog.Dec2011
        clients/odbc/driver/ODBCUtil.c
        clients/odbc/driver/ODBCUtil.h
        clients/odbc/driver/SQLColumnPrivileges.c
        clients/odbc/driver/SQLColumns.c
        clients/odbc/driver/SQLConnect.c
        clients/odbc/driver/SQLExecute.c
        clients/odbc/driver/SQLForeignKeys.c
        clients/odbc/driver/SQLGetInfo.c
        clients/odbc/driver/SQLPrepare.c
        clients/odbc/driver/SQLPrimaryKeys.c
        clients/odbc/driver/SQLProcedures.c
        clients/odbc/driver/SQLSetConnectAttr.c
        clients/odbc/driver/SQLSpecialColumns.c
        clients/odbc/driver/SQLStatistics.c
        clients/odbc/driver/SQLTablePrivileges.c
        clients/odbc/driver/SQLTables.c
Branch: Dec2011
Log Message:

ODBC: Implemented database name as catalog, fixed catalog functions.
The catalog functions (functions like SQLTables that return a result
set describing the database catalog) interpret their arguments that
are used for filtering the result in different ways depending on the
function and on the value of the SQL_ATTR_METADATA_ID attribute.  This
is now also implemented.
Also fixed SQLColumns and SQLSpecialColumns to return the proper
values for various column types.  SQLSpecialColumns was totally bogus,
and SQLColumns didn't recognize 'wrd'.
(One changeset because it is more work than it is worth to split this up.)


diffs (truncated from 2723 to 300 lines):

diff --git a/clients/ChangeLog.Dec2011 b/clients/ChangeLog.Dec2011
--- a/clients/ChangeLog.Dec2011
+++ b/clients/ChangeLog.Dec2011
@@ -1,6 +1,11 @@
 # ChangeLog file for clients
 # This file is updated with Maddlog
 
+* 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/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"
+              " \"p\".\"auth_id\" = \"a\".\"id\" and"
+              " \"t\".\"schema_id\" = \"s\".\"id\" and"
+              " \"t\".\"system\" = false and"
+              " \"p\".\"grantor\" = \"g\".\"id\" and"
+              " \"e\".\"name\" = 'gdk_dbname'");
+       assert(strlen(query) < 1100);
        query_end += strlen(query_end);
 
        /* Construct the selection condition query part */
-       if (stmt->Dbc->sql_attr_metadata_id == SQL_TRUE) {
-               /* treat arguments as identifiers */
-               /* remove trailing blanks */
-               while (NameLength2 > 0 &&
-                      isspace((int) SchemaName[NameLength2 - 1]))
-                       NameLength2--;
-               while (NameLength3 > 0 &&
-                      isspace((int) TableName[NameLength3 - 1]))
-                       NameLength3--;
-               while (NameLength4 > 0 &&
-                      isspace((int) ColumnName[NameLength4 - 1]))
-                       NameLength4--;
-               if (NameLength2 > 0) {
-                       sprintf(query_end, " and \"s\".\"name\" = '");
-                       query_end += strlen(query_end);
-                       while (NameLength2-- > 0)
-                               *query_end++ = tolower(*SchemaName++);
-                       *query_end++ = '\'';
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to