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 : * SQLSetStmtAttr()
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 :
35 :
36 : SQLRETURN
37 12 : MNDBSetStmtAttr(ODBCStmt *stmt,
38 : SQLINTEGER Attribute,
39 : SQLPOINTER ValuePtr,
40 : SQLINTEGER StringLength)
41 : {
42 : /* TODO: check parameters: ValuePtr and StringLength */
43 :
44 12 : if (Attribute == SQL_ATTR_CONCURRENCY ||
45 12 : Attribute == SQL_ATTR_CURSOR_SCROLLABLE ||
46 : Attribute == SQL_ATTR_CURSOR_SENSITIVITY ||
47 : Attribute == SQL_ATTR_CURSOR_TYPE ||
48 : Attribute == SQL_ATTR_USE_BOOKMARKS) {
49 0 : if (stmt->State >= EXECUTED0) {
50 : /* Invalid cursor state */
51 0 : addStmtError(stmt, "24000", NULL, 0);
52 0 : return SQL_ERROR;
53 : }
54 0 : if (stmt->State > INITED) {
55 : /* Attribute cannot be set now */
56 0 : addStmtError(stmt, "HY011", NULL, 0);
57 0 : return SQL_ERROR;
58 : }
59 : }
60 :
61 12 : switch (Attribute) {
62 : #define desc ((ODBCDesc *) ValuePtr) /* abbrev. */
63 0 : case SQL_ATTR_APP_PARAM_DESC: /* SQLHANDLE */
64 0 : if (ValuePtr == SQL_NULL_HDESC ||
65 0 : desc == stmt->AutoApplParamDescr) {
66 0 : stmt->ApplParamDescr = stmt->AutoApplParamDescr;
67 0 : return SQL_SUCCESS;
68 : }
69 0 : if (!isValidDesc(desc)) {
70 : /* Invalid attribute value */
71 0 : addStmtError(stmt, "HY024", NULL, 0);
72 0 : return SQL_ERROR;
73 : }
74 0 : if (desc->sql_desc_alloc_type == SQL_DESC_ALLOC_AUTO) {
75 : /* Invalid use of an automatically allocated
76 : descriptor handle */
77 0 : addStmtError(stmt, "HY017", NULL, 0);
78 0 : return SQL_ERROR;
79 : }
80 0 : stmt->ApplParamDescr = desc;
81 0 : break;
82 0 : case SQL_ATTR_APP_ROW_DESC: /* SQLHANDLE */
83 0 : if (ValuePtr == SQL_NULL_HDESC ||
84 0 : desc == stmt->AutoApplRowDescr) {
85 0 : stmt->ApplRowDescr = stmt->AutoApplRowDescr;
86 0 : return SQL_SUCCESS;
87 : }
88 0 : if (!isValidDesc(desc)) {
89 : /* Invalid attribute value */
90 0 : addStmtError(stmt, "HY024", NULL, 0);
91 0 : return SQL_ERROR;
92 : }
93 0 : if (desc->sql_desc_alloc_type == SQL_DESC_ALLOC_AUTO) {
94 : /* Invalid use of an automatically allocated
95 : descriptor handle */
96 0 : addStmtError(stmt, "HY017", NULL, 0);
97 0 : return SQL_ERROR;
98 : }
99 0 : stmt->ApplRowDescr = desc;
100 0 : break;
101 : #undef desc
102 0 : case SQL_ATTR_CURSOR_SCROLLABLE: /* SQLULEN */
103 0 : switch ((SQLULEN) (uintptr_t) ValuePtr) {
104 0 : case SQL_NONSCROLLABLE:
105 0 : stmt->cursorType = SQL_CURSOR_FORWARD_ONLY;
106 0 : break;
107 0 : case SQL_SCROLLABLE:
108 0 : stmt->cursorType = SQL_CURSOR_STATIC;
109 0 : break;
110 0 : default:
111 : /* Invalid attribute value */
112 0 : addStmtError(stmt, "HY024", NULL, 0);
113 0 : return SQL_ERROR;
114 : }
115 0 : stmt->cursorScrollable = (SQLULEN) (uintptr_t) ValuePtr;
116 0 : break;
117 0 : case SQL_ATTR_CURSOR_TYPE: /* SQLULEN */
118 0 : switch ((SQLULEN) (uintptr_t) ValuePtr) {
119 0 : case SQL_CURSOR_KEYSET_DRIVEN:
120 : case SQL_CURSOR_DYNAMIC:
121 : /* Option value changed */
122 0 : addStmtError(stmt, "01S02", NULL, 0);
123 :
124 : /* fall through */
125 0 : case SQL_CURSOR_STATIC:
126 0 : stmt->cursorScrollable = SQL_SCROLLABLE;
127 0 : stmt->cursorType = SQL_CURSOR_STATIC;
128 0 : break;
129 0 : case SQL_CURSOR_FORWARD_ONLY:
130 0 : stmt->cursorScrollable = SQL_NONSCROLLABLE;
131 0 : stmt->cursorType = SQL_CURSOR_FORWARD_ONLY;
132 0 : break;
133 0 : default:
134 : /* Invalid attribute value */
135 0 : addStmtError(stmt, "HY024", NULL, 0);
136 0 : return SQL_ERROR;
137 : }
138 : break;
139 0 : case SQL_ATTR_ENABLE_AUTO_IPD: /* SQLULEN */
140 0 : switch ((SQLULEN) (uintptr_t) ValuePtr) {
141 : case SQL_TRUE:
142 : case SQL_FALSE:
143 : break;
144 0 : default:
145 : /* Invalid attribute value */
146 0 : addStmtError(stmt, "HY024", NULL, 0);
147 0 : return SQL_ERROR;
148 : }
149 : /* ignore value, always treat as SQL_TRUE */
150 : break;
151 0 : case SQL_ATTR_IMP_PARAM_DESC: /* SQLHANDLE */
152 : case SQL_ATTR_IMP_ROW_DESC: /* SQLHANDLE */
153 : /* Invalid use of an automatically allocated
154 : descriptor handle */
155 0 : addStmtError(stmt, "HY017", NULL, 0);
156 0 : return SQL_ERROR;
157 8 : case SQL_ATTR_MAX_LENGTH: /* SQLULEN */
158 : case SQL_ATTR_MAX_ROWS: /* SQLULEN */
159 8 : if ((SQLULEN) (uintptr_t) ValuePtr != 0 &&
160 8 : (SQLULEN) (uintptr_t) ValuePtr != 2147483647)
161 8 : addStmtError(stmt, "01S02", NULL, 0);
162 : break;
163 0 : case SQL_ATTR_NOSCAN: /* SQLULEN */
164 0 : switch ((SQLULEN) (uintptr_t) ValuePtr) {
165 : case SQL_NOSCAN_ON:
166 : case SQL_NOSCAN_OFF:
167 0 : break;
168 0 : default:
169 : /* Invalid attribute value */
170 0 : addStmtError(stmt, "HY024", NULL, 0);
171 0 : return SQL_ERROR;
172 : }
173 0 : stmt->noScan = (SQLULEN) (uintptr_t) ValuePtr;
174 0 : break;
175 0 : case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* SQLULEN* */
176 0 : return MNDBSetDescField(stmt->ApplParamDescr, 0,
177 : SQL_DESC_BIND_OFFSET_PTR, ValuePtr,
178 : StringLength);
179 0 : case SQL_ATTR_PARAM_BIND_TYPE: /* SQLULEN */
180 : {
181 0 : SQLUINTEGER v = (SQLUINTEGER) (SQLULEN) (uintptr_t) ValuePtr;
182 0 : return MNDBSetDescField(stmt->ApplParamDescr, 0,
183 : SQL_DESC_BIND_TYPE, (SQLPOINTER) (uintptr_t) v,
184 : StringLength);
185 : }
186 0 : case SQL_ATTR_PARAM_OPERATION_PTR: /* SQLUSMALLINT* */
187 0 : return MNDBSetDescField(stmt->ApplParamDescr, 0,
188 : SQL_DESC_ARRAY_STATUS_PTR, ValuePtr,
189 : StringLength);
190 0 : case SQL_ATTR_PARAM_STATUS_PTR: /* SQLUSMALLINT* */
191 0 : return MNDBSetDescField(stmt->ImplParamDescr, 0,
192 : SQL_DESC_ARRAY_STATUS_PTR, ValuePtr,
193 : StringLength);
194 0 : case SQL_ATTR_PARAMS_PROCESSED_PTR: /* SQLULEN* */
195 0 : return MNDBSetDescField(stmt->ImplParamDescr, 0,
196 : SQL_DESC_ROWS_PROCESSED_PTR, ValuePtr,
197 : StringLength);
198 0 : case SQL_ATTR_PARAMSET_SIZE: /* SQLULEN */
199 0 : return MNDBSetDescField(stmt->ApplParamDescr, 0,
200 : SQL_DESC_ARRAY_SIZE, ValuePtr,
201 : StringLength);
202 4 : case SQL_ATTR_QUERY_TIMEOUT: /* SQLULEN */
203 4 : if ((uintptr_t) ValuePtr > 0x7FFFFFFF) {
204 4 : stmt->qtimeout = 0x7FFFFFFF;
205 4 : addStmtError(stmt, "01S02", NULL, 0);
206 : } else {
207 0 : stmt->qtimeout = (SQLULEN) (uintptr_t) ValuePtr;
208 : }
209 : break;
210 0 : case SQL_ATTR_RETRIEVE_DATA: /* SQLULEN */
211 0 : switch ((SQLULEN) (uintptr_t) ValuePtr) {
212 : case SQL_RD_ON:
213 : case SQL_RD_OFF:
214 0 : break;
215 0 : default:
216 : /* Invalid attribute value */
217 0 : addStmtError(stmt, "HY024", NULL, 0);
218 0 : return SQL_ERROR;
219 : }
220 0 : stmt->retrieveData = (SQLULEN) (uintptr_t) ValuePtr;
221 0 : break;
222 0 : case SQL_ATTR_ROW_ARRAY_SIZE: /* SQLULEN */
223 : case SQL_ROWSET_SIZE:
224 0 : return MNDBSetDescField(stmt->ApplRowDescr, 0,
225 : SQL_DESC_ARRAY_SIZE, ValuePtr,
226 : StringLength);
227 0 : case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* SQLULEN* */
228 0 : return MNDBSetDescField(stmt->ApplRowDescr, 0,
229 : SQL_DESC_BIND_OFFSET_PTR, ValuePtr,
230 : StringLength);
231 0 : case SQL_ATTR_ROW_BIND_TYPE: /* SQLULEN */
232 0 : return MNDBSetDescField(stmt->ApplRowDescr, 0,
233 : SQL_DESC_BIND_TYPE, ValuePtr,
234 : StringLength);
235 0 : case SQL_ATTR_ROW_OPERATION_PTR: /* SQLUSMALLINT* */
236 0 : return MNDBSetDescField(stmt->ApplRowDescr, 0,
237 : SQL_DESC_ARRAY_STATUS_PTR, ValuePtr,
238 : StringLength);
239 0 : case SQL_ATTR_ROW_STATUS_PTR: /* SQLUSMALLINT* */
240 0 : return MNDBSetDescField(stmt->ImplRowDescr, 0,
241 : SQL_DESC_ARRAY_STATUS_PTR, ValuePtr,
242 : StringLength);
243 0 : case SQL_ATTR_ROWS_FETCHED_PTR: /* SQLULEN* */
244 0 : return MNDBSetDescField(stmt->ImplRowDescr, 0,
245 : SQL_DESC_ROWS_PROCESSED_PTR, ValuePtr,
246 : StringLength);
247 0 : case SQL_ATTR_METADATA_ID: /* SQLULEN */
248 0 : switch ((SQLULEN) (uintptr_t) ValuePtr) {
249 : case SQL_TRUE:
250 : case SQL_FALSE:
251 0 : break;
252 0 : default:
253 : /* Invalid attribute value */
254 0 : addStmtError(stmt, "HY024", NULL, 0);
255 0 : return SQL_ERROR;
256 : }
257 0 : stmt->Dbc->sql_attr_metadata_id = (SQLUINTEGER) (SQLULEN) (uintptr_t) ValuePtr;
258 0 : break;
259 :
260 0 : case SQL_ATTR_CONCURRENCY: /* SQLULEN */
261 0 : switch ((SQLULEN) (uintptr_t) ValuePtr) {
262 : case SQL_CONCUR_READ_ONLY:
263 : /* the only value we support */
264 : break;
265 0 : case SQL_CONCUR_LOCK:
266 : case SQL_CONCUR_ROWVER:
267 : case SQL_CONCUR_VALUES:
268 : /* Optional feature not implemented */
269 0 : addStmtError(stmt, "HYC00", NULL, 0);
270 0 : return SQL_ERROR;
271 : }
272 : break;
273 :
274 : /* TODO: implement requested behavior */
275 0 : case SQL_ATTR_ASYNC_ENABLE: /* SQLULEN */
276 : #ifdef SQL_ATTR_ASYNC_STMT_EVENT
277 : case SQL_ATTR_ASYNC_STMT_EVENT: /* SQLPOINTER */
278 : #endif
279 : #ifdef SQL_ATTR_ASYNC_STMT_PCALLBACK
280 : case SQL_ATTR_ASYNC_PCALLBACK: /* SQLPOINTER */
281 : #endif
282 : #ifdef SQL_ATTR_ASYNC_STMT_PCONTEXT
283 : case SQL_ATTR_ASYNC_PCONTEXT: /* SQLPOINTER */
284 : #endif
285 : case SQL_ATTR_CURSOR_SENSITIVITY: /* SQLULEN */
286 : case SQL_ATTR_FETCH_BOOKMARK_PTR: /* SQLLEN* */
287 : case SQL_ATTR_KEYSET_SIZE: /* SQLULEN */
288 : case SQL_ATTR_SIMULATE_CURSOR: /* SQLULEN */
289 : case SQL_ATTR_USE_BOOKMARKS: /* SQLULEN */
290 : /* Optional feature not implemented */
291 0 : addStmtError(stmt, "HYC00", NULL, 0);
292 0 : return SQL_ERROR;
293 :
294 0 : case SQL_ATTR_ROW_NUMBER: /* SQLULEN */
295 : /* invalid attribute, can only be used with SQLGetStmtAttr */
296 : default:
297 : /* Invalid attribute/option identifier */
298 0 : addStmtError(stmt, "HY092", NULL, 0);
299 0 : return SQL_ERROR;
300 : }
301 :
302 12 : return stmt->Error ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
303 : }
304 :
305 : SQLRETURN SQL_API
306 : SQLSetStmtAttr(SQLHSTMT StatementHandle,
307 : SQLINTEGER Attribute,
308 : SQLPOINTER ValuePtr,
309 : SQLINTEGER StringLength)
310 : {
311 : #ifdef ODBCDEBUG
312 12 : ODBCLOG("SQLSetStmtAttr %p %s %p %d\n",
313 : StatementHandle, translateStmtAttribute(Attribute),
314 : ValuePtr, (int) StringLength);
315 : #endif
316 :
317 12 : if (!isValidStmt((ODBCStmt *) StatementHandle))
318 : return SQL_INVALID_HANDLE;
319 :
320 12 : clearStmtErrors((ODBCStmt *) StatementHandle);
321 :
322 12 : return MNDBSetStmtAttr((ODBCStmt *) StatementHandle,
323 : Attribute,
324 : ValuePtr,
325 : StringLength);
326 : }
327 :
328 : SQLRETURN SQL_API
329 : SQLSetStmtAttrW(SQLHSTMT StatementHandle,
330 : SQLINTEGER Attribute,
331 : SQLPOINTER ValuePtr,
332 : SQLINTEGER StringLength)
333 : {
334 : #ifdef ODBCDEBUG
335 0 : ODBCLOG("SQLSetStmtAttrW %p %s %p %d\n",
336 : StatementHandle, translateStmtAttribute(Attribute),
337 : ValuePtr, (int) StringLength);
338 : #endif
339 :
340 0 : if (!isValidStmt((ODBCStmt *) StatementHandle))
341 : return SQL_INVALID_HANDLE;
342 :
343 0 : clearStmtErrors((ODBCStmt *) StatementHandle);
344 :
345 : /* there are no string-valued attributes */
346 :
347 0 : return MNDBSetStmtAttr((ODBCStmt *) StatementHandle,
348 : Attribute,
349 : ValuePtr,
350 : StringLength);
351 : }
|