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 : }
|