LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLExecDirect.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 46 79 58.2 %
Date: 2024-04-26 00:35:57 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 (thats 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         102 : ODBCExecDirect(ODBCStmt *stmt, const SQLCHAR *StatementText, SQLINTEGER TextLength)
      38             : {
      39         102 :         char *query;
      40         102 :         const char *err;
      41         102 :         MapiMsg ret;
      42         102 :         MapiHdl hdl;
      43             : 
      44         102 :         hdl = stmt->hdl;
      45             : 
      46         102 :         if (stmt->State >= EXECUTED1 ||
      47           8 :             (stmt->State == EXECUTED0 && mapi_more_results(hdl))) {
      48             :                 /* Invalid cursor state */
      49           0 :                 addStmtError(stmt, "24000", NULL, 0);
      50           0 :                 return SQL_ERROR;
      51             :         }
      52             : 
      53         102 :         if (stmt->qtimeout != stmt->Dbc->qtimeout) {
      54           0 :                 char buf[48];
      55           0 :                 snprintf(buf, sizeof(buf), "call sys.%s(%" PRIu64 ")",
      56           0 :                          (stmt->Dbc->major == 11 && stmt->Dbc->minor >= 37)
      57             :                          ? "setquerytimeout" : "settimeout",
      58             :                          (uint64_t) stmt->qtimeout);
      59           0 :                 if (mapi_query_handle(hdl, buf) == MOK)
      60           0 :                         stmt->Dbc->qtimeout = stmt->qtimeout;
      61             :         }
      62             : 
      63         102 :         query = ODBCTranslateSQL(stmt->Dbc, StatementText, (size_t) TextLength,
      64             :                                  stmt->noScan);
      65         102 :         if (query == NULL) {
      66             :                 /* Memory allocation error */
      67           0 :                 addStmtError(stmt, "HY001", NULL, 0);
      68           0 :                 return SQL_ERROR;
      69             :         }
      70             : 
      71         102 :         ODBCResetStmt(stmt);
      72             : 
      73             : #ifdef ODBCDEBUG
      74         102 :         ODBCLOG("SQLExecDirect: \"%s\"\n", query);
      75             : #endif
      76             : 
      77         102 :         if (stmt->next == NULL &&
      78         100 :             stmt->Dbc->FirstStmt == stmt &&
      79          91 :             stmt->cursorType == SQL_CURSOR_FORWARD_ONLY) {
      80             :                 /* we're the only Stmt handle, and we're only going forward */
      81          91 :                 if (stmt->Dbc->cachelimit != 10000)
      82           5 :                         mapi_cache_limit(stmt->Dbc->mid, 10000);
      83          91 :                 stmt->Dbc->cachelimit = 10000;
      84             :         } else {
      85          11 :                 if (stmt->Dbc->cachelimit != 100)
      86           2 :                         mapi_cache_limit(stmt->Dbc->mid, 100);
      87          11 :                 stmt->Dbc->cachelimit = 100;
      88             :         }
      89         102 :         ret = mapi_query_handle(hdl, query);
      90         102 :         free(query);
      91         102 :         switch (ret) {
      92             :         case MOK:
      93         101 :                 break;
      94           0 :         case MTIMEOUT:
      95             :                 /* Timeout expired / Communication link failure */
      96           0 :                 addStmtError(stmt, stmt->Dbc->sql_attr_connection_timeout ? "HYT00" : "08S01", mapi_error_str(stmt->Dbc->mid), 0);
      97           0 :                 return SQL_ERROR;
      98           1 :         default:
      99           1 :                 err = mapi_result_error(hdl);
     100           1 :                 if (err == NULL)
     101           0 :                         err = mapi_error_str(stmt->Dbc->mid);
     102           0 :                 if (err != NULL) {
     103           1 :                         const char *e = mapi_result_errorcode(hdl);
     104             : 
     105           1 :                         if (e) {
     106           1 :                                 addStmtError(stmt, e, err, 0);
     107           1 :                                 return SQL_ERROR;
     108             :                         }
     109             :                 }
     110             :                 /* General error */
     111           0 :                 addStmtError(stmt, "HY000", err, 0);
     112           0 :                 return SQL_ERROR;
     113             :         }
     114             : 
     115             :         /* now get the result data and store it to our internal data
     116             :          * structure */
     117             : 
     118         101 :         return ODBCInitResult(stmt);
     119             : }
     120             : 
     121             : SQLRETURN
     122         102 : MNDBExecDirect(ODBCStmt *stmt,
     123             :                const SQLCHAR *StatementText,
     124             :                SQLINTEGER TextLength)
     125             : {
     126         102 :         SQLRETURN ret;
     127         102 :         SQLINTEGER i;
     128             : 
     129             :         /* check input parameter */
     130         102 :         if (StatementText == NULL) {
     131             :                 /* Invalid use of null pointer */
     132           0 :                 addStmtError(stmt, "HY009", NULL, 0);
     133           0 :                 return SQL_ERROR;
     134             :         }
     135             : 
     136         102 :         fixODBCstring(StatementText, TextLength, SQLINTEGER,
     137             :                       addStmtError, stmt, return SQL_ERROR);
     138      173909 :         for (i = 0; i < TextLength; i++)
     139             :                 /* TODO FIX: only when the statement starts with PREPARE the
     140             :                    questions marks have a special meaning */
     141      173807 :                 if (StatementText[i] == '?') {
     142             :                         /* query may have parameters, take the long route */
     143           0 :                         ret = MNDBPrepare(stmt, StatementText, TextLength);
     144           0 :                         if (ret == SQL_SUCCESS)
     145           0 :                                 ret = MNDBExecute(stmt);
     146           0 :                         return ret;
     147             :                 }
     148             : 
     149             :         /* no parameters, take the direct route */
     150         102 :         return ODBCExecDirect(stmt, StatementText, TextLength);
     151             : }
     152             : 
     153             : SQLRETURN SQL_API
     154             : SQLExecDirect(SQLHSTMT StatementHandle,
     155             :               SQLCHAR *StatementText,
     156             :               SQLINTEGER TextLength)
     157             : {
     158             : #ifdef ODBCDEBUG
     159          18 :         ODBCLOG("SQLExecDirect %p\n", StatementHandle);
     160             : #endif
     161             : 
     162          18 :         if (!isValidStmt((ODBCStmt *) StatementHandle))
     163             :                 return SQL_INVALID_HANDLE;
     164             : 
     165          18 :         clearStmtErrors((ODBCStmt *) StatementHandle);
     166             : 
     167          18 :         return MNDBExecDirect((ODBCStmt *) StatementHandle,
     168             :                               StatementText,
     169             :                               TextLength);
     170             : }
     171             : 
     172             : SQLRETURN SQL_API
     173             : SQLExecDirectA(SQLHSTMT StatementHandle,
     174             :                SQLCHAR *StatementText,
     175             :                SQLINTEGER TextLength)
     176             : {
     177           0 :         return SQLExecDirect(StatementHandle, StatementText, TextLength);
     178             : }
     179             : 
     180             : SQLRETURN SQL_API
     181             : SQLExecDirectW(SQLHSTMT StatementHandle,
     182             :                SQLWCHAR *StatementText,
     183             :                SQLINTEGER TextLength)
     184             : {
     185           0 :         ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
     186           0 :         SQLRETURN rc;
     187           0 :         SQLCHAR *sql;
     188             : 
     189             : #ifdef ODBCDEBUG
     190           0 :         ODBCLOG("SQLExecDirectW %p\n", StatementHandle);
     191             : #endif
     192             : 
     193           0 :         if (!isValidStmt(stmt))
     194             :                  return SQL_INVALID_HANDLE;
     195             : 
     196           0 :         clearStmtErrors(stmt);
     197             : 
     198           0 :         fixWcharIn(StatementText, TextLength, SQLCHAR, sql,
     199             :                    addStmtError, stmt, return SQL_ERROR);
     200             : 
     201           0 :         rc = MNDBExecDirect((ODBCStmt *) StatementHandle, sql, SQL_NTS);
     202             : 
     203           0 :         if (sql)
     204           0 :                 free(sql);
     205             : 
     206             :         return rc;
     207             : }

Generated by: LCOV version 1.14