Changeset: f562072706d4 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f562072706d4
Modified Files:
        
Branch: Dec2011
Log Message:

Merge heads.


diffs (truncated from 327 to 300 lines):

diff --git a/clients/ChangeLog.Dec2011 b/clients/ChangeLog.Dec2011
--- a/clients/ChangeLog.Dec2011
+++ b/clients/ChangeLog.Dec2011
@@ -1,6 +1,10 @@
 # ChangeLog file for clients
 # This file is updated with Maddlog
 
+* Tue Nov 15 2011 Sjoerd Mullender <[email protected]>
+- ODBC: Fixed SQLNumResultCols and SQLDescribeCol to return useful
+  information after a call to SQLPrepare and before any SQLExecute.
+
 * Wed Nov  9 2011 Sjoerd Mullender <[email protected]>
 - mclient: The exact interpretation of the -i (--interactive) option
   and the - filename argument have changed.  The - filename argument
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -197,6 +197,7 @@ static char *nullstring = default_nullst
 
 #if defined(_MSC_VER) && _MSC_VER >= 1400
 #define fileno _fileno
+#define isatty _isatty
 #endif
 
 static timertype
diff --git a/clients/odbc/driver/SQLExecute.c b/clients/odbc/driver/SQLExecute.c
--- a/clients/odbc/driver/SQLExecute.c
+++ b/clients/odbc/driver/SQLExecute.c
@@ -143,6 +143,7 @@ ODBCInitResult(ODBCStmt *stmt)
                break;
        }
 
+       assert(stmt->ImplRowDescr == NULL || stmt->ImplRowDescr->sql_desc_count 
== nrCols);
        setODBCDescRecCount(stmt->ImplRowDescr, nrCols);
 
        if (nrCols == 0)
@@ -174,18 +175,26 @@ ODBCInitResult(ODBCStmt *stmt)
                        s = "";
                if (*s) {
                        rec->sql_desc_unnamed = SQL_NAMED;
+                       if (rec->sql_desc_label)
+                               free(rec->sql_desc_label);
                        rec->sql_desc_label = (SQLCHAR *) strdup(s);
+                       if (rec->sql_desc_name)
+                               free(rec->sql_desc_name);
                        rec->sql_desc_name = (SQLCHAR *) strdup(s);
                } else {
                        rec->sql_desc_unnamed = SQL_UNNAMED;
                        rec->sql_desc_label = NULL;
                        rec->sql_desc_name = NULL;
                }
+               if (rec->sql_desc_base_column_name)
+                       free(rec->sql_desc_base_column_name);
                rec->sql_desc_base_column_name = NULL; /* see below */
 
                s = mapi_get_type(hdl, i);
                if (s == NULL)  /* shouldn't happen */
                        s = "";
