LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLBindParameter.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 41 68 60.3 %
Date: 2024-12-19 23:10:26 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * This code was created by Peter Harvey (mostly during Christmas 98/99).
      15             :  * This code is LGPL. Please ensure that this message remains in future
      16             :  * distributions and uses of this code (that's about all I get out of it).
      17             :  * - Peter Harvey pharvey@codebydesign.com
      18             :  *
      19             :  * This file has been modified for the MonetDB project.  See the file
      20             :  * Copyright in this directory for more information.
      21             :  */
      22             : 
      23             : /**********************************************************************
      24             :  * SQLBindParameter()
      25             :  * CLI Compliance: ODBC (Microsoft)
      26             :  *
      27             :  * Note: this function does not yet support Output parameters, only SQL_PARAM_INPUT.
      28             :  *
      29             :  * Author: Martin van Dinther, Sjoerd Mullender
      30             :  * Date  : 30 Aug 2002
      31             :  *
      32             :  **********************************************************************/
      33             : 
      34             : #include "ODBCGlobal.h"
      35             : #include "ODBCStmt.h"
      36             : 
      37             : SQLRETURN
      38           9 : MNDBBindParameter(ODBCStmt *stmt,
      39             :                   SQLUSMALLINT ParameterNumber,
      40             :                   SQLSMALLINT InputOutputType,
      41             :                   SQLSMALLINT ValueType,
      42             :                   SQLSMALLINT ParameterType,
      43             :                   SQLULEN ColumnSize,
      44             :                   SQLSMALLINT DecimalDigits,
      45             :                   SQLPOINTER ParameterValuePtr,
      46             :                   SQLLEN BufferLength,
      47             :                   SQLLEN *StrLen_or_IndPtr)
      48             : {
      49           9 :         ODBCDesc *apd, *ipd;
      50           9 :         ODBCDescRec *apdrec, *ipdrec;
      51           9 :         SQLRETURN rc;
      52             : 
      53           9 :         if (!isValidStmt(stmt))
      54             :                  return SQL_INVALID_HANDLE;
      55             : 
      56           9 :         clearStmtErrors(stmt);
      57             : 
      58             :         /* check input parameters */
      59           9 :         if (ParameterNumber <= 0) {
      60             :                 /* Invalid descriptor index */
      61           0 :                 addStmtError(stmt, "07009", NULL, 0);
      62           0 :                 return SQL_ERROR;
      63             :         }
      64             :         /* For safety: limit the maximum number of columns to bind */
      65           9 :         if (ParameterNumber > MONETDB_MAX_BIND_COLS) {
      66             :                 /* General error */
      67           0 :                 addStmtError(stmt, "HY000", "Maximum number of bind columns (8192) exceeded", 0);
      68           0 :                 return SQL_ERROR;
      69             :         }
      70             : 
      71           9 :         switch (InputOutputType) {
      72             :         case SQL_PARAM_INPUT:
      73           9 :                 break;
      74           0 :         case SQL_PARAM_INPUT_OUTPUT:
      75             :         case SQL_PARAM_OUTPUT:
      76             :                 /* Optional feature not implemented */
      77           0 :                 addStmtError(stmt, "HYC00", "Output parameters are not supported", 0);
      78           0 :                 return SQL_ERROR;
      79           0 :         default:
      80             :                 /* Invalid parameter type */
      81           0 :                 addStmtError(stmt, "HY105", NULL, 0);
      82           0 :                 return SQL_ERROR;
      83             :         }
      84             : 
      85           9 :         if (ParameterValuePtr == NULL && StrLen_or_IndPtr == NULL
      86             :             /* && InputOutputType != SQL_PARAM_OUTPUT */ ) {
      87             :                 /* Invalid use of null pointer */
      88           0 :                 addStmtError(stmt, "HY009", NULL, 0);
      89           0 :                 return SQL_ERROR;
      90             :         }
      91             : 
      92           9 :         if (BufferLength < 0) {
      93             :                 /* Invalid string or buffer length */
      94           0 :                 addStmtError(stmt, "HY090", NULL, 0);
      95           0 :                 return SQL_ERROR;
      96             :         }
      97             : 
      98             :         /* can't let SQLSetDescField below do this check since it
      99             :            returns the wrong error code if the type is incorrect */
     100           9 :         switch (ValueType) {
     101             :         case SQL_C_CHAR:
     102             :         case SQL_C_WCHAR:
     103             :         case SQL_C_BINARY:
     104             :         case SQL_C_BIT:
     105             :         case SQL_C_STINYINT:
     106             :         case SQL_C_UTINYINT:
     107             :         case SQL_C_TINYINT:
     108             :         case SQL_C_SSHORT:
     109             :         case SQL_C_USHORT:
     110             :         case SQL_C_SHORT:
     111             :         case SQL_C_SLONG:
     112             :         case SQL_C_ULONG:
     113             :         case SQL_C_LONG:
     114             :         case SQL_C_SBIGINT:
     115             :         case SQL_C_UBIGINT:
     116             :         case SQL_C_NUMERIC:
     117             :         case SQL_C_FLOAT:
     118             :         case SQL_C_DOUBLE:
     119             :         case SQL_C_TYPE_DATE:
     120             :         case SQL_C_TYPE_TIME:
     121             :         case SQL_C_TYPE_TIMESTAMP:
     122             :         case SQL_C_INTERVAL_YEAR:
     123             :         case SQL_C_INTERVAL_MONTH:
     124             :         case SQL_C_INTERVAL_YEAR_TO_MONTH:
     125             :         case SQL_C_INTERVAL_DAY:
     126             :         case SQL_C_INTERVAL_HOUR:
     127             :         case SQL_C_INTERVAL_MINUTE:
     128             :         case SQL_C_INTERVAL_SECOND:
     129             :         case SQL_C_INTERVAL_DAY_TO_HOUR:
     130             :         case SQL_C_INTERVAL_DAY_TO_MINUTE:
     131             :         case SQL_C_INTERVAL_DAY_TO_SECOND:
     132             :         case SQL_C_INTERVAL_HOUR_TO_MINUTE:
     133             :         case SQL_C_INTERVAL_HOUR_TO_SECOND:
     134             :         case SQL_C_INTERVAL_MINUTE_TO_SECOND:
     135             :         case SQL_C_GUID:
     136             :         case SQL_C_DEFAULT:
     137           9 :                 break;
     138           0 :         default:
     139             :                 /* Invalid application buffer type */
     140           0 :                 addStmtError(stmt, "HY003", NULL, 0);
     141           0 :                 return SQL_ERROR;
     142             :         }
     143             : 
     144           9 :         apd = stmt->ApplParamDescr;
     145           9 :         ipd = stmt->ImplParamDescr;
     146             : 
     147           9 :         apdrec = addODBCDescRec(apd, ParameterNumber);
     148           9 :         ipdrec = addODBCDescRec(ipd, ParameterNumber);
     149             : 
     150             :         /* we disallow types not supported by the server */
     151           9 :         switch (ParameterType) {
     152           1 :         case SQL_CHAR:
     153             :         case SQL_VARCHAR:
     154             :         case SQL_LONGVARCHAR:
     155             : /*      case SQL_BINARY: */
     156             :         case SQL_VARBINARY:
     157             :         case SQL_LONGVARBINARY:
     158             :         case SQL_TYPE_DATE:
     159             :         case SQL_INTERVAL_MONTH:
     160             : /*      case SQL_INTERVAL_YEAR: */
     161             : /*      case SQL_INTERVAL_YEAR_TO_MONTH: */
     162             : /*      case SQL_INTERVAL_DAY: */
     163             : /*      case SQL_INTERVAL_HOUR: */
     164             : /*      case SQL_INTERVAL_MINUTE: */
     165             : /*      case SQL_INTERVAL_DAY_TO_HOUR: */
     166             : /*      case SQL_INTERVAL_DAY_TO_MINUTE: */
     167             : /*      case SQL_INTERVAL_HOUR_TO_MINUTE: */
     168           1 :                 ipdrec->sql_desc_length = ColumnSize;
     169           1 :                 break;
     170           1 :         case SQL_TYPE_TIME:
     171             :         case SQL_TYPE_TIMESTAMP:
     172             :         case SQL_INTERVAL_SECOND:
     173             : /*      case SQL_INTERVAL_DAY_TO_SECOND: */
     174             : /*      case SQL_INTERVAL_HOUR_TO_SECOND: */
     175             : /*      case SQL_INTERVAL_MINUTE_TO_SECOND: */
     176           1 :                 ipdrec->sql_desc_precision = DecimalDigits;
     177           1 :                 ipdrec->sql_desc_length = ColumnSize;
     178           1 :                 break;
     179           0 :         case SQL_DECIMAL:
     180             :         case SQL_NUMERIC:
     181           0 :                 ipdrec->sql_desc_precision = (SQLSMALLINT) ColumnSize;
     182           0 :                 ipdrec->sql_desc_scale = DecimalDigits;
     183           0 :                 break;
     184           1 :         case SQL_FLOAT:
     185             :         case SQL_REAL:
     186             :         case SQL_DOUBLE:
     187           1 :                 ipdrec->sql_desc_precision = (SQLSMALLINT) ColumnSize;
     188           1 :                 break;
     189             :         case SQL_WCHAR:
     190             :         case SQL_WVARCHAR:
     191             :         case SQL_WLONGVARCHAR:
     192             :         case SQL_BIT:
     193             :         case SQL_TINYINT:
     194             :         case SQL_SMALLINT:
     195             :         case SQL_INTEGER:
     196             :         case SQL_BIGINT:
     197             :         case SQL_HUGEINT:
     198             :         case SQL_GUID:
     199             :                 break;
     200           0 :         default:
     201             :                 /* Invalid SQL data type */
     202           0 :                 addStmtError(stmt, "HY004", NULL, 0);
     203           0 :                 return SQL_ERROR;
     204             : 
     205             :         /* these types are not allowed by the server */
     206           0 :         case SQL_BINARY:
     207             :         case SQL_INTERVAL_YEAR:
     208             :         case SQL_INTERVAL_YEAR_TO_MONTH:
     209             :         case SQL_INTERVAL_DAY:
     210             :         case SQL_INTERVAL_HOUR:
     211             :         case SQL_INTERVAL_MINUTE:
     212             :         case SQL_INTERVAL_DAY_TO_HOUR:
     213             :         case SQL_INTERVAL_DAY_TO_MINUTE:
     214             :         case SQL_INTERVAL_HOUR_TO_MINUTE:
     215             :         case SQL_INTERVAL_DAY_TO_SECOND:
     216             :         case SQL_INTERVAL_HOUR_TO_SECOND:
     217             :         case SQL_INTERVAL_MINUTE_TO_SECOND:
     218             :                 /* Optional feature not implemented */
     219           0 :                 addStmtError(stmt, "HYC00", NULL, 0);
     220           0 :                 return SQL_ERROR;
     221             :         }
     222             : 
     223           9 :         rc = MNDBSetDescField(apd, ParameterNumber, SQL_DESC_CONCISE_TYPE, (SQLPOINTER) (intptr_t) ValueType, 0);
     224           9 :         if (!SQL_SUCCEEDED(rc))
     225             :                 return rc;
     226           9 :         rc = MNDBSetDescField(ipd, ParameterNumber, SQL_DESC_CONCISE_TYPE, (SQLPOINTER) (intptr_t) ParameterType, 0);
     227           9 :         if (!SQL_SUCCEEDED(rc))
     228             :                 return rc;
     229           9 :         ipdrec->sql_desc_parameter_type = InputOutputType;
     230           9 :         apdrec->sql_desc_data_ptr = ParameterValuePtr;
     231           9 :         apdrec->sql_desc_octet_length = BufferLength;
     232           9 :         apdrec->sql_desc_indicator_ptr = StrLen_or_IndPtr;
     233           9 :         apdrec->sql_desc_octet_length_ptr = StrLen_or_IndPtr;
     234             : 
     235           9 :         return SQL_SUCCESS;
     236             : }
     237             : 
     238             : SQLRETURN SQL_API
     239             : SQLBindParameter(SQLHSTMT StatementHandle,
     240             :                  SQLUSMALLINT ParameterNumber,
     241             :                  SQLSMALLINT InputOutputType,
     242             :                  SQLSMALLINT ValueType,
     243             :                  SQLSMALLINT ParameterType,
     244             :                  SQLULEN ColumnSize,
     245             :                  SQLSMALLINT DecimalDigits,
     246             :                  SQLPOINTER ParameterValuePtr,
     247             :                  SQLLEN BufferLength,
     248             :                  SQLLEN *StrLen_or_IndPtr)
     249             : {
     250             : #ifdef ODBCDEBUG
     251           9 :         ODBCLOG("SQLBindParameter %p %u %d %s %s " ULENFMT " %d %p " LENFMT " %p\n",
     252             :                 StatementHandle, (unsigned int) ParameterNumber,
     253             :                 (int) InputOutputType, translateCType(ValueType),
     254             :                 translateSQLType(ParameterType),
     255             :                 ULENCAST ColumnSize, (int) DecimalDigits,
     256             :                 ParameterValuePtr, LENCAST BufferLength,
     257             :                 StrLen_or_IndPtr);
     258             : #endif
     259             : 
     260           9 :         return MNDBBindParameter((ODBCStmt *) StatementHandle, ParameterNumber,
     261             :                                  InputOutputType, ValueType, ParameterType,
     262             :                                  ColumnSize, DecimalDigits, ParameterValuePtr,
     263             :                                  BufferLength, StrLen_or_IndPtr);
     264             : }

Generated by: LCOV version 1.14