LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLSetDescField.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 27 193 14.0 %
Date: 2024-10-03 20:03:20 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             :  * SQLSetDescField()
      25             :  * CLI Compliance: ISO 92
      26             :  **********************************************************************/
      27             : 
      28             : #include "ODBCGlobal.h"
      29             : #include "ODBCStmt.h"
      30             : #include "ODBCUtil.h"
      31             : 
      32             : SQLRETURN
      33          30 : MNDBSetDescField(ODBCDesc *desc,
      34             :                  SQLSMALLINT RecNumber,
      35             :                  SQLSMALLINT FieldIdentifier,
      36             :                  SQLPOINTER ValuePtr,
      37             :                  SQLINTEGER BufferLength)
      38             : {
      39          30 :         ODBCDescRec *rec;
      40          30 :         struct sql_types *tp;
      41             : 
      42          30 :         if (isAD(desc))
      43             :                 tp = ODBC_c_types;
      44             :         else
      45           9 :                 tp = ODBC_sql_types;
      46             : 
      47          30 :         switch (FieldIdentifier) {
      48           0 :         case SQL_DESC_ALLOC_TYPE:               /* SQLSMALLINT */
      49             :                 /* Invalid descriptor field identifier */
      50           0 :                 addDescError(desc, "HY091", NULL, 0);
      51           0 :                 return SQL_ERROR;
      52           0 :         case SQL_DESC_ARRAY_SIZE:               /* SQLULEN */
      53           0 :                 if ((SQLULEN) (uintptr_t) ValuePtr == 0) {
      54             :                         /* Invalid attribute/option identifier */
      55           0 :                         addDescError(desc, "HY092", NULL, 0);
      56           0 :                         return SQL_ERROR;
      57             :                 }
      58           0 :                 if (isAD(desc)) {
      59             :                         /* limit size to protect against bugs */
      60           0 :                         if ((SQLULEN) (uintptr_t) ValuePtr > 10000) {
      61             :                                 /* Driver does not support this function */
      62           0 :                                 addDescError(desc, "IM001", NULL, 0);
      63           0 :                                 return SQL_ERROR;
      64             :                         }
      65           0 :                         desc->sql_desc_array_size = (SQLULEN) (uintptr_t) ValuePtr;
      66             :                 }
      67             :                 return SQL_SUCCESS;
      68           0 :         case SQL_DESC_ARRAY_STATUS_PTR:         /* SQLUSMALLINT * */
      69           0 :                 desc->sql_desc_array_status_ptr = (SQLUSMALLINT *) ValuePtr;
      70           0 :                 return SQL_SUCCESS;
      71           0 :         case SQL_DESC_BIND_OFFSET_PTR:          /* SQLLEN * */
      72           0 :                 if (isAD(desc))
      73           0 :                         desc->sql_desc_bind_offset_ptr = (SQLLEN *) ValuePtr;
      74             :                 return SQL_SUCCESS;
      75           0 :         case SQL_DESC_BIND_TYPE:                /* SQLINTEGER */
      76           0 :                 if (isAD(desc))
      77           0 :                         desc->sql_desc_bind_type = (SQLINTEGER) (intptr_t) ValuePtr;
      78             :                 return SQL_SUCCESS;
      79           0 :         case SQL_DESC_COUNT:                    /* SQLSMALLINT */
      80           0 :                 if (isIRD(desc)) {
      81             :                         /* Invalid descriptor field identifier */
      82           0 :                         addDescError(desc, "HY091", NULL, 0);
      83           0 :                         return SQL_ERROR;
      84             :                 }
      85           0 :                 setODBCDescRecCount(desc, (int) (SQLSMALLINT) (intptr_t) ValuePtr);
      86           0 :                 return SQL_SUCCESS;
      87           0 :         case SQL_DESC_ROWS_PROCESSED_PTR:       /* SQLULEN * */
      88           0 :                 if (desc->Stmt)
      89           0 :                         desc->sql_desc_rows_processed_ptr = (SQLULEN *) ValuePtr;
      90             :                 return SQL_SUCCESS;
      91             :         }
      92             : 
      93          30 :         if (RecNumber <= 0) {
      94             :                 /* Invalid descriptor index */
      95           0 :                 addDescError(desc, "07009", NULL, 0);
      96           0 :                 return SQL_ERROR;
      97             :         }
      98          30 :         if (RecNumber > desc->sql_desc_count)
      99             :                 return SQL_NO_DATA;
     100             : 
     101          30 :         if (isIRD(desc)) {
     102             :                 /* the Implementation Row Descriptor is read-only */
     103             :                 /* Invalid descriptor field identifier */
     104           0 :                 addDescError(desc, "HY091", NULL, 0);
     105           0 :                 return SQL_ERROR;
     106             :         }
     107             : 
     108          30 :         rec = &desc->descRec[RecNumber];
     109             : 
     110             :         /* break for read-only fields since the error is the same as
     111             :            unknown FieldIdentifier */
     112          30 :         switch (FieldIdentifier) {
     113             :         case SQL_DESC_AUTO_UNIQUE_VALUE:        /* SQLINTEGER */
     114             :         case SQL_DESC_BASE_COLUMN_NAME:         /* SQLCHAR * */
     115             :         case SQL_DESC_BASE_TABLE_NAME:          /* SQLCHAR * */
     116             :         case SQL_DESC_CASE_SENSITIVE:           /* SQLINTEGER */
     117             :         case SQL_DESC_CATALOG_NAME:             /* SQLCHAR * */
     118             :         case SQL_DESC_DISPLAY_SIZE:             /* SQLLEN */
     119             :         case SQL_DESC_FIXED_PREC_SCALE:         /* SQLSMALLINT */
     120             :         case SQL_DESC_LABEL:                    /* SQLCHAR * */
     121             :         case SQL_DESC_LITERAL_PREFIX:           /* SQLCHAR * */
     122             :         case SQL_DESC_LITERAL_SUFFIX:           /* SQLCHAR * */
     123             :         case SQL_DESC_LOCAL_TYPE_NAME:          /* SQLCHAR * */
     124             :         case SQL_DESC_NULLABLE:                 /* SQLSMALLINT */
     125             :         case SQL_DESC_ROWVER:                   /* SQLSMALLINT */
     126             :         case SQL_DESC_SCHEMA_NAME:              /* SQLCHAR * */
     127             :         case SQL_DESC_SEARCHABLE:               /* SQLSMALLINT */
     128             :         case SQL_DESC_TABLE_NAME:               /* SQLCHAR * */
     129             :         case SQL_DESC_TYPE_NAME:                /* SQLCHAR * */
     130             :         case SQL_DESC_UNSIGNED:                 /* SQLSMALLINT */
     131             :         case SQL_DESC_UPDATABLE:                /* SQLSMALLINT */
     132             :                 break;          /* read-only or unused */
     133             :         case SQL_DESC_CONCISE_TYPE:             /* SQLSMALLINT */
     134         368 :                 while (tp->concise_type != 0) {
     135         368 :                         if ((intptr_t) tp->concise_type == (intptr_t) ValuePtr) {
     136          30 :                                 if (tp->concise_type == SQL_HUGEINT)
     137           0 :                                         desc->Dbc->allow_hugeint = true;
     138          30 :                                 rec->sql_desc_concise_type = tp->concise_type;
     139          30 :                                 rec->sql_desc_type = tp->type;
     140          30 :                                 rec->sql_desc_datetime_interval_code = tp->code;
     141          30 :                                 if (tp->precision != UNAFFECTED)
     142          15 :                                         rec->sql_desc_precision = tp->precision;
     143          30 :                                 if (tp->datetime_interval_precision != UNAFFECTED)
     144           0 :                                         rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision;
     145          30 :                                 if (tp->length != UNAFFECTED)
     146           3 :                                         rec->sql_desc_length = tp->length;
     147          30 :                                 if (tp->scale != UNAFFECTED)
     148           0 :                                         rec->sql_desc_scale = tp->scale;
     149          30 :                                 rec->sql_desc_fixed_prec_scale = tp->fixed;
     150          30 :                                 rec->sql_desc_num_prec_radix = tp->radix;
     151          30 :                                 return SQL_SUCCESS;
     152             :                         }
     153         338 :                         tp++;
     154             :                 }
     155             :                 /* Invalid attribute/option identifier */
     156           0 :                 addDescError(desc, "HY092", NULL, 0);
     157           0 :                 return SQL_ERROR;
     158           0 :         case SQL_DESC_DATA_PTR:                 /* SQLPOINTER */
     159             :                 /* TODO: consistency check */
     160           0 :                 rec->sql_desc_data_ptr = ValuePtr;
     161           0 :                 return SQL_SUCCESS;
     162             :         case SQL_DESC_DATETIME_INTERVAL_CODE:   /* SQLSMALLINT */
     163           0 :                 while (tp->concise_type != 0) {
     164           0 :                         if ((intptr_t) tp->code == (intptr_t) ValuePtr &&
     165           0 :                             tp->type == rec->sql_desc_type) {
     166           0 :                                 rec->sql_desc_concise_type = tp->concise_type;
     167           0 :                                 rec->sql_desc_type = tp->type;
     168           0 :                                 rec->sql_desc_datetime_interval_code = tp->code;
     169           0 :                                 if (tp->precision != UNAFFECTED)
     170           0 :                                         rec->sql_desc_precision = tp->precision;
     171           0 :                                 if (tp->datetime_interval_precision != UNAFFECTED)
     172           0 :                                         rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision;
     173           0 :                                 if (tp->length != UNAFFECTED)
     174           0 :                                         rec->sql_desc_length = tp->length;
     175           0 :                                 if (tp->scale != UNAFFECTED)
     176           0 :                                         rec->sql_desc_scale = tp->scale;
     177           0 :                                 rec->sql_desc_fixed_prec_scale = tp->fixed;
     178           0 :                                 rec->sql_desc_num_prec_radix = tp->radix;
     179           0 :                                 return SQL_SUCCESS;
     180             :                         }
     181           0 :                         tp++;
     182             :                 }
     183             :                 /* Inconsistent descriptor information */
     184           0 :                 addDescError(desc, "HY021", NULL, 0);
     185           0 :                 return SQL_ERROR;
     186           0 :         case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* SQLINTEGER */
     187           0 :                 rec->sql_desc_datetime_interval_precision = (SQLINTEGER) (intptr_t) ValuePtr;
     188           0 :                 return SQL_SUCCESS;
     189           0 :         case SQL_DESC_INDICATOR_PTR:            /* SQLLEN * */
     190           0 :                 if (isAD(desc))
     191           0 :                         rec->sql_desc_indicator_ptr = (SQLLEN *) ValuePtr;
     192             :                 return SQL_SUCCESS;
     193           0 :         case SQL_DESC_LENGTH:                   /* SQLULEN */
     194           0 :                 rec->sql_desc_length = (SQLULEN) (uintptr_t) ValuePtr;
     195           0 :                 return SQL_SUCCESS;
     196           0 :         case SQL_DESC_NAME:                     /* SQLCHAR * */
     197           0 :                 if (isID(desc)) {
     198           0 :                         fixODBCstring(ValuePtr, BufferLength, SQLINTEGER,
     199             :                                       addDescError, desc, return SQL_ERROR);
     200           0 :                         if (rec->sql_desc_name != NULL)
     201           0 :                                 free(rec->sql_desc_name);
     202           0 :                         rec->sql_desc_name = (SQLCHAR *) dupODBCstring((SQLCHAR *) ValuePtr, (size_t) BufferLength);
     203           0 :                         if (rec->sql_desc_name == NULL) {
     204             :                                 /* Memory allocation error */
     205           0 :                                 addDescError(desc, "HY001", NULL, 0);
     206           0 :                                 return SQL_ERROR;
     207             :                         }
     208           0 :                         rec->sql_desc_unnamed = *rec->sql_desc_name ? SQL_NAMED : SQL_UNNAMED;
     209             :                 }
     210             :                 return SQL_SUCCESS;
     211           0 :         case SQL_DESC_NUM_PREC_RADIX:
     212           0 :                 rec->sql_desc_num_prec_radix = (SQLINTEGER) (intptr_t) ValuePtr;
     213           0 :                 return SQL_SUCCESS;
     214           0 :         case SQL_DESC_OCTET_LENGTH:             /* SQLLEN */
     215           0 :                 rec->sql_desc_octet_length = (SQLLEN) (intptr_t) ValuePtr;
     216           0 :                 return SQL_SUCCESS;
     217           0 :         case SQL_DESC_OCTET_LENGTH_PTR:         /* SQLLEN * */
     218           0 :                 if (isAD(desc))
     219           0 :                         rec->sql_desc_octet_length_ptr = (SQLLEN *) ValuePtr;
     220             :                 return SQL_SUCCESS;
     221           0 :         case SQL_DESC_PARAMETER_TYPE:           /* SQLSMALLINT */
     222           0 :                 switch ((SQLSMALLINT) (intptr_t) ValuePtr) {
     223             :                 case SQL_PARAM_INPUT:
     224           0 :                         break;
     225           0 :                 case SQL_PARAM_INPUT_OUTPUT:
     226             :                 case SQL_PARAM_OUTPUT:
     227             :                         /* Driver does not support this function */
     228           0 :                         addDescError(desc, "IM001", NULL, 0);
     229           0 :                         return SQL_ERROR;
     230           0 :                 default:
     231             :                         /* Invalid attribute/option identifier */
     232           0 :                         addDescError(desc, "HY092", NULL, 0);
     233           0 :                         return SQL_ERROR;
     234             :                 }
     235           0 :                 if (isIPD(desc))
     236           0 :                         rec->sql_desc_parameter_type = (SQLSMALLINT) (intptr_t) ValuePtr;
     237             :                 return SQL_SUCCESS;
     238           0 :         case SQL_DESC_PRECISION:                /* SQLSMALLINT */
     239           0 :                 rec->sql_desc_precision = (SQLSMALLINT) (intptr_t) ValuePtr;
     240           0 :                 return SQL_SUCCESS;
     241           0 :         case SQL_DESC_SCALE:                    /* SQLSMALLINT */
     242           0 :                 rec->sql_desc_scale = (SQLSMALLINT) (intptr_t) ValuePtr;
     243           0 :                 return SQL_SUCCESS;
     244             :         case SQL_DESC_TYPE:                     /* SQLSMALLINT */
     245           0 :                 while (tp->concise_type != 0) {
     246           0 :                         if ((SQLSMALLINT) (intptr_t) ValuePtr == tp->type &&
     247           0 :                             (((SQLSMALLINT) (intptr_t) ValuePtr != SQL_DATETIME &&
     248           0 :                               (SQLSMALLINT) (intptr_t) ValuePtr != SQL_INTERVAL) ||
     249           0 :                              tp->code == rec->sql_desc_datetime_interval_code)) {
     250           0 :                                 if (tp->concise_type == SQL_HUGEINT)
     251           0 :                                         desc->Dbc->allow_hugeint = true;
     252           0 :                                 rec->sql_desc_concise_type = tp->concise_type;
     253           0 :                                 rec->sql_desc_type = tp->type;
     254           0 :                                 rec->sql_desc_datetime_interval_code = tp->code;
     255           0 :                                 if (tp->precision != UNAFFECTED)
     256           0 :                                         rec->sql_desc_precision = tp->precision;
     257           0 :                                 if (tp->datetime_interval_precision != UNAFFECTED)
     258           0 :                                         rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision;
     259           0 :                                 if (tp->length != UNAFFECTED)
     260           0 :                                         rec->sql_desc_length = tp->length;
     261           0 :                                 if (tp->scale != UNAFFECTED)
     262           0 :                                         rec->sql_desc_scale = tp->scale;
     263           0 :                                 rec->sql_desc_fixed_prec_scale = tp->fixed;
     264           0 :                                 rec->sql_desc_num_prec_radix = tp->radix;
     265           0 :                                 return SQL_SUCCESS;
     266             :                         }
     267           0 :                         tp++;
     268             :                 }
     269             :                 /* Inconsistent descriptor information */
     270           0 :                 addDescError(desc, "HY021", NULL, 0);
     271           0 :                 return SQL_ERROR;
     272           0 :         case SQL_DESC_UNNAMED:                  /* SQLSMALLINT */
     273           0 :                 if ((SQLSMALLINT) (intptr_t) ValuePtr == SQL_NAMED) {
     274             :                         /* Invalid descriptor field identifier */
     275           0 :                         addDescError(desc, "HY091", NULL, 0);
     276           0 :                         return SQL_ERROR;
     277           0 :                 } else if ((SQLSMALLINT) (intptr_t) ValuePtr == SQL_UNNAMED && isIPD(desc)) {
     278           0 :                         rec->sql_desc_unnamed = SQL_UNNAMED;
     279           0 :                         if (rec->sql_desc_name)
     280           0 :                                 free(rec->sql_desc_name);
     281           0 :                         rec->sql_desc_name = NULL;
     282           0 :                         return SQL_SUCCESS;
     283             :                 }
     284             :                 /* Inconsistent descriptor information */
     285           0 :                 addDescError(desc, "HY021", NULL, 0);
     286           0 :                 return SQL_ERROR;
     287             :         }
     288             : 
     289             :         /* Invalid descriptor field identifier */
     290           0 :         addDescError(desc, "HY091", NULL, 0);
     291           0 :         return SQL_ERROR;
     292             : }
     293             : 
     294             : SQLRETURN SQL_API
     295             : SQLSetDescField(SQLHDESC DescriptorHandle,
     296             :                 SQLSMALLINT RecNumber,
     297             :                 SQLSMALLINT FieldIdentifier,
     298             :                 SQLPOINTER ValuePtr,
     299             :                 SQLINTEGER BufferLength)
     300             : {
     301             : #ifdef ODBCDEBUG
     302           0 :         ODBCLOG("SQLSetDescField %p %d %s %p %d\n",
     303             :                 DescriptorHandle, (int) RecNumber,
     304             :                 translateFieldIdentifier(FieldIdentifier),
     305             :                 ValuePtr, (int) BufferLength);
     306             : #endif
     307             : 
     308           0 :         if (!isValidDesc((ODBCDesc *) DescriptorHandle))
     309             :                 return SQL_INVALID_HANDLE;
     310             : 
     311           0 :         clearDescErrors((ODBCDesc *) DescriptorHandle);
     312             : 
     313           0 :         return MNDBSetDescField((ODBCDesc *) DescriptorHandle, RecNumber, FieldIdentifier, ValuePtr, BufferLength);
     314             : }
     315             : 
     316             : SQLRETURN SQL_API
     317             : SQLSetDescFieldW(SQLHDESC DescriptorHandle,
     318             :                  SQLSMALLINT RecNumber,
     319             :                  SQLSMALLINT FieldIdentifier,
     320             :                  SQLPOINTER ValuePtr,
     321             :                  SQLINTEGER BufferLength)
     322             : {
     323           0 :         ODBCDesc *desc = (ODBCDesc *) DescriptorHandle;
     324           0 :         SQLRETURN rc;
     325           0 :         SQLPOINTER ptr;
     326           0 :         SQLINTEGER n;
     327             : 
     328             : #ifdef ODBCDEBUG
     329           0 :         ODBCLOG("SQLSetDescFieldW %p %d %s %p %d\n",
     330             :                 DescriptorHandle, (int) RecNumber,
     331             :                 translateFieldIdentifier(FieldIdentifier),
     332             :                 ValuePtr, (int) BufferLength);
     333             : #endif
     334             : 
     335           0 :         if (!isValidDesc(desc))
     336             :                 return SQL_INVALID_HANDLE;
     337             : 
     338           0 :         clearDescErrors(desc);
     339             : 
     340           0 :         switch (FieldIdentifier) {
     341           0 :         case SQL_DESC_NAME:
     342           0 :                 if (BufferLength > 0)        /* convert from bytes to characters */
     343           0 :                         BufferLength /= 2;
     344           0 :                 fixWcharIn(ValuePtr, BufferLength, SQLCHAR, ptr,
     345             :                            addDescError, desc, return SQL_ERROR);
     346           0 :                 n = SQL_NTS;
     347           0 :                 break;
     348             :         default:
     349             :                 ptr = ValuePtr;
     350             :                 n = BufferLength;
     351             :                 break;
     352             :         }
     353             : 
     354           0 :         rc = MNDBSetDescField(desc, RecNumber, FieldIdentifier, ptr, n);
     355             : 
     356           0 :         if (ptr && ptr != ValuePtr)
     357           0 :                 free(ptr);
     358             : 
     359             :         return rc;
     360             : }

Generated by: LCOV version 1.14