1/*********************************************************************
2 *
3 * This is based on code created by Peter Harvey,
4 * (pharvey@codebydesign.com).
5 *
6 * Modified and extended by Nick Gorham
7 * (nick@lurcher.org).
8 *
9 * Any bugs or problems should be considered the fault of Nick and not
10 * Peter.
11 *
12 * copyright (c) 1999 Nick Gorham
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 **********************************************************************
29 *
30 * $Id: SQLSetStmtOption.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $
31 *
32 * $Log: SQLSetStmtOption.c,v $
33 * Revision 1.10 2009/02/18 17:59:08 lurcher
34 * Shift to using config.h, the compile lines were making it hard to spot warnings
35 *
36 * Revision 1.9 2009/02/04 09:30:02 lurcher
37 * Fix some SQLINTEGER/SQLLEN conflicts
38 *
39 * Revision 1.8 2007/11/29 12:00:31 lurcher
40 * Add 64 bit type changes to SQLExtendedFetch etc
41 *
42 * Revision 1.7 2005/11/23 08:29:16 lurcher
43 * Add cleanup in postgres driver
44 *
45 * Revision 1.6 2005/04/05 09:11:31 lurcher
46 * The config string being passed into ConfigDsn was wrong, removed semicolon, and added terminating double null
47 *
48 * Revision 1.5 2003/10/30 18:20:46 lurcher
49 *
50 * Fix broken thread protection
51 * Remove SQLNumResultCols after execute, lease S4/S% to driver
52 * Fix string overrun in SQLDriverConnect
53 * Add initial support for Interix
54 *
55 * Revision 1.4 2003/03/05 09:48:45 lurcher
56 *
57 * Add some 64 bit fixes
58 *
59 * Revision 1.3 2002/12/05 17:44:31 lurcher
60 *
61 * Display unknown return values in return logging
62 *
63 * Revision 1.2 2001/12/13 13:00:32 lurcher
64 *
65 * Remove most if not all warnings on 64 bit platforms
66 * Add support for new MS 3.52 64 bit changes
67 * Add override to disable the stopping of tracing
68 * Add MAX_ROWS support in postgres driver
69 *
70 * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher
71 *
72 * First upload to SourceForge
73 *
74 * Revision 1.4 2001/08/08 17:05:17 nick
75 *
76 * Add support for attribute setting in the ini files
77 *
78 * Revision 1.3 2001/07/03 09:30:41 nick
79 *
80 * Add ability to alter size of displayed message in the log
81 *
82 * Revision 1.2 2001/04/12 17:43:36 nick
83 *
84 * Change logging and added autotest to odbctest
85 *
86 * Revision 1.1.1.1 2000/09/04 16:42:52 nick
87 * Imported Sources
88 *
89 * Revision 1.8 2000/06/20 13:30:12 ngorham
90 *
91 * Fix problems when using bookmarks
92 *
93 * Revision 1.7 1999/11/13 23:41:01 ngorham
94 *
95 * Alter the way DM logging works
96 * Upgrade the Postgres driver to 6.4.6
97 *
98 * Revision 1.6 1999/10/24 23:54:19 ngorham
99 *
100 * First part of the changes to the error reporting
101 *
102 * Revision 1.5 1999/09/21 22:34:26 ngorham
103 *
104 * Improve performance by removing unneeded logging calls when logging is
105 * disabled
106 *
107 * Revision 1.4 1999/07/10 21:10:17 ngorham
108 *
109 * Adjust error sqlstate from driver manager, depending on requested
110 * version (ODBC2/3)
111 *
112 * Revision 1.3 1999/07/04 21:05:08 ngorham
113 *
114 * Add LGPL Headers to code
115 *
116 * Revision 1.2 1999/06/30 23:56:55 ngorham
117 *
118 * Add initial thread safety code
119 *
120 * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb
121 * first go at it
122 *
123 * Revision 1.4 1999/06/03 22:20:25 ngorham
124 *
125 * Finished off the ODBC3-2 mapping
126 *
127 * Revision 1.3 1999/06/02 20:12:10 ngorham
128 *
129 * Fixed botched log entry, and removed the dos \r from the sql header files.
130 *
131 * Revision 1.2 1999/06/02 19:57:21 ngorham
132 *
133 * Added code to check if a attempt is being made to compile with a C++
134 * Compiler, and issue a message.
135 * Start work on the ODBC2-3 conversions.
136 *
137 * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey
138 * Imported sources
139 *
140 * Revision 1.2 1999/05/09 23:27:11 nick
141 * All the API done now
142 *
143 * Revision 1.1 1999/04/25 23:06:11 nick
144 * Initial revision
145 *
146 *
147 **********************************************************************/
148
149#include <config.h>
150#include "drivermanager.h"
151
152static char const rcsid[]= "$RCSfile: SQLSetStmtOption.c,v $ $Revision: 1.10 $";
153
154SQLRETURN SQLSetStmtOptionA( SQLHSTMT statement_handle,
155 SQLUSMALLINT option,
156 SQLULEN value )
157{
158 return SQLSetStmtOption( statement_handle, option, value );
159}
160
161SQLRETURN SQLSetStmtOption( SQLHSTMT statement_handle,
162 SQLUSMALLINT option,
163 SQLULEN value )
164{
165 DMHSTMT statement = (DMHSTMT) statement_handle;
166 SQLRETURN ret;
167 SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ];
168
169 /*
170 * check statement
171 */
172
173 if ( !__validate_stmt( statement ))
174 {
175 dm_log_write( __FILE__,
176 __LINE__,
177 LOG_INFO,
178 LOG_INFO,
179 "Error: SQL_INVALID_HANDLE" );
180
181 return SQL_INVALID_HANDLE;
182 }
183
184 function_entry( statement );
185
186 if ( log_info.log_flag )
187 {
188 sprintf( statement -> msg, "\n\t\tEntry:\
189\n\t\t\tStatement = %p\
190\n\t\t\tOption = %s\
191\n\t\t\tValue = %d",
192 statement,
193 __stmt_attr_as_string( s1, option ),
194 (int)value );
195
196 dm_log_write( __FILE__,
197 __LINE__,
198 LOG_INFO,
199 LOG_INFO,
200 statement -> msg );
201 }
202
203 thread_protect( SQL_HANDLE_STMT, statement );
204
205 /*
206 * check states
207 */
208
209 if ( option == SQL_CONCURRENCY ||
210 option == SQL_CURSOR_TYPE ||
211 option == SQL_SIMULATE_CURSOR ||
212 option == SQL_USE_BOOKMARKS )
213 {
214 if ( statement -> state == STATE_S2 ||
215 statement -> state == STATE_S3 )
216 {
217 dm_log_write( __FILE__,
218 __LINE__,
219 LOG_INFO,
220 LOG_INFO,
221 "Error: S1011" );
222
223 __post_internal_error( &statement -> error,
224 ERROR_S1011, NULL,
225 statement -> connection -> environment -> requested_version );
226
227 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
228 }
229 else if ( statement -> state == STATE_S4 ||
230 statement -> state == STATE_S5 ||
231 statement -> state == STATE_S6 ||
232 statement -> state == STATE_S7 )
233 {
234 dm_log_write( __FILE__,
235 __LINE__,
236 LOG_INFO,
237 LOG_INFO,
238 "Error: 24000" );
239
240 __post_internal_error( &statement -> error,
241 ERROR_24000, NULL,
242 statement -> connection -> environment -> requested_version );
243
244 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
245 }
246 else if ( statement -> state == STATE_S8 ||
247 statement -> state == STATE_S9 ||
248 statement -> state == STATE_S10 ||
249 statement -> state == STATE_S11 ||
250 statement -> state == STATE_S12 ||
251 statement -> state == STATE_S13 ||
252 statement -> state == STATE_S14 ||
253 statement -> state == STATE_S15 )
254 {
255 if ( statement -> prepared )
256 {
257 dm_log_write( __FILE__,
258 __LINE__,
259 LOG_INFO,
260 LOG_INFO,
261 "Error: S1011" );
262
263 __post_internal_error( &statement -> error,
264 ERROR_S1011, NULL,
265 statement -> connection -> environment -> requested_version );
266
267 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
268 }
269 else
270 {
271 dm_log_write( __FILE__,
272 __LINE__,
273 LOG_INFO,
274 LOG_INFO,
275 "Error: S1010" );
276
277 __post_internal_error( &statement -> error,
278 ERROR_S1010, NULL,
279 statement -> connection -> environment -> requested_version );
280
281 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
282 }
283 }
284 }
285 else
286 {
287 if ( statement -> state == STATE_S8 ||
288 statement -> state == STATE_S9 ||
289 statement -> state == STATE_S10 ||
290 statement -> state == STATE_S11 ||
291 statement -> state == STATE_S12 )
292 {
293 dm_log_write( __FILE__,
294 __LINE__,
295 LOG_INFO,
296 LOG_INFO,
297 "Error: S1010" );
298
299 __post_internal_error( &statement -> error,
300 ERROR_S1010, NULL,
301 statement -> connection -> environment -> requested_version );
302
303 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
304 }
305 }
306
307 if ( option == SQL_ATTR_IMP_ROW_DESC ||
308 option == SQL_ATTR_IMP_PARAM_DESC )
309 {
310 dm_log_write( __FILE__,
311 __LINE__,
312 LOG_INFO,
313 LOG_INFO,
314 "Error: HY017" );
315
316 __post_internal_error( &statement -> error,
317 ERROR_HY017, NULL,
318 statement -> connection -> environment -> requested_version );
319
320 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
321 }
322
323 /*
324 * is it a legitimate value
325 */
326 ret = dm_check_statement_attrs( statement, option, (SQLPOINTER)value );
327
328 if ( ret != SQL_SUCCESS )
329 {
330 dm_log_write( __FILE__,
331 __LINE__,
332 LOG_INFO,
333 LOG_INFO,
334 "Error: HY011" );
335
336 __post_internal_error( &statement -> error,
337 ERROR_HY024, NULL,
338 statement -> connection -> environment -> requested_version );
339
340 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
341 }
342
343 /*
344 * is it something overridden
345 */
346
347 value = (SQLULEN) __attr_override( statement, SQL_HANDLE_STMT, option, (void*) value, NULL );
348
349 if ( CHECK_SQLSETSTMTOPTION( statement -> connection ))
350 {
351 ret = SQLSETSTMTOPTION( statement -> connection,
352 statement -> driver_stmt,
353 option,
354 value );
355 }
356 else if ( CHECK_SQLSETSTMTATTR( statement -> connection ))
357 {
358 switch ( option )
359 {
360 case SQL_ATTR_APP_PARAM_DESC:
361 if ( value )
362 memcpy( &statement -> apd, (void*)value,
363 sizeof( statement -> apd ));
364
365 ret = SQL_SUCCESS;
366 break;
367
368 case SQL_ATTR_APP_ROW_DESC:
369 if ( value )
370 memcpy( &statement -> ard, (void*)value,
371 sizeof( statement -> ard ));
372
373 ret = SQL_SUCCESS;
374 break;
375
376 case SQL_ATTR_IMP_PARAM_DESC:
377 if ( value )
378 memcpy( &statement -> ipd, (void*)value,
379 sizeof( statement -> ipd ));
380
381 ret = SQL_SUCCESS;
382 break;
383
384 case SQL_ATTR_IMP_ROW_DESC:
385 if ( value )
386 memcpy( &statement -> ird, (void*)value,
387 sizeof( statement -> ird ));
388
389 ret = SQL_SUCCESS;
390 break;
391
392 default:
393 ret = SQLSETSTMTATTR( statement -> connection,
394 statement -> driver_stmt,
395 option,
396 value,
397 SQL_NTS );
398 break;
399 }
400 }
401 else if ( CHECK_SQLSETSTMTATTRW( statement -> connection ))
402 {
403 switch ( option )
404 {
405 case SQL_ATTR_APP_PARAM_DESC:
406 if ( value )
407 memcpy( &statement -> apd, (void*)value,
408 sizeof( statement -> apd ));
409
410 ret = SQL_SUCCESS;
411 break;
412
413 case SQL_ATTR_APP_ROW_DESC:
414 if ( value )
415 memcpy( &statement -> ard, (void*)value,
416 sizeof( statement -> ard ));
417
418 ret = SQL_SUCCESS;
419 break;
420
421 case SQL_ATTR_IMP_PARAM_DESC:
422 if ( value )
423 memcpy( &statement -> ipd, (void*)value,
424 sizeof( statement -> ipd ));
425
426 ret = SQL_SUCCESS;
427 break;
428
429 case SQL_ATTR_IMP_ROW_DESC:
430 if ( value )
431 memcpy( &statement -> ird, (void*)value,
432 sizeof( statement -> ird ));
433
434 ret = SQL_SUCCESS;
435 break;
436
437 default:
438 ret = SQLSETSTMTATTRW( statement -> connection,
439 statement -> driver_stmt,
440 option,
441 value,
442 SQL_NTS );
443 break;
444 }
445 }
446 else
447 {
448 dm_log_write( __FILE__,
449 __LINE__,
450 LOG_INFO,
451 LOG_INFO,
452 "Error: IM001" );
453
454 __post_internal_error( &statement -> error,
455 ERROR_IM001, NULL,
456 statement -> connection -> environment -> requested_version );
457
458 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
459 }
460
461 /*
462 * take notice of this
463 */
464
465 if ( option == SQL_USE_BOOKMARKS && SQL_SUCCEEDED( ret ))
466 {
467 statement -> bookmarks_on = (SQLULEN) value;
468 }
469
470 if ( log_info.log_flag )
471 {
472 sprintf( statement -> msg,
473 "\n\t\tExit:[%s]",
474 __get_return_status( ret, s1 ));
475
476 dm_log_write( __FILE__,
477 __LINE__,
478 LOG_INFO,
479 LOG_INFO,
480 statement -> msg );
481 }
482
483 return function_return( SQL_HANDLE_STMT, statement, ret );
484}
485