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: 2024-04-18 20:40: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         124 : data_msdatetime_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
      53             : {
      54         124 :         int decimals = col->column_prec ? col->column_prec + 1: 0;
      55             : 
      56         124 :         switch (col->on_server.column_type) {
      57          42 :         case SYBMSTIME:
      58          42 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
      59          42 :                 drec->sql_desc_concise_type = SQL_SS_TIME2;
      60             :                 /* always hh:mm:ss[.fff] */
      61          42 :                 drec->sql_desc_display_size = 8 + decimals;
      62          42 :                 SET_INFO2("time", "'", "'", 8 + decimals);
      63          44 :         case SYBMSDATE:
      64          44 :                 drec->sql_desc_octet_length = sizeof(DATE_STRUCT);
      65          44 :                 drec->sql_desc_concise_type = SQL_TYPE_DATE;
      66             :                 /* always yyyy-mm-dd ?? */
      67          44 :                 drec->sql_desc_display_size = 10;
      68          44 :                 SET_INFO2("date", "'", "'", 10);
      69          16 :         case SYBMSDATETIMEOFFSET:
      70          16 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIMESTAMPOFFSET_STRUCT);
      71          16 :                 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          16 :                 drec->sql_desc_display_size = 26 + decimals;
      74          16 :                 SET_INFO2("datetimeoffset", "'", "'", 26 + decimals);
      75          22 :         case SYBMSDATETIME2:
      76          22 :                 drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
      77          22 :                 drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
      78          22 :                 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          22 :                 drec->sql_desc_display_size = 19 + decimals;
      81          22 :                 SET_INFO2("datetime2", "'", "'", 19 + decimals);
      82             :         default:
      83             :                 break;
      84             :         }
      85             : }
      86             : 
      87             : static void
      88         474 : data_variant_set_type_info(TDSCOLUMN * col TDS_UNUSED, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
      89             : {
      90         474 :         drec->sql_desc_concise_type = SQL_SS_VARIANT;
      91         474 :         drec->sql_desc_display_size = 8000;
      92         474 :         drec->sql_desc_octet_length = 0;
      93         474 :         SET_INFO2("sql_variant", "", "", 8000);
      94             : }
      95             : 
      96             : static void
      97         664 : data_numeric_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
      98             : {
      99         664 :         const char *type_name =
     100         664 :                 col->on_server.column_type == SYBNUMERIC ? "numeric" : "decimal";
     101             : 
     102         664 :         drec->sql_desc_concise_type = SQL_NUMERIC;
     103         664 :         drec->sql_desc_octet_length = col->column_prec + 2;
     104         664 :         drec->sql_desc_display_size = col->column_prec + 2;
     105         664 :         drec->sql_desc_num_prec_radix = 10;
     106         664 :         SET_INFO2(type_name, "", "", col->column_prec);
     107             : }
     108             : 
     109             : static void
     110           4 : data_clrudt_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
     111             : {
     112           4 :         drec->sql_desc_concise_type = SQL_LONGVARBINARY;
     113             :         /* TODO ??? */
     114           4 :         drec->sql_desc_display_size = col->column_size * 2;
     115           4 : }
     116             : 
     117             : static void
     118          16 : data_sybbigtime_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver TDS_UNUSED)
     119             : {
     120          16 :         if (col->on_server.column_type == SYB5BIGTIME) {
     121           8 :                 drec->sql_desc_concise_type = SQL_SS_TIME2;
     122             :                 /* we always format using hh:mm:ss[.ffffff], see convert_tds2sql.c */
     123           8 :                 drec->sql_desc_display_size = 15;
     124           8 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
     125           8 :                 drec->sql_desc_precision = 6;
     126           8 :                 drec->sql_desc_scale     = 6;
     127           8 :                 drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     128           8 :                 SET_INFO2("bigtime", "'", "'", 15);
     129             :         }
     130             : 
     131           8 :         assert(col->on_server.column_type == SYB5BIGDATETIME);
     132             : 
     133           8 :         drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
     134           8 :         drec->sql_desc_display_size = 26;
     135           8 :         drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
     136           8 :         drec->sql_desc_precision = 6;
     137           8 :         drec->sql_desc_scale     = 6;
     138           8 :         drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     139           8 :         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       13756 : data_generic_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
     151             : {
     152       13756 :         TDS_SERVER_TYPE col_type = col->on_server.column_type;
     153       13756 :         int col_size = col->on_server.column_size;
     154             : 
     155       13756 :         switch (tds_get_conversion_type(col_type, col_size)) {
     156          28 :         case XSYBNCHAR:
     157          28 :                 drec->sql_desc_concise_type = SQL_WCHAR;
     158          28 :                 drec->sql_desc_display_size = col->on_server.column_size / 2;
     159          28 :                 SET_INFO2("nchar", "'", "'", col->on_server.column_size / 2);
     160             : 
     161         138 :         case XSYBCHAR:
     162             :         case SYBCHAR:
     163         138 :                 drec->sql_desc_concise_type = SQL_CHAR;
     164         138 :                 drec->sql_desc_display_size = col->on_server.column_size;
     165         138 :                 SET_INFO("char", "'", "'");
     166             : 
     167             :         /* TODO really sure ?? SYBNVARCHAR sybase only ?? */
     168        1739 :         case SYBNVARCHAR:
     169             :         case XSYBNVARCHAR:
     170        1739 :                 drec->sql_desc_concise_type = SQL_WVARCHAR;
     171        1739 :                 drec->sql_desc_display_size = col->on_server.column_size / 2;
     172        1739 :                 drec->sql_desc_length = col->on_server.column_size / 2u;
     173        1739 :                 if (col->char_conv) {
     174        1739 :                         unsigned char bytes_per_char = ODBC_CLAMP(col->char_conv->to.charset.max_bytes_per_char, 2, 3);
     175        1739 :                         drec->sql_desc_octet_length = (col->on_server.column_size / 2u) * bytes_per_char;
     176             :                 }
     177        1739 :                 if (is_blob_col(col)) {
     178           4 :                         drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     179           4 :                         drec->sql_desc_octet_length = drec->sql_desc_length =
     180             :                                 SQL_SS_LENGTH_UNLIMITED;
     181             :                 }
     182        1739 :                 SET_INFO("nvarchar", "'", "'");
     183             : 
     184        2769 :         case XSYBVARCHAR:
     185             :         case SYBVARCHAR:
     186        2769 :                 drec->sql_desc_concise_type = SQL_VARCHAR;
     187        2769 :                 drec->sql_desc_display_size = col->on_server.column_size;
     188        2769 :                 if (is_blob_col(col)) {
     189          18 :                         drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     190          18 :                         drec->sql_desc_octet_length = drec->sql_desc_length =
     191             :                                 SQL_SS_LENGTH_UNLIMITED;
     192             :                 }
     193        2769 :                 SET_INFO("varchar", "'", "'");
     194             : 
     195         432 :         case SYBNTEXT:
     196         432 :                 drec->sql_desc_concise_type = SQL_WLONGVARCHAR;
     197         432 :                 drec->sql_desc_display_size = col->on_server.column_size / 2;
     198         432 :                 SET_INFO2("ntext", "'", "'", col->on_server.column_size / 2);
     199             : 
     200         632 :         case SYBTEXT:
     201         632 :                 drec->sql_desc_concise_type = SQL_LONGVARCHAR;
     202         632 :                 drec->sql_desc_display_size = col->on_server.column_size;
     203         632 :                 SET_INFO("text", "'", "'");
     204             : 
     205         288 :         case SYBBIT:
     206             :         case SYBBITN:
     207         288 :                 drec->sql_desc_concise_type = SQL_BIT;
     208         288 :                 drec->sql_desc_display_size = 1;
     209         288 :                 drec->sql_desc_unsigned = SQL_TRUE;
     210         288 :                 SET_INFO2("bit", "", "", 1);
     211             : 
     212             : #if (ODBCVER >= 0x0300)
     213         164 :         case SYB5INT8:
     214             :         case SYBINT8:
     215             :                 /* TODO return numeric for odbc2 and convert bigint to numeric */
     216         164 :                 drec->sql_desc_concise_type = SQL_BIGINT;
     217         164 :                 drec->sql_desc_display_size = 20;
     218         164 :                 SET_INFO2("bigint", "", "", 19);
     219             : #endif
     220             : 
     221        1985 :         case SYBINT4:
     222        1985 :                 drec->sql_desc_concise_type = SQL_INTEGER;
     223        1985 :                 drec->sql_desc_display_size = 11;    /* -1000000000 */
     224        1985 :                 SET_INFO2("int", "", "", 10);
     225             : 
     226        2015 :         case SYBINT2:
     227        2015 :                 drec->sql_desc_concise_type = SQL_SMALLINT;
     228        2015 :                 drec->sql_desc_display_size = 6;     /* -10000 */
     229        2015 :                 SET_INFO2("smallint", "", "", 5);
     230             : 
     231         244 :         case SYBUINT1:
     232             :         case SYBINT1:
     233         244 :                 drec->sql_desc_unsigned = SQL_TRUE;
     234         244 :         case SYBSINT1: /* TODO not another type_name ?? */
     235         244 :                 drec->sql_desc_concise_type = SQL_TINYINT;
     236         244 :                 drec->sql_desc_display_size = 3;     /* 255 */
     237         244 :                 SET_INFO2("tinyint", "", "", 3);
     238             : 
     239             : #if (ODBCVER >= 0x0300)
     240          30 :         case SYBUINT8:
     241          30 :                 drec->sql_desc_unsigned = SQL_TRUE;
     242          30 :                 drec->sql_desc_concise_type = SQL_BIGINT;
     243          30 :                 drec->sql_desc_display_size = 20;
     244             :                 /* TODO return numeric for odbc2 and convert bigint to numeric */
     245          30 :                 SET_INFO2("unsigned bigint", "", "", 20);
     246             : #endif
     247             : 
     248          30 :         case SYBUINT4:
     249          30 :                 drec->sql_desc_unsigned = SQL_TRUE;
     250          30 :                 drec->sql_desc_concise_type = SQL_INTEGER;
     251          30 :                 drec->sql_desc_display_size = 10;
     252          30 :                 SET_INFO2("unsigned int", "", "", 10);
     253             : 
     254          32 :         case SYBUINT2:
     255          32 :                 drec->sql_desc_unsigned = SQL_TRUE;
     256          32 :                 drec->sql_desc_concise_type = SQL_SMALLINT;
     257          32 :                 drec->sql_desc_display_size = 5;     /* 65535 */
     258          32 :                 SET_INFO2("unsigned smallint", "", "", 5);
     259             : 
     260         248 :         case SYBREAL:
     261         248 :                 drec->sql_desc_concise_type = SQL_REAL;
     262         248 :                 drec->sql_desc_display_size = 14;
     263         248 :                 SET_INFO2("real", "", "", odbc_ver == SQL_OV_ODBC3 ? 24 : 7);
     264             : 
     265         634 :         case SYBFLT8:
     266         634 :                 drec->sql_desc_concise_type = SQL_DOUBLE;
     267         634 :                 drec->sql_desc_display_size = 24;    /* FIXME -- what should the correct size be? */
     268         634 :                 SET_INFO2("float", "", "", odbc_ver == SQL_OV_ODBC3 ? 53 : 15);
     269             : 
     270         272 :         case SYBMONEY:
     271             :                 /* TODO check money format returned by propretary ODBC, scale == 4 but we use 2 digits */
     272         272 :                 drec->sql_desc_concise_type = SQL_DECIMAL;
     273         272 :                 drec->sql_desc_octet_length = 21;
     274         272 :                 drec->sql_desc_display_size = 21;
     275         272 :                 drec->sql_desc_precision = 19;
     276         272 :                 drec->sql_desc_scale     = 4;
     277         272 :                 SET_INFO2("money", "$", "", 19);
     278             : 
     279          80 :         case SYBMONEY4:
     280          80 :                 drec->sql_desc_concise_type = SQL_DECIMAL;
     281          80 :                 drec->sql_desc_octet_length = 12;
     282          80 :                 drec->sql_desc_display_size = 12;
     283          80 :                 drec->sql_desc_precision = 10;
     284          80 :                 drec->sql_desc_scale     = 4;
     285          80 :                 SET_INFO2("money", "$", "", 10);
     286             : 
     287        1034 :         case SYBDATETIME:
     288        1034 :                 drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
     289        1034 :                 drec->sql_desc_display_size = 23;
     290        1034 :                 drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
     291        1034 :                 drec->sql_desc_precision = 3;
     292        1034 :                 drec->sql_desc_scale     = 3;
     293        1034 :                 drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     294        1034 :                 SET_INFO2("datetime", "'", "'", 23);
     295             : 
     296         104 :         case SYBDATETIME4:
     297         104 :                 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         104 :                 drec->sql_desc_display_size = 19;
     301         104 :                 drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
     302         104 :                 drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
     303         104 :                 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          30 :         case SYBTIME:
     314          30 :                 drec->sql_desc_concise_type = SQL_SS_TIME2;
     315          30 :                 drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
     316             :                 /* we always format using hh:mm:ss[.fff], see convert_tds2sql.c */
     317          30 :                 drec->sql_desc_display_size = 12;
     318          30 :                 drec->sql_desc_precision = 3;
     319          30 :                 drec->sql_desc_scale     = 3;
     320          30 :                 SET_INFO2("time", "'", "'", 12);
     321             : 
     322          34 :         case SYBDATE:
     323          34 :                 drec->sql_desc_octet_length = sizeof(DATE_STRUCT);
     324          34 :                 drec->sql_desc_concise_type = SQL_TYPE_DATE;
     325             :                 /* we always format using yyyy-mm-dd, see convert_tds2sql.c */
     326          34 :                 drec->sql_desc_display_size = 10;
     327          34 :                 SET_INFO2("date", "'", "'", 10);
     328             : 
     329          46 :         case XSYBBINARY:
     330             :         case SYBBINARY:
     331          46 :                 drec->sql_desc_concise_type = SQL_BINARY;
     332          46 :                 drec->sql_desc_display_size = col->column_size * 2;
     333             :                 /* handle TIMESTAMP using usertype */
     334          46 :                 if (col->column_usertype == 80)
     335           6 :                         SET_INFO("timestamp", "0x", "");
     336          40 :                 SET_INFO("binary", "0x", "");
     337             : 
     338          74 :         case SYBLONGBINARY:
     339          74 :                 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          70 :                 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         302 :                 drec->sql_desc_concise_type = SQL_LONGVARBINARY;
     351         302 :                 drec->sql_desc_display_size = col->column_size * 2;
     352         302 :                 SET_INFO("image", "0x", "");
     353             : 
     354         322 :         case XSYBVARBINARY:
     355             :         case SYBVARBINARY:
     356         322 :                 drec->sql_desc_concise_type = SQL_VARBINARY;
     357         322 :                 drec->sql_desc_display_size = col->column_size * 2;
     358         322 :                 if (is_blob_col(col)) {
     359          20 :                         drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     360          20 :                         drec->sql_desc_octet_length = drec->sql_desc_length =
     361             :                                 SQL_SS_LENGTH_UNLIMITED;
     362             :                 }
     363         322 :                 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          52 :         case SYBUNIQUE:
     383             : #ifdef SQL_GUID
     384          52 :                 drec->sql_desc_concise_type = SQL_GUID;
     385             : #else
     386             :                 drec->sql_desc_concise_type = SQL_CHAR;
     387             : #endif
     388          52 :                 drec->sql_desc_display_size = 36;
     389             :                 /* FIXME for Sybase ?? */
     390          52 :                 SET_INFO2("uniqueidentifier", "'", "'", 36);
     391             : #endif
     392             : 
     393           6 :         case SYBMSXML:
     394           6 :                 drec->sql_desc_concise_type = SQL_SS_XML;
     395           6 :                 drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
     396           6 :                 drec->sql_desc_octet_length = drec->sql_desc_length =
     397             :                         SQL_SS_LENGTH_UNLIMITED;
     398           6 :                 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       15038 : odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
     422             : {
     423       15038 :         drec->sql_desc_precision = col->column_prec;
     424       15038 :         drec->sql_desc_scale     = col->column_scale;
     425       15038 :         drec->sql_desc_unsigned = SQL_FALSE;
     426       15038 :         drec->sql_desc_octet_length = drec->sql_desc_length = col->on_server.column_size;
     427       15038 :         drec->sql_desc_num_prec_radix = 0;
     428       15038 :         drec->sql_desc_datetime_interval_code = 0;
     429             : 
     430       15038 :         ((TDS_FUNCS *) col->funcs)->set_type_info(col, drec, odbc_ver);
     431             : 
     432       15038 :         drec->sql_desc_type = drec->sql_desc_concise_type;
     433       15038 :         if (drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)
     434        1168 :                 drec->sql_desc_type = SQL_DATETIME;
     435       15038 : }
     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