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
