LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLExecDirect.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 57 81 70.4 %
Date: 2024-10-04 20:04:04 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * This code was created by Peter Harvey (mostly during Christmas 98/99).
      15             :  * This code is LGPL. Please ensure that this message remains in future
      16             :  * distributions and uses of this code (that's about all I get out of it).
      17             :  * - Peter Harvey pharvey@codebydesign.com
      18             :  *
      19             :  * This file has been modified for the MonetDB project.  See the file
      20             :  * Copyright in this directory for more information.
      21             :  */
      22             : 
      23             : /**********************************************************************
      24             :  * SQLExecDirect()
      25             :  * CLI Compliance: ISO 92
      26             :  *
      27             :  * Author: Martin van Dinther, Sjoerd Mullender
      28             :  * Date  : 30 Aug 2002
      29             :  *
      30             :  **********************************************************************/
      31             : 
      32             : #include "ODBCGlobal.h"
      33             : #include "ODBCStmt.h"
      34             : #include "ODBCUtil.h"
      35             : 
      36             : static SQLRETURN
      37         108 : ODBCExecDirect(ODBCStmt *stmt, const SQLCHAR *StatementText, SQLINTEGER TextLength)
      38             : {
      39         108 :         char *query;
      40         108 :         const char *err;
      41         108 :         MapiMsg ret;
      42         108 :         MapiHdl hdl;
      43         108 :         long timeout;
      44             : 
      45         108 :         hdl = stmt->hdl;
      46             : 
      47         108 :         if (stmt->State >= EXECUTED1 ||
      48           8 :             (stmt->State == EXECUTED0 && mapi_more_results(hdl))) {
      49             :                 /* Invalid cursor state */
      50           0 :                 addStmtError(stmt, "24000", NULL, 0);
      51           0 :                 return SQL_ERROR;
      52             :         }
      53             : 
      54         108 :         if (stmt->qtimeout != stmt->Dbc->qtimeout) {
      55           0 :                 char buf[48];
      56           0 :                 snprintf(buf, sizeof(buf), "call sys.%s(%" PRIu64 ")",
      57           0 :                          (stmt->Dbc->major == 11 && stmt->Dbc->minor >= 37)
      58             :                          ? "setquerytimeout" : "settimeout",
      59             :                          (uint64_t) stmt->qtimeout);
      60           0 :                 if (mapi_query_handle(hdl, buf) == MOK)
      61           0 :                         stmt->Dbc->qtimeout = stmt->qtimeout;
      62             :         }
      63             : 
      64         108 :         query = ODBCTranslateSQL(stmt->Dbc, StatementText, (size_t) TextLength,
      65             :                                  stmt->noScan);
      66         108 :         if (query == NULL) {
      67             :                 /* Memory allocation error */
      68           0 :                 addStmtError(stmt, "HY001", NULL, 0);
      69           0 :                 return SQL_ERROR;
      70             :         }
      71             : 
      72         108 :         ODBCResetStmt(stmt);
      73             : 
      74             : #ifdef ODBCDEBUG
      75         108 :         ODBCLOG("SQLExecDirect: \"%s\"\n", query);
      76             : #endif
      77             : 
      78         108 :         if (stmt->next == NULL &&
      79         107 :             stmt->Dbc->FirstStmt == stmt &&
      80          98 :             stmt->cursorType == SQL_CURSOR_FORWARD_ONLY) {
      81             :                 /* we're the only Stmt handle, and we're only going forward */
      82          98 :                 if (stmt->Dbc->cachelimit != 10000)
      83          13 :                         mapi_cache_limit(stmt->Dbc->mid, 10000);
      84          98 :                 stmt->Dbc->cachelimit = 10000;
      85             :         } else {
      86          10 :                 if (stmt->Dbc->cachelimit != 100)
      87           1 :                         mapi_cache_limit(stmt->Dbc->mid, 100);
      88          10 :                 stmt->Dbc->cachelimit = 100;
      89             :         }
      90         108 :         ret = mapi_query_handle(hdl, query);
      91         108 :         free(query);
      92         108 :         switch (ret) {
      93             :         case MOK:
      94         105 :                 break;
      95           0 :         case MTIMEOUT:
      96             :                 /* Connection timeout expired / Communication link failure */
      97           0 :                 timeout = msetting_long(stmt->Dbc->settings, MP_REPLY_TIMEOUT);
      98           0 :                 addStmtError(stmt, timeout > 0 ? "HYT01" : "08S01", mapi_error_str(stmt->Dbc->mid), 0);
      99           0 :                 return SQL_ERROR;
     100           3 :         default:
     101           3 :                 err = mapi_result_error(hdl);
     102           3 :                 if (err == NULL)
     103           0 :                         err = mapi_error_str(stmt->Dbc->mid);
     104           0 :                 if (err != NULL) {
     105           3 :                         const char *e = mapi_result_errorcode(hdl);
     106             : 
     107           3 :                         if (e) {
     108           3 :                                 addStmtError(stmt, e, err, 0);
     109           3 :                                 return SQL_ERROR;
     110             :                         }
     111             :                 }
     112             :                 /* General error */
     113           0 :                 addStmtError(stmt, "HY000", err, 0);
     114           0 :                 return SQL_ERROR;
     115             :         }
     116             : 
     117             :         /* now get the result data and store it to our internal data
     118             :          * structure */
     119             : 
     120         105 :         return ODBCInitResult(stmt);
     121             : }
     122             : 
     123             : SQLRETURN
     124         108 : MNDBExecDirect(ODBCStmt *stmt,
     125             :                const SQLCHAR *StatementText,
     126             :                SQLINTEGER TextLength)
     127             : {
     128         108 :         SQLRETURN ret;
     129         108 :         SQLINTEGER i;
     130             : 
     131             :         /* check input parameter */
     132         108 :         if (StatementText == NULL) {
     133             :                 /* Invalid use of null pointer */
     134           0 :                 addStmtError(stmt, "HY009", NULL, 0);
     135           0 :                 return SQL_ERROR;
     136             :         }
     137             : 
     138         108 :         fixODBCstring(StatementText, TextLength, SQLINTEGER,
     139             :                       addStmtError, stmt, return SQL_ERROR);
     140      174448 :         for (i = 0; i < TextLength; i++)
     141             :                 /* TODO FIX: only when the statement starts with PREPARE the
     142             :                    questions marks have a special meaning */
     143      174340 :                 if (StatementText[i] == '?') {
     144             :                         /* query may have parameters, take the long route */
     145           0 :                         ret = MNDBPrepare(stmt, StatementText, TextLength);
     146           0 :                         if (ret == SQL_SUCCESS)
     147           0 :                                 ret = MNDBExecute(stmt);
     148           0 :                         return ret;
     149             :                 }
     150             : 
     151             :         /* no parameters, take the direct route */
     152         108 :         return ODBCExecDirect(stmt, StatementText, TextLength);
     153             : }
     154             : 
     155             : SQLRETURN SQL_API
     156             : SQLExecDirect(SQLHSTMT StatementHandle,
     157             :               SQLCHAR *StatementText,
     158             :               SQLINTEGER TextLength)
     159             : {
     160             : #ifdef ODBCDEBUG
     161          25 :         ODBCLOG("SQLExecDirect %p\n", StatementHandle);
     162             : #endif
     163             : 
     164          25 :         if (!isValidStmt((ODBCStmt *) StatementHandle))
     165             :                 return SQL_INVALID_HANDLE;
     166             : 
     167          25 :         clearStmtErrors((ODBCStmt *) StatementHandle);
     168             : 
     169          25 :         return MNDBExecDirect((ODBCStmt *) StatementHandle,
     170             :                               StatementText,
     171             :                               TextLength);
     172             : }
     173             : 
     174             : SQLRETURN SQL_API
     175             : SQLExecDirectA(SQLHSTMT StatementHandle,
     176             :                SQLCHAR *StatementText,
     177             :                SQLINTEGER TextLength)
     178             : {
     179           0 :         return SQLExecDirect(StatementHandle, StatementText, TextLength);
     180             : }
     181             : 
     182             : SQLRETURN SQL_API
     183             : SQLExecDirectW(SQLHSTMT StatementHandle,
     184             :                SQLWCHAR *StatementText,
     185             :                SQLINTEGER TextLength)
     186             : {
     187           1 :         ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
     188           1 :         SQLRETURN rc;
     189           1 :         SQLCHAR *sql;
     190             : 
     191             : #ifdef ODBCDEBUG
     192           1 :         ODBCLOG("SQLExecDirectW %p\n", StatementHandle);
     193             : #endif
     194             : 
     195           1 :         if (!isValidStmt(stmt))
     196             :                  return SQL_INVALID_HANDLE;
     197             : 
     198           1 :         clearStmtErrors(stmt);
     199             : 
     200           1 :         fixWcharIn(StatementText, TextLength, SQLCHAR, sql,
     201             :                    addStmtError, stmt, return SQL_ERROR);
     202             : 
     203           1 :         rc = MNDBExecDirect((ODBCStmt *) StatementHandle, sql, SQL_NTS);
     204             : 
     205           1 :         if (sql)
     206           1 :                 free(sql);
     207             : 
     208             :         return rc;
     209             : }

Generated by: LCOV version 1.14