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: SQLSetStmtAttr.c,v 1.16 2009/02/18 17:59:08 lurcher Exp $ |
31 | * |
32 | * $Log: SQLSetStmtAttr.c,v $ |
33 | * Revision 1.16 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.15 2009/02/04 09:30:02 lurcher |
37 | * Fix some SQLINTEGER/SQLLEN conflicts |
38 | * |
39 | * Revision 1.14 2007/12/17 13:13:03 lurcher |
40 | * Fix a couple of descriptor typo's |
41 | * |
42 | * Revision 1.13 2007/02/12 11:49:34 lurcher |
43 | * Add QT4 support to existing GUI parts |
44 | * |
45 | * Revision 1.12 2006/04/27 16:39:50 lurcher |
46 | * fix missing return from SQLSetStmtAttr changes |
47 | * |
48 | * Revision 1.11 2006/04/24 08:42:10 lurcher |
49 | * Handle resetting statement descriptors to implicit values, by passing in NULL or the implicit descrptor to SQLSetStmtAttr with the attribute SQL_ATTR_APP_PARAM_DESC or SQL_ATTR_APP_ROW_DESC. Also catch trying to call SQLGetDescField on a closed connection |
50 | * |
51 | * Revision 1.10 2005/11/23 08:29:16 lurcher |
52 | * Add cleanup in postgres driver |
53 | * |
54 | * Revision 1.9 2003/10/30 18:20:46 lurcher |
55 | * |
56 | * Fix broken thread protection |
57 | * Remove SQLNumResultCols after execute, lease S4/S% to driver |
58 | * Fix string overrun in SQLDriverConnect |
59 | * Add initial support for Interix |
60 | * |
61 | * Revision 1.8 2003/03/05 09:48:45 lurcher |
62 | * |
63 | * Add some 64 bit fixes |
64 | * |
65 | * Revision 1.7 2003/02/27 12:19:40 lurcher |
66 | * |
67 | * Add the A functions as well as the W |
68 | * |
69 | * Revision 1.6 2002/12/05 17:44:31 lurcher |
70 | * |
71 | * Display unknown return values in return logging |
72 | * |
73 | * Revision 1.5 2002/09/18 14:49:32 lurcher |
74 | * |
75 | * DataManagerII additions and some more threading fixes |
76 | * |
77 | * Revision 1.3 2002/07/16 13:08:18 lurcher |
78 | * |
79 | * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit |
80 | * within ODBC 2 |
81 | * Make DSN's double clickable in ODBCConfig |
82 | * |
83 | * Revision 1.2 2001/12/13 13:00:32 lurcher |
84 | * |
85 | * Remove most if not all warnings on 64 bit platforms |
86 | * Add support for new MS 3.52 64 bit changes |
87 | * Add override to disable the stopping of tracing |
88 | * Add MAX_ROWS support in postgres driver |
89 | * |
90 | * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher |
91 | * |
92 | * First upload to SourceForge |
93 | * |
94 | * Revision 1.8 2001/08/08 17:05:17 nick |
95 | * |
96 | * Add support for attribute setting in the ini files |
97 | * |
98 | * Revision 1.7 2001/07/03 09:30:41 nick |
99 | * |
100 | * Add ability to alter size of displayed message in the log |
101 | * |
102 | * Revision 1.6 2001/04/12 17:43:36 nick |
103 | * |
104 | * Change logging and added autotest to odbctest |
105 | * |
106 | * Revision 1.5 2001/03/28 14:57:22 nick |
107 | * |
108 | * Fix bugs in corsor lib introduced bu UNCODE and other changes |
109 | * |
110 | * Revision 1.4 2001/01/09 22:33:13 nick |
111 | * |
112 | * Stop passing NULL into SQLExtendedFetch |
113 | * Further fixes to unicode to ansi conversions |
114 | * |
115 | * Revision 1.3 2000/12/18 12:53:29 nick |
116 | * |
117 | * More pooling tweeks |
118 | * |
119 | * Revision 1.2 2000/11/22 19:03:40 nick |
120 | * |
121 | * Fix problem with error status in SQLSpecialColumns |
122 | * |
123 | * Revision 1.1.1.1 2000/09/04 16:42:52 nick |
124 | * Imported Sources |
125 | * |
126 | * Revision 1.11 2000/06/24 18:45:09 ngorham |
127 | * |
128 | * Fix for SQLExtendedFetch on big endian platforms. the row count pointer |
129 | * was declared as a small not a int. |
130 | * |
131 | * Revision 1.10 2000/06/20 13:30:10 ngorham |
132 | * |
133 | * Fix problems when using bookmarks |
134 | * |
135 | * Revision 1.9 2000/02/11 00:41:46 ngorham |
136 | * |
137 | * Added a couple of fixes for drivers without SQLExtendedFetch |
138 | * |
139 | * Revision 1.8 1999/11/13 23:41:01 ngorham |
140 | * |
141 | * Alter the way DM logging works |
142 | * Upgrade the Postgres driver to 6.4.6 |
143 | * |
144 | * Revision 1.7 1999/10/24 23:54:19 ngorham |
145 | * |
146 | * First part of the changes to the error reporting |
147 | * |
148 | * Revision 1.6 1999/09/21 22:34:26 ngorham |
149 | * |
150 | * Improve performance by removing unneeded logging calls when logging is |
151 | * disabled |
152 | * |
153 | * Revision 1.5 1999/09/19 22:24:34 ngorham |
154 | * |
155 | * Added support for the cursor library |
156 | * |
157 | * Revision 1.4 1999/07/10 21:10:17 ngorham |
158 | * |
159 | * Adjust error sqlstate from driver manager, depending on requested |
160 | * version (ODBC2/3) |
161 | * |
162 | * Revision 1.3 1999/07/04 21:05:08 ngorham |
163 | * |
164 | * Add LGPL Headers to code |
165 | * |
166 | * Revision 1.2 1999/06/30 23:56:55 ngorham |
167 | * |
168 | * Add initial thread safety code |
169 | * |
170 | * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb |
171 | * first go at it |
172 | * |
173 | * Revision 1.6 1999/06/04 16:29:00 ngorham |
174 | * |
175 | * Added chack that SQLSetStmtAttr exists in the driver before calling it |
176 | * |
177 | * Revision 1.5 1999/06/03 22:20:25 ngorham |
178 | * |
179 | * Finished off the ODBC3-2 mapping |
180 | * |
181 | * Revision 1.4 1999/06/02 23:48:45 ngorham |
182 | * |
183 | * Added more 3-2 mapping |
184 | * |
185 | * Revision 1.3 1999/06/02 20:12:10 ngorham |
186 | * |
187 | * Fixed botched log entry, and removed the dos \r from the sql header files. |
188 | * |
189 | * Revision 1.2 1999/06/02 19:57:21 ngorham |
190 | * |
191 | * Added code to check if a attempt is being made to compile with a C++ |
192 | * Compiler, and issue a message. |
193 | * Start work on the ODBC2-3 conversions. |
194 | * |
195 | * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey |
196 | * Imported sources |
197 | * |
198 | * Revision 1.3 1999/05/09 23:27:11 nick |
199 | * All the API done now |
200 | * |
201 | * Revision 1.2 1999/05/03 19:50:43 nick |
202 | * Another check point |
203 | * |
204 | * Revision 1.1 1999/04/25 23:06:11 nick |
205 | * Initial revision |
206 | * |
207 | * |
208 | **********************************************************************/ |
209 | |
210 | #include <config.h> |
211 | #include "drivermanager.h" |
212 | |
213 | static char const rcsid[]= "$RCSfile: SQLSetStmtAttr.c,v $ $Revision: 1.16 $" ; |
214 | |
215 | SQLRETURN SQLSetStmtAttrA( SQLHSTMT statement_handle, |
216 | SQLINTEGER attribute, |
217 | SQLPOINTER value, |
218 | SQLINTEGER string_length ) |
219 | { |
220 | return SQLSetStmtAttr( statement_handle, |
221 | attribute, |
222 | value, |
223 | string_length ); |
224 | } |
225 | |
226 | SQLRETURN SQLSetStmtAttr( SQLHSTMT statement_handle, |
227 | SQLINTEGER attribute, |
228 | SQLPOINTER value, |
229 | SQLINTEGER string_length ) |
230 | { |
231 | DMHSTMT statement = (DMHSTMT) statement_handle; |
232 | SQLRETURN ret; |
233 | SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; |
234 | |
235 | /* |
236 | * check statement |
237 | */ |
238 | |
239 | if ( !__validate_stmt( statement )) |
240 | { |
241 | dm_log_write( __FILE__, |
242 | __LINE__, |
243 | LOG_INFO, |
244 | LOG_INFO, |
245 | "Error: SQL_INVALID_HANDLE" ); |
246 | |
247 | return SQL_INVALID_HANDLE; |
248 | } |
249 | |
250 | function_entry( statement ); |
251 | |
252 | if ( log_info.log_flag ) |
253 | { |
254 | sprintf( statement -> msg, "\n\t\tEntry:\ |
255 | \n\t\t\tStatement = %p\ |
256 | \n\t\t\tAttribute = %s\ |
257 | \n\t\t\tValue = %p\ |
258 | \n\t\t\tStrLen = %d" , |
259 | statement, |
260 | __stmt_attr_as_string( s1, attribute ), |
261 | value, |
262 | (int)string_length ); |
263 | |
264 | dm_log_write( __FILE__, |
265 | __LINE__, |
266 | LOG_INFO, |
267 | LOG_INFO, |
268 | statement -> msg ); |
269 | } |
270 | |
271 | thread_protect( SQL_HANDLE_STMT, statement ); |
272 | |
273 | /* |
274 | * check states |
275 | */ |
276 | |
277 | if ( attribute == SQL_ATTR_CONCURRENCY || |
278 | attribute == SQL_ATTR_CURSOR_TYPE || |
279 | attribute == SQL_ATTR_SIMULATE_CURSOR || |
280 | attribute == SQL_ATTR_USE_BOOKMARKS || |
281 | attribute == SQL_ATTR_CURSOR_SCROLLABLE || |
282 | attribute == SQL_ATTR_CURSOR_SENSITIVITY ) |
283 | { |
284 | if ( statement -> state == STATE_S2 || |
285 | statement -> state == STATE_S3 ) |
286 | { |
287 | dm_log_write( __FILE__, |
288 | __LINE__, |
289 | LOG_INFO, |
290 | LOG_INFO, |
291 | "Error: HY011" ); |
292 | |
293 | __post_internal_error( &statement -> error, |
294 | ERROR_HY011, NULL, |
295 | statement -> connection -> environment -> requested_version ); |
296 | |
297 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
298 | } |
299 | else if ( statement -> state == STATE_S4 || |
300 | statement -> state == STATE_S5 || |
301 | statement -> state == STATE_S6 || |
302 | statement -> state == STATE_S7 ) |
303 | { |
304 | dm_log_write( __FILE__, |
305 | __LINE__, |
306 | LOG_INFO, |
307 | LOG_INFO, |
308 | "Error: 24000" ); |
309 | |
310 | __post_internal_error( &statement -> error, |
311 | ERROR_24000, NULL, |
312 | statement -> connection -> environment -> requested_version ); |
313 | |
314 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
315 | } |
316 | else if ( statement -> state == STATE_S8 || |
317 | statement -> state == STATE_S9 || |
318 | statement -> state == STATE_S10 || |
319 | statement -> state == STATE_S11 || |
320 | statement -> state == STATE_S12 || |
321 | statement -> state == STATE_S13 || |
322 | statement -> state == STATE_S14 || |
323 | statement -> state == STATE_S15 ) |
324 | { |
325 | if ( statement -> prepared ) |
326 | { |
327 | dm_log_write( __FILE__, |
328 | __LINE__, |
329 | LOG_INFO, |
330 | LOG_INFO, |
331 | "Error: HY011" ); |
332 | |
333 | __post_internal_error( &statement -> error, |
334 | ERROR_HY011, NULL, |
335 | statement -> connection -> environment -> requested_version ); |
336 | |
337 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
338 | } |
339 | else |
340 | { |
341 | dm_log_write( __FILE__, |
342 | __LINE__, |
343 | LOG_INFO, |
344 | LOG_INFO, |
345 | "Error: HY010" ); |
346 | |
347 | __post_internal_error( &statement -> error, |
348 | ERROR_HY010, NULL, |
349 | statement -> connection -> environment -> requested_version ); |
350 | |
351 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
352 | } |
353 | } |
354 | } |
355 | else |
356 | { |
357 | if ( statement -> state == STATE_S8 || |
358 | statement -> state == STATE_S9 || |
359 | statement -> state == STATE_S10 || |
360 | statement -> state == STATE_S11 || |
361 | statement -> state == STATE_S12 ) |
362 | { |
363 | dm_log_write( __FILE__, |
364 | __LINE__, |
365 | LOG_INFO, |
366 | LOG_INFO, |
367 | "Error: HY010" ); |
368 | |
369 | __post_internal_error( &statement -> error, |
370 | ERROR_HY010, NULL, |
371 | statement -> connection -> environment -> requested_version ); |
372 | |
373 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
374 | } |
375 | } |
376 | |
377 | if ( (!CHECK_SQLSETSTMTATTR( statement -> connection ) && |
378 | !CHECK_SQLSETSTMTATTRW( statement -> connection )) && |
379 | !CHECK_SQLSETSTMTOPTION( statement -> connection )) |
380 | { |
381 | dm_log_write( __FILE__, |
382 | __LINE__, |
383 | LOG_INFO, |
384 | LOG_INFO, |
385 | "Error: IM001" ); |
386 | |
387 | __post_internal_error( &statement -> error, |
388 | ERROR_IM001, NULL, |
389 | statement -> connection -> environment -> requested_version ); |
390 | |
391 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
392 | } |
393 | |
394 | /* |
395 | * map descriptors to our copies |
396 | */ |
397 | |
398 | if ( attribute == SQL_ATTR_APP_ROW_DESC ) |
399 | { |
400 | DMHDESC desc = ( DMHDESC ) value; |
401 | |
402 | /* |
403 | * needs to reset to implicit descriptor, this is safe |
404 | * without a validate, as the value is either null, or the |
405 | * same as a descriptor we know is valid |
406 | */ |
407 | |
408 | if ( desc == NULL || desc == statement -> implicit_ard ) |
409 | { |
410 | DRV_SQLHDESC drv_desc = NULL; |
411 | |
412 | ret = SQL_SUCCESS; |
413 | |
414 | if ( desc == statement -> implicit_ard ) |
415 | { |
416 | drv_desc = statement -> implicit_ard -> driver_desc; |
417 | } |
418 | |
419 | if ( CHECK_SQLSETSTMTATTR( statement -> connection )) |
420 | { |
421 | ret = SQLSETSTMTATTR( statement -> connection, |
422 | statement -> driver_stmt, |
423 | attribute, |
424 | drv_desc, |
425 | 0 ); |
426 | } |
427 | else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) |
428 | { |
429 | ret = SQLSETSTMTATTRW( statement -> connection, |
430 | statement -> driver_stmt, |
431 | attribute, |
432 | statement -> implicit_ard -> driver_desc, |
433 | 0 ); |
434 | } |
435 | else |
436 | { |
437 | ret = SQLSETSTMTOPTION( statement -> connection, |
438 | statement -> driver_stmt, |
439 | attribute, |
440 | statement -> implicit_ard -> driver_desc ); |
441 | } |
442 | |
443 | if ( ret != SQL_SUCCESS ) |
444 | { |
445 | if ( log_info.log_flag ) |
446 | { |
447 | sprintf( statement -> msg, |
448 | "\n\t\tExit:[%s]" , |
449 | __get_return_status( ret, s1 )); |
450 | |
451 | dm_log_write( __FILE__, |
452 | __LINE__, |
453 | LOG_INFO, |
454 | LOG_INFO, |
455 | statement -> msg ); |
456 | } |
457 | |
458 | return function_return( SQL_HANDLE_STMT, statement, ret ); |
459 | } |
460 | |
461 | /* |
462 | * copy DM descriptor |
463 | */ |
464 | |
465 | statement -> apd = statement -> implicit_apd; |
466 | |
467 | if ( log_info.log_flag ) |
468 | { |
469 | sprintf( statement -> msg, |
470 | "\n\t\tExit:[%s]" , |
471 | __get_return_status( ret, s1 )); |
472 | |
473 | dm_log_write( __FILE__, |
474 | __LINE__, |
475 | LOG_INFO, |
476 | LOG_INFO, |
477 | statement -> msg ); |
478 | } |
479 | |
480 | return function_return( SQL_HANDLE_STMT, statement, ret ); |
481 | } |
482 | |
483 | if ( !__validate_desc( desc )) |
484 | { |
485 | thread_release( SQL_HANDLE_STMT, statement ); |
486 | |
487 | sprintf( statement -> msg, |
488 | "\n\t\tExit:[%s]" , |
489 | __get_return_status( SQL_INVALID_HANDLE, s1 )); |
490 | |
491 | dm_log_write( __FILE__, |
492 | __LINE__, |
493 | LOG_INFO, |
494 | LOG_INFO, |
495 | statement -> msg ); |
496 | |
497 | return SQL_INVALID_HANDLE; |
498 | } |
499 | |
500 | if ( desc -> implicit && |
501 | desc != statement -> implicit_ard ) |
502 | { |
503 | dm_log_write( __FILE__, |
504 | __LINE__, |
505 | LOG_INFO, |
506 | LOG_INFO, |
507 | "Error: HY017" ); |
508 | |
509 | __post_internal_error( &statement -> error, |
510 | ERROR_HY017, NULL, |
511 | statement -> connection -> environment -> requested_version ); |
512 | |
513 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
514 | } |
515 | |
516 | if ( desc -> connection != |
517 | statement -> connection ) |
518 | { |
519 | dm_log_write( __FILE__, |
520 | __LINE__, |
521 | LOG_INFO, |
522 | LOG_INFO, |
523 | "Error: HY024" ); |
524 | |
525 | __post_internal_error( &statement -> error, |
526 | ERROR_HY024, NULL, |
527 | statement -> connection -> environment -> requested_version ); |
528 | |
529 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
530 | } |
531 | |
532 | /* |
533 | * set the value to the driver descriptor handle |
534 | */ |
535 | value = ( SQLPOINTER ) desc -> driver_desc; |
536 | statement -> ard = desc; |
537 | desc -> associated_with = statement; |
538 | } |
539 | |
540 | if ( attribute == SQL_ATTR_APP_PARAM_DESC ) |
541 | { |
542 | DMHDESC desc = ( DMHDESC ) value; |
543 | |
544 | /* |
545 | * needs to reset to implicit descriptor, this is safe |
546 | * without a validate, as the value is either null, or the |
547 | * same as a descriptor we know is valid |
548 | */ |
549 | |
550 | if ( desc == NULL || desc == statement -> implicit_apd ) |
551 | { |
552 | DRV_SQLHDESC drv_desc = NULL; |
553 | |
554 | ret = SQL_SUCCESS; |
555 | |
556 | if ( desc == statement -> implicit_apd ) |
557 | { |
558 | drv_desc = statement -> implicit_apd -> driver_desc; |
559 | } |
560 | |
561 | if ( CHECK_SQLSETSTMTATTR( statement -> connection )) |
562 | { |
563 | ret = SQLSETSTMTATTR( statement -> connection, |
564 | statement -> driver_stmt, |
565 | attribute, |
566 | statement -> implicit_apd -> driver_desc, |
567 | 0 ); |
568 | } |
569 | else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) |
570 | { |
571 | ret = SQLSETSTMTATTRW( statement -> connection, |
572 | statement -> driver_stmt, |
573 | attribute, |
574 | statement -> implicit_apd -> driver_desc, |
575 | 0 ); |
576 | } |
577 | else |
578 | { |
579 | ret = SQLSETSTMTOPTION( statement -> connection, |
580 | statement -> driver_stmt, |
581 | attribute, |
582 | drv_desc ); |
583 | } |
584 | |
585 | if ( ret != SQL_SUCCESS ) |
586 | { |
587 | if ( log_info.log_flag ) |
588 | { |
589 | sprintf( statement -> msg, |
590 | "\n\t\tExit:[%s]" , |
591 | __get_return_status( ret, s1 )); |
592 | |
593 | dm_log_write( __FILE__, |
594 | __LINE__, |
595 | LOG_INFO, |
596 | LOG_INFO, |
597 | statement -> msg ); |
598 | } |
599 | |
600 | return function_return( SQL_HANDLE_STMT, statement, ret ); |
601 | } |
602 | |
603 | /* |
604 | * copy DM descriptor |
605 | */ |
606 | |
607 | statement -> apd = statement -> implicit_apd; |
608 | |
609 | if ( log_info.log_flag ) |
610 | { |
611 | sprintf( statement -> msg, |
612 | "\n\t\tExit:[%s]" , |
613 | __get_return_status( ret, s1 )); |
614 | |
615 | dm_log_write( __FILE__, |
616 | __LINE__, |
617 | LOG_INFO, |
618 | LOG_INFO, |
619 | statement -> msg ); |
620 | } |
621 | |
622 | return function_return( SQL_HANDLE_STMT, statement, ret ); |
623 | } |
624 | |
625 | if ( !__validate_desc( desc )) |
626 | { |
627 | sprintf( statement -> msg, |
628 | "\n\t\tExit:[%s]" , |
629 | __get_return_status( SQL_INVALID_HANDLE, s1 )); |
630 | |
631 | dm_log_write( __FILE__, |
632 | __LINE__, |
633 | LOG_INFO, |
634 | LOG_INFO, |
635 | statement -> msg ); |
636 | |
637 | thread_release( SQL_HANDLE_STMT, statement ); |
638 | |
639 | return SQL_INVALID_HANDLE; |
640 | } |
641 | |
642 | if ( desc -> implicit && |
643 | desc != statement -> implicit_apd ) |
644 | { |
645 | dm_log_write( __FILE__, |
646 | __LINE__, |
647 | LOG_INFO, |
648 | LOG_INFO, |
649 | "Error: HY017" ); |
650 | |
651 | __post_internal_error( &statement -> error, |
652 | ERROR_HY017, NULL, |
653 | statement -> connection -> environment -> requested_version ); |
654 | |
655 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
656 | } |
657 | |
658 | if ( desc -> connection != |
659 | statement -> connection ) |
660 | { |
661 | dm_log_write( __FILE__, |
662 | __LINE__, |
663 | LOG_INFO, |
664 | LOG_INFO, |
665 | "Error: HY024" ); |
666 | |
667 | __post_internal_error( &statement -> error, |
668 | ERROR_HY024, NULL, |
669 | statement -> connection -> environment -> requested_version ); |
670 | |
671 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
672 | } |
673 | |
674 | /* |
675 | * set the value to the driver descriptor handle |
676 | */ |
677 | value = ( SQLPOINTER ) desc -> driver_desc; |
678 | statement -> apd = desc; |
679 | desc -> associated_with = statement; |
680 | } |
681 | |
682 | /* |
683 | * save for internal use |
684 | */ |
685 | |
686 | if ( attribute == SQL_ATTR_METADATA_ID ) |
687 | { |
688 | statement -> metadata_id = (SQLLEN) value; |
689 | } |
690 | |
691 | if ( attribute == SQL_ATTR_IMP_ROW_DESC || |
692 | attribute == SQL_ATTR_IMP_PARAM_DESC ) |
693 | { |
694 | dm_log_write( __FILE__, |
695 | __LINE__, |
696 | LOG_INFO, |
697 | LOG_INFO, |
698 | "Error: HY017" ); |
699 | |
700 | __post_internal_error( &statement -> error, |
701 | ERROR_HY017, NULL, |
702 | statement -> connection -> environment -> requested_version ); |
703 | |
704 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
705 | } |
706 | |
707 | /* |
708 | * is it a legitimate value |
709 | */ |
710 | ret = dm_check_statement_attrs( statement, attribute, value ); |
711 | |
712 | if ( ret != SQL_SUCCESS ) |
713 | { |
714 | dm_log_write( __FILE__, |
715 | __LINE__, |
716 | LOG_INFO, |
717 | LOG_INFO, |
718 | "Error: HY024" ); |
719 | |
720 | __post_internal_error( &statement -> error, |
721 | ERROR_HY024, NULL, |
722 | statement -> connection -> environment -> requested_version ); |
723 | |
724 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
725 | } |
726 | |
727 | /* |
728 | * is it something overridden |
729 | */ |
730 | |
731 | value = __attr_override( statement, SQL_HANDLE_STMT, attribute, value, &string_length ); |
732 | |
733 | /* |
734 | * does the call need mapping from 3 to 2 |
735 | */ |
736 | |
737 | if ( attribute == SQL_ATTR_FETCH_BOOKMARK_PTR && |
738 | statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && |
739 | CHECK_SQLEXTENDEDFETCH( statement -> connection ) && |
740 | !CHECK_SQLFETCHSCROLL( statement -> connection )) |
741 | { |
742 | statement -> fetch_bm_ptr = (SQLULEN*) value; |
743 | /* |
744 | * pass on if required |
745 | */ |
746 | if ( statement -> connection -> cl_handle ) |
747 | { |
748 | if ( CHECK_SQLSETSTMTATTR( statement -> connection )) |
749 | { |
750 | SQLSETSTMTATTR( statement -> connection, |
751 | statement -> driver_stmt, |
752 | attribute, |
753 | value, |
754 | string_length ); |
755 | } |
756 | else |
757 | { |
758 | ret = SQLSETSTMTOPTION( statement -> connection, |
759 | statement -> driver_stmt, |
760 | attribute, |
761 | value ); |
762 | } |
763 | } |
764 | ret = SQL_SUCCESS; |
765 | } |
766 | else if ( attribute == SQL_ATTR_ROW_STATUS_PTR && |
767 | statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) |
768 | { |
769 | statement -> row_st_arr = (SQLUSMALLINT*) value; |
770 | /* |
771 | * pass on if required |
772 | */ |
773 | if ( statement -> connection -> cl_handle ) |
774 | { |
775 | if ( CHECK_SQLSETSTMTATTR( statement -> connection )) |
776 | { |
777 | SQLSETSTMTATTR( statement -> connection, |
778 | statement -> driver_stmt, |
779 | attribute, |
780 | value, |
781 | string_length ); |
782 | } |
783 | else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) |
784 | { |
785 | SQLSETSTMTATTRW( statement -> connection, |
786 | statement -> driver_stmt, |
787 | attribute, |
788 | value, |
789 | string_length ); |
790 | } |
791 | else |
792 | { |
793 | ret = SQLSETSTMTOPTION( statement -> connection, |
794 | statement -> driver_stmt, |
795 | attribute, |
796 | value ); |
797 | } |
798 | } |
799 | ret = SQL_SUCCESS; |
800 | } |
801 | else if ( attribute == SQL_ATTR_ROWS_FETCHED_PTR && |
802 | statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) |
803 | { |
804 | statement -> row_ct_ptr = (SQLULEN*) value; |
805 | /* |
806 | * pass on if required |
807 | */ |
808 | if ( statement -> connection -> cl_handle ) |
809 | { |
810 | if ( CHECK_SQLSETSTMTATTR( statement -> connection )) |
811 | { |
812 | SQLSETSTMTATTR( statement -> connection, |
813 | statement -> driver_stmt, |
814 | attribute, |
815 | value, |
816 | string_length ); |
817 | } |
818 | else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) |
819 | { |
820 | SQLSETSTMTATTRW( statement -> connection, |
821 | statement -> driver_stmt, |
822 | attribute, |
823 | value, |
824 | string_length ); |
825 | } |
826 | else |
827 | { |
828 | ret = SQLSETSTMTOPTION( statement -> connection, |
829 | statement -> driver_stmt, |
830 | attribute, |
831 | value ); |
832 | } |
833 | } |
834 | ret = SQL_SUCCESS; |
835 | } |
836 | else if ( attribute == SQL_ATTR_ROW_ARRAY_SIZE && |
837 | statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) |
838 | { |
839 | /* |
840 | * save this in case we need it in SQLExtendedFetch |
841 | */ |
842 | statement -> row_array_size = (SQLULEN) value; |
843 | |
844 | if ( CHECK_SQLSETSTMTATTR( statement -> connection )) |
845 | { |
846 | ret = SQLSETSTMTATTR( statement -> connection, |
847 | statement -> driver_stmt, |
848 | SQL_ROWSET_SIZE, |
849 | value, |
850 | string_length ); |
851 | } |
852 | else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) |
853 | { |
854 | ret = SQLSETSTMTATTRW( statement -> connection, |
855 | statement -> driver_stmt, |
856 | SQL_ROWSET_SIZE, |
857 | value, |
858 | string_length ); |
859 | } |
860 | else |
861 | { |
862 | ret = SQLSETSTMTOPTION( statement -> connection, |
863 | statement -> driver_stmt, |
864 | SQL_ROWSET_SIZE, |
865 | value ); |
866 | } |
867 | } |
868 | else if ( CHECK_SQLSETSTMTATTR( statement -> connection )) |
869 | { |
870 | ret = SQLSETSTMTATTR( statement -> connection, |
871 | statement -> driver_stmt, |
872 | attribute, |
873 | value, |
874 | string_length ); |
875 | } |
876 | else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) |
877 | { |
878 | ret = SQLSETSTMTATTRW( statement -> connection, |
879 | statement -> driver_stmt, |
880 | attribute, |
881 | value, |
882 | string_length ); |
883 | } |
884 | else |
885 | { |
886 | /* |
887 | * Is it in the legal range of values |
888 | */ |
889 | |
890 | if ( attribute < SQL_STMT_DRIVER_MIN && |
891 | ( attribute > SQL_ROW_NUMBER || attribute < SQL_QUERY_TIMEOUT )) |
892 | { |
893 | dm_log_write( __FILE__, |
894 | __LINE__, |
895 | LOG_INFO, |
896 | LOG_INFO, |
897 | "Error: HY092" ); |
898 | |
899 | __post_internal_error( &statement -> error, |
900 | ERROR_HY092, NULL, |
901 | statement -> connection -> environment -> requested_version ); |
902 | |
903 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
904 | } |
905 | |
906 | ret = SQLSETSTMTOPTION( statement -> connection, |
907 | statement -> driver_stmt, |
908 | attribute, |
909 | value ); |
910 | } |
911 | |
912 | /* |
913 | * take notice of this |
914 | */ |
915 | |
916 | if ( attribute == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) |
917 | { |
918 | statement -> bookmarks_on = (SQLULEN) value; |
919 | } |
920 | |
921 | if ( log_info.log_flag ) |
922 | { |
923 | sprintf( statement -> msg, |
924 | "\n\t\tExit:[%s]" , |
925 | __get_return_status( ret, s1 )); |
926 | |
927 | dm_log_write( __FILE__, |
928 | __LINE__, |
929 | LOG_INFO, |
930 | LOG_INFO, |
931 | statement -> msg ); |
932 | } |
933 | |
934 | return function_return( SQL_HANDLE_STMT, statement, ret ); |
935 | } |
936 | |