1/* 2 * odbc3.c 3 * 4 * $Id: odbc3.c,v 1.32 2007/09/04 06:25:24 source Exp $ 5 * 6 * ODBC 3.x functions 7 * 8 * The iODBC driver manager. 9 * 10 * Copyright (C) 1996-2006 by OpenLink Software <iodbc@openlinksw.com> 11 * All Rights Reserved. 12 * 13 * This software is released under the terms of either of the following 14 * licenses: 15 * 16 * - GNU Library General Public License (see LICENSE.LGPL) 17 * - The BSD License (see LICENSE.BSD). 18 * 19 * Note that the only valid version of the LGPL license as far as this 20 * project is concerned is the original GNU Library General Public License 21 * Version 2, dated June 1991. 22 * 23 * While not mandated by the BSD license, any patches you make to the 24 * iODBC source code may be contributed back into the iODBC project 25 * at your discretion. Contributions will benefit the Open Source and 26 * Data Access community as a whole. Submissions may be made at: 27 * 28 * http://www.iodbc.org 29 * 30 * 31 * GNU Library Generic Public License Version 2 32 * ============================================ 33 * This library is free software; you can redistribute it and/or 34 * modify it under the terms of the GNU Library General Public 35 * License as published by the Free Software Foundation; only 36 * Version 2 of the License dated June 1991. 37 * 38 * This library is distributed in the hope that it will be useful, 39 * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 41 * Library General Public License for more details. 42 * 43 * You should have received a copy of the GNU Library General Public 44 * License along with this library; if not, write to the Free 45 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 46 * 47 * 48 * The BSD License 49 * =============== 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in 58 * the documentation and/or other materials provided with the 59 * distribution. 60 * 3. Neither the name of OpenLink Software Inc. nor the names of its 61 * contributors may be used to endorse or promote products derived 62 * from this software without specific prior written permission. 63 * 64 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 65 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 66 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 67 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 68 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 69 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 70 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 71 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 72 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 73 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 74 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 75 */ 76 77 78#include "iodbc.h" 79 80#include <sql.h> 81#include <sqlext.h> 82#include <iodbcext.h> 83 84#if (ODBCVER >= 0x300) 85#include <sqlucode.h> 86 87#include <unicode.h> 88 89#include <dlproc.h> 90 91#include <herr.h> 92#include <henv.h> 93#include <hdesc.h> 94#include <hdbc.h> 95#include <hstmt.h> 96 97#include <itrace.h> 98 99 100/* 101 * SQL_ATTR_CONNECTION_POOLING value 102 */ 103SQLINTEGER _iodbcdm_attr_connection_pooling = SQL_CP_DEFAULT; 104 105 106/* 107 * Externals 108 */ 109SQLRETURN SQLAllocEnv_Internal (SQLHENV * phenv, int odbc_ver); 110SQLRETURN SQLFreeEnv_Internal (SQLHENV henv); 111SQLRETURN SQLAllocConnect_Internal (SQLHENV henv, SQLHDBC * phdbc); 112SQLRETURN SQLFreeConnect_Internal (SQLHDBC hdbc, int ver); 113SQLRETURN SQLAllocStmt_Internal (SQLHDBC hdbc, SQLHSTMT * phstmt); 114SQLRETURN SQLFreeStmt_Internal (SQLHSTMT hstmt, SQLUSMALLINT fOption); 115SQLRETURN SQLTransact_Internal (SQLHENV henv, SQLHDBC hdbc, SQLUSMALLINT fType); 116 117RETCODE SQL_API 118SQLAllocHandle_Internal ( 119 SQLSMALLINT handleType, 120 SQLHANDLE inputHandle, 121 SQLHANDLE * outputHandlePtr) 122{ 123 switch (handleType) 124 { 125 case SQL_HANDLE_ENV: 126 return SQLAllocEnv_Internal (outputHandlePtr, 0); 127 128 case SQL_HANDLE_DBC: 129 { 130 GENV (genv, inputHandle); 131 132 if (!IS_VALID_HENV (genv)) 133 { 134 return SQL_INVALID_HANDLE; 135 } 136 CLEAR_ERRORS (genv); 137 if (genv->odbc_ver == 0) 138 { 139 PUSHSQLERR (genv->herr, en_HY010); 140 return SQL_ERROR; 141 } 142 143 return SQLAllocConnect_Internal (inputHandle, outputHandlePtr); 144 } 145 146 case SQL_HANDLE_STMT: 147 { 148 CONN (con, inputHandle); 149 150 if (!IS_VALID_HDBC (con)) 151 { 152 return SQL_INVALID_HANDLE; 153 } 154 CLEAR_ERRORS (con); 155 156 return SQLAllocStmt_Internal (inputHandle, outputHandlePtr); 157 } 158 159 case SQL_HANDLE_DESC: 160 { 161 CONN (con, inputHandle); 162 HPROC hproc = SQL_NULL_HPROC; 163 RETCODE retcode; 164 DESC_t *new_desc; 165 166 if (!IS_VALID_HDBC (con)) 167 { 168 return SQL_INVALID_HANDLE; 169 } 170 CLEAR_ERRORS (con); 171 172 if (((ENV_t *)(con->henv))->dodbc_ver == SQL_OV_ODBC2) 173 { 174 PUSHSQLERR (con->herr, en_HYC00); 175 return SQL_ERROR; 176 } 177 if (!outputHandlePtr) 178 { 179 PUSHSQLERR (con->herr, en_HY009); 180 return SQL_ERROR; 181 } 182 183 hproc = _iodbcdm_getproc (con, en_AllocHandle); 184 185 if (hproc == SQL_NULL_HPROC) 186 { 187 PUSHSQLERR (con->herr, en_IM001); 188 return SQL_ERROR; 189 } 190 191 new_desc = (DESC_t *) MEM_ALLOC (sizeof (DESC_t)); 192 if (!new_desc) 193 { 194 PUSHSQLERR (con->herr, en_HY001); 195 return SQL_ERROR; 196 } 197 memset (new_desc, 0, sizeof (DESC_t)); 198 CALL_DRIVER (con, con, retcode, hproc, 199 (handleType, con->dhdbc, &new_desc->dhdesc)); 200 201 if (!SQL_SUCCEEDED (retcode)) 202 { 203 MEM_FREE (new_desc); 204 return SQL_ERROR; 205 } 206 207 new_desc->type = SQL_HANDLE_DESC; 208 new_desc->hdbc = con; 209 new_desc->hstmt = NULL; 210 new_desc->herr = NULL; 211 new_desc->desc_cip = 0; 212 *outputHandlePtr = new_desc; 213 214 new_desc->next = (DESC_t *) con->hdesc; 215 con->hdesc = new_desc; 216 217 return SQL_SUCCESS; 218 } 219 220 default: 221 if (IS_VALID_HDBC (inputHandle)) 222 { 223 CONN (con, inputHandle); 224 PUSHSQLERR (con->herr, en_HY092); 225 return SQL_ERROR; 226 } 227 else if (IS_VALID_HENV (inputHandle)) 228 { 229 GENV (genv, inputHandle); 230 PUSHSQLERR (genv->herr, en_HY092); 231 return SQL_ERROR; 232 } 233 return SQL_INVALID_HANDLE; 234 } 235} 236 237 238RETCODE SQL_API 239SQLAllocHandle ( 240 SQLSMALLINT handleType, 241 SQLHANDLE inputHandle, 242 SQLHANDLE * outputHandlePtr) 243{ 244 int retcode = SQL_SUCCESS; 245 246 if (handleType == SQL_HANDLE_ENV) 247 { 248 /* 249 * One time initialization 250 */ 251 Init_iODBC(); 252 253 ODBC_LOCK (); 254 255 retcode = SQLAllocEnv_Internal (outputHandlePtr, 0); 256 257 /* 258 * Start tracing 259 */ 260 TRACE (trace_SQLAllocHandle (TRACE_ENTER, 261 handleType, inputHandle, outputHandlePtr)); 262 263 TRACE (trace_SQLAllocHandle (TRACE_LEAVE, 264 handleType, inputHandle, outputHandlePtr)); 265 266 ODBC_UNLOCK (); 267 268 return retcode; 269 } 270 271 ODBC_LOCK (); 272 273 TRACE (trace_SQLAllocHandle (TRACE_ENTER, 274 handleType, inputHandle, outputHandlePtr)); 275 276 retcode = 277 SQLAllocHandle_Internal (handleType, inputHandle, outputHandlePtr); 278 279 TRACE (trace_SQLAllocHandle (TRACE_LEAVE, 280 handleType, inputHandle, outputHandlePtr)); 281 282 ODBC_UNLOCK (); 283 284 return retcode; 285} 286 287 288RETCODE SQL_API 289SQLAllocHandleStd ( 290 SQLSMALLINT handleType, 291 SQLHANDLE inputHandle, 292 SQLHANDLE * outputHandlePtr) 293{ 294 int retcode = SQL_SUCCESS; 295 296 if (handleType == SQL_HANDLE_ENV) 297 { 298 /* 299 * One time initialization 300 */ 301 Init_iODBC(); 302 303 ODBC_LOCK (); 304 305 retcode = SQLAllocEnv_Internal (outputHandlePtr, SQL_OV_ODBC3); 306 307 /* 308 * Start tracing 309 */ 310 TRACE (trace_SQLAllocHandle (TRACE_ENTER, 311 handleType, inputHandle, outputHandlePtr)); 312 313 TRACE (trace_SQLAllocHandle (TRACE_LEAVE, 314 handleType, inputHandle, outputHandlePtr)); 315 316 ODBC_UNLOCK (); 317 318 return retcode; 319 } 320 321 ODBC_LOCK (); 322 323 TRACE (trace_SQLAllocHandle (TRACE_ENTER, 324 handleType, inputHandle, outputHandlePtr)); 325 326 retcode = 327 SQLAllocHandle_Internal (handleType, inputHandle, outputHandlePtr); 328 329 TRACE (trace_SQLAllocHandle (TRACE_LEAVE, 330 handleType, inputHandle, outputHandlePtr)); 331 332 ODBC_UNLOCK (); 333 334 return retcode; 335} 336 337 338/**** SQLFreeHandle ****/ 339 340extern unsigned long _iodbc_env_counter; 341 342static RETCODE 343_SQLFreeHandle_ENV ( 344 SQLSMALLINT handleType, 345 SQLHANDLE handle) 346{ 347 int retcode = SQL_SUCCESS; 348 349 ODBC_LOCK (); 350 351 TRACE (trace_SQLFreeHandle (TRACE_ENTER, handleType, handle)); 352 353 retcode = SQLFreeEnv_Internal ((SQLHENV) handle); 354 355 TRACE (trace_SQLFreeHandle (TRACE_LEAVE, handleType, handle)); 356 357 MEM_FREE (handle); 358 359 /* 360 * Close trace after last environment handle is freed 361 */ 362 if (--_iodbc_env_counter == 0) 363 trace_stop(); 364 365 ODBC_UNLOCK (); 366 367 return retcode; 368} 369 370 371static RETCODE 372_SQLFreeHandle_DBC ( 373 SQLSMALLINT handleType, 374 SQLHANDLE handle) 375{ 376 ENTER_HDBC ((SQLHDBC) handle, 1, 377 trace_SQLFreeHandle (TRACE_ENTER, handleType, handle)); 378 379 retcode = SQLFreeConnect_Internal ((SQLHDBC) handle, 3); 380 381 LEAVE_HDBC ((SQLHDBC) handle, 1, 382 trace_SQLFreeHandle (TRACE_LEAVE, handleType, handle); 383 MEM_FREE (handle) 384 ); 385} 386 387static RETCODE 388_SQLFreeHandle_STMT ( 389 SQLSMALLINT handleType, 390 SQLHANDLE handle) 391{ 392 ENTER_STMT ((SQLHSTMT) handle, 393 trace_SQLFreeHandle (TRACE_ENTER, handleType, handle)); 394 395 retcode = SQLFreeStmt_Internal ((SQLHSTMT) handle, SQL_DROP); 396 397 LEAVE_STMT ((SQLHSTMT) handle, 398 trace_SQLFreeHandle (TRACE_LEAVE, handleType, handle); 399 _iodbcdm_dropstmt ((SQLHSTMT) handle); 400 ); 401} 402 403static RETCODE 404_SQLFreeHandle_DESC ( 405 SQLSMALLINT handleType, 406 SQLHANDLE handle) 407{ 408 DESC (pdesc, handle); 409 CONN (pdbc, pdesc->hdbc); 410 HPROC hproc; 411 RETCODE retcode = SQL_SUCCESS; 412 DESC_t *curr_desc; 413 414 if (IS_VALID_HSTMT (pdesc->hstmt)) 415 { /* the desc handle is implicit */ 416 PUSHSQLERR (pdesc->herr, en_HY017); 417 return SQL_ERROR; 418 } 419 CLEAR_ERRORS (pdesc); 420 421 /* remove it from the dbc's list */ 422 curr_desc = (DESC_t *) pdbc->hdesc; 423 while (curr_desc) 424 { 425 if (curr_desc == pdesc) 426 { 427 pdbc->hdesc = pdesc->next; 428 break; 429 } 430 if (curr_desc->next == pdesc) 431 { 432 curr_desc->next = pdesc->next; 433 break; 434 } 435 curr_desc = curr_desc->next; 436 } 437 if (!curr_desc) 438 return SQL_INVALID_HANDLE; 439 440 /* and call the driver's function */ 441 hproc = SQL_NULL_HPROC; 442 if (pdesc->dhdesc) 443 { /* the driver has descriptors */ 444 hproc = _iodbcdm_getproc (pdbc, en_FreeHandle); 445 if (hproc == SQL_NULL_HPROC) 446 { 447 PUSHSQLERR (pdesc->herr, en_IM001); 448 retcode = SQL_ERROR; 449 } 450 else 451 CALL_DRIVER (pdbc, pdesc, retcode, hproc, 452 (handleType, pdesc->dhdesc)); 453 } 454 455 _iodbcdm_freesqlerrlist (pdesc->herr); 456 457 /* invalidate the handle */ 458 pdesc->type = 0; 459 460 return retcode; 461} 462 463 464RETCODE SQL_API 465SQLFreeHandle ( 466 SQLSMALLINT handleType, 467 SQLHANDLE handle) 468{ 469 switch (handleType) 470 { 471 case SQL_HANDLE_ENV: 472 return _SQLFreeHandle_ENV (handleType, handle); 473 474 case SQL_HANDLE_DBC: 475 return _SQLFreeHandle_DBC (handleType, handle); 476 477 case SQL_HANDLE_STMT: 478 return _SQLFreeHandle_STMT (handleType, handle); 479 480 case SQL_HANDLE_DESC: 481 { 482 ENTER_DESC ((SQLHDESC) handle, 483 trace_SQLFreeHandle (TRACE_ENTER, handleType, handle)); 484 485 retcode = _SQLFreeHandle_DESC (handleType, handle); 486 487 LEAVE_DESC ((SQLHDESC) handle, 488 trace_SQLFreeHandle (TRACE_LEAVE, handleType, handle); 489 MEM_FREE (handle); 490 ); 491 } 492 break; 493 494 default: 495 if (IS_VALID_HDBC (handle)) 496 { 497 CONN (con, handle); 498 PUSHSQLERR (con->herr, en_HY092); 499 return SQL_ERROR; 500 } 501 else if (IS_VALID_HENV (handle)) 502 { 503 GENV (genv, handle); 504 PUSHSQLERR (genv->herr, en_HY092); 505 return SQL_ERROR; 506 } 507 } 508 509 return SQL_INVALID_HANDLE; 510} 511 512 513/**** SQLSetEnvAttr ****/ 514 515static RETCODE 516SQLSetEnvAttr_Internal (SQLHENV environmentHandle, 517 SQLINTEGER Attribute, 518 SQLPOINTER ValuePtr, 519 SQLINTEGER StringLength) 520{ 521 GENV (genv, environmentHandle); 522 523 StringLength = StringLength; /*UNUSED*/ 524 525 if (genv != NULL && genv->hdbc) 526 { 527 PUSHSQLERR (genv->herr, en_HY010); 528 return SQL_ERROR; 529 } 530 531 switch (Attribute) 532 { 533 case SQL_ATTR_CONNECTION_POOLING: 534 switch ((SQLINTEGER) (SQLULEN) ValuePtr) 535 { 536 case SQL_CP_OFF: 537 case SQL_CP_ONE_PER_DRIVER: 538 case SQL_CP_ONE_PER_HENV: 539 _iodbcdm_attr_connection_pooling = (SQLINTEGER) (SQLULEN) ValuePtr; 540 return SQL_SUCCESS; 541 542 default: 543 if (genv) 544 PUSHSQLERR (genv->herr, en_HY024); 545 return SQL_ERROR; 546 } 547 548 case SQL_ATTR_CP_MATCH: 549 switch ((SQLINTEGER) (SQLULEN) ValuePtr) 550 { 551 case SQL_CP_STRICT_MATCH: 552 case SQL_CP_RELAXED_MATCH: 553 genv->cp_match = (SQLINTEGER) (SQLULEN) ValuePtr; 554 return SQL_SUCCESS; 555 556 default: 557 PUSHSQLERR (genv->herr, en_HY024); 558 return SQL_ERROR; 559 } 560 561 case SQL_ATTR_ODBC_VERSION: 562 switch ((SQLINTEGER) (SQLULEN) ValuePtr) 563 { 564 case SQL_OV_ODBC2: 565 case SQL_OV_ODBC3: 566 genv->odbc_ver = (SQLINTEGER) (SQLULEN) ValuePtr; 567 return (SQL_SUCCESS); 568 569 default: 570 PUSHSQLERR (genv->herr, en_HY024); 571 return SQL_ERROR; 572 } 573 574 case SQL_ATTR_OUTPUT_NTS: 575 switch ((SQLINTEGER) (SQLULEN) ValuePtr) 576 { 577 case SQL_TRUE: 578 return SQL_SUCCESS; 579 580 case SQL_FALSE: 581 PUSHSQLERR (genv->herr, en_HYC00); 582 return SQL_ERROR; 583 584 default: 585 PUSHSQLERR (genv->herr, en_HY024); 586 return SQL_ERROR; 587 } 588 589 default: 590 PUSHSQLERR (genv->herr, en_HY092); 591 return SQL_ERROR; 592 } 593} 594 595 596RETCODE SQL_API 597SQLSetEnvAttr ( 598 SQLHENV EnvironmentHandle, 599 SQLINTEGER Attribute, 600 SQLPOINTER ValuePtr, 601 SQLINTEGER StringLength) 602{ 603 if (Attribute == SQL_ATTR_CONNECTION_POOLING) 604 { 605 SQLRETURN retcode = SQL_SUCCESS; 606 607 /* ENTER_HENV without EnvironmentHandle check */ 608 ODBC_LOCK (); 609 TRACE (trace_SQLSetEnvAttr (TRACE_ENTER, 610 EnvironmentHandle, 611 Attribute, 612 ValuePtr, StringLength)); 613 614 retcode = SQLSetEnvAttr_Internal ( 615 EnvironmentHandle, 616 Attribute, 617 ValuePtr, StringLength); 618 619 /* LEAVE_HENV without done: label */ 620 TRACE (trace_SQLSetEnvAttr (TRACE_LEAVE, 621 EnvironmentHandle, 622 Attribute, 623 ValuePtr, StringLength)); 624 ODBC_UNLOCK (); 625 return retcode; 626 } 627 else 628 { 629 ENTER_HENV (EnvironmentHandle, 630 trace_SQLSetEnvAttr (TRACE_ENTER, 631 EnvironmentHandle, 632 Attribute, 633 ValuePtr, StringLength)); 634 635 retcode = SQLSetEnvAttr_Internal ( 636 EnvironmentHandle, 637 Attribute, 638 ValuePtr, StringLength); 639 640 LEAVE_HENV (EnvironmentHandle, 641 trace_SQLSetEnvAttr (TRACE_LEAVE, 642 EnvironmentHandle, 643 Attribute, 644 ValuePtr, StringLength)); 645 } 646} 647 648 649static RETCODE 650SQLGetEnvAttr_Internal ( 651 SQLHENV environmentHandle, 652 SQLINTEGER Attribute, 653 SQLPOINTER ValuePtr, 654 SQLINTEGER BufferLength, 655 SQLINTEGER * StringLengthPtr) 656{ 657 GENV (genv, environmentHandle); 658 SQLRETURN retcode = SQL_SUCCESS; 659 660 if (Attribute != SQL_ATTR_CONNECTION_POOLING && 661 Attribute != SQL_ATTR_CP_MATCH && 662 Attribute != SQL_ATTR_ODBC_VERSION && 663 Attribute != SQL_ATTR_OUTPUT_NTS && 664 Attribute != SQL_ATTR_WCHAR_SIZE) 665 { 666 PUSHSQLERR (genv->herr, en_HY092); 667 return SQL_ERROR; 668 } 669 670 /* ODBC DM env attributes */ 671 if (Attribute == SQL_ATTR_ODBC_VERSION) 672 { 673 if (ValuePtr) 674 *((SQLINTEGER *) ValuePtr) = genv->odbc_ver; 675 return SQL_SUCCESS; 676 } 677 if (Attribute == SQL_ATTR_CONNECTION_POOLING) 678 { 679 if (ValuePtr) 680 *((SQLUINTEGER *) ValuePtr) = _iodbcdm_attr_connection_pooling; 681 return SQL_SUCCESS; 682 } 683 if (Attribute == SQL_ATTR_CP_MATCH) 684 { 685 if (ValuePtr) 686 *((SQLUINTEGER *) ValuePtr) = genv->cp_match; 687 return SQL_SUCCESS; 688 } 689 if (Attribute == SQL_ATTR_OUTPUT_NTS) 690 { 691 if (ValuePtr) 692 *((SQLINTEGER *) ValuePtr) = SQL_TRUE; 693 return SQL_SUCCESS; 694 } 695 if (Attribute == SQL_ATTR_WCHAR_SIZE) 696 { 697 if (ValuePtr) 698 *((SQLINTEGER *) ValuePtr) = sizeof(wchar_t); 699 return SQL_SUCCESS; 700 } 701 702 /* fall back to the first driver */ 703 if (IS_VALID_HDBC (genv->hdbc)) 704 { 705 CONN (con, genv->hdbc); 706 HPROC hproc = _iodbcdm_getproc (con, en_GetEnvAttr); 707 if (hproc != SQL_NULL_HPROC) 708 { 709 ENVR (env, con->henv); 710 CALL_DRIVER (con, genv, retcode, hproc, 711 (env->dhenv, Attribute, ValuePtr, BufferLength, 712 StringLengthPtr)); 713 return retcode; 714 } 715 else 716 { /* possibly an ODBC2 driver */ 717 PUSHSQLERR (genv->herr, en_IM001); 718 return SQL_ERROR; 719 } 720 } 721 else 722 { 723 switch ((SQLINTEGER) Attribute) 724 { 725 case SQL_ATTR_CONNECTION_POOLING: 726 if (ValuePtr) 727 *((SQLINTEGER *) ValuePtr) = SQL_CP_OFF; 728 break; 729 730 case SQL_ATTR_CP_MATCH: 731 if (ValuePtr) 732 *((SQLINTEGER *) ValuePtr) = SQL_CP_STRICT_MATCH; 733 break; 734 735 case SQL_ATTR_ODBC_VERSION: 736 if (ValuePtr) 737 *((SQLINTEGER *) ValuePtr) = genv->odbc_ver; 738 break; 739 } 740 } 741 return SQL_SUCCESS; 742} 743 744 745RETCODE SQL_API 746SQLGetEnvAttr ( 747 SQLHENV EnvironmentHandle, 748 SQLINTEGER Attribute, 749 SQLPOINTER ValuePtr, 750 SQLINTEGER BufferLength, 751 SQLINTEGER * StringLengthPtr) 752{ 753 if (Attribute == SQL_ATTR_CONNECTION_POOLING) 754 { 755 SQLRETURN retcode = SQL_SUCCESS; 756 757 /* ENTER_HENV without EnvironmentHandle check */ 758 ODBC_LOCK (); 759 TRACE (trace_SQLGetEnvAttr (TRACE_ENTER, 760 EnvironmentHandle, 761 Attribute, 762 ValuePtr, BufferLength, StringLengthPtr)); 763 764 retcode = SQLGetEnvAttr_Internal ( 765 EnvironmentHandle, 766 Attribute, 767 ValuePtr, BufferLength, StringLengthPtr); 768 769 /* LEAVE_HENV without done: label */ 770 TRACE (trace_SQLGetEnvAttr (TRACE_LEAVE, 771 EnvironmentHandle, 772 Attribute, 773 ValuePtr, BufferLength, StringLengthPtr)); 774 ODBC_UNLOCK (); 775 return retcode; 776 } 777 else 778 { 779 ENTER_HENV (EnvironmentHandle, 780 trace_SQLGetEnvAttr (TRACE_ENTER, 781 EnvironmentHandle, 782 Attribute, 783 ValuePtr, BufferLength, StringLengthPtr)); 784 785 retcode = SQLGetEnvAttr_Internal ( 786 EnvironmentHandle, 787 Attribute, 788 ValuePtr, BufferLength, StringLengthPtr); 789 790 LEAVE_HENV (EnvironmentHandle, 791 trace_SQLGetEnvAttr (TRACE_LEAVE, 792 EnvironmentHandle, 793 Attribute, 794 ValuePtr, BufferLength, StringLengthPtr)); 795 } 796} 797 798 799RETCODE SQL_API 800SQLGetStmtAttr_Internal ( 801 SQLHSTMT statementHandle, 802 SQLINTEGER Attribute, 803 SQLPOINTER ValuePtr, 804 SQLINTEGER BufferLength, 805 SQLINTEGER * StringLengthPtr, 806 SQLCHAR waMode) 807{ 808 STMT (stmt, statementHandle); 809 CONN (pdbc, stmt->hdbc); 810 ENVR (penv, pdbc->henv); 811 HPROC hproc = SQL_NULL_HPROC; 812 SQLRETURN retcode = SQL_SUCCESS; 813 814 waMode = waMode; /*UNUSED*/ 815 816 switch (Attribute) 817 { 818 case SQL_ATTR_IMP_PARAM_DESC: 819 820 if (ValuePtr) 821 { 822 if (IS_VALID_HDESC (stmt->desc[IMP_PARAM_DESC])) 823 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[IMP_PARAM_DESC]; 824 else if (IS_VALID_HDESC (stmt->imp_desc[IMP_PARAM_DESC])) 825 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[IMP_PARAM_DESC]; 826 else 827 { 828 PUSHSQLERR (stmt->herr, en_IM001); 829 return SQL_ERROR; 830 } 831 } 832 if (StringLengthPtr) 833 *StringLengthPtr = SQL_IS_POINTER; 834 return SQL_SUCCESS; 835 836 case SQL_ATTR_APP_PARAM_DESC: 837 838 if (ValuePtr) 839 { 840 if (IS_VALID_HDESC (stmt->desc[APP_PARAM_DESC])) 841 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[APP_PARAM_DESC]; 842 else if (IS_VALID_HDESC (stmt->imp_desc[APP_PARAM_DESC])) 843 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[APP_PARAM_DESC]; 844 else 845 { 846 PUSHSQLERR (stmt->herr, en_IM001); 847 return SQL_ERROR; 848 } 849 } 850 if (StringLengthPtr) 851 *StringLengthPtr = SQL_IS_POINTER; 852 return SQL_SUCCESS; 853 854 case SQL_ATTR_IMP_ROW_DESC: 855 856 if (ValuePtr) 857 { 858 if (IS_VALID_HDESC (stmt->desc[IMP_ROW_DESC])) 859 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[IMP_ROW_DESC]; 860 else if (IS_VALID_HDESC (stmt->imp_desc[IMP_ROW_DESC])) 861 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[IMP_ROW_DESC]; 862 else 863 { 864 PUSHSQLERR (stmt->herr, en_IM001); 865 return SQL_ERROR; 866 } 867 } 868 if (StringLengthPtr) 869 *StringLengthPtr = SQL_IS_POINTER; 870 return SQL_SUCCESS; 871 872 case SQL_ATTR_APP_ROW_DESC: 873 874 if (ValuePtr) 875 { 876 if (IS_VALID_HDESC (stmt->desc[APP_ROW_DESC])) 877 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[APP_ROW_DESC]; 878 else if (IS_VALID_HDESC (stmt->imp_desc[APP_ROW_DESC])) 879 *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[APP_ROW_DESC]; 880 else 881 { 882 PUSHSQLERR (stmt->herr, en_IM001); 883 return SQL_ERROR; 884 } 885 } 886 if (StringLengthPtr) 887 *StringLengthPtr = SQL_IS_POINTER; 888 return SQL_SUCCESS; 889 890 case SQL_ATTR_ROW_ARRAY_SIZE: 891 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 892 { 893 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 894 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 895 ValuePtr, BufferLength, StringLengthPtr)); 896 if (hproc == SQL_NULL_HPROC) 897 { 898 PUSHSQLERR (stmt->herr, en_IM001); 899 return SQL_ERROR; 900 } 901 return retcode; 902 } 903 else 904 { /* an ODBC2 driver */ 905 if (ValuePtr) 906 *((SQLUINTEGER *) ValuePtr) = stmt->row_array_size; 907 return SQL_SUCCESS; 908 } 909 910 case SQL_ATTR_ENABLE_AUTO_IPD: 911 case SQL_ATTR_CURSOR_SENSITIVITY: 912 case SQL_ATTR_CURSOR_SCROLLABLE: 913 case SQL_ATTR_PARAM_BIND_TYPE: 914 case SQL_ATTR_PARAM_OPERATION_PTR: 915 case SQL_ATTR_PARAM_STATUS_PTR: 916 case SQL_ATTR_PARAM_BIND_OFFSET_PTR: 917 case SQL_ATTR_ROW_BIND_OFFSET_PTR: 918 case SQL_ATTR_ROW_OPERATION_PTR: 919 920 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 921 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 922 ValuePtr, BufferLength, StringLengthPtr)); 923 if (hproc == SQL_NULL_HPROC) 924 { 925 PUSHSQLERR (stmt->herr, en_IM001); 926 return SQL_ERROR; 927 } 928 return retcode; 929 930 case SQL_ATTR_FETCH_BOOKMARK_PTR: 931 932 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 933 { 934 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 935 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 936 ValuePtr, BufferLength, StringLengthPtr)); 937 if (hproc == SQL_NULL_HPROC) 938 { 939 PUSHSQLERR (stmt->herr, en_IM001); 940 return SQL_ERROR; 941 } 942 return retcode; 943 } 944 else 945 { /* an ODBC2 driver */ 946 if (ValuePtr) 947 *((SQLPOINTER *) ValuePtr) = stmt->fetch_bookmark_ptr; 948 return SQL_SUCCESS; 949 } 950 951 case SQL_ATTR_ROWS_FETCHED_PTR: 952 953 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 954 { 955 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 956 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 957 ValuePtr, BufferLength, StringLengthPtr)); 958 if (hproc == SQL_NULL_HPROC) 959 { 960 PUSHSQLERR (stmt->herr, en_IM001); 961 return SQL_ERROR; 962 } 963 return retcode; 964 } 965 else 966 { /* an ODBC2 driver */ 967 if (ValuePtr) 968 *((SQLPOINTER *) ValuePtr) = stmt->rows_fetched_ptr; 969 return SQL_SUCCESS; 970 } 971 972 case SQL_ATTR_METADATA_ID: 973 974 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 975 { 976 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 977 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 978 ValuePtr, BufferLength, StringLengthPtr)); 979 if (hproc == SQL_NULL_HPROC) 980 { 981 PUSHSQLERR (stmt->herr, en_IM001); 982 return SQL_ERROR; 983 } 984 return retcode; 985 } 986 else 987 { /* an ODBC2 driver */ 988 if (ValuePtr) 989 *((SQLUINTEGER *) ValuePtr) = SQL_FALSE; 990 return SQL_SUCCESS; 991 } 992 993 case SQL_ATTR_PARAMS_PROCESSED_PTR: 994 995 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 996 { 997 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 998 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 999 ValuePtr, BufferLength, StringLengthPtr)); 1000 if (hproc == SQL_NULL_HPROC) 1001 { 1002 PUSHSQLERR (stmt->herr, en_IM001); 1003 return SQL_ERROR; 1004 } 1005 return retcode; 1006 } 1007 else 1008 { /* an ODBC2 driver */ 1009 if (ValuePtr) 1010 *((SQLUINTEGER **) ValuePtr) = (SQLUINTEGER *) stmt->params_processed_ptr; 1011 return SQL_SUCCESS; 1012 } 1013 1014 case SQL_ATTR_PARAMSET_SIZE: 1015 1016 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1017 { 1018 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1019 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 1020 ValuePtr, BufferLength, StringLengthPtr)); 1021 if (hproc == SQL_NULL_HPROC) 1022 { 1023 PUSHSQLERR (stmt->herr, en_IM001); 1024 return SQL_ERROR; 1025 } 1026 return retcode; 1027 } 1028 else 1029 { /* an ODBC2 driver */ 1030 if (ValuePtr) 1031 *((SQLUINTEGER *) ValuePtr) = stmt->paramset_size; 1032 return SQL_SUCCESS; 1033 } 1034 1035 case SQL_ATTR_ROW_STATUS_PTR: 1036 1037 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1038 { 1039 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1040 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 1041 ValuePtr, BufferLength, StringLengthPtr)); 1042 if (hproc == SQL_NULL_HPROC) 1043 { 1044 PUSHSQLERR (stmt->herr, en_IM001); 1045 return SQL_ERROR; 1046 } 1047 return retcode; 1048 } 1049 else 1050 { /* an ODBC2 driver */ 1051 if (ValuePtr) 1052 *((SQLUINTEGER **) ValuePtr) = stmt->row_status_allocated == SQL_FALSE ? 1053 (SQLUINTEGER *) stmt->row_status_ptr : 1054 NULL; 1055 return SQL_SUCCESS; 1056 } 1057 1058 case SQL_ATTR_ASYNC_ENABLE: 1059 case SQL_ATTR_MAX_ROWS: 1060 case SQL_ATTR_QUERY_TIMEOUT: 1061 case SQL_ATTR_CONCURRENCY: 1062 case SQL_ROWSET_SIZE: 1063 case SQL_ATTR_CURSOR_TYPE: 1064 case SQL_ATTR_KEYSET_SIZE: 1065 case SQL_ATTR_NOSCAN: 1066 case SQL_ATTR_RETRIEVE_DATA: 1067 case SQL_ATTR_ROW_BIND_TYPE: 1068 case SQL_ATTR_ROW_NUMBER: 1069 case SQL_ATTR_SIMULATE_CURSOR: 1070 case SQL_ATTR_USE_BOOKMARKS: 1071 case SQL_ATTR_MAX_LENGTH: 1072 1073 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1074 { 1075 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1076 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, 1077 ValuePtr, BufferLength, StringLengthPtr)); 1078 if (hproc == SQL_NULL_HPROC) 1079 { 1080 PUSHSQLERR (stmt->herr, en_IM001); 1081 return SQL_ERROR; 1082 } 1083 return retcode; 1084 } 1085 else 1086 { /* an ODBC2 driver */ 1087 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_GetStmtOption)) 1088 != SQL_NULL_HPROC) 1089 { 1090 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1091 (stmt->dhstmt, Attribute, ValuePtr)); 1092 return retcode; 1093 } 1094 else 1095 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_GetStmtOptionA)) 1096 != SQL_NULL_HPROC) 1097 { 1098 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1099 (stmt->dhstmt, Attribute, ValuePtr)); 1100 return retcode; 1101 } 1102 else 1103 { 1104 PUSHSQLERR (stmt->herr, en_IM001); 1105 return SQL_ERROR; 1106 } 1107 } 1108 1109 default: 1110 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1111 penv->unicode_driver, en_GetStmtAttr, (stmt->dhstmt, Attribute, ValuePtr, 1112 BufferLength, StringLengthPtr)); 1113 if (hproc == SQL_NULL_HPROC) 1114 { 1115 PUSHSQLERR (stmt->herr, en_IM001); 1116 return SQL_ERROR; 1117 } 1118 return retcode; 1119 } 1120 return SQL_SUCCESS; 1121} 1122 1123 1124RETCODE SQL_API 1125SQLGetStmtAttr ( 1126 SQLHSTMT statementHandle, 1127 SQLINTEGER Attribute, 1128 SQLPOINTER ValuePtr, 1129 SQLINTEGER BufferLength, 1130 SQLINTEGER * StringLengthPtr) 1131{ 1132 ENTER_STMT (statementHandle, 1133 trace_SQLGetStmtAttr (TRACE_ENTER, 1134 statementHandle, 1135 Attribute, 1136 ValuePtr, BufferLength, StringLengthPtr)); 1137 1138 retcode = SQLGetStmtAttr_Internal(statementHandle, Attribute, ValuePtr, 1139 BufferLength, StringLengthPtr, 'A'); 1140 1141 LEAVE_STMT (statementHandle, 1142 trace_SQLGetStmtAttr (TRACE_LEAVE, 1143 statementHandle, 1144 Attribute, 1145 ValuePtr, BufferLength, StringLengthPtr)); 1146} 1147 1148 1149RETCODE SQL_API 1150SQLGetStmtAttrA ( 1151 SQLHSTMT statementHandle, 1152 SQLINTEGER Attribute, 1153 SQLPOINTER ValuePtr, 1154 SQLINTEGER BufferLength, 1155 SQLINTEGER * StringLengthPtr) 1156{ 1157 ENTER_STMT (statementHandle, 1158 trace_SQLGetStmtAttr (TRACE_ENTER, 1159 statementHandle, 1160 Attribute, 1161 ValuePtr, BufferLength, StringLengthPtr)); 1162 1163 retcode = SQLGetStmtAttr_Internal(statementHandle, Attribute, ValuePtr, 1164 BufferLength, StringLengthPtr, 'A'); 1165 1166 LEAVE_STMT (statementHandle, 1167 trace_SQLGetStmtAttr (TRACE_LEAVE, 1168 statementHandle, 1169 Attribute, 1170 ValuePtr, BufferLength, StringLengthPtr)); 1171} 1172 1173 1174RETCODE SQL_API 1175SQLGetStmtAttrW ( 1176 SQLHSTMT statementHandle, 1177 SQLINTEGER Attribute, 1178 SQLPOINTER ValuePtr, 1179 SQLINTEGER BufferLength, 1180 SQLINTEGER * StringLengthPtr) 1181{ 1182 ENTER_STMT (statementHandle, 1183 trace_SQLGetStmtAttrW (TRACE_ENTER, 1184 statementHandle, 1185 Attribute, 1186 ValuePtr, BufferLength, StringLengthPtr)); 1187 1188 retcode = SQLGetStmtAttr_Internal ( 1189 statementHandle, 1190 Attribute, 1191 ValuePtr, BufferLength, StringLengthPtr, 1192 'W'); 1193 1194 LEAVE_STMT (statementHandle, 1195 trace_SQLGetStmtAttrW (TRACE_LEAVE, 1196 statementHandle, 1197 Attribute, 1198 ValuePtr, BufferLength, StringLengthPtr)); 1199} 1200 1201 1202/**** SQLSetStmtAttr ****/ 1203 1204RETCODE SQL_API 1205SQLSetStmtAttr_Internal ( 1206 SQLHSTMT statementHandle, 1207 SQLINTEGER Attribute, 1208 SQLPOINTER ValuePtr, 1209 SQLINTEGER StringLength, 1210 SQLCHAR waMode) 1211{ 1212 STMT (stmt, statementHandle); 1213 CONN (pdbc, stmt->hdbc); 1214 ENVR (penv, pdbc->henv); 1215 HPROC hproc = SQL_NULL_HPROC; 1216 SQLRETURN retcode = SQL_SUCCESS; 1217 1218 waMode = waMode; /*UNUSED*/ 1219 1220 if (stmt->state == en_stmt_needdata) 1221 { 1222 PUSHSQLERR (stmt->herr, en_HY010); 1223 return SQL_ERROR; 1224 } 1225 1226 switch (Attribute) 1227 { 1228 1229 case SQL_ATTR_APP_PARAM_DESC: 1230 1231 if (ValuePtr == SQL_NULL_HDESC || ValuePtr == stmt->imp_desc[APP_PARAM_DESC]) 1232 { 1233 HDESC hdesc = ValuePtr == SQL_NULL_HDESC ? ValuePtr : stmt->imp_desc[APP_PARAM_DESC]->dhdesc; 1234 1235 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1236 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1237 hdesc, StringLength)); 1238 if (hproc == SQL_NULL_HPROC) 1239 { 1240 PUSHSQLERR (stmt->herr, en_IM001); 1241 return SQL_ERROR; 1242 } 1243 if (!SQL_SUCCEEDED (retcode)) 1244 return SQL_ERROR; 1245 1246 stmt->desc[APP_PARAM_DESC] = SQL_NULL_HDESC; 1247 return SQL_SUCCESS; 1248 } 1249 1250 if (!IS_VALID_HDESC (ValuePtr)) 1251 { 1252 PUSHSQLERR (stmt->herr, en_HY024); 1253 return SQL_ERROR; 1254 } 1255 else 1256 { 1257 DESC (pdesc, ValuePtr); 1258 if (pdesc->hdbc != stmt->hdbc || IS_VALID_HSTMT (pdesc->hstmt)) 1259 { 1260 PUSHSQLERR (stmt->herr, en_HY017); 1261 return SQL_ERROR; 1262 } 1263 1264 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1265 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1266 pdesc->dhdesc, StringLength)); 1267 if (hproc == SQL_NULL_HPROC) 1268 { 1269 PUSHSQLERR (stmt->herr, en_IM001); 1270 return SQL_ERROR; 1271 } 1272 if (!SQL_SUCCEEDED (retcode)) 1273 return SQL_ERROR; 1274 1275 stmt->desc[APP_PARAM_DESC] = (DESC_t *) ValuePtr; 1276 return SQL_SUCCESS; 1277 } 1278 1279 case SQL_ATTR_APP_ROW_DESC: 1280 1281 if (ValuePtr == SQL_NULL_HDESC || ValuePtr == stmt->imp_desc[APP_ROW_DESC]) 1282 { 1283 HDESC hdesc = ValuePtr == SQL_NULL_HDESC ? ValuePtr : stmt->imp_desc[APP_ROW_DESC]->dhdesc; 1284 1285 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1286 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1287 hdesc, StringLength)); 1288 if (hproc == SQL_NULL_HPROC) 1289 { 1290 PUSHSQLERR (stmt->herr, en_IM001); 1291 return SQL_ERROR; 1292 } 1293 if (!SQL_SUCCEEDED (retcode)) 1294 return SQL_ERROR; 1295 1296 stmt->desc[APP_ROW_DESC] = SQL_NULL_HDESC; 1297 return SQL_SUCCESS; 1298 } 1299 1300 if (!IS_VALID_HDESC (ValuePtr)) 1301 { 1302 PUSHSQLERR (stmt->herr, en_HY024); 1303 return SQL_ERROR; 1304 } 1305 else 1306 { 1307 DESC (pdesc, ValuePtr); 1308 if (pdesc->hdbc != stmt->hdbc || IS_VALID_HSTMT (pdesc->hstmt)) 1309 { 1310 PUSHSQLERR (stmt->herr, en_HY017); 1311 return SQL_ERROR; 1312 } 1313 1314 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1315 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1316 pdesc->dhdesc, StringLength)); 1317 if (hproc == SQL_NULL_HPROC) 1318 { 1319 PUSHSQLERR (stmt->herr, en_IM001); 1320 return SQL_ERROR; 1321 } 1322 if (!SQL_SUCCEEDED (retcode)) 1323 return SQL_ERROR; 1324 1325 stmt->desc[APP_ROW_DESC] = (DESC_t *) ValuePtr; 1326 return SQL_SUCCESS; 1327 } 1328 1329 case SQL_ATTR_CURSOR_SCROLLABLE: 1330 case SQL_ATTR_CURSOR_SENSITIVITY: 1331 case SQL_ATTR_ENABLE_AUTO_IPD: 1332 case SQL_ATTR_METADATA_ID: 1333 case SQL_ATTR_PARAM_BIND_OFFSET_PTR: 1334 case SQL_ATTR_PARAM_BIND_TYPE: 1335 case SQL_ATTR_PARAM_OPERATION_PTR: 1336 case SQL_ATTR_PARAM_STATUS_PTR: 1337 case SQL_ATTR_ROW_BIND_OFFSET_PTR: 1338 case SQL_ATTR_ROW_OPERATION_PTR: 1339 1340 1341 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1342 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1343 ValuePtr, StringLength)); 1344 if (hproc == SQL_NULL_HPROC) 1345 { 1346 PUSHSQLERR (stmt->herr, en_IM001); 1347 return SQL_ERROR; 1348 } 1349 return retcode; 1350 1351 case SQL_ATTR_ROWS_FETCHED_PTR: 1352 1353 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1354 { 1355 1356 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1357 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1358 ValuePtr, StringLength)); 1359 if (hproc == SQL_NULL_HPROC) 1360 { 1361 PUSHSQLERR (stmt->herr, en_IM001); 1362 return SQL_ERROR; 1363 } 1364 1365 return retcode; 1366 } 1367 else 1368 { /* an ODBC2 driver */ 1369 stmt->rows_fetched_ptr = ValuePtr; 1370 return SQL_SUCCESS; 1371 } 1372 1373 case SQL_ATTR_FETCH_BOOKMARK_PTR: 1374 1375 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1376 { 1377 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1378 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1379 ValuePtr, StringLength)); 1380 if (hproc == SQL_NULL_HPROC) 1381 { 1382 PUSHSQLERR (stmt->herr, en_IM001); 1383 return SQL_ERROR; 1384 } 1385 1386 return retcode; 1387 } 1388 else 1389 { /* an ODBC2 driver */ 1390 stmt->fetch_bookmark_ptr = ValuePtr; 1391 return SQL_SUCCESS; 1392 } 1393 1394 case SQL_ATTR_PARAMS_PROCESSED_PTR: 1395 1396 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1397 { 1398 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1399 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1400 ValuePtr, StringLength)); 1401 if (hproc == SQL_NULL_HPROC) 1402 { 1403 PUSHSQLERR (stmt->herr, en_IM001); 1404 return SQL_ERROR; 1405 } 1406 1407 return retcode; 1408 } 1409 else 1410 { /* an ODBC2 driver */ 1411 stmt->params_processed_ptr = ValuePtr; 1412 return SQL_SUCCESS; 1413 } 1414 1415 case SQL_ATTR_PARAMSET_SIZE: 1416 1417 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1418 { 1419 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1420 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1421 ValuePtr, StringLength)); 1422 if (hproc == SQL_NULL_HPROC) 1423 { 1424 PUSHSQLERR (stmt->herr, en_IM001); 1425 return SQL_ERROR; 1426 } 1427 1428 return retcode; 1429 } 1430 else 1431 { /* an ODBC2 driver */ 1432 stmt->paramset_size = (SQLUINTEGER) (SQLULEN) ValuePtr; 1433 return SQL_SUCCESS; 1434 } 1435 1436 case SQL_ATTR_ROW_ARRAY_SIZE: 1437 1438 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1439 { 1440 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1441 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1442 ValuePtr, StringLength)); 1443 if (hproc == SQL_NULL_HPROC) 1444 { 1445 PUSHSQLERR (stmt->herr, en_IM001); 1446 return SQL_ERROR; 1447 } 1448 1449 if (SQL_SUCCEEDED (retcode)) 1450 { 1451 stmt->rowset_size = Attribute; 1452 if (retcode == SQL_SUCCESS_WITH_INFO) 1453 { 1454 SQLUINTEGER data; 1455 if (SQLGetStmtAttr_Internal (statementHandle, SQL_ROWSET_SIZE, &data, 1456 0, NULL, 'A') == SQL_SUCCESS) 1457 stmt->rowset_size = data; 1458 } 1459 } 1460 return retcode; 1461 } 1462 else 1463 { /* an ODBC2 driver */ 1464 if ((SQLUINTEGER) (SQLULEN) ValuePtr < 1) 1465 { 1466 PUSHSQLERR (stmt->herr, en_HY024); 1467 return SQL_ERROR; 1468 } 1469 stmt->row_array_size = (SQLUINTEGER) (SQLULEN) ValuePtr; 1470 1471 /* reallocate the row_status_ptr */ 1472 if (stmt->row_status_ptr && stmt->row_status_allocated == SQL_TRUE) 1473 { 1474 MEM_FREE (stmt->row_status_ptr); 1475 stmt->row_status_allocated = SQL_FALSE; 1476 } 1477 stmt->row_status_ptr = MEM_ALLOC (sizeof (SQLUINTEGER) * stmt->row_array_size); 1478 if (!stmt->row_status_ptr) 1479 { 1480 PUSHSQLERR (stmt->herr, en_HY001); 1481 return SQL_ERROR; 1482 } 1483 stmt->row_status_allocated = SQL_TRUE; 1484 1485 /* 1486 * Tell the driver the rowset size has changed 1487 */ 1488 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_SetStmtOption)) 1489 != SQL_NULL_HPROC) 1490 { 1491 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1492 (stmt->dhstmt, SQL_ROWSET_SIZE, stmt->row_array_size)); 1493 1494 if (SQL_SUCCEEDED (retcode)) 1495 { 1496 stmt->rowset_size = Attribute;; 1497 if (retcode == SQL_SUCCESS_WITH_INFO) 1498 { 1499 SQLUINTEGER data; 1500 if (SQLGetStmtOption_Internal (statementHandle, SQL_ROWSET_SIZE, 1501 &data) == SQL_SUCCESS) 1502 stmt->rowset_size = data; 1503 } 1504 } 1505 return retcode; 1506 } 1507 else 1508 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_SetStmtOptionA)) 1509 != SQL_NULL_HPROC) 1510 { 1511 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1512 (stmt->dhstmt, SQL_ROWSET_SIZE, stmt->row_array_size)); 1513 1514 if (SQL_SUCCEEDED (retcode)) 1515 { 1516 stmt->rowset_size = Attribute;; 1517 if (retcode == SQL_SUCCESS_WITH_INFO) 1518 { 1519 SQLUINTEGER data; 1520 if (SQLGetStmtOption_Internal (statementHandle, SQL_ROWSET_SIZE, 1521 &data) == SQL_SUCCESS) 1522 stmt->rowset_size = data; 1523 } 1524 } 1525 return retcode; 1526 } 1527 else 1528 { 1529 PUSHSQLERR (stmt->herr, en_IM001); 1530 return SQL_ERROR; 1531 } 1532 1533 return SQL_SUCCESS; 1534 } 1535 1536 case SQL_ATTR_ROW_STATUS_PTR: 1537 1538 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1539 { 1540 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1541 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1542 ValuePtr, StringLength)); 1543 if (hproc == SQL_NULL_HPROC) 1544 { 1545 PUSHSQLERR (stmt->herr, en_IM001); 1546 return SQL_ERROR; 1547 } 1548 1549 return retcode; 1550 } 1551 else 1552 { /* an ODBC2 driver */ 1553 /* free the implicit row status ptr (if any) */ 1554 if (stmt->row_status_ptr && stmt->row_status_allocated == SQL_TRUE) 1555 { 1556 MEM_FREE (stmt->row_status_ptr); 1557 stmt->row_status_allocated = SQL_FALSE; 1558 } 1559 stmt->row_status_ptr = ValuePtr; 1560 return SQL_SUCCESS; 1561 } 1562 1563 case SQL_ATTR_ASYNC_ENABLE: 1564 case SQL_ATTR_CONCURRENCY: 1565 case SQL_ATTR_CURSOR_TYPE: 1566 case SQL_ATTR_KEYSET_SIZE: 1567 case SQL_ATTR_MAX_ROWS: 1568 case SQL_ATTR_NOSCAN: 1569 case SQL_ATTR_QUERY_TIMEOUT: 1570 case SQL_ATTR_RETRIEVE_DATA: 1571 case SQL_ATTR_ROW_BIND_TYPE: 1572 case SQL_ATTR_ROW_NUMBER: 1573 case SQL_ATTR_SIMULATE_CURSOR: 1574 case SQL_ATTR_USE_BOOKMARKS: 1575 case SQL_ROWSET_SIZE: 1576 case SQL_ATTR_MAX_LENGTH: 1577 1578 if (((ENV_t *) ((DBC_t *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) 1579 { 1580 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, 1581 penv->unicode_driver, en_SetStmtAttr, (stmt->dhstmt, Attribute, 1582 ValuePtr, StringLength)); 1583 if (hproc == SQL_NULL_HPROC) 1584 { 1585 PUSHSQLERR (stmt->herr, en_IM001); 1586 return SQL_ERROR; 1587 } 1588 1589 if (Attribute == SQL_ATTR_ROW_BIND_TYPE && SQL_SUCCEEDED (retcode)) 1590 stmt->bind_type = Attribute; 1591 1592 return retcode; 1593 } 1594 else 1595 { /* an ODBC2 driver */ 1596 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_SetStmtOption)) 1597 != SQL_NULL_HPROC) 1598 { 1599 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1600 (stmt->dhstmt, Attribute, ValuePtr)); 1601 if (Attribute == SQL_ATTR_ROW_BIND_TYPE && SQL_SUCCEEDED (retcode)) 1602 stmt->bind_type = Attribute; 1603 return retcode; 1604 } 1605 else 1606 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_SetStmtOptionA)) 1607 != SQL_NULL_HPROC) 1608 { 1609 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1610 (stmt->dhstmt, Attribute, ValuePtr)); 1611 if (Attribute == SQL_ATTR_ROW_BIND_TYPE && SQL_SUCCEEDED (retcode)) 1612 stmt->bind_type = Attribute; 1613 return retcode; 1614 } 1615 else 1616 { 1617 PUSHSQLERR (stmt->herr, en_IM001); 1618 return SQL_ERROR; 1619 } 1620 } 1621 default: 1622 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_SetStmtOption)) 1623 != SQL_NULL_HPROC) 1624 { 1625 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1626 (stmt->dhstmt, Attribute, ValuePtr)); 1627 return retcode; 1628 } 1629 else 1630 if ((hproc = _iodbcdm_getproc (stmt->hdbc, en_SetStmtOptionA)) 1631 != SQL_NULL_HPROC) 1632 { 1633 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 1634 (stmt->dhstmt, Attribute, ValuePtr)); 1635 1636 return retcode; 1637 } 1638 else 1639 { 1640 PUSHSQLERR (stmt->herr, en_IM001); 1641 1642 return SQL_ERROR; 1643 } 1644 } 1645 1646 return SQL_SUCCESS; 1647} 1648 1649 1650RETCODE SQL_API 1651SQLSetStmtAttr ( 1652 SQLHSTMT statementHandle, 1653 SQLINTEGER Attribute, 1654 SQLPOINTER ValuePtr, 1655 SQLINTEGER StringLength) 1656{ 1657 ENTER_STMT (statementHandle, 1658 trace_SQLSetStmtAttr (TRACE_ENTER, 1659 statementHandle, 1660 Attribute, 1661 ValuePtr, 1662 StringLength)); 1663 1664 retcode = SQLSetStmtAttr_Internal( 1665 statementHandle, 1666 Attribute, 1667 ValuePtr, 1668 StringLength, 1669 'A'); 1670 1671 LEAVE_STMT (statementHandle, 1672 trace_SQLSetStmtAttr (TRACE_LEAVE, 1673 statementHandle, 1674 Attribute, 1675 ValuePtr, 1676 StringLength)); 1677} 1678 1679 1680RETCODE SQL_API 1681SQLSetStmtAttrA ( 1682 SQLHSTMT statementHandle, 1683 SQLINTEGER Attribute, 1684 SQLPOINTER ValuePtr, 1685 SQLINTEGER StringLength) 1686{ 1687 ENTER_STMT (statementHandle, 1688 trace_SQLSetStmtAttr (TRACE_ENTER, 1689 statementHandle, 1690 Attribute, 1691 ValuePtr, 1692 StringLength)); 1693 1694 retcode = SQLSetStmtAttr_Internal( 1695 statementHandle, 1696 Attribute, 1697 ValuePtr, 1698 StringLength, 1699 'A'); 1700 1701 LEAVE_STMT (statementHandle, 1702 trace_SQLSetStmtAttr (TRACE_LEAVE, 1703 statementHandle, 1704 Attribute, 1705 ValuePtr, 1706 StringLength)); 1707} 1708 1709 1710RETCODE SQL_API 1711SQLSetStmtAttrW ( 1712 SQLHSTMT statementHandle, 1713 SQLINTEGER Attribute, 1714 SQLPOINTER ValuePtr, 1715 SQLINTEGER StringLength) 1716{ 1717 ENTER_STMT (statementHandle, 1718 trace_SQLSetStmtAttrW (TRACE_ENTER, 1719 statementHandle, 1720 Attribute, 1721 ValuePtr, 1722 StringLength)); 1723 1724 retcode = SQLSetStmtAttr_Internal( 1725 statementHandle, 1726 Attribute, 1727 ValuePtr, 1728 StringLength, 1729 'W'); 1730 1731 LEAVE_STMT (statementHandle, 1732 trace_SQLSetStmtAttrW (TRACE_LEAVE, 1733 statementHandle, 1734 Attribute, 1735 ValuePtr, 1736 StringLength)); 1737} 1738 1739 1740static RETCODE 1741SQLSetConnectAttr_Internal ( 1742 SQLHDBC connectionHandle, 1743 SQLINTEGER Attribute, 1744 SQLPOINTER ValuePtr, 1745 SQLINTEGER StringLength, 1746 SQLCHAR waMode) 1747{ 1748 CONN (con, connectionHandle); 1749 ENVR (penv, con->henv); 1750 HPROC hproc = SQL_NULL_HPROC; 1751 HPROC hproc2 = SQL_NULL_HPROC; 1752 SQLRETURN retcode = SQL_SUCCESS; 1753 void * _ValuePtr = NULL; 1754 SWORD unicode_driver = (penv ? penv->unicode_driver : 0); 1755 SQLUINTEGER odbc_ver; 1756 SQLUINTEGER dodbc_ver; 1757 1758 odbc_ver = ((GENV_t *) con->genv)->odbc_ver; 1759 dodbc_ver = (penv != SQL_NULL_HENV) ? penv->dodbc_ver : odbc_ver; 1760 1761 if (con->state == en_dbc_needdata) 1762 { 1763 PUSHSQLERR (con->herr, en_HY010); 1764 return SQL_ERROR; 1765 } 1766 1767 if (penv && 1768 ((unicode_driver && waMode != 'W') 1769 || (!unicode_driver && waMode == 'W'))) 1770 { 1771 switch(Attribute) 1772 { 1773 case SQL_ATTR_CURRENT_CATALOG: 1774 case SQL_ATTR_TRACEFILE: 1775 case SQL_ATTR_TRANSLATE_LIB: 1776 1777 if (waMode != 'W') 1778 { 1779 /* ansi=>unicode*/ 1780 _ValuePtr = dm_SQL_A2W((SQLCHAR *) ValuePtr, StringLength); 1781 } 1782 else 1783 { 1784 /* unicode=>ansi*/ 1785 StringLength = (StringLength != SQL_NTS) ? (SQLINTEGER) (StringLength / sizeof(wchar_t)) : SQL_NTS; 1786 _ValuePtr = dm_SQL_W2A((SQLWCHAR *) ValuePtr, StringLength); 1787 } 1788 ValuePtr = _ValuePtr; 1789 StringLength = SQL_NTS; 1790 break; 1791 } 1792 } 1793 1794 GET_UHPROC(con, hproc2, en_SetConnectOption, unicode_driver); 1795 1796 if (dodbc_ver == SQL_OV_ODBC3 && 1797 ( odbc_ver == SQL_OV_ODBC3 1798 || (odbc_ver == SQL_OV_ODBC2 && hproc2 == SQL_NULL_HPROC))) 1799 { 1800 CALL_UDRIVER(con, con, retcode, hproc, unicode_driver, 1801 en_SetConnectAttr, (con->dhdbc, Attribute, ValuePtr, StringLength)); 1802 if (hproc != SQL_NULL_HPROC) 1803 return retcode; 1804 } 1805 1806 switch (Attribute) 1807 { 1808 1809 case SQL_ATTR_AUTO_IPD: 1810 PUSHSQLERR (con->herr, en_HY092); 1811 return SQL_ERROR; 1812 1813 default: 1814 retcode = _iodbcdm_SetConnectOption (con, Attribute, 1815 (SQLULEN) ValuePtr, waMode); 1816 return retcode; 1817 } 1818} 1819 1820 1821RETCODE SQL_API 1822SQLSetConnectAttr ( 1823 SQLHDBC connectionHandle, 1824 SQLINTEGER Attribute, 1825 SQLPOINTER ValuePtr, 1826 SQLINTEGER StringLength) 1827{ 1828 ENTER_HDBC (connectionHandle, 0, 1829 trace_SQLSetConnectAttr (TRACE_ENTER, 1830 connectionHandle, 1831 Attribute, 1832 ValuePtr, StringLength)); 1833 1834 retcode = SQLSetConnectAttr_Internal ( 1835 connectionHandle, 1836 Attribute, 1837 ValuePtr, StringLength, 1838 'A'); 1839 1840 LEAVE_HDBC (connectionHandle, 0, 1841 trace_SQLSetConnectAttr (TRACE_LEAVE, 1842 connectionHandle, 1843 Attribute, 1844 ValuePtr, StringLength)); 1845} 1846 1847 1848RETCODE SQL_API 1849SQLSetConnectAttrA ( 1850 SQLHDBC connectionHandle, 1851 SQLINTEGER Attribute, 1852 SQLPOINTER ValuePtr, 1853 SQLINTEGER StringLength) 1854{ 1855 ENTER_HDBC (connectionHandle, 0, 1856 trace_SQLSetConnectAttr (TRACE_ENTER, 1857 connectionHandle, 1858 Attribute, 1859 ValuePtr, StringLength)); 1860 1861 retcode = SQLSetConnectAttr_Internal ( 1862 connectionHandle, 1863 Attribute, 1864 ValuePtr, StringLength, 1865 'A'); 1866 1867 LEAVE_HDBC (connectionHandle, 0, 1868 trace_SQLSetConnectAttr (TRACE_LEAVE, 1869 connectionHandle, 1870 Attribute, 1871 ValuePtr, StringLength)); 1872} 1873 1874 1875RETCODE SQL_API 1876SQLSetConnectAttrW ( 1877 SQLHDBC connectionHandle, 1878 SQLINTEGER Attribute, 1879 SQLPOINTER ValuePtr, 1880 SQLINTEGER StringLength) 1881{ 1882 ENTER_HDBC (connectionHandle, 0, 1883 trace_SQLSetConnectAttrW (TRACE_ENTER, 1884 connectionHandle, 1885 Attribute, 1886 ValuePtr, StringLength)); 1887 1888 retcode = SQLSetConnectAttr_Internal ( 1889 connectionHandle, 1890 Attribute, 1891 ValuePtr, StringLength, 1892 'W'); 1893 1894 LEAVE_HDBC (connectionHandle, 0, 1895 trace_SQLSetConnectAttrW (TRACE_LEAVE, 1896 connectionHandle, 1897 Attribute, 1898 ValuePtr, StringLength)); 1899} 1900 1901 1902static RETCODE 1903SQLGetConnectAttr_Internal ( 1904 SQLHDBC connectionHandle, 1905 SQLINTEGER Attribute, 1906 SQLPOINTER ValuePtr, 1907 SQLINTEGER StringLength, 1908 SQLINTEGER * StringLengthPtr, 1909 SQLCHAR waMode) 1910{ 1911 CONN (con, connectionHandle); 1912 ENVR (penv, con->henv); 1913 HPROC hproc = SQL_NULL_HPROC; 1914 HPROC hproc2 = SQL_NULL_HPROC; 1915 RETCODE retcode = SQL_SUCCESS; 1916 void * _Value = NULL; 1917 void * valueOut = ValuePtr; 1918 SWORD unicode_driver = (penv ? penv->unicode_driver : 0); 1919 SQLUINTEGER odbc_ver; 1920 SQLUINTEGER dodbc_ver; 1921 1922 odbc_ver = ((GENV_t *) con->genv)->odbc_ver; 1923 dodbc_ver = (penv != SQL_NULL_HENV) ? penv->dodbc_ver : odbc_ver; 1924 1925 if (con->state == en_dbc_needdata) 1926 { 1927 PUSHSQLERR (con->herr, en_HY010); 1928 return SQL_ERROR; 1929 } 1930 1931 if (penv && 1932 ((unicode_driver && waMode != 'W') 1933 || (!unicode_driver && waMode == 'W'))) 1934 { 1935 switch(Attribute) 1936 { 1937 case SQL_ATTR_CURRENT_CATALOG: 1938 case SQL_ATTR_TRACEFILE: 1939 case SQL_ATTR_TRANSLATE_LIB: 1940 1941 if (waMode != 'W') 1942 { 1943 /* ansi=>unicode*/ 1944 StringLength *= sizeof(wchar_t); 1945 if ((_Value = malloc(StringLength + 1)) == NULL) 1946 { 1947 PUSHSQLERR (con->herr, en_HY001); 1948 return SQL_ERROR; 1949 } 1950 } 1951 else 1952 { 1953 /* unicode=>ansi*/ 1954 StringLength /= sizeof(wchar_t); 1955 if ((_Value = malloc(StringLength + 1)) == NULL) 1956 { 1957 PUSHSQLERR (con->herr, en_HY001); 1958 return SQL_ERROR; 1959 } 1960 } 1961 valueOut = _Value; 1962 break; 1963 } 1964 } 1965 1966 GET_UHPROC(con, hproc2, en_GetConnectOption, unicode_driver); 1967 1968 if (dodbc_ver == SQL_OV_ODBC3 && 1969 ( odbc_ver == SQL_OV_ODBC3 1970 || (odbc_ver == SQL_OV_ODBC2 && hproc2 == SQL_NULL_HPROC))) 1971 { 1972 CALL_UDRIVER(con, con, retcode, hproc, unicode_driver, 1973 en_GetConnectAttr, (con->dhdbc, Attribute, valueOut, StringLength, 1974 StringLengthPtr)); 1975 } 1976 1977 if (hproc != SQL_NULL_HPROC) 1978 { 1979 if (ValuePtr 1980 && SQL_SUCCEEDED (retcode) 1981 && ((unicode_driver && waMode != 'W') 1982 || (!unicode_driver && waMode == 'W'))) 1983 { 1984 switch(Attribute) 1985 { 1986 case SQL_ATTR_CURRENT_CATALOG: 1987 case SQL_ATTR_TRACEFILE: 1988 case SQL_ATTR_TRANSLATE_LIB: 1989 if (waMode != 'W') 1990 { 1991 /* ansi<=unicode*/ 1992 SQLSMALLINT retlen; 1993 1994 dm_StrCopyOut2_W2A ((SQLWCHAR *) valueOut, 1995 (SQLCHAR *) ValuePtr, 1996 StringLength / sizeof(wchar_t), &retlen); 1997 if (StringLengthPtr) 1998 *StringLengthPtr = retlen; 1999 } 2000 else 2001 { 2002 /* unicode<=ansi*/ 2003 SQLSMALLINT retlen; 2004 2005 dm_StrCopyOut2_A2W ((SQLCHAR *) valueOut, 2006 (SQLWCHAR *) ValuePtr, 2007 StringLength, &retlen); 2008 if (StringLengthPtr) 2009 *StringLengthPtr = retlen * sizeof(wchar_t); 2010 } 2011 } 2012 } 2013 MEM_FREE(_Value); 2014 return retcode; 2015 } 2016 MEM_FREE(_Value); 2017 2018 retcode = _iodbcdm_GetConnectOption (con, Attribute, ValuePtr, waMode); 2019 if (!SQL_SUCCEEDED (retcode)) 2020 return retcode; 2021 2022 if (StringLengthPtr) 2023 { 2024 *StringLengthPtr = 0; 2025 if (ValuePtr) 2026 switch (Attribute) 2027 { 2028 case SQL_ATTR_CURRENT_CATALOG: 2029 case SQL_ATTR_TRACEFILE: 2030 case SQL_ATTR_TRANSLATE_LIB: 2031 if (waMode != 'W') 2032 *StringLengthPtr = STRLEN (ValuePtr); 2033 else 2034 *StringLengthPtr = WCSLEN (ValuePtr) * sizeof(wchar_t); 2035 } 2036 } 2037 return retcode; 2038} 2039 2040 2041RETCODE SQL_API 2042SQLGetConnectAttr ( 2043 SQLHDBC connectionHandle, 2044 SQLINTEGER Attribute, 2045 SQLPOINTER ValuePtr, 2046 SQLINTEGER StringLength, 2047 SQLINTEGER * StringLengthPtr) 2048{ 2049 ENTER_HDBC (connectionHandle, 0, 2050 trace_SQLGetConnectAttr (TRACE_ENTER, 2051 connectionHandle, 2052 Attribute, 2053 ValuePtr, StringLength, StringLengthPtr)); 2054 2055 retcode = SQLGetConnectAttr_Internal( 2056 connectionHandle, 2057 Attribute, 2058 ValuePtr, StringLength, StringLengthPtr, 2059 'A'); 2060 2061 LEAVE_HDBC (connectionHandle, 0, 2062 trace_SQLGetConnectAttr (TRACE_LEAVE, 2063 connectionHandle, 2064 Attribute, 2065 ValuePtr, StringLength, StringLengthPtr)); 2066} 2067 2068 2069RETCODE SQL_API 2070SQLGetConnectAttrA ( 2071 SQLHDBC connectionHandle, 2072 SQLINTEGER Attribute, 2073 SQLPOINTER ValuePtr, 2074 SQLINTEGER StringLength, 2075 SQLINTEGER * StringLengthPtr) 2076{ 2077 ENTER_HDBC (connectionHandle, 0, 2078 trace_SQLGetConnectAttr (TRACE_ENTER, 2079 connectionHandle, 2080 Attribute, 2081 ValuePtr, StringLength, StringLengthPtr)); 2082 2083 retcode = SQLGetConnectAttr_Internal( 2084 connectionHandle, 2085 Attribute, 2086 ValuePtr, StringLength, StringLengthPtr, 2087 'A'); 2088 2089 LEAVE_HDBC (connectionHandle, 0, 2090 trace_SQLGetConnectAttr (TRACE_LEAVE, 2091 connectionHandle, 2092 Attribute, 2093 ValuePtr, StringLength, StringLengthPtr)); 2094} 2095 2096 2097RETCODE SQL_API 2098SQLGetConnectAttrW (SQLHDBC connectionHandle, 2099 SQLINTEGER Attribute, 2100 SQLPOINTER ValuePtr, 2101 SQLINTEGER StringLength, 2102 SQLINTEGER * StringLengthPtr) 2103{ 2104 ENTER_HDBC (connectionHandle, 0, 2105 trace_SQLGetConnectAttrW (TRACE_ENTER, 2106 connectionHandle, 2107 Attribute, 2108 ValuePtr, StringLength, StringLengthPtr)); 2109 2110 retcode = SQLGetConnectAttr_Internal( 2111 connectionHandle, 2112 Attribute, 2113 ValuePtr, StringLength, StringLengthPtr, 2114 'W'); 2115 2116 LEAVE_HDBC (connectionHandle, 0, 2117 trace_SQLGetConnectAttrW (TRACE_LEAVE, 2118 connectionHandle, 2119 Attribute, 2120 ValuePtr, StringLength, StringLengthPtr)); 2121} 2122 2123 2124RETCODE SQL_API 2125SQLGetDescField_Internal ( 2126 SQLHDESC descriptorHandle, 2127 SQLSMALLINT RecNumber, 2128 SQLSMALLINT FieldIdentifier, 2129 SQLPOINTER ValuePtr, 2130 SQLINTEGER BufferLength, 2131 SQLINTEGER * StringLengthPtr, 2132 SQLCHAR waMode) 2133{ 2134 DESC (desc, descriptorHandle); 2135 CONN (pdbc, desc->hdbc); 2136 ENVR (penv, pdbc->henv); 2137 HPROC hproc = SQL_NULL_HPROC; 2138 SQLRETURN retcode = SQL_SUCCESS; 2139 void * valueOut = ValuePtr; 2140 void * _ValuePtr = NULL; 2141 2142 if ((penv->unicode_driver && waMode != 'W') 2143 || (!penv->unicode_driver && waMode == 'W')) 2144 { 2145 switch(FieldIdentifier) 2146 { 2147 case SQL_DESC_BASE_COLUMN_NAME: 2148 case SQL_DESC_BASE_TABLE_NAME: 2149 case SQL_DESC_CATALOG_NAME: 2150 case SQL_DESC_LABEL: 2151 case SQL_DESC_LITERAL_PREFIX: 2152 case SQL_DESC_LITERAL_SUFFIX: 2153 case SQL_DESC_LOCAL_TYPE_NAME: 2154 case SQL_DESC_NAME: 2155 case SQL_DESC_SCHEMA_NAME: 2156 case SQL_DESC_TABLE_NAME: 2157 case SQL_DESC_TYPE_NAME: 2158 if (waMode != 'W') 2159 { 2160 /* ansi=>unicode*/ 2161 BufferLength *= sizeof(wchar_t); 2162 if ((_ValuePtr = malloc(BufferLength + 1)) == NULL) 2163 { 2164 PUSHSQLERR (desc->herr, en_HY001); 2165 return SQL_ERROR; 2166 } 2167 } 2168 else 2169 { 2170 /* unicode=>ansi*/ 2171 BufferLength /= sizeof(wchar_t); 2172 if ((_ValuePtr = malloc(BufferLength + 1)) == NULL) 2173 { 2174 PUSHSQLERR (desc->herr, en_HY001); 2175 return SQL_ERROR; 2176 } 2177 } 2178 valueOut = _ValuePtr; 2179 break; 2180 } 2181 } 2182 2183 CALL_UDRIVER(desc->hdbc, desc, retcode, hproc, penv->unicode_driver, 2184 en_GetDescField, (desc->dhdesc, RecNumber, FieldIdentifier, valueOut, 2185 BufferLength, StringLengthPtr)); 2186 2187 if (hproc == SQL_NULL_HPROC) 2188 { 2189 MEM_FREE(_ValuePtr); 2190 PUSHSQLERR (desc->herr, en_IM001); 2191 return SQL_ERROR; 2192 } 2193 2194 if (ValuePtr 2195 && SQL_SUCCEEDED (retcode) 2196 && ((penv->unicode_driver && waMode != 'W') 2197 || (!penv->unicode_driver && waMode == 'W'))) 2198 { 2199 switch(FieldIdentifier) 2200 { 2201 case SQL_DESC_BASE_COLUMN_NAME: 2202 case SQL_DESC_BASE_TABLE_NAME: 2203 case SQL_DESC_CATALOG_NAME: 2204 case SQL_DESC_LABEL: 2205 case SQL_DESC_LITERAL_PREFIX: 2206 case SQL_DESC_LITERAL_SUFFIX: 2207 case SQL_DESC_LOCAL_TYPE_NAME: 2208 case SQL_DESC_NAME: 2209 case SQL_DESC_SCHEMA_NAME: 2210 case SQL_DESC_TABLE_NAME: 2211 case SQL_DESC_TYPE_NAME: 2212 if (waMode != 'W') 2213 { 2214 /* ansi<=unicode*/ 2215 SQLSMALLINT retlen; 2216 2217 dm_StrCopyOut2_W2A ((SQLWCHAR *) valueOut, 2218 (SQLCHAR *) ValuePtr, 2219 BufferLength / sizeof(wchar_t), &retlen); 2220 if (StringLengthPtr) 2221 *StringLengthPtr = retlen; 2222 } 2223 else 2224 { 2225 /* unicode<=ansi*/ 2226 SQLSMALLINT retlen; 2227 2228 dm_StrCopyOut2_A2W ((SQLCHAR *) valueOut, 2229 (SQLWCHAR *) ValuePtr, 2230 BufferLength, &retlen); 2231 if (StringLengthPtr) 2232 *StringLengthPtr = retlen * sizeof(wchar_t); 2233 } 2234 break; 2235 } 2236 } 2237 2238 MEM_FREE(_ValuePtr); 2239 2240 return retcode; 2241} 2242 2243 2244RETCODE SQL_API 2245SQLGetDescField ( 2246 SQLHDESC descriptorHandle, 2247 SQLSMALLINT RecNumber, 2248 SQLSMALLINT FieldIdentifier, 2249 SQLPOINTER ValuePtr, 2250 SQLINTEGER BufferLength, 2251 SQLINTEGER * StringLengthPtr) 2252{ 2253 ENTER_DESC (descriptorHandle, 2254 trace_SQLGetDescField (TRACE_ENTER, 2255 descriptorHandle, 2256 RecNumber, 2257 FieldIdentifier, 2258 ValuePtr, BufferLength, StringLengthPtr)); 2259 2260 retcode = SQLGetDescField_Internal( 2261 descriptorHandle, 2262 RecNumber, 2263 FieldIdentifier, 2264 ValuePtr, BufferLength, StringLengthPtr, 2265 'A'); 2266 2267 LEAVE_DESC (descriptorHandle, 2268 trace_SQLGetDescField (TRACE_LEAVE, 2269 descriptorHandle, 2270 RecNumber, 2271 FieldIdentifier, 2272 ValuePtr, BufferLength, StringLengthPtr)); 2273} 2274 2275 2276RETCODE SQL_API 2277SQLGetDescFieldA ( 2278 SQLHDESC descriptorHandle, 2279 SQLSMALLINT RecNumber, 2280 SQLSMALLINT FieldIdentifier, 2281 SQLPOINTER ValuePtr, 2282 SQLINTEGER BufferLength, 2283 SQLINTEGER * StringLengthPtr) 2284{ 2285 ENTER_DESC (descriptorHandle, 2286 trace_SQLGetDescField (TRACE_ENTER, 2287 descriptorHandle, 2288 RecNumber, 2289 FieldIdentifier, 2290 ValuePtr, BufferLength, StringLengthPtr)); 2291 2292 retcode = SQLGetDescField_Internal ( 2293 descriptorHandle, 2294 RecNumber, 2295 FieldIdentifier, 2296 ValuePtr, BufferLength, StringLengthPtr, 2297 'A'); 2298 2299 LEAVE_DESC (descriptorHandle, 2300 trace_SQLGetDescField (TRACE_LEAVE, 2301 descriptorHandle, 2302 RecNumber, 2303 FieldIdentifier, 2304 ValuePtr, BufferLength, StringLengthPtr)); 2305} 2306 2307 2308RETCODE SQL_API 2309SQLGetDescFieldW ( 2310 SQLHDESC descriptorHandle, 2311 SQLSMALLINT RecNumber, 2312 SQLSMALLINT FieldIdentifier, 2313 SQLPOINTER ValuePtr, 2314 SQLINTEGER BufferLength, 2315 SQLINTEGER * StringLengthPtr) 2316{ 2317 ENTER_DESC (descriptorHandle, 2318 trace_SQLGetDescFieldW (TRACE_ENTER, 2319 descriptorHandle, 2320 RecNumber, 2321 FieldIdentifier, 2322 ValuePtr, BufferLength, StringLengthPtr)); 2323 2324 retcode = SQLGetDescField_Internal ( 2325 descriptorHandle, 2326 RecNumber, 2327 FieldIdentifier, 2328 ValuePtr, BufferLength, StringLengthPtr, 2329 'W'); 2330 2331 LEAVE_DESC (descriptorHandle, 2332 trace_SQLGetDescFieldW (TRACE_LEAVE, 2333 descriptorHandle, 2334 RecNumber, 2335 FieldIdentifier, 2336 ValuePtr, BufferLength, StringLengthPtr)); 2337} 2338 2339 2340RETCODE SQL_API 2341SQLSetDescField_Internal ( 2342 SQLHDESC descriptorHandle, 2343 SQLSMALLINT RecNumber, 2344 SQLSMALLINT FieldIdentifier, 2345 SQLPOINTER ValuePtr, 2346 SQLINTEGER BufferLength, 2347 SQLCHAR waMode) 2348{ 2349 DESC (desc, descriptorHandle); 2350 CONN (pdbc, desc->hdbc); 2351 ENVR (penv, pdbc->henv); 2352 HPROC hproc = SQL_NULL_HPROC; 2353 SQLRETURN retcode = SQL_SUCCESS; 2354 void * _ValuePtr = NULL; 2355 2356 if ((penv->unicode_driver && waMode != 'W') 2357 || (!penv->unicode_driver && waMode == 'W')) 2358 { 2359 switch(FieldIdentifier) 2360 { 2361 case SQL_DESC_BASE_COLUMN_NAME: 2362 case SQL_DESC_BASE_TABLE_NAME: 2363 case SQL_DESC_CATALOG_NAME: 2364 case SQL_DESC_LABEL: 2365 case SQL_DESC_LITERAL_PREFIX: 2366 case SQL_DESC_LITERAL_SUFFIX: 2367 case SQL_DESC_LOCAL_TYPE_NAME: 2368 case SQL_DESC_NAME: 2369 case SQL_DESC_SCHEMA_NAME: 2370 case SQL_DESC_TABLE_NAME: 2371 case SQL_DESC_TYPE_NAME: 2372 if (waMode != 'W') 2373 { 2374 /* ansi=>unicode*/ 2375 _ValuePtr = dm_SQL_A2W((SQLCHAR *) ValuePtr, BufferLength); 2376 } 2377 else 2378 { 2379 /* unicode=>ansi*/ 2380 BufferLength = (BufferLength != SQL_NTS) ? (SQLINTEGER) (BufferLength / sizeof(wchar_t)) : SQL_NTS; 2381 _ValuePtr = dm_SQL_W2A((SQLWCHAR *) ValuePtr, BufferLength); 2382 } 2383 ValuePtr = _ValuePtr; 2384 BufferLength = SQL_NTS; 2385 break; 2386 } 2387 } 2388 CALL_UDRIVER(desc->hdbc, desc, retcode, hproc, penv->unicode_driver, 2389 en_SetDescField, (desc->dhdesc, RecNumber, FieldIdentifier, ValuePtr, 2390 BufferLength)); 2391 2392 MEM_FREE(_ValuePtr); 2393 2394 if (hproc == SQL_NULL_HPROC) 2395 { 2396 PUSHSQLERR (desc->herr, en_IM001); 2397 return SQL_ERROR; 2398 } 2399 2400 return retcode; 2401} 2402 2403 2404RETCODE SQL_API 2405SQLSetDescField ( 2406 SQLHDESC descriptorHandle, 2407 SQLSMALLINT RecNumber, 2408 SQLSMALLINT FieldIdentifier, 2409 SQLPOINTER ValuePtr, 2410 SQLINTEGER BufferLength) 2411{ 2412 ENTER_DESC (descriptorHandle, 2413 trace_SQLSetDescField (TRACE_ENTER, 2414 descriptorHandle, 2415 RecNumber, FieldIdentifier, ValuePtr, BufferLength)); 2416 2417 retcode = SQLSetDescField_Internal (descriptorHandle, 2418 RecNumber, FieldIdentifier, ValuePtr, BufferLength, 'A'); 2419 2420 LEAVE_DESC (descriptorHandle, 2421 trace_SQLSetDescField (TRACE_LEAVE, 2422 descriptorHandle, 2423 RecNumber, FieldIdentifier, ValuePtr, BufferLength)); 2424} 2425 2426 2427RETCODE SQL_API 2428SQLSetDescFieldA ( 2429 SQLHDESC descriptorHandle, 2430 SQLSMALLINT RecNumber, 2431 SQLSMALLINT FieldIdentifier, 2432 SQLPOINTER ValuePtr, 2433 SQLINTEGER BufferLength) 2434{ 2435 ENTER_DESC (descriptorHandle, 2436 trace_SQLSetDescField (TRACE_ENTER, 2437 descriptorHandle, 2438 RecNumber, FieldIdentifier, ValuePtr, BufferLength)); 2439 2440 retcode = SQLSetDescField_Internal (descriptorHandle, 2441 RecNumber, FieldIdentifier, ValuePtr, BufferLength, 'A'); 2442 2443 LEAVE_DESC (descriptorHandle, 2444 trace_SQLSetDescField (TRACE_LEAVE, 2445 descriptorHandle, 2446 RecNumber, FieldIdentifier, ValuePtr, BufferLength)); 2447} 2448 2449 2450RETCODE SQL_API 2451SQLSetDescFieldW ( 2452 SQLHDESC descriptorHandle, 2453 SQLSMALLINT RecNumber, 2454 SQLSMALLINT FieldIdentifier, 2455 SQLPOINTER ValuePtr, 2456 SQLINTEGER BufferLength) 2457{ 2458 ENTER_DESC (descriptorHandle, 2459 trace_SQLSetDescFieldW (TRACE_ENTER, 2460 descriptorHandle, 2461 RecNumber, FieldIdentifier, ValuePtr, BufferLength)); 2462 2463 retcode = SQLSetDescField_Internal (descriptorHandle, 2464 RecNumber, FieldIdentifier, ValuePtr, BufferLength, 'W'); 2465 2466 LEAVE_DESC (descriptorHandle, 2467 trace_SQLSetDescFieldW (TRACE_LEAVE, 2468 descriptorHandle, 2469 RecNumber, FieldIdentifier, ValuePtr, BufferLength)); 2470} 2471 2472 2473RETCODE SQL_API 2474SQLGetDescRec_Internal ( 2475 SQLHDESC descriptorHandle, 2476 SQLSMALLINT RecNumber, 2477 SQLPOINTER Name, 2478 SQLSMALLINT BufferLength, 2479 SQLSMALLINT * StringLengthPtr, 2480 SQLSMALLINT * TypePtr, 2481 SQLSMALLINT * SubTypePtr, 2482 SQLLEN * LengthPtr, 2483 SQLSMALLINT * PrecisionPtr, 2484 SQLSMALLINT * ScalePtr, 2485 SQLSMALLINT * NullablePtr, 2486 SQLCHAR waMode) 2487{ 2488 DESC (desc, descriptorHandle); 2489 CONN (pdbc, desc->hdbc); 2490 ENVR (penv, pdbc->henv); 2491 HPROC hproc = SQL_NULL_HPROC; 2492 SQLRETURN retcode = SQL_SUCCESS; 2493 void * nameOut = Name; 2494 void * _Name = NULL; 2495 2496 if ((penv->unicode_driver && waMode != 'W') 2497 || (!penv->unicode_driver && waMode == 'W')) 2498 { 2499 if (waMode != 'W') 2500 { 2501 /* ansi=>unicode*/ 2502 if ((_Name = malloc(BufferLength * sizeof(wchar_t) + 1)) == NULL) 2503 { 2504 PUSHSQLERR (desc->herr, en_HY001); 2505 return SQL_ERROR; 2506 } 2507 } 2508 else 2509 { 2510 /* unicode=>ansi*/ 2511 if ((_Name = malloc(BufferLength + 1)) == NULL) 2512 { 2513 PUSHSQLERR (desc->herr, en_HY001); 2514 return SQL_ERROR; 2515 } 2516 } 2517 nameOut = _Name; 2518 } 2519 2520 CALL_UDRIVER(desc->hdbc, desc, retcode, hproc, penv->unicode_driver, 2521 en_GetDescRec, (desc->dhdesc, RecNumber, nameOut, BufferLength, 2522 StringLengthPtr, TypePtr, SubTypePtr, LengthPtr, PrecisionPtr, 2523 ScalePtr, NullablePtr)); 2524 2525 if (hproc == SQL_NULL_HPROC) 2526 { 2527 MEM_FREE(_Name); 2528 PUSHSQLERR (desc->herr, en_IM001); 2529 return SQL_ERROR; 2530 } 2531 2532 if (Name 2533 && SQL_SUCCEEDED (retcode) 2534 && ((penv->unicode_driver && waMode != 'W') 2535 || (!penv->unicode_driver && waMode == 'W'))) 2536 { 2537 if (waMode != 'W') 2538 { 2539 /* ansi<=unicode*/ 2540 dm_StrCopyOut2_W2A ((SQLWCHAR *) nameOut, (SQLCHAR *) Name, BufferLength, StringLengthPtr); 2541 } 2542 else 2543 { 2544 /* unicode<=ansi*/ 2545 dm_StrCopyOut2_A2W ((SQLCHAR *) nameOut, (SQLWCHAR *) Name, BufferLength, StringLengthPtr); 2546 } 2547 } 2548 2549 MEM_FREE(_Name); 2550 2551 return retcode; 2552} 2553 2554 2555RETCODE SQL_API 2556SQLGetDescRec ( 2557 SQLHDESC descriptorHandle, 2558 SQLSMALLINT RecNumber, 2559 SQLCHAR * Name, 2560 SQLSMALLINT BufferLength, 2561 SQLSMALLINT * StringLengthPtr, 2562 SQLSMALLINT * TypePtr, 2563 SQLSMALLINT * SubTypePtr, 2564 SQLLEN * LengthPtr, 2565 SQLSMALLINT * PrecisionPtr, 2566 SQLSMALLINT * ScalePtr, 2567 SQLSMALLINT * NullablePtr) 2568{ 2569 ENTER_DESC (descriptorHandle, 2570 trace_SQLGetDescRec (TRACE_ENTER, 2571 descriptorHandle, 2572 RecNumber, 2573 Name, BufferLength, StringLengthPtr, 2574 TypePtr, 2575 SubTypePtr, 2576 LengthPtr, 2577 PrecisionPtr, 2578 ScalePtr, 2579 NullablePtr)); 2580 2581 retcode = SQLGetDescRec_Internal( 2582 descriptorHandle, 2583 RecNumber, 2584 Name, BufferLength, StringLengthPtr, 2585 TypePtr, 2586 SubTypePtr, 2587 LengthPtr, 2588 PrecisionPtr, 2589 ScalePtr, 2590 NullablePtr, 2591 'A'); 2592 2593 LEAVE_DESC (descriptorHandle, 2594 trace_SQLGetDescRec (TRACE_LEAVE, 2595 descriptorHandle, 2596 RecNumber, 2597 Name, BufferLength, StringLengthPtr, 2598 TypePtr, 2599 SubTypePtr, 2600 LengthPtr, 2601 PrecisionPtr, 2602 ScalePtr, 2603 NullablePtr)); 2604} 2605 2606 2607RETCODE SQL_API 2608SQLGetDescRecA ( 2609 SQLHDESC descriptorHandle, 2610 SQLSMALLINT RecNumber, 2611 SQLCHAR * Name, 2612 SQLSMALLINT BufferLength, 2613 SQLSMALLINT * StringLengthPtr, 2614 SQLSMALLINT * TypePtr, 2615 SQLSMALLINT * SubTypePtr, 2616 SQLLEN * LengthPtr, 2617 SQLSMALLINT * PrecisionPtr, 2618 SQLSMALLINT * ScalePtr, 2619 SQLSMALLINT * NullablePtr) 2620{ 2621 ENTER_DESC (descriptorHandle, 2622 trace_SQLGetDescRec (TRACE_ENTER, 2623 descriptorHandle, 2624 RecNumber, 2625 Name, BufferLength, StringLengthPtr, 2626 TypePtr, 2627 SubTypePtr, 2628 LengthPtr, 2629 PrecisionPtr, 2630 ScalePtr, 2631 NullablePtr)); 2632 2633 retcode = SQLGetDescRec_Internal( 2634 descriptorHandle, 2635 RecNumber, 2636 Name, BufferLength, StringLengthPtr, 2637 TypePtr, 2638 SubTypePtr, 2639 LengthPtr, 2640 PrecisionPtr, 2641 ScalePtr, 2642 NullablePtr, 2643 'A'); 2644 2645 LEAVE_DESC (descriptorHandle, 2646 trace_SQLGetDescRec (TRACE_LEAVE, 2647 descriptorHandle, 2648 RecNumber, 2649 Name, BufferLength, StringLengthPtr, 2650 TypePtr, 2651 SubTypePtr, 2652 LengthPtr, 2653 PrecisionPtr, 2654 ScalePtr, 2655 NullablePtr)); 2656} 2657 2658 2659RETCODE SQL_API 2660SQLGetDescRecW ( 2661 SQLHDESC descriptorHandle, 2662 SQLSMALLINT RecNumber, 2663 SQLWCHAR * Name, 2664 SQLSMALLINT BufferLength, 2665 SQLSMALLINT * StringLengthPtr, 2666 SQLSMALLINT * TypePtr, 2667 SQLSMALLINT * SubTypePtr, 2668 SQLLEN * LengthPtr, 2669 SQLSMALLINT * PrecisionPtr, 2670 SQLSMALLINT * ScalePtr, 2671 SQLSMALLINT * NullablePtr) 2672{ 2673 ENTER_DESC (descriptorHandle, 2674 trace_SQLGetDescRecW (TRACE_ENTER, 2675 descriptorHandle, 2676 RecNumber, 2677 Name, BufferLength, StringLengthPtr, 2678 TypePtr, 2679 SubTypePtr, 2680 LengthPtr, 2681 PrecisionPtr, 2682 ScalePtr, 2683 NullablePtr)); 2684 2685 retcode = SQLGetDescRec_Internal( 2686 descriptorHandle, 2687 RecNumber, 2688 Name, BufferLength, StringLengthPtr, 2689 TypePtr, 2690 SubTypePtr, 2691 LengthPtr, 2692 PrecisionPtr, 2693 ScalePtr, 2694 NullablePtr, 2695 'W'); 2696 2697 LEAVE_DESC (descriptorHandle, 2698 trace_SQLGetDescRecW (TRACE_LEAVE, 2699 descriptorHandle, 2700 RecNumber, 2701 Name, BufferLength, StringLengthPtr, 2702 TypePtr, 2703 SubTypePtr, 2704 LengthPtr, 2705 PrecisionPtr, 2706 ScalePtr, 2707 NullablePtr)); 2708} 2709 2710 2711static RETCODE 2712SQLSetDescRec_Internal ( 2713 SQLHDESC DescriptorHandle, 2714 SQLSMALLINT RecNumber, 2715 SQLSMALLINT Type, 2716 SQLSMALLINT SubType, 2717 SQLLEN Length, 2718 SQLSMALLINT Precision, 2719 SQLSMALLINT Scale, 2720 SQLPOINTER Data, 2721 SQLLEN * StringLength, 2722 SQLLEN * Indicator) 2723{ 2724 DESC (desc, DescriptorHandle); 2725 HPROC hproc; 2726 RETCODE retcode; 2727 2728 hproc = _iodbcdm_getproc (desc->hdbc, en_SetDescRec); 2729 if (!hproc) 2730 { 2731 PUSHSQLERR (desc->herr, en_IM001); 2732 return SQL_ERROR; 2733 } 2734 2735 CALL_DRIVER (desc->hdbc, desc, retcode, hproc, 2736 (desc->dhdesc, RecNumber, Type, SubType, Length, Precision, Scale, 2737 Data, StringLength, Indicator)); 2738 2739 return retcode; 2740} 2741 2742RETCODE SQL_API 2743SQLSetDescRec ( 2744 SQLHDESC DescriptorHandle, 2745 SQLSMALLINT RecNumber, 2746 SQLSMALLINT Type, 2747 SQLSMALLINT SubType, 2748 SQLLEN Length, 2749 SQLSMALLINT Precision, 2750 SQLSMALLINT Scale, 2751 SQLPOINTER Data, 2752 SQLLEN * StringLength, 2753 SQLLEN * Indicator) 2754{ 2755 ENTER_DESC (DescriptorHandle, 2756 trace_SQLSetDescRec (TRACE_ENTER, 2757 DescriptorHandle, RecNumber, Type, SubType, Length, Precision, 2758 Scale, Data, StringLength, Indicator)); 2759 2760 retcode = SQLSetDescRec_Internal ( 2761 DescriptorHandle, RecNumber, Type, SubType, Length, Precision, 2762 Scale, Data, StringLength, Indicator); 2763 2764 LEAVE_DESC (DescriptorHandle, 2765 trace_SQLSetDescRec (TRACE_LEAVE, 2766 DescriptorHandle, RecNumber, Type, SubType, Length, Precision, 2767 Scale, Data, StringLength, Indicator)); 2768} 2769 2770 2771static RETCODE 2772SQLCopyDesc_Internal ( 2773 SQLHDESC SourceDescHandle, 2774 SQLHDESC TargetDescHandle) 2775{ 2776 DESC (desc, SourceDescHandle); 2777 DESC (desc1, TargetDescHandle); 2778 HPROC hproc; 2779 RETCODE retcode; 2780 2781 hproc = _iodbcdm_getproc (desc->hdbc, en_CopyDesc); 2782 if (!hproc) 2783 { 2784 PUSHSQLERR (desc->herr, en_IM001); 2785 return SQL_ERROR; 2786 } 2787 2788 CALL_DRIVER (desc->hdbc, desc, retcode, hproc, 2789 (desc->dhdesc, desc1->dhdesc)); 2790 2791 return retcode; 2792} 2793 2794 2795RETCODE SQL_API 2796SQLCopyDesc ( 2797 SQLHDESC SourceDescHandle, 2798 SQLHDESC TargetDescHandle) 2799{ 2800 ENTER_DESC (SourceDescHandle, 2801 trace_SQLCopyDesc (TRACE_ENTER, 2802 SourceDescHandle, 2803 TargetDescHandle)); 2804 2805 retcode = SQLCopyDesc_Internal ( 2806 SourceDescHandle, 2807 TargetDescHandle); 2808 2809 LEAVE_DESC (SourceDescHandle, 2810 trace_SQLCopyDesc (TRACE_LEAVE, 2811 SourceDescHandle, 2812 TargetDescHandle)); 2813} 2814 2815 2816RETCODE SQL_API 2817SQLColAttribute_Internal ( 2818 SQLHSTMT statementHandle, 2819 SQLUSMALLINT ColumnNumber, 2820 SQLUSMALLINT FieldIdentifier, 2821 SQLPOINTER CharacterAttributePtr, 2822 SQLSMALLINT BufferLength, 2823 SQLSMALLINT * StringLengthPtr, 2824 SQLLEN * NumericAttributePtr, 2825 SQLCHAR waMode) 2826{ 2827 STMT (stmt, statementHandle); 2828 CONN (pdbc, stmt->hdbc); 2829 ENVR (penv, pdbc->henv); 2830 GENV (genv, pdbc->genv); 2831 HPROC hproc = SQL_NULL_HPROC; 2832 HPROC hproc2 = SQL_NULL_HPROC; 2833 SQLRETURN retcode = SQL_SUCCESS; 2834 void * charAttrOut = CharacterAttributePtr; 2835 void * _charAttr = NULL; 2836 SQLUINTEGER odbc_ver; 2837 SQLUINTEGER dodbc_ver; 2838 2839 odbc_ver = ((GENV_t *) pdbc->genv)->odbc_ver; 2840 dodbc_ver = (penv != SQL_NULL_HENV) ? penv->dodbc_ver : odbc_ver; 2841 2842 if ((penv->unicode_driver && waMode != 'W') 2843 || (!penv->unicode_driver && waMode == 'W')) 2844 { 2845 switch(FieldIdentifier) 2846 { 2847 case SQL_COLUMN_NAME: 2848 2849 case SQL_DESC_BASE_COLUMN_NAME: 2850 case SQL_DESC_BASE_TABLE_NAME: 2851 case SQL_DESC_CATALOG_NAME: 2852 case SQL_DESC_LABEL: 2853 case SQL_DESC_LITERAL_PREFIX: 2854 case SQL_DESC_LITERAL_SUFFIX: 2855 case SQL_DESC_LOCAL_TYPE_NAME: 2856 case SQL_DESC_NAME: 2857 case SQL_DESC_SCHEMA_NAME: 2858 case SQL_DESC_TABLE_NAME: 2859 case SQL_DESC_TYPE_NAME: 2860 if (waMode != 'W') 2861 { 2862 /* ansi=>unicode*/ 2863 BufferLength *= sizeof(wchar_t); 2864 if ((_charAttr = malloc(BufferLength + 1)) == NULL) 2865 { 2866 PUSHSQLERR (stmt->herr, en_HY001); 2867 return SQL_ERROR; 2868 } 2869 } 2870 else 2871 { 2872 /* unicode=>ansi*/ 2873 BufferLength /= sizeof(wchar_t); 2874 if ((_charAttr = malloc(BufferLength + 1)) == NULL) 2875 { 2876 PUSHSQLERR (stmt->herr, en_HY001); 2877 return SQL_ERROR; 2878 } 2879 } 2880 charAttrOut = _charAttr; 2881 break; 2882 } 2883 } 2884 2885 GET_UHPROC(stmt->hdbc, hproc2, en_ColAttributes, penv->unicode_driver); 2886 2887 if (dodbc_ver == SQL_OV_ODBC3 && 2888 ( odbc_ver == SQL_OV_ODBC3 2889 || (odbc_ver == SQL_OV_ODBC2 && hproc2 == SQL_NULL_HPROC))) 2890 { 2891 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, penv->unicode_driver, 2892 en_ColAttribute, (stmt->dhstmt, ColumnNumber, FieldIdentifier, 2893 charAttrOut, BufferLength, StringLengthPtr, NumericAttributePtr)); 2894 } 2895 2896 if (hproc != SQL_NULL_HPROC) 2897 { 2898 if (SQL_SUCCEEDED (retcode) && FieldIdentifier == SQL_DESC_CONCISE_TYPE) 2899 { 2900 SQLINTEGER *ptr = (SQLINTEGER *)NumericAttributePtr; 2901 2902 /* 2903 * Convert sql type to ODBC version of application 2904 */ 2905 if (ptr) 2906 *ptr = _iodbcdm_map_sql_type (*ptr, genv->odbc_ver); 2907 } 2908 2909 if (CharacterAttributePtr 2910 && SQL_SUCCEEDED (retcode) 2911 && ((penv->unicode_driver && waMode != 'W') 2912 || (!penv->unicode_driver && waMode == 'W'))) 2913 { 2914 switch(FieldIdentifier) 2915 { 2916 case SQL_COLUMN_NAME: 2917 case SQL_DESC_BASE_COLUMN_NAME: 2918 case SQL_DESC_BASE_TABLE_NAME: 2919 case SQL_DESC_CATALOG_NAME: 2920 case SQL_DESC_LABEL: 2921 case SQL_DESC_LITERAL_PREFIX: 2922 case SQL_DESC_LITERAL_SUFFIX: 2923 case SQL_DESC_LOCAL_TYPE_NAME: 2924 case SQL_DESC_NAME: 2925 case SQL_DESC_SCHEMA_NAME: 2926 case SQL_DESC_TABLE_NAME: 2927 case SQL_DESC_TYPE_NAME: 2928 if (waMode != 'W') 2929 { 2930 /* ansi<=unicode*/ 2931 dm_StrCopyOut2_W2A ((SQLWCHAR *) charAttrOut, 2932 (SQLCHAR *) CharacterAttributePtr, 2933 BufferLength / sizeof(wchar_t), StringLengthPtr); 2934 } 2935 else 2936 { 2937 /* unicode<=ansi*/ 2938 dm_StrCopyOut2_A2W ((SQLCHAR *) charAttrOut, 2939 (SQLWCHAR *) CharacterAttributePtr, 2940 BufferLength, StringLengthPtr); 2941 if (StringLengthPtr) 2942 *StringLengthPtr = *StringLengthPtr * sizeof(wchar_t); 2943 } 2944 } 2945 } 2946 MEM_FREE(_charAttr); 2947 return retcode; 2948 } 2949 2950 2951 if (ColumnNumber == 0) 2952 { 2953 char *szval = ""; 2954 int isSz = 0; 2955 SQLINTEGER val = 0; 2956 2957 MEM_FREE(_charAttr); 2958 2959 switch (FieldIdentifier) 2960 { 2961 case SQL_DESC_AUTO_UNIQUE_VALUE: 2962 case SQL_DESC_CASE_SENSITIVE: 2963 case SQL_DESC_FIXED_PREC_SCALE: 2964 case SQL_DESC_UNSIGNED: 2965 val = SQL_FALSE; 2966 break; 2967 2968 case SQL_DESC_LABEL: 2969 case SQL_DESC_CATALOG_NAME: 2970 case SQL_DESC_LITERAL_PREFIX: 2971 case SQL_DESC_LITERAL_SUFFIX: 2972 case SQL_DESC_LOCAL_TYPE_NAME: 2973 case SQL_DESC_NAME: 2974 case SQL_DESC_SCHEMA_NAME: 2975 case SQL_DESC_TABLE_NAME: 2976 case SQL_DESC_TYPE_NAME: 2977 isSz = 1; 2978 break; 2979 2980 case SQL_DESC_CONCISE_TYPE: 2981 case SQL_DESC_TYPE: 2982 val = SQL_BINARY; 2983 break; 2984 2985 case SQL_DESC_COUNT: 2986 hproc = _iodbcdm_getproc (stmt->hdbc, en_NumResultCols); 2987 if (!hproc) 2988 { 2989 PUSHSQLERR (stmt->herr, en_IM001); 2990 return SQL_ERROR; 2991 } 2992 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 2993 (stmt->dhstmt, NumericAttributePtr)); 2994 return retcode; 2995 2996 case SQL_DESC_LENGTH: 2997 case SQL_DESC_DATETIME_INTERVAL_CODE: 2998 case SQL_DESC_SCALE: 2999 val = 0; 3000 break; 3001 3002 case SQL_DESC_DISPLAY_SIZE: 3003 val = 8; 3004 break; 3005 3006 case SQL_DESC_NULLABLE: 3007 val = SQL_NO_NULLS; 3008 break; 3009 3010 case SQL_DESC_OCTET_LENGTH: 3011 case SQL_DESC_PRECISION: 3012 val = 4; 3013 break; 3014 3015 case SQL_DESC_SEARCHABLE: 3016 val = SQL_PRED_NONE; 3017 break; 3018 3019 case SQL_DESC_UNNAMED: 3020 val = SQL_UNNAMED; 3021 break; 3022 3023 case SQL_DESC_UPDATABLE: 3024 val = SQL_ATTR_READONLY; 3025 break; 3026 3027 default: 3028 PUSHSQLERR (stmt->herr, en_HYC00); 3029 return SQL_ERROR; 3030 } 3031 if (isSz) 3032 { 3033 int len = STRLEN (szval), len1; 3034 len1 = len > BufferLength ? BufferLength - 1 : len; 3035 if (CharacterAttributePtr) 3036 { 3037 STRNCPY (CharacterAttributePtr, szval, len1); 3038 ((SQLCHAR *) CharacterAttributePtr)[len1] = 0; 3039 } 3040 if (StringLengthPtr) 3041 *StringLengthPtr = len; 3042 } 3043 else 3044 { 3045 if (NumericAttributePtr) 3046 *((SQLINTEGER *) NumericAttributePtr) = val; 3047 } 3048 return SQL_SUCCESS; 3049 } 3050 else 3051 { /* all other */ 3052 switch (FieldIdentifier) 3053 { 3054 case SQL_DESC_SCALE: 3055 FieldIdentifier = SQL_COLUMN_SCALE; 3056 break; 3057 3058 case SQL_DESC_LENGTH: 3059 FieldIdentifier = SQL_COLUMN_LENGTH; 3060 break; 3061 3062 case SQL_DESC_PRECISION: 3063 FieldIdentifier = SQL_COLUMN_PRECISION; 3064 break; 3065 3066 case SQL_DESC_COUNT: 3067 FieldIdentifier = SQL_COLUMN_COUNT; 3068 break; 3069 3070 case SQL_DESC_NAME: 3071 FieldIdentifier = SQL_COLUMN_NAME; 3072 break; 3073 3074 case SQL_DESC_NULLABLE: 3075 FieldIdentifier = SQL_COLUMN_NULLABLE; 3076 break; 3077 3078 case SQL_DESC_TYPE: 3079 FieldIdentifier = SQL_COLUMN_TYPE; 3080 break; 3081 3082 case SQL_DESC_BASE_COLUMN_NAME: 3083 case SQL_DESC_BASE_TABLE_NAME: 3084 case SQL_DESC_LITERAL_PREFIX: 3085 case SQL_DESC_LITERAL_SUFFIX: 3086 case SQL_DESC_LOCAL_TYPE_NAME: 3087 case SQL_DESC_NUM_PREC_RADIX: 3088 case SQL_DESC_OCTET_LENGTH: 3089 case SQL_DESC_UNNAMED: 3090 MEM_FREE(_charAttr); 3091 PUSHSQLERR (stmt->herr, en_HY091); 3092 return SQL_ERROR; 3093 } 3094 3095 CALL_UDRIVER(stmt->hdbc, stmt, retcode, hproc, penv->unicode_driver, 3096 en_ColAttributes, (stmt->dhstmt, ColumnNumber, FieldIdentifier, 3097 charAttrOut, BufferLength, StringLengthPtr, NumericAttributePtr)); 3098 3099 if (hproc == SQL_NULL_HPROC) 3100 { 3101 MEM_FREE(_charAttr); 3102 PUSHSQLERR (stmt->herr, en_IM001); 3103 return SQL_ERROR; 3104 } 3105 3106 if (SQL_SUCCEEDED (retcode) && FieldIdentifier == SQL_DESC_CONCISE_TYPE) 3107 { 3108 SQLINTEGER *ptr = (SQLINTEGER *)NumericAttributePtr; 3109 3110 /* 3111 * Convert sql type to ODBC version of application 3112 */ 3113 if (ptr) 3114 *ptr = _iodbcdm_map_sql_type (*ptr, genv->odbc_ver); 3115 } 3116 3117 if (CharacterAttributePtr 3118 && SQL_SUCCEEDED (retcode) 3119 && ((penv->unicode_driver && waMode != 'W') 3120 || (!penv->unicode_driver && waMode == 'W'))) 3121 { 3122 switch(FieldIdentifier) 3123 { 3124 case SQL_COLUMN_QUALIFIER_NAME: 3125 case SQL_COLUMN_NAME: 3126 case SQL_COLUMN_LABEL: 3127 case SQL_COLUMN_OWNER_NAME: 3128 case SQL_COLUMN_TABLE_NAME: 3129 case SQL_COLUMN_TYPE_NAME: 3130 3131 case SQL_DESC_BASE_COLUMN_NAME: 3132 case SQL_DESC_BASE_TABLE_NAME: 3133 case SQL_DESC_LITERAL_PREFIX: 3134 case SQL_DESC_LITERAL_SUFFIX: 3135 case SQL_DESC_LOCAL_TYPE_NAME: 3136 case SQL_DESC_NAME: 3137 if (waMode != 'W') 3138 { 3139 /* ansi<=unicode*/ 3140 dm_StrCopyOut2_W2A ((SQLWCHAR *) charAttrOut, 3141 (SQLCHAR *) CharacterAttributePtr, 3142 BufferLength / sizeof(wchar_t), StringLengthPtr); 3143 } 3144 else 3145 { 3146 /* unicode<=ansi*/ 3147 dm_StrCopyOut2_A2W ((SQLCHAR *) charAttrOut, 3148 (SQLWCHAR *) CharacterAttributePtr, 3149 BufferLength, StringLengthPtr); 3150 if (StringLengthPtr) 3151 *StringLengthPtr = *StringLengthPtr * sizeof(wchar_t); 3152 } 3153 } 3154 } 3155 MEM_FREE(_charAttr); 3156 return retcode; 3157 } 3158} 3159 3160 3161RETCODE SQL_API 3162SQLColAttribute ( 3163 SQLHSTMT statementHandle, 3164 SQLUSMALLINT ColumnNumber, 3165 SQLUSMALLINT FieldIdentifier, 3166 SQLPOINTER CharacterAttributePtr, 3167 SQLSMALLINT BufferLength, 3168 SQLSMALLINT * StringLengthPtr, 3169 SQLLEN * NumericAttributePtr) 3170{ 3171 ENTER_STMT (statementHandle, 3172 trace_SQLColAttribute (TRACE_ENTER, 3173 statementHandle, 3174 ColumnNumber, 3175 FieldIdentifier, 3176 CharacterAttributePtr, BufferLength, StringLengthPtr, 3177 NumericAttributePtr)); 3178 3179 retcode = SQLColAttribute_Internal ( 3180 statementHandle, 3181 ColumnNumber, 3182 FieldIdentifier, 3183 CharacterAttributePtr, BufferLength, StringLengthPtr, 3184 NumericAttributePtr, 'A'); 3185 3186 LEAVE_STMT (statementHandle, 3187 trace_SQLColAttribute (TRACE_LEAVE, 3188 statementHandle, 3189 ColumnNumber, 3190 FieldIdentifier, 3191 CharacterAttributePtr, BufferLength, StringLengthPtr, 3192 NumericAttributePtr)); 3193} 3194 3195 3196RETCODE SQL_API 3197SQLColAttributeA ( 3198 SQLHSTMT statementHandle, 3199 SQLUSMALLINT ColumnNumber, 3200 SQLUSMALLINT FieldIdentifier, 3201 SQLPOINTER CharacterAttributePtr, 3202 SQLSMALLINT BufferLength, 3203 SQLSMALLINT * StringLengthPtr, 3204 SQLLEN * NumericAttributePtr) 3205{ 3206 ENTER_STMT (statementHandle, 3207 trace_SQLColAttribute (TRACE_ENTER, 3208 statementHandle, 3209 ColumnNumber, 3210 FieldIdentifier, 3211 CharacterAttributePtr, BufferLength, StringLengthPtr, 3212 NumericAttributePtr)); 3213 3214 retcode = SQLColAttribute_Internal ( 3215 statementHandle, 3216 ColumnNumber, 3217 FieldIdentifier, 3218 CharacterAttributePtr, BufferLength, StringLengthPtr, 3219 NumericAttributePtr, 'A'); 3220 3221 LEAVE_STMT (statementHandle, 3222 trace_SQLColAttribute (TRACE_LEAVE, 3223 statementHandle, 3224 ColumnNumber, 3225 FieldIdentifier, 3226 CharacterAttributePtr, BufferLength, StringLengthPtr, 3227 NumericAttributePtr)); 3228} 3229 3230 3231RETCODE SQL_API 3232SQLColAttributeW ( 3233 SQLHSTMT statementHandle, 3234 SQLUSMALLINT ColumnNumber, 3235 SQLUSMALLINT FieldIdentifier, 3236 SQLPOINTER CharacterAttributePtr, 3237 SQLSMALLINT BufferLength, 3238 SQLSMALLINT * StringLengthPtr, 3239 SQLLEN * NumericAttributePtr) 3240{ 3241 ENTER_STMT (statementHandle, 3242 trace_SQLColAttributeW (TRACE_ENTER, 3243 statementHandle, 3244 ColumnNumber, 3245 FieldIdentifier, 3246 CharacterAttributePtr, BufferLength, StringLengthPtr, 3247 NumericAttributePtr)); 3248 3249 retcode = SQLColAttribute_Internal ( 3250 statementHandle, 3251 ColumnNumber, 3252 FieldIdentifier, 3253 CharacterAttributePtr, BufferLength, StringLengthPtr, 3254 NumericAttributePtr, 3255 'W'); 3256 3257 LEAVE_STMT (statementHandle, 3258 trace_SQLColAttributeW (TRACE_LEAVE, 3259 statementHandle, 3260 ColumnNumber, 3261 FieldIdentifier, 3262 CharacterAttributePtr, BufferLength, StringLengthPtr, 3263 NumericAttributePtr)); 3264} 3265 3266 3267static RETCODE 3268SQLEndTran_Internal ( 3269 SQLSMALLINT handleType, 3270 SQLHANDLE Handle, 3271 SQLSMALLINT completionType) 3272{ 3273 switch (handleType) 3274 { 3275 case SQL_HANDLE_DBC: 3276 case SQL_HANDLE_ENV: 3277 break; 3278 default: 3279 return SQL_INVALID_HANDLE; 3280 } 3281 3282 return SQLTransact_Internal ( 3283 handleType == SQL_HANDLE_ENV ? Handle : SQL_NULL_HENV, 3284 handleType == SQL_HANDLE_DBC ? Handle : SQL_NULL_HDBC, 3285 completionType); 3286} 3287 3288 3289RETCODE SQL_API 3290SQLEndTran ( 3291 SQLSMALLINT handleType, 3292 SQLHANDLE Handle, 3293 SQLSMALLINT completionType) 3294{ 3295 SQLRETURN retcode = SQL_SUCCESS; 3296 3297 ODBC_LOCK (); 3298 TRACE (trace_SQLEndTran (TRACE_ENTER, handleType, Handle, completionType)); 3299 3300 retcode = SQLEndTran_Internal (handleType, Handle, completionType); 3301 3302 TRACE (trace_SQLEndTran (TRACE_LEAVE, handleType, Handle, completionType)); 3303 ODBC_UNLOCK (); 3304 3305 return retcode; 3306} 3307 3308 3309static RETCODE 3310SQLBulkOperations_Internal ( 3311 SQLHSTMT statementHandle, 3312 SQLSMALLINT Operation) 3313{ 3314 STMT (stmt, statementHandle); 3315 HPROC hproc; 3316 RETCODE retcode; 3317 3318 switch (Operation) 3319 { 3320 case SQL_ADD: 3321 case SQL_UPDATE_BY_BOOKMARK: 3322 case SQL_DELETE_BY_BOOKMARK: 3323 case SQL_FETCH_BY_BOOKMARK: 3324 break; 3325 default: 3326 PUSHSQLERR (stmt->herr, en_HY092); 3327 return SQL_ERROR; 3328 } 3329 3330 hproc = _iodbcdm_getproc (stmt->hdbc, en_BulkOperations); 3331 if (hproc) 3332 { 3333 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 3334 (stmt->dhstmt, Operation)); 3335 3336 if (Operation == SQL_FETCH_BY_BOOKMARK 3337 && SQL_SUCCEEDED (retcode)) 3338 _iodbcdm_ConvBindData (stmt); 3339 return retcode; 3340 } 3341 3342 switch (Operation) 3343 { 3344 case SQL_ADD: 3345 retcode = _iodbcdm_SetPos (statementHandle, 3346 0, SQL_ADD, SQL_LOCK_NO_CHANGE); 3347 return retcode; 3348 3349 default: 3350 PUSHSQLERR (stmt->herr, en_HYC00); 3351 return SQL_ERROR; 3352 } 3353} 3354 3355 3356RETCODE SQL_API 3357SQLBulkOperations ( 3358 SQLHSTMT StatementHandle, 3359 SQLSMALLINT Operation) 3360{ 3361 ENTER_STMT (StatementHandle, 3362 trace_SQLBulkOperations (TRACE_ENTER, StatementHandle, Operation)); 3363 3364 retcode = SQLBulkOperations_Internal (StatementHandle, Operation); 3365 3366 LEAVE_STMT (StatementHandle, 3367 trace_SQLBulkOperations (TRACE_LEAVE, StatementHandle, Operation)); 3368} 3369 3370 3371static RETCODE 3372SQLFetchScroll_Internal ( 3373 SQLHSTMT statementHandle, 3374 SQLSMALLINT fetchOrientation, 3375 SQLLEN fetchOffset) 3376{ 3377 STMT (stmt, statementHandle); 3378 HPROC hproc = SQL_NULL_HPROC; 3379 RETCODE retcode; 3380 CONN (pdbc, stmt->hdbc); 3381 HPROC hproc2 = SQL_NULL_HPROC; 3382 SQLUINTEGER odbc_ver = ((GENV_t *) pdbc->genv)->odbc_ver; 3383 SQLUINTEGER dodbc_ver = ((ENV_t *) pdbc->henv)->dodbc_ver; 3384 3385 /* check arguments */ 3386 switch (fetchOrientation) 3387 { 3388 case SQL_FETCH_NEXT: 3389 case SQL_FETCH_PRIOR: 3390 case SQL_FETCH_FIRST: 3391 case SQL_FETCH_LAST: 3392 case SQL_FETCH_ABSOLUTE: 3393 case SQL_FETCH_RELATIVE: 3394 case SQL_FETCH_BOOKMARK: 3395 break; 3396 3397 default: 3398 PUSHSQLERR (stmt->herr, en_HY092); 3399 return SQL_ERROR; 3400 } 3401 3402 /* check state */ 3403 if (stmt->asyn_on == en_NullProc) 3404 { 3405 switch (stmt->state) 3406 { 3407 case en_stmt_allocated: 3408 case en_stmt_prepared: 3409 case en_stmt_fetched: 3410 case en_stmt_needdata: 3411 case en_stmt_mustput: 3412 case en_stmt_canput: 3413 PUSHSQLERR (stmt->herr, en_S1010); 3414 return SQL_ERROR; 3415 3416 default: 3417 break; 3418 } 3419 } 3420 else if (stmt->asyn_on != en_FetchScroll) 3421 { 3422 PUSHSQLERR (stmt->herr, en_S1010); 3423 return SQL_ERROR; 3424 } 3425 3426 hproc2 = _iodbcdm_getproc (stmt->hdbc, en_ExtendedFetch); 3427 3428 if (dodbc_ver == SQL_OV_ODBC3 && 3429 ( odbc_ver == SQL_OV_ODBC3 3430 || (odbc_ver == SQL_OV_ODBC2 && hproc2 == SQL_NULL_HPROC))) 3431 { 3432 hproc = _iodbcdm_getproc (stmt->hdbc, en_FetchScroll); 3433 if (hproc) 3434 { 3435 CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, 3436 (stmt->dhstmt, fetchOrientation, fetchOffset)); 3437 } 3438 } 3439 3440 if (hproc == SQL_NULL_HPROC) 3441 { 3442 if (!stmt->row_status_ptr) 3443 { 3444 PUSHSQLERR (stmt->herr, en_HYC00); 3445 return SQL_ERROR; 3446 } 3447 3448 if (fetchOrientation == SQL_FETCH_BOOKMARK) 3449 { 3450 if (fetchOffset) 3451 { 3452 PUSHSQLERR (stmt->herr, en_HYC00); 3453 return SQL_ERROR; 3454 } 3455 retcode = _iodbcdm_ExtendedFetch (statementHandle, fetchOrientation, 3456 stmt->fetch_bookmark_ptr ? *((SQLINTEGER *) stmt->fetch_bookmark_ptr) 3457 : 0, (SQLULEN *) stmt->rows_fetched_ptr, 3458 (SQLUSMALLINT *) stmt->row_status_ptr); 3459 } 3460 else 3461 retcode = 3462 _iodbcdm_ExtendedFetch (statementHandle, fetchOrientation, 3463 fetchOffset, (SQLULEN *) stmt->rows_fetched_ptr, 3464 (SQLUSMALLINT *) stmt->row_status_ptr); 3465 } 3466 3467 /* state transition */ 3468 if (stmt->asyn_on == en_FetchScroll) 3469 { 3470 switch (retcode) 3471 { 3472 case SQL_SUCCESS: 3473 case SQL_SUCCESS_WITH_INFO: 3474 case SQL_NO_DATA_FOUND: 3475 case SQL_ERROR: 3476 stmt->asyn_on = en_NullProc; 3477 break; 3478 3479 case SQL_STILL_EXECUTING: 3480 default: 3481 return retcode; 3482 } 3483 } 3484 3485 switch (stmt->state) 3486 { 3487 case en_stmt_cursoropen: 3488 case en_stmt_xfetched: 3489 switch (retcode) 3490 { 3491 case SQL_SUCCESS: 3492 case SQL_SUCCESS_WITH_INFO: 3493 case SQL_NO_DATA_FOUND: 3494 stmt->state = en_stmt_xfetched; 3495 stmt->cursor_state = en_stmt_cursor_xfetched; 3496 break; 3497 3498 case SQL_STILL_EXECUTING: 3499 stmt->asyn_on = en_FetchScroll; 3500 break; 3501 3502 default: 3503 break; 3504 } 3505 break; 3506 3507 default: 3508 break; 3509 } 3510 3511 return retcode; 3512} 3513 3514 3515RETCODE SQL_API 3516SQLFetchScroll ( 3517 SQLHSTMT StatementHandle, 3518 SQLSMALLINT FetchOrientation, 3519 SQLLEN FetchOffset) 3520{ 3521 ENTER_STMT (StatementHandle, 3522 trace_SQLFetchScroll (TRACE_ENTER, 3523 StatementHandle, 3524 FetchOrientation, 3525 FetchOffset)); 3526 3527 retcode = SQLFetchScroll_Internal ( 3528 StatementHandle, 3529 FetchOrientation, 3530 FetchOffset); 3531 3532 if (SQL_SUCCEEDED (retcode)) 3533 _iodbcdm_ConvBindData ((STMT_t *) StatementHandle); 3534 3535 LEAVE_STMT (StatementHandle, 3536 trace_SQLFetchScroll (TRACE_LEAVE, 3537 StatementHandle, 3538 FetchOrientation, 3539 FetchOffset)); 3540} 3541 3542 3543SQLRETURN SQL_API 3544SQLBindParam ( 3545 SQLHSTMT hstmt, 3546 SQLUSMALLINT ipar, 3547 SQLSMALLINT fCType, 3548 SQLSMALLINT fSqlType, 3549 SQLULEN cbParamDef, 3550 SQLSMALLINT ibScale, 3551 SQLPOINTER rgbValue, 3552 SQLLEN *pcbValue) 3553{ 3554 return SQLBindParameter (hstmt, ipar, SQL_PARAM_INPUT, fCType, fSqlType, cbParamDef, ibScale, rgbValue, SQL_MAX_OPTION_STRING_LENGTH, pcbValue); 3555} 3556 3557 3558static SQLRETURN 3559SQLCloseCursor_Internal (SQLHSTMT hstmt) 3560{ 3561 STMT (pstmt, hstmt); 3562 CONN (pdbc, pstmt->hdbc); 3563 HPROC hproc = SQL_NULL_HPROC; 3564 SQLRETURN retcode = SQL_SUCCESS; 3565 HPROC hproc2 = SQL_NULL_HPROC; 3566 SQLUINTEGER odbc_ver = ((GENV_t *) pdbc->genv)->odbc_ver; 3567 SQLUINTEGER dodbc_ver = ((ENV_t *) pdbc->henv)->dodbc_ver; 3568 3569 /* check state */ 3570 if (pstmt->state >= en_stmt_needdata || pstmt->asyn_on != en_NullProc) 3571 { 3572 PUSHSQLERR (pstmt->herr, en_S1010); 3573 3574 return SQL_ERROR; 3575 } 3576 3577 hproc2 = _iodbcdm_getproc (pstmt->hdbc, en_FreeStmt); 3578 3579 if (dodbc_ver == SQL_OV_ODBC3 && 3580 ( odbc_ver == SQL_OV_ODBC3 3581 || (odbc_ver == SQL_OV_ODBC2 && hproc2 == SQL_NULL_HPROC))) 3582 { 3583 hproc = _iodbcdm_getproc (pstmt->hdbc, en_CloseCursor); 3584 if (hproc) 3585 { 3586 CALL_DRIVER (pstmt->hdbc, pstmt, retcode, hproc, 3587 (pstmt->dhstmt)); 3588 } 3589 } 3590 3591 if (hproc == SQL_NULL_HPROC) 3592 { 3593 hproc = _iodbcdm_getproc (pstmt->hdbc, en_FreeStmt); 3594 3595 if (hproc == SQL_NULL_HPROC) 3596 { 3597 PUSHSQLERR (pstmt->herr, en_IM001); 3598 return SQL_ERROR; 3599 } 3600 3601 CALL_DRIVER (pstmt->hdbc, pstmt, retcode, hproc, 3602 (pstmt->dhstmt, SQL_CLOSE)); 3603 } 3604 3605 if (retcode != SQL_SUCCESS 3606 && retcode != SQL_SUCCESS_WITH_INFO) 3607 { 3608 return retcode; 3609 } 3610 3611 /* 3612 * State transition 3613 */ 3614 pstmt->cursor_state = en_stmt_cursor_no; 3615 3616 switch (pstmt->state) 3617 { 3618 case en_stmt_allocated: 3619 case en_stmt_prepared: 3620 break; 3621 3622 case en_stmt_executed_with_info: 3623 case en_stmt_executed: 3624 case en_stmt_cursoropen: 3625 case en_stmt_fetched: 3626 case en_stmt_xfetched: 3627 if (pstmt->prep_state) 3628 pstmt->state = en_stmt_prepared; 3629 else 3630 pstmt->state = en_stmt_allocated; 3631 break; 3632 3633 default: 3634 break; 3635 } 3636 3637 return retcode; 3638} 3639 3640 3641SQLRETURN SQL_API 3642SQLCloseCursor (SQLHSTMT hstmt) 3643{ 3644 ENTER_STMT (hstmt, 3645 trace_SQLCloseCursor (TRACE_ENTER, hstmt)); 3646 3647 retcode = SQLCloseCursor_Internal (hstmt); 3648 3649 LEAVE_STMT (hstmt, 3650 trace_SQLCloseCursor (TRACE_LEAVE, hstmt)); 3651} 3652 3653#endif /* ODBCVER >= 0x0300 */ 3654