+               if (rec->sql_desc_type_name)
+                       free(rec->sql_desc_type_name);
                rec->sql_desc_type_name = (SQLCHAR *) strdup(s);
                concise_type = ODBCConciseType(s);
                if (concise_type == SQL_INTERVAL_MONTH) {
@@ -264,13 +273,19 @@ ODBCInitResult(ODBCStmt *stmt)
                s = mapi_get_table(hdl, i);
                if (s) {
                        char *p = strchr(s, '.');
+                       if (rec->sql_desc_table_name)
+                               free(rec->sql_desc_table_name);
                        if (p) {
+                               if (rec->sql_desc_schema_name)
+                                       free(rec->sql_desc_schema_name);
                                rec->sql_desc_schema_name = (SQLCHAR *) 
dupODBCstring((SQLCHAR *) s, p - s);
                                rec->sql_desc_table_name = (SQLCHAR *) strdup(p 
+ 1);
                                if (p != s) {
                                        /* base table name and base
                                         * column name exist if there
                                         * is a schema name */
+                                       if (rec->sql_desc_base_table_name)
+                                               
free(rec->sql_desc_base_table_name);
                                        rec->sql_desc_base_table_name = 
(SQLCHAR *) strdup(p + 1);
                                        if (rec->sql_desc_name)
                                                rec->sql_desc_base_column_name 
= (SQLCHAR *) strdup((char *) rec->sql_desc_name);
@@ -285,7 +300,8 @@ ODBCInitResult(ODBCStmt *stmt)
                        rec->sql_desc_length = mapi_get_len(hdl, i);
 
                rec->sql_desc_local_type_name = NULL;
-               rec->sql_desc_catalog_name = stmt->Dbc->dbname ? (SQLCHAR *) 
strdup(stmt->Dbc->dbname) : NULL;
+               if (rec->sql_desc_catalog_name == NULL)
+                       rec->sql_desc_catalog_name = stmt->Dbc->dbname ? 
(SQLCHAR *) strdup(stmt->Dbc->dbname) : NULL;
                rec->sql_desc_literal_prefix = NULL;
                rec->sql_desc_literal_suffix = NULL;
 
@@ -326,19 +342,21 @@ SQLExecute_(ODBCStmt *stmt)
        SQLINTEGER offset;
 
        /* check statement cursor state, query should be prepared */
-       if (stmt->State == INITED || (stmt->State >= EXECUTED0 && stmt->queryid 
< 0)) {
+       if (stmt->State == INITED ||
+           (stmt->State >= EXECUTED0 && stmt->queryid < 0)) {
                /* Function sequence error */
                addStmtError(stmt, "HY010", NULL, 0);
                return SQL_ERROR;
        }
-       if (stmt->State >= EXECUTED1 || (stmt->State == EXECUTED0 && 
mapi_more_results(stmt->hdl))) {
+       if (stmt->State >= EXECUTED1 ||
+           (stmt->State == EXECUTED0 && mapi_more_results(stmt->hdl))) {
                /* Invalid cursor state */
                addStmtError(stmt, "24000", NULL, 0);
                return SQL_ERROR;
        }
 
        /* internal state correctness checks */
-       assert(stmt->ImplRowDescr->descRec == NULL);
+       assert(stmt->ImplRowDescr->descRec != NULL);
 
        assert(stmt->Dbc);
        assert(stmt->Dbc->mid);
diff --git a/clients/odbc/driver/SQLNumResultCols.c 
b/clients/odbc/driver/SQLNumResultCols.c
--- a/clients/odbc/driver/SQLNumResultCols.c
+++ b/clients/odbc/driver/SQLNumResultCols.c
@@ -69,16 +69,6 @@ SQLNumResultCols(SQLHSTMT StatementHandl
                return SQL_ERROR;
        }
 
-       /* When the query is only prepared (via SQLPrepare) we do not have
-        * the correct nrCols value yet (this is a limitation of the current
-        * MonetDB SQL frontend implementation). */
-       /* we only have a correct nrCols value when the query is executed */
-       if (stmt->State < EXECUTED0) {
-               /* General error */
-               addStmtError(stmt, "HY000", "Cannot return the number of output 
columns. Query must be executed first", 0);
-               return SQL_ERROR;
-       }
-
        /* We can now set the "number of output columns" value */
        /* Note: row count can be 0 (for non SELECT queries) */
        *ColumnCountPtr = stmt->ImplRowDescr->sql_desc_count;
diff --git a/clients/odbc/driver/SQLPrepare.c b/clients/odbc/driver/SQLPrepare.c
--- a/clients/odbc/driver/SQLPrepare.c
+++ b/clients/odbc/driver/SQLPrepare.c
@@ -60,7 +60,8 @@ SQLPrepare_(ODBCStmt *stmt,
        char *query, *s;
        MapiMsg ret;
        MapiHdl hdl;
-       int nrParams;
+       int nrows;
+       ODBCDescRec *prec, *rrec; /* param and row descriptors */
        ODBCDescRec *rec;
        int i;
 
@@ -90,8 +91,8 @@ SQLPrepare_(ODBCStmt *stmt,
 #ifdef ODBCDEBUG
        ODBCLOG("SQLPrepare: \"%s\"\n", query);
 #endif
-       s = malloc(strlen(query) + 9);
-       strcat(strcpy(s, "prepare "), query);
+       s = malloc(strlen(query) + 15);
+       strcat(strcpy(s, "prepareresult "), query);
        free(query);
 
        ODBCResetStmt(stmt);
@@ -118,15 +119,57 @@ SQLPrepare_(ODBCStmt *stmt,
                addStmtError(stmt, "HY001", 0, 0);
                return SQL_ERROR;
        }
-       nrParams = (int) mapi_rows_affected(hdl);
-       setODBCDescRecCount(stmt->ImplParamDescr, nrParams);
-       rec = stmt->ImplParamDescr->descRec + 1;
-       for (i = 0; i < nrParams; i++, rec++) {
+       nrows = (int) mapi_rows_affected(hdl);
+       /* these two will be adjusted later */
+       setODBCDescRecCount(stmt->ImplParamDescr, nrows);
+       setODBCDescRecCount(stmt->ImplRowDescr, nrows);
+       prec = stmt->ImplParamDescr->descRec + 1;
+       rrec = stmt->ImplRowDescr->descRec + 1;
+       stmt->nparams = 0;
+       for (i = 0; i < nrows; i++) {
                struct sql_types *tp;
                int concise_type;
                int length, scale;
 
                mapi_fetch_row(hdl);
+               s = mapi_fetch_field(hdl, 5); /* column name: null -> param */
+               if (s == NULL) {
+                       stmt->nparams++;
+                       rec = prec++;
+                       rec->sql_desc_nullable = SQL_NULLABLE;
+                       rec->sql_desc_searchable = SQL_UNSEARCHABLE;
+                       rec->sql_desc_unnamed = SQL_UNNAMED;
+                       rec->sql_desc_label = NULL;
+                       rec->sql_desc_name = NULL;
+                       rec->sql_desc_schema_name = NULL;
+                       rec->sql_desc_table_name = NULL;
+                       rec->sql_desc_base_table_name = NULL;
+                       rec->sql_desc_base_column_name = NULL;
+                       rec->sql_desc_parameter_type = SQL_PARAM_INPUT;
+               } else {
+                       rec = rrec++;
+                       rec->sql_desc_nullable = SQL_NULLABLE_UNKNOWN;
+                       rec->sql_desc_searchable = SQL_PRED_SEARCHABLE;
+                       rec->sql_desc_unnamed = SQL_NAMED;
+                       rec->sql_desc_label = (SQLCHAR *) strdup(s);
+                       rec->sql_desc_name = (SQLCHAR *) strdup(s);
+                       s = mapi_fetch_field(hdl, 3); /* schema name */
+                       rec->sql_desc_schema_name = s && *s ? (SQLCHAR *) 
strdup(s) : NULL;
+                       s = mapi_fetch_field(hdl, 4); /* table name */
+                       rec->sql_desc_table_name = s && *s ? (SQLCHAR *) 
strdup(s) : NULL;
+                       if (rec->sql_desc_schema_name) {
+                               /* base table name and base column
+                                * name exist if there is a schema
+                                * name */
+                               rec->sql_desc_base_table_name = (SQLCHAR *) 
strdup((char *) rec->sql_desc_table_name);
+                               rec->sql_desc_base_column_name = (SQLCHAR *) 
strdup((char *) rec->sql_desc_name);
+                       } else {
+                               rec->sql_desc_base_table_name = NULL;
+                               rec->sql_desc_base_column_name = NULL;
+                       }
+                       rec->sql_desc_parameter_type = 0;
+               }
+
                s = mapi_fetch_field(hdl, 0); /* type */
                rec->sql_desc_type_name = (SQLCHAR *) strdup(s);
                concise_type = ODBCConciseType(s);
@@ -138,7 +181,7 @@ SQLPrepare_(ODBCStmt *stmt,
                scale = atoi(s);
 
                /* for interval types, length and scale are used
-                  differently */
+                * differently */
                if (concise_type == SQL_INTERVAL_MONTH) {
                        switch (length) {
                        case 1:
@@ -219,27 +262,20 @@ SQLPrepare_(ODBCStmt *stmt,
                        rec->sql_desc_case_sensitive = SQL_FALSE;
 
                rec->sql_desc_local_type_name = NULL;
-               rec->sql_desc_nullable = SQL_NULLABLE;
-               rec->sql_desc_parameter_type = SQL_PARAM_INPUT;
                rec->sql_desc_rowver = SQL_FALSE;
-               rec->sql_desc_unnamed = SQL_UNNAMED;
                rec->sql_desc_catalog_name = stmt->Dbc->dbname ? (SQLCHAR *) 
strdup(stmt->Dbc->dbname) : NULL;
 
                /* unused fields */
-               rec->sql_desc_auto_unique_value = 0;
-               rec->sql_desc_base_column_name = NULL;
-               rec->sql_desc_base_table_name = NULL;
+               rec->sql_desc_auto_unique_value = SQL_FALSE;
                rec->sql_desc_data_ptr = NULL;
                rec->sql_desc_display_size = 0;
                rec->sql_desc_indicator_ptr = NULL;
-               rec->sql_desc_label = NULL;
                rec->sql_desc_literal_prefix = NULL;
                rec->sql_desc_literal_suffix = NULL;
                rec->sql_desc_octet_length_ptr = NULL;
                rec->sql_desc_schema_name = NULL;
-               rec->sql_desc_searchable = 0;
                rec->sql_desc_table_name = NULL;
-               rec->sql_desc_updatable = 0;
+               rec->sql_desc_updatable = SQL_ATTR_READONLY;
 
                /* this must come after other fields have been
                 * initialized */
@@ -253,10 +289,17 @@ SQLPrepare_(ODBCStmt *stmt,
                }
        }
 
+       assert(prec - stmt->ImplParamDescr->descRec == stmt->nparams + 1);
+       assert(rrec - stmt->ImplRowDescr->descRec == nrows - stmt->nparams + 1);
+       setODBCDescRecCount(stmt->ImplParamDescr, stmt->nparams);
+       setODBCDescRecCount(stmt->ImplRowDescr, nrows - stmt->nparams);
+
        /* update the internal state */
        stmt->queryid = mapi_get_tableid(hdl);
-       stmt->nparams = nrParams;
-       stmt->State = PREPARED1;        /* XXX or PREPARED0, depending on query 
*/
+       if (stmt->ImplRowDescr->sql_desc_count == 0)
+               stmt->State = PREPARED0; /* no columns: no result set */
+       else
+               stmt->State = PREPARED1;
 
        return SQL_SUCCESS;
 }
diff --git a/sql/backends/monet5/sql_result.mx 
b/sql/backends/monet5/sql_result.mx
--- a/sql/backends/monet5/sql_result.mx
+++ b/sql/backends/monet5/sql_result.mx
@@ -706,16 +706,16 @@ mvc_export_prepare(mvc *c, stream *out, 
                                len3++;
                                max3 *= 10;
                        }
+                       name = e->rname;
+                       if (!name && e->type == e_column && e->l)
+                               name = e->l;
+                       slen = strlen(name);
+                       if (slen > len5)
+                               len5 = slen;
                        name = e->name;
                        if (!name && e->type == e_column && e->r)
                                name = e->r;
                        slen = strlen(name);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to