LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLExecute.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 166 258 64.3 %
Date: 2021-10-13 02:24:04 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * This code was created by Peter Harvey (mostly during Christmas 98/99).
      11             :  * This code is LGPL. Please ensure that this message remains in future
      12             :  * distributions and uses of this code (thats about all I get out of it).
      13             :  * - Peter Harvey pharvey@codebydesign.com
      14             :  *
      15             :  * This file has been modified for the MonetDB project.  See the file
      16             :  * Copyright in this directory for more information.
      17             :  */
      18             : 
      19             : /**********************************************************************
      20             :  * SQLExecute()
      21             :  * CLI Compliance: ISO 92
      22             :  *
      23             :  * Author: Martin van Dinther, Sjoerd Mullender
      24             :  * Date  : 30 Aug 2002
      25             :  *
      26             :  **********************************************************************/
      27             : 
      28             : #include "ODBCGlobal.h"
      29             : #include "ODBCStmt.h"
      30             : #include "ODBCUtil.h"
      31             : #include <limits.h>
      32             : 
      33             : static struct msql_types {
      34             :         char *name;
      35             :         int concise_type;
      36             : } msql_types[] = {
      37             :         {"bigint", SQL_BIGINT},
      38             :         {"blob", SQL_LONGVARBINARY},
      39             :         {"boolean", SQL_BIT},
      40             :         {"char", SQL_WCHAR},
      41             :         {"clob", SQL_WLONGVARCHAR},
      42             :         {"date", SQL_TYPE_DATE},
      43             :         {"day_interval", SQL_INTERVAL_SECOND},
      44             :         {"decimal", SQL_DECIMAL},
      45             :         {"double", SQL_DOUBLE},
      46             :         {"hugeint", SQL_HUGEINT},
      47             :         /* {"inet", SQL_WCHAR}, */
      48             :         {"int", SQL_INTEGER},
      49             :         /* {"json", SQL_WCHAR}, */
      50             :         {"month_interval", SQL_INTERVAL_MONTH},
      51             :         {"oid", SQL_BIGINT},
      52             :         {"real", SQL_REAL},
      53             :         {"sec_interval", SQL_INTERVAL_SECOND},
      54             :         {"smallint", SQL_SMALLINT},
      55             :         {"table", 0},
      56             :         {"time", SQL_TYPE_TIME},
      57             :         {"timetz", SQL_TYPE_TIME},
      58             :         {"timestamp", SQL_TYPE_TIMESTAMP},
      59             :         {"timestamptz", SQL_TYPE_TIMESTAMP},
      60             :         {"tinyint", SQL_TINYINT},
      61             :         /* {"url", SQL_WCHAR}, */
      62             :         {"uuid", SQL_GUID},
      63             :         {"varchar", SQL_WVARCHAR},
      64             :         {0, 0},                 /* sentinel */
      65             : };
      66             : 
      67             : int
      68          43 : ODBCConciseType(const char *name)
      69             : {
      70             :         struct msql_types *p;
      71             : 
      72         597 :         for (p = msql_types; p->name; p++)
      73         597 :                 if (strcmp(p->name, name) == 0)
      74          43 :                         return p->concise_type;
      75             :         return 0;
      76             : }
      77             : 
      78             : #ifdef ODBCDEBUG
      79             : static char *
      80           0 : translatequerytype(int querytype)
      81             : {
      82           0 :         switch (querytype) {
      83             :         case Q_PARSE:
      84             :                 return "Q_PARSE";
      85           0 :         case Q_TABLE:
      86           0 :                 return "Q_TABLE";
      87           0 :         case Q_UPDATE:
      88           0 :                 return "Q_UPDATE";
      89           0 :         case Q_SCHEMA:
      90           0 :                 return "Q_SCHEMA";
      91           0 :         case Q_TRANS:
      92           0 :                 return "Q_TRANS";
      93           0 :         case Q_PREPARE:
      94           0 :                 return "Q_PREPARE";
      95           0 :         case Q_BLOCK:
      96           0 :                 return "Q_BLOCK";
      97           0 :         default:
      98           0 :                 return "unknown";
      99             :         }
     100             : }
     101             : #endif
     102             : 
     103             : SQLRETURN
     104        2006 : ODBCInitResult(ODBCStmt *stmt)
     105             : {
     106             :         int i = 0;
     107             :         int nrCols;
     108             :         ODBCDescRec *rec;
     109             :         MapiHdl hdl;
     110             :         const char *errstr;
     111             : 
     112        2006 :         hdl = stmt->hdl;
     113             : 
     114             :         /* initialize the Result meta data values */
     115        2006 :         stmt->currentRow = 0;
     116        2006 :         stmt->startRow = 0;
     117        2006 :         stmt->rowSetSize = 0;
     118        2006 :         stmt->retrieved = 0;
     119        2006 :         stmt->currentCol = 0;
     120             : 
     121        2006 :       repeat:
     122        2006 :         errstr = mapi_result_error(hdl);
     123        2006 :         if (errstr) {
     124             :                 const char *sqlstate;
     125             : 
     126           0 :                 if ((sqlstate = mapi_result_errorcode(hdl)) != NULL)
     127           0 :                         addStmtError(stmt, sqlstate, errstr, 0);
     128             :                 else {
     129             :                         /* Syntax error or access violation */
     130           0 :                         addStmtError(stmt, "42000", errstr, 0);
     131             :                 }
     132           0 :                 return SQL_ERROR;
     133             :         }
     134        2006 :         nrCols = mapi_get_field_count(hdl);
     135        2006 :         stmt->querytype = mapi_get_querytype(hdl);
     136             : #if SIZEOF_SIZE_T == SIZEOF_INT
     137             :         if (mapi_rows_affected(hdl) >= (int64_t) 1 << (sizeof(int) * CHAR_BIT)) {
     138             :                 /* General error */
     139             :                 addStmtError(stmt, "HY000", "Too many rows to handle", 0);
     140             :                 return SQL_ERROR;
     141             :         }
     142             : #endif
     143        2006 :         stmt->rowcount = (SQLULEN) mapi_rows_affected(hdl);
     144             : 
     145             : #ifdef ODBCDEBUG
     146        2006 :         ODBCLOG("ODBCInitResult: querytype %s, rowcount %lu\n",
     147             :                 translatequerytype(stmt->querytype),
     148             :                 (unsigned long) stmt->rowcount);
     149             : #endif
     150             : 
     151        2006 :         switch (stmt->querytype) {
     152           3 :         case Q_TABLE:   /* Q_TABLE */
     153             :                 /* result set generating query */
     154           3 :                 assert(nrCols > 0);
     155           3 :                 stmt->State = EXECUTED1;
     156           3 :                 break;
     157        2000 :         case Q_UPDATE:          /* Q_UPDATE */
     158             :                 /* result count generating query */
     159        2000 :                 assert(nrCols == 0);
     160        2000 :                 stmt->State = EXECUTED0;
     161        2000 :                 break;
     162           3 :         default:
     163             :                 /* resultless query */
     164           3 :                 if (mapi_result_error(hdl) == NULL && mapi_next_result(hdl) == 1)
     165           0 :                         goto repeat;
     166           3 :                 stmt->State = EXECUTED0;
     167           3 :                 stmt->rowcount = 0;
     168             :                 nrCols = 0;
     169           3 :                 break;
     170             :         }
     171             : 
     172             : #if 0
     173             :         /* XXX is this correct? */
     174             :         assert(stmt->ImplRowDescr == NULL ||
     175             :                stmt->ImplRowDescr->sql_desc_count == nrCols ||
     176             :                stmt->ImplRowDescr->sql_desc_count == 0);
     177             : #endif
     178        2006 :         setODBCDescRecCount(stmt->ImplRowDescr, nrCols);
     179             : 
     180        2006 :         if (nrCols == 0)
     181             :                 return SQL_SUCCESS;
     182           3 :         if (stmt->ImplRowDescr->descRec == NULL) {
     183           0 :                 stmt->State = stmt->queryid >= 0 ? (stmt->State == EXECUTED0 ? PREPARED0 : PREPARED1) : INITED;
     184             : 
     185             :                 /* Memory allocation error */
     186           0 :                 addStmtError(stmt, "HY001", NULL, 0);
     187           0 :                 return SQL_ERROR;
     188             :         }
     189             : 
     190           3 :         rec = stmt->ImplRowDescr->descRec + 1;
     191             : 
     192          31 :         for (i = 0; i < nrCols; i++) {
     193             :                 struct sql_types *tp;
     194             :                 int concise_type;
     195             :                 char *s;
     196             : 
     197          28 :                 rec->sql_desc_auto_unique_value = SQL_FALSE;
     198          28 :                 rec->sql_desc_nullable = SQL_NULLABLE_UNKNOWN;
     199          28 :                 rec->sql_desc_rowver = SQL_FALSE;
     200          28 :                 rec->sql_desc_searchable = SQL_PRED_SEARCHABLE;
     201          28 :                 rec->sql_desc_updatable = SQL_ATTR_READONLY;
     202             : 
     203          28 :                 s = mapi_get_name(hdl, i);
     204             :                 /* HACK to compensate for generated column names */
     205          28 :                 if (s == NULL || strcmp(s, "single_value") == 0)
     206             :                         s = "";
     207          28 :                 if (*s) {
     208          28 :                         rec->sql_desc_unnamed = SQL_NAMED;
     209          28 :                         if (rec->sql_desc_label)
     210          10 :                                 free(rec->sql_desc_label);
     211          28 :                         rec->sql_desc_label = (SQLCHAR *) strdup(s);
     212          28 :                         if (rec->sql_desc_label == NULL)
     213           0 :                                 goto nomem;
     214          28 :                         if (rec->sql_desc_name)
     215          10 :                                 free(rec->sql_desc_name);
     216          28 :                         rec->sql_desc_name = (SQLCHAR *) strdup(s);
     217          28 :                         if (rec->sql_desc_name == NULL)
     218           0 :                                 goto nomem;
     219             :                 } else {
     220           0 :                         rec->sql_desc_unnamed = SQL_UNNAMED;
     221           0 :                         rec->sql_desc_label = NULL;
     222           0 :                         rec->sql_desc_name = NULL;
     223             :                 }
     224          28 :                 if (rec->sql_desc_base_column_name)
     225           0 :                         free(rec->sql_desc_base_column_name);
     226          28 :                 rec->sql_desc_base_column_name = NULL; /* see below */
     227             : 
     228          28 :                 s = mapi_get_type(hdl, i);
     229          28 :                 if (s == NULL)  /* shouldn't happen */
     230             :                         s = "";
     231          28 :                 if (!stmt->Dbc->allow_hugeint && strcmp(s, "hugeint") == 0)
     232             :                         s = "bigint";
     233          28 :                 if (rec->sql_desc_type_name)
     234          10 :                         free(rec->sql_desc_type_name);
     235          28 :                 rec->sql_desc_type_name = (SQLCHAR *) strdup(s);
     236          28 :                 if (rec->sql_desc_type_name == NULL)
     237           0 :                         goto nomem;
     238          28 :                 concise_type = ODBCConciseType(s);
     239          28 :                 if (concise_type == SQL_INTERVAL_MONTH) {
     240           0 :                         switch (mapi_get_digits(hdl, i)) {
     241             :                         case 1:
     242             :                                 concise_type = SQL_INTERVAL_YEAR;
     243             :                                 break;
     244             :                         case 2:
     245             :                                 concise_type = SQL_INTERVAL_YEAR_TO_MONTH;
     246             :                                 break;
     247             :                         case 3:
     248             :                                 concise_type = SQL_INTERVAL_MONTH;
     249             :                                 break;
     250             :                         default:
     251           0 :                                 assert(0);
     252             :                         }
     253          28 :                 } else if (concise_type == SQL_INTERVAL_SECOND) {
     254           0 :                         switch (mapi_get_digits(hdl, i)) {
     255             :                         case 4:
     256             :                                 concise_type = SQL_INTERVAL_DAY;
     257             :                                 break;
     258             :                         case 5:
     259             :                                 concise_type = SQL_INTERVAL_DAY_TO_HOUR;
     260             :                                 break;
     261             :                         case 6:
     262             :                                 concise_type = SQL_INTERVAL_DAY_TO_MINUTE;
     263             :                                 break;
     264             :                         case 7:
     265             :                                 concise_type = SQL_INTERVAL_DAY_TO_SECOND;
     266             :                                 break;
     267             :                         case 8:
     268             :                                 concise_type = SQL_INTERVAL_HOUR;
     269             :                                 break;
     270             :                         case 9:
     271             :                                 concise_type = SQL_INTERVAL_HOUR_TO_MINUTE;
     272             :                                 break;
     273             :                         case 10:
     274             :                                 concise_type = SQL_INTERVAL_HOUR_TO_SECOND;
     275             :                                 break;
     276             :                         case 11:
     277             :                                 concise_type = SQL_INTERVAL_MINUTE;
     278             :                                 break;
     279             :                         case 12:
     280             :                                 concise_type = SQL_INTERVAL_MINUTE_TO_SECOND;
     281             :                                 break;
     282             :                         case 13:
     283             :                                 concise_type = SQL_INTERVAL_SECOND;
     284             :                                 break;
     285             :                         default:
     286           0 :                                 assert(0);
     287             :                         }
     288             :                 }
     289         314 :                 for (tp = ODBC_sql_types; tp->concise_type; tp++)
     290         314 :                         if (concise_type == tp->concise_type)
     291             :                                 break;
     292          28 :                 rec->sql_desc_concise_type = tp->concise_type;
     293          28 :                 rec->sql_desc_type = tp->type;
     294          28 :                 rec->sql_desc_datetime_interval_code = tp->code;
     295          28 :                 switch (concise_type) {
     296           0 :                 case SQL_DECIMAL:
     297             :                 case SQL_NUMERIC:
     298           0 :                         rec->sql_desc_precision = mapi_get_digits(hdl, i);
     299           0 :                         rec->sql_desc_scale = mapi_get_scale(hdl, i);
     300           0 :                         break;
     301          28 :                 default:
     302          28 :                         if (tp->precision != UNAFFECTED)
     303           6 :                                 rec->sql_desc_precision = tp->precision;
     304          28 :                         if (tp->scale != UNAFFECTED)
     305           0 :                                 rec->sql_desc_scale = tp->scale;
     306             :                         break;
     307             :                 }
     308          28 :                 if (tp->datetime_interval_precision != UNAFFECTED)
     309           0 :                         rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision;
     310          28 :                 rec->sql_desc_fixed_prec_scale = tp->fixed;
     311          28 :                 rec->sql_desc_num_prec_radix = tp->radix;
     312          28 :                 rec->sql_desc_unsigned = tp->radix == 0 ? SQL_TRUE : SQL_FALSE;
     313             : 
     314          28 :                 if (rec->sql_desc_concise_type == SQL_CHAR ||
     315          28 :                     rec->sql_desc_concise_type == SQL_VARCHAR ||
     316          28 :                     rec->sql_desc_concise_type == SQL_LONGVARCHAR ||
     317          26 :                     rec->sql_desc_concise_type == SQL_WCHAR ||
     318          18 :                     rec->sql_desc_concise_type == SQL_WVARCHAR ||
     319             :                     rec->sql_desc_concise_type == SQL_WLONGVARCHAR)
     320          10 :                         rec->sql_desc_case_sensitive = SQL_TRUE;
     321             :                 else
     322          18 :                         rec->sql_desc_case_sensitive = SQL_FALSE;
     323             : 
     324          28 :                 s = mapi_get_table(hdl, i);
     325          28 :                 if (s) {
     326          28 :                         char *p = strchr(s, '.');
     327          28 :                         if (rec->sql_desc_table_name)
     328          10 :                                 free(rec->sql_desc_table_name);
     329          28 :                         if (p) {
     330          28 :                                 if (rec->sql_desc_schema_name)
     331           0 :                                         free(rec->sql_desc_schema_name);
     332          28 :                                 rec->sql_desc_schema_name = (SQLCHAR *) dupODBCstring((SQLCHAR *) s, p - s);
     333          28 :                                 if (rec->sql_desc_schema_name == NULL)
     334           0 :                                         goto nomem;
     335          28 :                                 rec->sql_desc_table_name = (SQLCHAR *) strdup(p + 1);
     336          28 :                                 if (rec->sql_desc_table_name == NULL)
     337           0 :                                         goto nomem;
     338          28 :                                 if (p != s) {
     339             :                                         /* base table name and base
     340             :                                          * column name exist if there
     341             :                                          * is a schema name */
     342          10 :                                         if (rec->sql_desc_base_table_name)
     343           0 :                                                 free(rec->sql_desc_base_table_name);
     344          10 :                                         rec->sql_desc_base_table_name = (SQLCHAR *) strdup(p + 1);
     345          10 :                                         if (rec->sql_desc_base_table_name == NULL)
     346           0 :                                                 goto nomem;
     347          10 :                                         if (rec->sql_desc_name) {
     348          10 :                                                 rec->sql_desc_base_column_name = (SQLCHAR *) strdup((char *) rec->sql_desc_name);
     349          10 :                                                 if (rec->sql_desc_base_column_name == NULL)
     350           0 :                                                         goto nomem;
     351             :                                         }
     352             :                                 }
     353             :                         } else {
     354           0 :                                 rec->sql_desc_table_name = (SQLCHAR *) strdup(s);
     355           0 :                                 if (rec->sql_desc_table_name == NULL)
     356           0 :                                         goto nomem;
     357             :                         }
     358             :                 }
     359             : 
     360          28 :                 if (rec->sql_desc_type != SQL_INTERVAL &&
     361          28 :                     (rec->sql_desc_length = mapi_get_digits(hdl, i)) == 0)
     362           2 :                         rec->sql_desc_length = mapi_get_len(hdl, i);
     363             : 
     364          28 :                 rec->sql_desc_local_type_name = NULL;
     365          28 :                 if (rec->sql_desc_catalog_name == NULL) {
     366          18 :                         if (stmt->Dbc->dbname) {
     367          18 :                                 rec->sql_desc_catalog_name = (SQLCHAR *) strdup(stmt->Dbc->dbname);
     368          18 :                                 if (rec->sql_desc_catalog_name == NULL)
     369           0 :                                         goto nomem;
     370             :                         } else
     371           0 :                                 rec->sql_desc_catalog_name = NULL;
     372             :                 }
     373          28 :                 rec->sql_desc_literal_prefix = NULL;
     374          28 :                 rec->sql_desc_literal_suffix = NULL;
     375             : 
     376             :                 /* unused fields */
     377          28 :                 rec->sql_desc_data_ptr = NULL;
     378          28 :                 rec->sql_desc_indicator_ptr = NULL;
     379          28 :                 rec->sql_desc_octet_length_ptr = NULL;
     380          28 :                 rec->sql_desc_parameter_type = 0;
     381             : 
     382             :                 /* this must come after other fields have been
     383             :                  * initialized */
     384          28 :                 rec->sql_desc_length = ODBCLength(rec, SQL_DESC_LENGTH);
     385          28 :                 rec->sql_desc_display_size = ODBCLength(rec, SQL_DESC_DISPLAY_SIZE);
     386          28 :                 rec->sql_desc_octet_length = ODBCLength(rec, SQL_DESC_OCTET_LENGTH);
     387          28 :                 if (rec->sql_desc_length == 0) {
     388           0 :                         rec->sql_desc_length = SQL_NO_TOTAL;
     389           0 :                         rec->sql_desc_display_size = SQL_NO_TOTAL;
     390           0 :                         rec->sql_desc_octet_length = SQL_NO_TOTAL;
     391             :                 }
     392             : 
     393          28 :                 rec++;
     394             :         }
     395             : 
     396           3 :         return stmt->Error ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
     397             : 
     398           0 :   nomem:
     399             :         /* Memory allocation error */
     400           0 :         addStmtError(stmt, "HY001", NULL, 0);
     401           0 :         return SQL_ERROR;
     402             : }
     403             : 
     404             : SQLRETURN
     405        2002 : MNDBExecute(ODBCStmt *stmt)
     406             : {
     407             :         MapiHdl hdl;
     408             :         MapiMsg msg;
     409             :         char *query;
     410             :         const char *errstr;
     411             :         char *sep;
     412             :         size_t querylen;
     413             :         size_t querypos;
     414             :         int i;
     415             :         ODBCDesc *desc;
     416             :         SQLLEN offset;
     417             : 
     418             :         /* check statement cursor state, query should be prepared */
     419        2002 :         if (stmt->State == INITED ||
     420        1999 :             (stmt->State >= EXECUTED0 && stmt->queryid < 0)) {
     421             :                 /* Function sequence error */
     422           0 :                 addStmtError(stmt, "HY010", NULL, 0);
     423           0 :                 return SQL_ERROR;
     424             :         }
     425        2002 :         if (stmt->State >= EXECUTED1 ||
     426        1999 :             (stmt->State == EXECUTED0 && mapi_more_results(stmt->hdl))) {
     427             :                 /* Invalid cursor state */
     428           0 :                 addStmtError(stmt, "24000", NULL, 0);
     429           0 :                 return SQL_ERROR;
     430             :         }
     431             : 
     432             :         /* internal state correctness checks */
     433        2002 :         assert(stmt->State == PREPARED0 || stmt->State == EXECUTED0 || stmt->ImplRowDescr->descRec != NULL);
     434             : 
     435        2002 :         assert(stmt->Dbc);
     436        2002 :         assert(stmt->Dbc->mid);
     437        2002 :         hdl = stmt->hdl;
     438             : 
     439        2002 :         assert(hdl);
     440             : 
     441        2002 :         desc = stmt->ApplParamDescr;
     442             : 
     443        2002 :         if (desc->sql_desc_count < stmt->nparams ||
     444        2002 :             stmt->ImplParamDescr->sql_desc_count < stmt->nparams) {
     445             :                 /* COUNT field incorrect */
     446           0 :                 addStmtError(stmt, "07002", NULL, 0);
     447           0 :                 return SQL_ERROR;
     448             :         }
     449             : 
     450        2002 :         querylen = 1024;
     451        2002 :         query = malloc(querylen); /* XXX allocate space for parameters */
     452        2002 :         if (query == NULL) {
     453             :                 /* Memory allocation error */
     454           0 :                 addStmtError(stmt, "HY001", NULL, 0);
     455           0 :                 return SQL_ERROR;
     456             :         }
     457        2002 :         if (stmt->qtimeout != stmt->Dbc->qtimeout) {
     458           0 :                 snprintf(query, querylen, "call sys.settimeout(%" PRIu64 ")",
     459             :                          (uint64_t) stmt->qtimeout);
     460           0 :                 if (mapi_query_handle(hdl, query) == MOK)
     461           0 :                         stmt->Dbc->qtimeout = stmt->qtimeout;
     462             :         }
     463        2002 :         querypos = snprintf(query, querylen, "execute %d (", stmt->queryid);
     464             :         /* XXX fill in parameter values */
     465        2002 :         if (desc->sql_desc_bind_offset_ptr)
     466           0 :                 offset = *desc->sql_desc_bind_offset_ptr;
     467             :         else
     468             :                 offset = 0;
     469             :         sep = "";
     470       12002 :         for (i = 1; i <= stmt->nparams; i++) {
     471       10000 :                 if (ODBCStore(stmt, i, offset, 0, &query, &querypos, &querylen, sep) == SQL_ERROR) {
     472           0 :                         if (query)
     473           0 :                                 free(query);
     474           0 :                         return SQL_ERROR;
     475             :                 }
     476             :                 sep = ",";
     477             :         }
     478        2002 :         if (querypos + 1 >= querylen) {
     479           0 :                 char *q = realloc(query, querylen += 10);
     480           0 :                 if (q == NULL) {
     481           0 :                         free(query);
     482           0 :                         addStmtError(stmt, "HY001", NULL, 0);
     483           0 :                         return SQL_ERROR;
     484             :                 }
     485           0 :                 query = q;
     486             :         }
     487        2002 :         query[querypos++] = ')';
     488        2002 :         query[querypos] = 0;
     489             : 
     490             : #ifdef ODBCDEBUG
     491        2002 :         ODBCLOG("SQLExecute %p %s\n", stmt, query);
     492             : #endif
     493             : 
     494             :         /* Have the server execute the query */
     495        2002 :         if (stmt->next == NULL && stmt->Dbc->FirstStmt == stmt &&
     496        2001 :             stmt->cursorType == SQL_CURSOR_FORWARD_ONLY) {
     497             :                 /* we're the only Stmt handle, and we're only going forward */
     498        2001 :                 if (stmt->Dbc->cachelimit != 10000)
     499        2000 :                         mapi_cache_limit(stmt->Dbc->mid, 10000);
     500        2001 :                 stmt->Dbc->cachelimit = 1000;
     501             :         } else {
     502           1 :                 if (stmt->Dbc->cachelimit != 100)
     503           1 :                         mapi_cache_limit(stmt->Dbc->mid, 100);
     504           1 :                 stmt->Dbc->cachelimit = 100;
     505             :         }
     506        2002 :         msg = mapi_query_handle(hdl, query);
     507        2002 :         free(query);
     508        2002 :         switch (msg) {
     509             :         case MOK:
     510             :                 break;
     511           0 :         case MTIMEOUT:
     512             :                 /* Timeout expired / Communication link failure */
     513           0 :                 addStmtError(stmt, stmt->Dbc->sql_attr_connection_timeout ? "HYT00" : "08S01", mapi_error_str(stmt->Dbc->mid), 0);
     514           0 :                 return SQL_ERROR;
     515           0 :         default:
     516           0 :                 errstr = mapi_result_error(hdl);
     517           0 :                 if (errstr == NULL)
     518           0 :                         errstr = mapi_error_str(stmt->Dbc->mid);
     519           0 :                 if (errstr) {
     520             :                         const char *sqlstate;
     521             : 
     522           0 :                         if ((sqlstate = mapi_result_errorcode(hdl)) != NULL) {
     523           0 :                                 addStmtError(stmt, sqlstate, errstr, 0);
     524           0 :                                 return SQL_ERROR;
     525             :                         }
     526             :                 }
     527             :                 /* General error */
     528           0 :                 addStmtError(stmt, "HY000", errstr, 0);
     529           0 :                 return SQL_ERROR;
     530             :         }
     531             : 
     532             :         /* now get the result data and store it to our internal data structure */
     533             : 
     534        2002 :         return ODBCInitResult(stmt);
     535             : }
     536             : 
     537             : SQLRETURN SQL_API
     538             : SQLExecute(SQLHSTMT StatementHandle)
     539             : {
     540             : #ifdef ODBCDEBUG
     541        2002 :         ODBCLOG("SQLExecute %p\n", StatementHandle);
     542             : #endif
     543             : 
     544        2002 :         if (!isValidStmt((ODBCStmt *) StatementHandle))
     545             :                 return SQL_INVALID_HANDLE;
     546             : 
     547        2002 :         clearStmtErrors((ODBCStmt *) StatementHandle);
     548             : 
     549        2002 :         return MNDBExecute((ODBCStmt *) StatementHandle);
     550             : }

Generated by: LCOV version 1.14