LCOV - code coverage report
Current view: top level - src/tds/unittests - allcolumns.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 166 171 97.1 %
Date: 2025-01-18 12:13:41 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
       3             :  * Copyright (C) 2017  Frediano Ziglio
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or
       6             :  * modify it under the terms of the GNU Library General Public
       7             :  * License as published by the Free Software Foundation; either
       8             :  * version 2 of the License, or (at your option) any later version.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * Library General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU Library General Public
      16             :  * License along with this library; if not, write to the
      17             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      18             :  * Boston, MA 02111-1307, USA.
      19             :  */
      20             : 
      21             : #define TDS_DONT_DEFINE_DEFAULT_FUNCTIONS
      22             : #include "common.h"
      23             : #include <assert.h>
      24             : #include <freetds/convert.h>
      25             : #include <freetds/checks.h>
      26             : 
      27             : static bool
      28        3384 : is_convert_pointer_type(int type)
      29             : {
      30        3384 :         switch (type) {
      31             :         case SYBCHAR: case SYBVARCHAR: case SYBTEXT: case XSYBCHAR: case XSYBVARCHAR:
      32             :         case SYBBINARY: case SYBVARBINARY: case SYBIMAGE: case XSYBBINARY: case XSYBVARBINARY:
      33             :         case SYBLONGBINARY:
      34             :                 return true;
      35             :         }
      36        2928 :         return false;
      37             : }
      38             : 
      39             : 
      40             : static void
      41        1728 : free_convert(int type, CONV_RESULT *cr)
      42             : {
      43        1728 :         if (is_convert_pointer_type(type))
      44         264 :                 free(cr->c);
      45        1728 : }
      46             : 
      47             : static void create_type(TDSSOCKET *tds, int desttype, int server_type, tds_any_type_t *func);
      48             : 
      49             : enum { TDSVER_MS = 0x704, TDSVER_SYB = 0x500 };
      50             : 
      51          24 : void tds_all_types(TDSSOCKET *tds, tds_any_type_t *func)
      52             : {
      53             :         int desttype;
      54             : 
      55          24 :         tds->conn->tds_version = TDSVER_MS;
      56             : 
      57             :         /*
      58             :          * Test every type
      59             :          */
      60        6168 :         for (desttype = 0; desttype < 0x100; desttype++) {
      61             :                 int types_buffer[10];
      62        6144 :                 int *types = types_buffer, *types_end;
      63             :                 int server_type;
      64             :                 int varint, other_varint;
      65             : 
      66        6144 :                 if (!is_tds_type_valid(desttype))
      67        9792 :                         continue;
      68             : 
      69        1392 :                 tds->conn->tds_version = TDSVER_MS;
      70             : 
      71             :                 /* if is only Sybase change version to Sybase */
      72        1392 :                 varint = tds_get_varint_size(tds->conn, desttype);
      73        1392 :                 tds->conn->tds_version ^= TDSVER_MS ^ TDSVER_SYB;
      74        1392 :                 other_varint = tds_get_varint_size(tds->conn, desttype);
      75        1392 :                 tds->conn->tds_version ^= TDSVER_MS ^ TDSVER_SYB;
      76        1392 :                 if (varint == 1 && varint != other_varint)
      77         288 :                         tds->conn->tds_version = TDSVER_SYB;
      78             : 
      79        1392 :                 server_type = desttype;
      80        1392 :                 switch (desttype) {
      81             :                 /* unsupported */
      82          48 :                 case SYBVOID:
      83             :                 case SYBINTERVAL:
      84          48 :                         continue;
      85             :                 /* nullable, use another type */
      86             :                 /* TODO, try all sizes */
      87          24 :                 case SYBINTN:
      88          24 :                         *types++ = SYBINT1;
      89          24 :                         *types++ = SYBINT2;
      90          24 :                         *types++ = SYBINT4;
      91          24 :                         *types++ = SYBINT8;
      92          24 :                         break;
      93          24 :                 case SYBUINTN:
      94          24 :                         *types++ = SYBUINT1;
      95          24 :                         *types++ = SYBUINT2;
      96          24 :                         *types++ = SYBUINT4;
      97          24 :                         *types++ = SYBUINT8;
      98          24 :                         tds->conn->tds_version = TDSVER_SYB;
      99          24 :                         break;
     100          24 :                 case SYBFLTN:
     101          24 :                         *types++ = SYBREAL;
     102          24 :                         *types++ = SYBFLT8;
     103          24 :                         break;
     104          24 :                 case SYBMONEYN:
     105          24 :                         *types++ = SYBMONEY4;
     106          24 :                         *types++ = SYBMONEY;
     107          24 :                         break;
     108          24 :                 case SYBDATETIMN:
     109          24 :                         *types++ = SYBDATETIME4;
     110          24 :                         *types++ = SYBDATETIME;
     111          24 :                         break;
     112          24 :                 case SYBDATEN:
     113          24 :                         *types++ = SYBDATE;
     114          24 :                         tds->conn->tds_version = TDSVER_SYB;
     115          24 :                         break;
     116          24 :                 case SYBTIMEN:
     117          24 :                         *types++ = SYBTIME;
     118          24 :                         tds->conn->tds_version = TDSVER_SYB;
     119          24 :                         break;
     120          24 :                 case SYB5INT8:
     121          24 :                         *types++ = SYBINT8;
     122          24 :                         break;
     123             :                 /* TODO tds_set_column_type */
     124             : 
     125         240 :                 case SYBXML: /* ?? */
     126             :                 case SYBNTEXT: /* ?? */
     127             :                 case XSYBNVARCHAR:
     128             :                 case XSYBNCHAR:
     129             :                 case SYBNVARCHAR:
     130             :                 case SYBMSUDT:
     131             :                 case SYBMSXML:
     132             :                 case SYBUNITEXT:
     133             :                 case SYBVARIANT: /* TODO */
     134             :                 case SYBSINT1: /* TODO */
     135             :                 case SYBMSTABLE: /* TODO */
     136         240 :                         continue;
     137             :                 }
     138             : 
     139        1104 :                 if (types == types_buffer)
     140         912 :                         *types++ = desttype;
     141             : 
     142        1104 :                 types_end = types;
     143        2424 :                 for (types = types_buffer; types != types_end; ++types) {
     144        1320 :                         create_type(tds, *types, server_type, func);
     145        1320 :                         if (*types != server_type)
     146         408 :                                 create_type(tds, *types, *types, func);
     147             :                 }
     148             :         }
     149          24 : }
     150             : 
     151        1728 : static void create_type(TDSSOCKET *tds, int desttype, int server_type, tds_any_type_t *func)
     152             : {
     153        1728 :         const TDSCONTEXT *ctx = tds_get_ctx(tds);
     154             :         int result;
     155        1728 :         TDS_CHAR *src = NULL;
     156             :         TDS_UINT srclen;
     157             : 
     158             :         CONV_RESULT cr;
     159        1728 :         const int srctype = SYBCHAR;
     160             : 
     161             :         TDSRESULTINFO *results;
     162             :         TDSCOLUMN *curcol;
     163             : 
     164        1728 :         cr.n.precision = 8;
     165        1728 :         cr.n.scale = 2;
     166             : 
     167        1728 :         switch (desttype) {
     168             :         case SYBCHAR:
     169             :         case SYBVARCHAR:
     170             :         case SYBTEXT:
     171             :         case XSYBVARCHAR:
     172             :         case XSYBCHAR:
     173             :                 src = "test of a character field";
     174             :                 break;
     175         144 :         case SYBDATETIME:
     176             :         case SYBDATETIME4:
     177         144 :                 src = "Apr 12, 1985 17:49:41";
     178         144 :                 break;
     179          96 :         case SYBMSDATE:
     180             :         case SYBDATE:
     181          96 :                 src = "2012-11-27";
     182          96 :                 break;
     183          72 :         case SYBTIME:
     184          72 :                 src = "15:27:12";
     185          72 :                 break;
     186          48 :         case SYBMSTIME:
     187             :         case SYB5BIGTIME:
     188          48 :                 src = "15:27:12.327862";
     189          48 :                 break;
     190          72 :         case SYBMSDATETIME2:
     191             :         case SYBMSDATETIMEOFFSET:
     192             :         case SYB5BIGDATETIME:
     193          72 :                 src = "2015-09-12 21:48:12.638161";
     194          72 :                 break;
     195          48 :         case SYBBINARY:
     196             :         case SYBIMAGE:
     197          48 :                 src = "0xbeef";
     198          48 :                 break;
     199         432 :         case SYBINT1:
     200             :         case SYBINT2:
     201             :         case SYBINT4:
     202             :         case SYBUINT1:
     203             :         case SYBUINT2:
     204             :         case SYBUINT4:
     205         432 :                 src = "255";
     206         432 :                 break;
     207         192 :         case SYBINT8:
     208             :         case SYBUINT8:
     209         192 :                 src = "374632567765";
     210         192 :                 break;
     211         288 :         case SYBFLT8:
     212             :         case SYBREAL:
     213             :         case SYBMONEY:
     214             :         case SYBMONEY4:
     215         288 :                 src = "1237.45";
     216             :                 cr.n.precision = 8;
     217             :                 cr.n.scale = 2;
     218         288 :                 break;
     219          48 :         case SYBNUMERIC:
     220             :         case SYBDECIMAL:
     221          48 :                 src = "947919.25";
     222             :                 cr.n.precision = 8;
     223             :                 cr.n.scale = 2;
     224          48 :                 break;
     225          24 :         case SYBUNIQUE:
     226          24 :                 src = "A8C60F70-5BD4-3E02-B769-7CCCCA585DCC";
     227          24 :                 break;
     228         144 :         case SYBBIT:
     229             :         default:
     230         144 :                 src = "1";
     231         144 :                 break;
     232             :         }
     233             :         assert(src);
     234        1728 :         srclen = strlen(src);
     235             : 
     236             :         /*
     237             :          * Now at last do the conversion
     238             :          */
     239             : 
     240        1728 :         result = tds_convert(ctx, srctype, src, srclen, desttype, &cr);
     241             : 
     242        1728 :         if (result < 0) {
     243           0 :                 if (result == TDS_CONVERT_NOAVAIL)      /* tds_willconvert returned true, but it lied. */
     244           0 :                         fprintf(stderr, "Conversion not yet implemented:\n\t");
     245             : 
     246           0 :                 fprintf(stderr, "failed (%d) to convert %d (%s, %d bytes) : %d (%s).\n",
     247             :                         result,
     248             :                         srctype, tds_prtype(srctype), srclen,
     249             :                         desttype, tds_prtype(desttype));
     250             : 
     251           0 :                 if (result == TDS_CONVERT_NOAVAIL)
     252           0 :                         exit(1);
     253             :         }
     254             : 
     255        1728 :         printf("converted %d (%s, %d bytes) -> %d (%s, %d bytes).\n",
     256             :                srctype, tds_prtype(srctype), srclen,
     257             :                desttype, tds_prtype(desttype), result);
     258             : 
     259        1728 :         results = tds_alloc_param_result(NULL);
     260        1728 :         assert(results);
     261        1728 :         curcol = results->columns[0];
     262        1728 :         assert(curcol);
     263             : 
     264        1728 :         tds_set_column_type(tds->conn, curcol, server_type);
     265        1728 :         curcol->on_server.column_size = curcol->column_size = curcol->column_cur_size = result;
     266        1728 :         if (is_numeric_type(desttype)) {
     267          48 :                 curcol->column_prec = cr.n.precision;
     268          48 :                 curcol->column_scale = cr.n.scale;
     269             :         }
     270        1728 :         switch (desttype) {
     271          48 :         case SYB5BIGDATETIME:
     272             :         case SYB5BIGTIME:
     273          48 :                 curcol->column_prec = curcol->column_scale = 6;
     274          48 :                 break;
     275             :         }
     276        1728 :         CHECK_COLUMN_EXTRA(curcol);
     277             : 
     278        1728 :         tds_alloc_param_data(curcol);
     279        1728 :         if (is_blob_col(curcol)) {
     280          72 :                 ((TDSBLOB *) curcol->column_data)->textvalue = cr.c;
     281          72 :                 cr.c = NULL;
     282        1656 :         } else if (is_convert_pointer_type(desttype)) {
     283         192 :                 memcpy(curcol->column_data, cr.c, result);
     284             :         } else {
     285        1464 :                 memcpy(curcol->column_data, &cr.i, result);
     286             :         }
     287             : 
     288        1728 :         func(tds, curcol);
     289             : 
     290             :         /* try to convert to SQL_VARIANT */
     291        1728 :         if (is_variant_inner_type(desttype)) {
     292             :                 TDSVARIANT *v;
     293             :                 TDSCOLUMN *basecol;
     294             : 
     295        1176 :                 tds->conn->tds_version = TDSVER_MS;
     296             : 
     297        1176 :                 results = tds_alloc_param_result(results);
     298        1176 :                 assert(results);
     299             : 
     300        1176 :                 basecol = results->columns[0];
     301        1176 :                 curcol = results->columns[1];
     302        1176 :                 tds_set_column_type(tds->conn, curcol, SYBVARIANT);
     303        1176 :                 CHECK_COLUMN_EXTRA(curcol);
     304             : 
     305        1176 :                 tds_alloc_param_data(curcol);
     306        1176 :                 v = (TDSVARIANT *) curcol->column_data;
     307        1176 :                 v->size = basecol->column_size;
     308        1176 :                 v->type = basecol->column_type;
     309        1176 :                 memcpy(v->collation, basecol->column_collation, sizeof(v->collation));
     310             : 
     311        1176 :                 assert(basecol->column_cur_size > 0);
     312        1176 :                 v->data = tds_new(TDS_CHAR, basecol->column_cur_size);
     313        1176 :                 assert(v->data);
     314        1176 :                 v->data_len = basecol->column_cur_size;
     315        1176 :                 curcol->column_cur_size = v->data_len;
     316        1176 :                 curcol->column_size = curcol->on_server.column_size = 8009;
     317        1176 :                 assert(!is_blob_col(basecol));
     318        1176 :                 memcpy(v->data, basecol->column_data, v->data_len);
     319        1176 :                 CHECK_COLUMN_EXTRA(curcol);
     320             : 
     321        1176 :                 func(tds, curcol);
     322             :         }
     323             : 
     324        1728 :         tds_free_results(results);
     325             : 
     326        1728 :         if (result >= 0)
     327        1728 :                 free_convert(desttype, &cr);
     328        1728 : }

Generated by: LCOV version 1.13