LCOV - code coverage report
Current view: top level - src/odbc - odbc_data.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 228 236 96.6 %
Date: 2025-02-21 09:36:06 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2             :  * Copyright (C) 2014  Frediano Ziglio
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Library General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2 of the License, or (at your option) any later version.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Library General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Library General Public
      15             :  * License along with this library; if not, write to the
      16             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17             :  * Boston, MA 02111-1307, USA.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : 
      22             : #include <stdarg.h>
      23             : #include <stdio.h>
      24             : 
      25             : #if HAVE_STDLIB_H
      26             : #include <stdlib.h>
      27             : #endif /* HAVE_STDLIB_H */
      28             : 
      29             : #if HAVE_STRING_H
      30             : #include <string.h>
      31             : #endif /* HAVE_STRING_H */
      32             : 
      33             : #include <assert.h>
      34             : #include <ctype.h>
      35             : 
      36             : #include <freetds/odbc.h>
      37             : #include <freetds/iconv.h>
      38             : #include <odbcss.h>
      39             : 
      40             : #define SET_INFO(type, prefix, suffix) do { \
      41             :         drec->sql_desc_literal_prefix = prefix; \
      42             :         drec->sql_desc_literal_suffix = suffix; \
      43             :         drec->sql_desc_type_name = type; \
      44             :         return; \
      45             :         } while(0)
      46             : #define SET_INFO2(type, prefix, suffix, len) do { \
      47             :         drec->sql_desc_length = (len); \
      48             :         SET_INFO(type, prefix, suffix); \
      49             :         } while(0)
      50             : 
      51             : static void
      52         224 : data_msdatetime_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
      53             : {
      54         224 :         int decimals = col->column_prec ? col->column_prec + 1: 0;
      55             : 
      56         224 :         switch (col->on_server.column_type) {
      57          78 :         case SYBMSTIME:
      58          78 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
      59          78 :                 drec->sql_desc_concise_type = SQL_SS_TIME2;
      60             :                 /* always hh:mm:ss[.fff] */
      61          78 :                 drec->sql_desc_display_size = 8 + decimals;
      62          78 :                 SET_INFO2("time", "'", "'", 8 + decimals);
      63          82 :         case SYBMSDATE:
      64          82 :                 drec->sql_desc_octet_length = sizeof(DATE_STRUCT);
      65          82 :                 drec->sql_desc_concise_type = SQL_TYPE_DATE;
      66             :                 /* always yyyy-mm-dd ?? */
      67          82 :                 drec->sql_desc_display_size = 10;
      68          82 :                 SET_INFO2("date", "'", "'", 10);
      69          26 :         case SYBMSDATETIMEOFFSET:
      70          26 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIMESTAMPOFFSET_STRUCT);
      71          26 :                 drec->sql_desc_concise_type = SQL_SS_TIMESTAMPOFFSET;
      72             :                 /* we always format using yyyy-mm-dd hh:mm:ss[.fff] +HH:MM, see convert_tds2sql.c */
      73          26 :                 drec->sql_desc_display_size = 26 + decimals;
      74          26 :                 SET_INFO2("datetimeoffset", "'", "'", 26 + decimals);
      75          38 :         case SYBMSDATETIME2:
      76          38 :                 drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
      77          38 :                 drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
      78          38 :                 drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
      79             :                 /* we always format using yyyy-mm-dd hh:mm:ss[.fff], see convert_tds2sql.c */
      80          38 :                 drec->sql_desc_display_size = 19 + decimals;
      81          38 :                 SET_INFO2("datetime2", "'", "'", 19 + decimals);
      82             :         default:
      83             :                 break;
      84             :         }
      85             : }
      86             : 
      87             : static void
      88         606 : data_variant_set_type_info(TDSCOLUMN * col TDS_UNUSED, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
      89             : {
      90         606 :         drec->sql_desc_concise_type = SQL_SS_VARIANT;
      91         606 :         drec->sql_desc_display_size = 8000;
      92         606 :         drec->sql_desc_octet_length = 0;
      93         606 :         SET_INFO2("sql_variant", "", "", 8000);
      94             : }
      95             : 
      96             : static void
      97         838 : data_numeric_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
      98             : {
      99         838 :         const char *type_name =
     100         838 :                 col->on_server.column_type == SYBNUMERIC ? "numeric" : "decimal";
     101             : 
     102         838 :         drec->sql_desc_concise_type = SQL_NUMERIC;
     103         838 :         drec->sql_desc_octet_length = col->column_prec + 2;
     104         838 :         drec->sql_desc_display_size = col->column_prec + 2;
     105         838 :         drec->sql_desc_num_prec_radix = 10;
     106         838 :         SET_INFO2(type_name, "", "", col->column_prec);
     107             : }
     108             : 
     109             : static void
     110           8 : data_clrudt_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
     111             : {
     112           8 :         drec->sql_desc_concise_type = SQL_LONGVARBINARY;
     113             :         /* TODO ??? */
     114           8 :         drec->sql_desc_display_size = col->column_size * 2;
     115           8 : }
     116             : 
     117             : static void
     118          20 : data_sybbigtime_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
     119             : {
     120          20 :         if (col->on_server.column_type == SYB5BIGTIME) {
     121          10 :                 drec->sql_desc_concise_type = SQL_SS_TIME2;
     122             :                 /* we always format using hh:mm:ss[.ffffff], see convert_tds2sql.c */
     123          10 :                 drec->sql_desc_display_size = 15;
     124          10 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
     125          10 :                 drec->sql_desc_precision = 6;
     126          10 :                 drec->sql_desc_scale     = 6;
     127          10 :                 drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     128          10 :                 SET_INFO2("bigtime", "'", "'", 15);
     129             :         }
     130             : 
     131          10 :         assert(col->on_server.column_type == SYB5BIGDATETIME);
     132             : 
     133          10 :         drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
     134          10 :         drec->sql_desc_display_size = 26;
     135          10 :         drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
     136          10 :         drec->sql_desc_precision = 6;
     137          10 :         drec->sql_desc_scale     = 6;
     138          10 :         drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     139          10 :         SET_INFO2("bigdatetime", "'", "'", 26);
     140             : }
     141             : 
     142             : static void
     143           0 : data_mstabletype_set_type_info(TDSCOLUMN *col TDS_UNUSED, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
     144             : {
     145           0 :         drec->sql_desc_concise_type = SQL_SS_TABLE;
     146           0 :         drec->sql_desc_octet_length = 0;
     147           0 : }
     148             : 
     149             : static void
     150       17997 : data_generic_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
     151             : {
     152       17997 :         TDS_SERVER_TYPE col_type = col->on_server.column_type;
     153       17997 :         int col_size = col->on_server.column_size;
     154             : 
     155       17997 :         switch (tds_get_conversion_type(col_type, col_size)) {
     156          40 :         case XSYBNCHAR:
     157          40 :                 drec->sql_desc_concise_type = SQL_WCHAR;
     158          40 :                 drec->sql_desc_display_size = col->on_server.column_size / 2;
     159          40 :                 SET_INFO2("nchar", "'", "'", col->on_server.column_size / 2);
     160             : 
     161         178 :         case XSYBCHAR:
     162             :         case SYBCHAR:
     163         178 :                 drec->sql_desc_concise_type = SQL_CHAR;
     164         178 :                 drec->sql_desc_display_size = col->on_server.column_size;
     165         178 :                 SET_INFO("char", "'", "'");
     166             : 
     167             :         /* TODO really sure ?? SYBNVARCHAR sybase only ?? */
     168        2333 :         case SYBNVARCHAR:
     169             :         case XSYBNVARCHAR:
     170        2333 :                 drec->sql_desc_concise_type = SQL_WVARCHAR;
     171        2333 :                 drec->sql_desc_display_size = col->on_server.column_size / 2;
     172        2333 :                 drec->sql_desc_length = col->on_server.column_size / 2u;
     173        2333 :                 if (col->char_conv) {
     174        2331 :                         unsigned char bytes_per_char = ODBC_CLAMP(col->char_conv->to.charset.max_bytes_per_char, 2, 3);
     175        2331 :                         drec->sql_desc_octet_length = (col->on_server.column_size / 2u) * bytes_per_char;
     176             :                 }
     177        2333 :                 if (is_blob_col(col)) {
     178           8 :                         drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     179           8 :                         drec->sql_desc_octet_length = drec->sql_desc_length =
     180             :                                 SQL_SS_LENGTH_UNLIMITED;
     181             :                 }
     182        2333 :                 SET_INFO("nvarchar", "'", "'");
     183             : 
     184        3736 :         case XSYBVARCHAR:
     185             :         case SYBVARCHAR:
     186        3736 :                 drec->sql_desc_concise_type = SQL_VARCHAR;
     187        3736 :                 drec->sql_desc_display_size = col->on_server.column_size;
     188        3736 :                 if (is_blob_col(col)) {
     189          36 :                         drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     190          36 :                         drec->sql_desc_octet_length = drec->sql_desc_length =
     191             :                                 SQL_SS_LENGTH_UNLIMITED;
     192             :                 }
     193        3736 :                 SET_INFO("varchar", "'", "'");
     194             : 
     195         574 :         case SYBNTEXT:
     196         574 :                 drec->sql_desc_concise_type = SQL_WLONGVARCHAR;
     197         574 :                 drec->sql_desc_display_size = col->on_server.column_size / 2;
     198         574 :                 SET_INFO2("ntext", "'", "'", col->on_server.column_size / 2);
     199             : 
     200         796 :         case SYBTEXT:
     201         796 :                 drec->sql_desc_concise_type = SQL_LONGVARCHAR;
     202         796 :                 drec->sql_desc_display_size = col->on_server.column_size;
     203         796 :                 SET_INFO("text", "'", "'");
     204             : 
     205         370 :         case SYBBIT:
     206             :         case SYBBITN:
     207         370 :                 drec->sql_desc_concise_type = SQL_BIT;
     208         370 :                 drec->sql_desc_display_size = 1;
     209         370 :                 drec->sql_desc_unsigned = SQL_TRUE;
     210         370 :                 SET_INFO2("bit", "", "", 1);
     211             : 
     212             : #if (ODBCVER >= 0x0300)
     213         214 :         case SYB5INT8:
     214             :         case SYBINT8:
     215             :                 /* TODO return numeric for odbc2 and convert bigint to numeric */
     216         214 :                 drec->sql_desc_concise_type = SQL_BIGINT;
     217         214 :                 drec->sql_desc_display_size = 20;
     218         214 :                 SET_INFO2("bigint", "", "", 19);
     219             : #endif
     220             : 
     221        2567 :         case SYBINT4:
     222        2567 :                 drec->sql_desc_concise_type = SQL_INTEGER;
     223        2567 :                 drec->sql_desc_display_size = 11;    /* -1000000000 */
     224        2567 :                 SET_INFO2("int", "", "", 10);
     225             : 
     226        2623 :         case SYBINT2:
     227        2623 :                 drec->sql_desc_concise_type = SQL_SMALLINT;
     228        2623 :                 drec->sql_desc_display_size = 6;     /* -10000 */
     229        2623 :                 SET_INFO2("smallint", "", "", 5);
     230             : 
     231         314 :         case SYBUINT1:
     232             :         case SYBINT1:
     233         314 :                 drec->sql_desc_unsigned = SQL_TRUE;
     234         314 :         case SYBSINT1: /* TODO not another type_name ?? */
     235         314 :                 drec->sql_desc_concise_type = SQL_TINYINT;
     236         314 :                 drec->sql_desc_display_size = 3;     /* 255 */
     237         314 :                 SET_INFO2("tinyint", "", "", 3);
     238             : 
     239             : #if (ODBCVER >= 0x0300)
     240          36 :         case SYBUINT8:
     241          36 :                 drec->sql_desc_unsigned = SQL_TRUE;
     242          36 :                 drec->sql_desc_concise_type = SQL_BIGINT;
     243          36 :                 drec->sql_desc_display_size = 20;
     244             :                 /* TODO return numeric for odbc2 and convert bigint to numeric */
     245          36 :                 SET_INFO2("unsigned bigint", "", "", 20);
     246             : #endif
     247             : 
     248          36 :         case SYBUINT4:
     249          36 :                 drec->sql_desc_unsigned = SQL_TRUE;
     250          36 :                 drec->sql_desc_concise_type = SQL_INTEGER;
     251          36 :                 drec->sql_desc_display_size = 10;
     252          36 :                 SET_INFO2("unsigned int", "", "", 10);
     253             : 
     254          38 :         case SYBUINT2:
     255          38 :                 drec->sql_desc_unsigned = SQL_TRUE;
     256          38 :                 drec->sql_desc_concise_type = SQL_SMALLINT;
     257          38 :                 drec->sql_desc_display_size = 5;     /* 65535 */
     258          38 :                 SET_INFO2("unsigned smallint", "", "", 5);
     259             : 
     260         316 :         case SYBREAL:
     261         316 :                 drec->sql_desc_concise_type = SQL_REAL;
     262         316 :                 drec->sql_desc_display_size = 14;
     263         316 :                 SET_INFO2("real", "", "", odbc_ver == SQL_OV_ODBC3 ? 24 : 7);
     264             : 
     265         812 :         case SYBFLT8:
     266         812 :                 drec->sql_desc_concise_type = SQL_DOUBLE;
     267         812 :                 drec->sql_desc_display_size = 24;    /* FIXME -- what should the correct size be? */
     268         812 :                 SET_INFO2("float", "", "", odbc_ver == SQL_OV_ODBC3 ? 53 : 15);
     269             : 
     270         356 :         case SYBMONEY:
     271             :                 /* TODO check money format returned by proprietary ODBC, scale == 4 but we use 2 digits */
     272         356 :                 drec->sql_desc_concise_type = SQL_DECIMAL;
     273         356 :                 drec->sql_desc_octet_length = 21;
     274         356 :                 drec->sql_desc_display_size = 21;
     275         356 :                 drec->sql_desc_precision = 19;
     276         356 :                 drec->sql_desc_scale     = 4;
     277         356 :                 SET_INFO2("money", "$", "", 19);
     278             : 
     279         100 :         case SYBMONEY4:
     280         100 :                 drec->sql_desc_concise_type = SQL_DECIMAL;
     281         100 :                 drec->sql_desc_octet_length = 12;
     282         100 :                 drec->sql_desc_display_size = 12;
     283         100 :                 drec->sql_desc_precision = 10;
     284         100 :                 drec->sql_desc_scale     = 4;
     285         100 :                 SET_INFO2("money", "$", "", 10);
     286             : 
     287        1332 :         case SYBDATETIME:
     288        1332 :                 drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
     289        1332 :                 drec->sql_desc_display_size = 23;
     290        1332 :                 drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
     291        1332 :                 drec->sql_desc_precision = 3;
     292        1332 :                 drec->sql_desc_scale     = 3;
     293        1332 :                 drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     294        1332 :                 SET_INFO2("datetime", "'", "'", 23);
     295             : 
     296         130 :         case SYBDATETIME4:
     297         130 :                 drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
     298             :                 /* TODO dependent on precision (decimal second digits) */
     299             :                 /* we always format using yyyy-mm-dd hh:mm:ss[.fff], see convert_tds2sql.c */
     300         130 :                 drec->sql_desc_display_size = 19;
     301         130 :                 drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
     302         130 :                 drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     303         130 :                 SET_INFO2("datetime", "'", "'", 16);
     304             : 
     305             :         /* The following two types are just Sybase types but as mainly our ODBC
     306             :          * driver is much more compatible with Windows use attributes similar
     307             :          * to MS one. For instance Sybase ODBC returns TIME into a TIME_STRUCT
     308             :          * however this truncate the precision to 0 as TIME does not have
     309             :          * fraction of seconds. Also Sybase ODBC have different concepts for
     310             :          * PRECISION for many types and making these 2 types compatibles with
     311             :          * Sybase would break this driver compatibility.
     312             :          */
     313          36 :         case SYBTIME:
     314          36 :                 drec->sql_desc_concise_type = SQL_SS_TIME2;
     315          36 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
     316             :                 /* we always format using hh:mm:ss[.fff], see convert_tds2sql.c */
     317          36 :                 drec->sql_desc_display_size = 12;
     318          36 :                 drec->sql_desc_precision = 3;
     319          36 :                 drec->sql_desc_scale     = 3;
     320          36 :                 SET_INFO2("time", "'", "'", 12);
     321             : 
     322          40 :         case SYBDATE:
     323          40 :                 drec->sql_desc_octet_length = sizeof(DATE_STRUCT);
     324          40 :                 drec->sql_desc_concise_type = SQL_TYPE_DATE;
     325             :                 /* we always format using yyyy-mm-dd, see convert_tds2sql.c */
     326          40 :                 drec->sql_desc_display_size = 10;
     327          40 :                 SET_INFO2("date", "'", "'", 10);
     328             : 
     329          58 :         case XSYBBINARY:
     330             :         case SYBBINARY:
     331          58 :                 drec->sql_desc_concise_type = SQL_BINARY;
     332          58 :                 drec->sql_desc_display_size = col->column_size * 2;
     333             :                 /* handle TIMESTAMP using usertype */
     334          58 :                 if (col->column_usertype == 80)
     335           8 :                         SET_INFO("timestamp", "0x", "");
     336          50 :                 SET_INFO("binary", "0x", "");
     337             : 
     338          76 :         case SYBLONGBINARY:
     339          76 :                 if (col->column_usertype == USER_UNICHAR_TYPE) {
     340           4 :                         drec->sql_desc_concise_type = SQL_WCHAR;
     341           4 :                         drec->sql_desc_display_size = col->on_server.column_size / 2;
     342           4 :                         SET_INFO2("unichar", "'", "'", col->on_server.column_size / 2);
     343             :                 }
     344          72 :                 if (col->column_usertype == USER_UNIVARCHAR_TYPE) {
     345          62 :                         drec->sql_desc_concise_type = SQL_WVARCHAR;
     346          62 :                         drec->sql_desc_display_size = col->on_server.column_size / 2;
     347          62 :                         SET_INFO2("univarchar", "'", "'", col->on_server.column_size / 2);
     348             :                 }
     349             :         case SYBIMAGE:
     350         374 :                 drec->sql_desc_concise_type = SQL_LONGVARBINARY;
     351         374 :                 drec->sql_desc_display_size = col->column_size * 2;
     352         374 :                 SET_INFO("image", "0x", "");
     353             : 
     354         436 :         case XSYBVARBINARY:
     355             :         case SYBVARBINARY:
     356         436 :                 drec->sql_desc_concise_type = SQL_VARBINARY;
     357         436 :                 drec->sql_desc_display_size = col->column_size * 2;
     358         436 :                 if (is_blob_col(col)) {
     359          40 :                         drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     360          40 :                         drec->sql_desc_octet_length = drec->sql_desc_length =
     361             :                                 SQL_SS_LENGTH_UNLIMITED;
     362             :                 }
     363         436 :                 SET_INFO("varbinary", "0x", "");
     364             : 
     365             :         case SYBINTN:
     366             :         case SYBDATETIMN:
     367             :         case SYBFLTN:
     368             :         case SYBMONEYN:
     369             :         case SYBUINTN:
     370             :         case SYBTIMEN:
     371             :         case SYBDATEN:
     372           0 :                 assert(0);
     373             : 
     374             :         case SYBVOID:
     375             :         case SYBINTERVAL:
     376             :         case SYBUNITEXT:
     377             :         case SYBXML:
     378             :         case SYBMSUDT:
     379             :                 break;
     380             : 
     381             : #if (ODBCVER >= 0x0300)
     382          74 :         case SYBUNIQUE:
     383             : #ifdef SQL_GUID
     384          74 :                 drec->sql_desc_concise_type = SQL_GUID;
     385             : #else
     386             :                 drec->sql_desc_concise_type = SQL_CHAR;
     387             : #endif
     388          74 :                 drec->sql_desc_display_size = 36;
     389             :                 /* FIXME for Sybase ?? */
     390          74 :                 SET_INFO2("uniqueidentifier", "'", "'", 36);
     391             : #endif
     392             : 
     393          12 :         case SYBMSXML:
     394          12 :                 drec->sql_desc_concise_type = SQL_SS_XML;
     395          12 :                 drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     396          12 :                 drec->sql_desc_octet_length = drec->sql_desc_length =
     397             :                         SQL_SS_LENGTH_UNLIMITED;
     398          12 :                 SET_INFO("xml", "'", "'");
     399             :         /* types already handled in other types, just to silent warnings */
     400             :         case SYBNUMERIC:
     401             :         case SYBDECIMAL:
     402             :         case SYBVARIANT:
     403             :         case SYBMSDATE:
     404             :         case SYBMSTIME:
     405             :         case SYBMSDATETIME2:
     406             :         case SYBMSDATETIMEOFFSET:
     407             :         case SYB5BIGDATETIME:
     408             :         case SYB5BIGTIME:
     409             :         case SYBMSTABLE:
     410             :                 break;
     411             :         }
     412           0 :         SET_INFO("", "", "");
     413             : }
     414             : 
     415             : static void
     416           0 : data_invalid_set_type_info(TDSCOLUMN * col TDS_UNUSED, struct _drecord *drec TDS_UNUSED, SQLINTEGER odbc_ver TDS_UNUSED)
     417             : {
     418           0 : }
     419             : 
     420             : void
     421       19693 : odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
     422             : {
     423       19693 :         drec->sql_desc_precision = col->column_prec;
     424       19693 :         drec->sql_desc_scale     = col->column_scale;
     425       19693 :         drec->sql_desc_unsigned = SQL_FALSE;
     426       19693 :         drec->sql_desc_octet_length = drec->sql_desc_length = col->on_server.column_size;
     427       19693 :         drec->sql_desc_num_prec_radix = 0;
     428       19693 :         drec->sql_desc_datetime_interval_code = 0;
     429             : 
     430       19693 :         ((TDS_FUNCS *) col->funcs)->set_type_info(col, drec, odbc_ver);
     431             : 
     432       19693 :         drec->sql_desc_type = drec->sql_desc_concise_type;
     433       19693 :         if (drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)
     434        1510 :                 drec->sql_desc_type = SQL_DATETIME;
     435       19693 : }
     436             : 
     437             : #  define TDS_DEFINE_FUNCS(name) \
     438             :         const TDS_FUNCS tds_ ## name ## _funcs = { \
     439             :                 TDS_COMMON_FUNCS(name), \
     440             :                 data_ ## name ## _set_type_info, \
     441             :         }
     442             : TDS_DEFINE_FUNCS(invalid);
     443             : TDS_DEFINE_FUNCS(generic);
     444             : TDS_DEFINE_FUNCS(numeric);
     445             : TDS_DEFINE_FUNCS(variant);
     446             : TDS_DEFINE_FUNCS(msdatetime);
     447             : TDS_DEFINE_FUNCS(clrudt);
     448             : TDS_DEFINE_FUNCS(sybbigtime);
     449             : TDS_DEFINE_FUNCS(mstabletype);

Generated by: LCOV version 1.13