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
213static char const rcsid[]= "$RCSfile: SQLSetStmtAttr.c,v $ $Revision: 1.16 $";
214
215SQLRETURN 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
226SQLRETURN 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