LCOV - code coverage report
Current view: top level - src/tds/unittests - convert.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 218 238 91.6 %
Date: 2024-03-23 08:24:27 Functions: 2 2 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             :  *
       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             : /* 
      21             :  * Purpose: test conversions.  If they work, test their performance.  
      22             :  * To test performance, call this program with an iteration count (10 is probably fine).
      23             :  * The following shows performance converting to varchar:
      24             :  * $ make convert && ./convert 1 |grep iterations |grep 'varchar\.' |sort -n 
      25             :  */
      26             : #include "common.h"
      27             : #include <assert.h>
      28             : #include <freetds/convert.h>
      29             : #include <freetds/replacements.h>
      30             : 
      31             : #include <freetds/time.h>
      32             : 
      33             : static int g_result = 0;
      34             : static TDSCONTEXT *ctx;
      35             : 
      36             : static void
      37        7552 : free_convert(int type, CONV_RESULT *cr)
      38             : {
      39        7552 :         switch (type) {
      40        3256 :         case SYBCHAR: case SYBVARCHAR: case SYBTEXT: case XSYBCHAR: case XSYBVARCHAR:
      41             :         case SYBBINARY: case SYBVARBINARY: case SYBIMAGE: case XSYBBINARY: case XSYBVARBINARY:
      42             :         case SYBLONGBINARY:
      43        3256 :                 free(cr->c);
      44             :                 break;
      45             :         }
      46        7552 : }
      47             : 
      48             : int
      49           8 : main(int argc, char **argv)
      50             : {
      51             :         int srctype;
      52             :         int desttype;
      53             : 
      54             :         /* some default inputs */
      55             :         static const int bit_input = 1;
      56             : 
      57             :         /* timing variables to compute performance */
      58             :         struct timeval start, end;
      59             :         double starttime, endtime;
      60             : 
      61           8 :         int i, j, iterations = 0, result;
      62             : 
      63           8 :         TDS_CHAR *src = NULL;
      64             :         TDS_UINT srclen;
      65             :         CONV_RESULT cr;
      66             : 
      67             :         TDS_NUMERIC numeric;
      68             :         TDS_MONEY money;
      69             :         TDS_MONEY4 money4;
      70             :         TDS_DATETIME datetime;
      71             :         TDS_DATETIME4 datetime4;
      72             :         TDS_DATETIMEALL dta;
      73             :         TDS_DATE date;
      74             :         TDS_TIME time;
      75             :         TDS_BIGDATETIME bigdatetime;
      76             :         TDS_BIGTIME bigtime;
      77             : 
      78             :         TDS_TINYINT tds_tinyint;
      79             :         TDS_SMALLINT tds_smallint;
      80             :         TDS_INT tds_int;
      81             :         TDS_INT8 tds_int8;
      82             :         TDS_USMALLINT tds_usmallint;
      83             :         TDS_UINT tds_uint;
      84             :         TDS_UINT8 tds_uint8;
      85             : 
      86             :         TDS_REAL tds_real;
      87             :         TDS_FLOAT tds_float;
      88             : 
      89             :         TDS_UNIQUE tds_unique;
      90             : 
      91           8 :         if (argc > 1) {
      92           0 :                 iterations = atoi(argv[1]);
      93           0 :                 printf("Computing %d iterations\n", iterations);
      94             :         }
      95             : 
      96           8 :         setbuf(stdout, NULL);
      97           8 :         setbuf(stderr, NULL);
      98             : 
      99           8 :         ctx = tds_alloc_context(NULL);
     100           8 :         assert(ctx);
     101           8 :         if (!ctx->locale->datetime_fmt) {
     102             :                 /* set default in case there's no locale file */
     103           0 :                 ctx->locale->datetime_fmt = strdup(STD_DATETIME_FMT);
     104             :         }
     105           8 :         free(ctx->locale->date_fmt);
     106           8 :         ctx->locale->date_fmt = strdup("%Y-%m-%d");
     107           8 :         free(ctx->locale->time_fmt);
     108           8 :         ctx->locale->time_fmt = strdup("%H:%M:%S");
     109             : 
     110             : 
     111             :         /*
     112             :          * Test every possible conversion pair
     113             :          */
     114      524296 :         for (i = 0; i < 0x10000; i++) {
     115      524288 :                 srctype  = i >> 8;
     116      524288 :                 desttype = i & 0xff;
     117      524288 :                 srctype = (srctype + SYBCHAR) & 0xff;
     118             : 
     119      524288 :                 if (!tds_willconvert(srctype, desttype)) {
     120             :                         /* pass a CONV_RESULT as input for make sure size and alignment is enough
     121             :                          * for all types */
     122             :                         CONV_RESULT src;
     123             : 
     124      516424 :                         memset(&src, 0, sizeof(src));
     125      516424 :                         srclen = 4;
     126      516424 :                         result = tds_convert(ctx, srctype, (const TDS_CHAR *) &src, srclen, desttype, &cr);
     127      516424 :                         if (result >= 0)
     128           0 :                                 free_convert(desttype, &cr);
     129      516424 :                         if (result != TDS_CONVERT_NOAVAIL) {
     130           0 :                                 printf("NOT EXPECTED: converted %d (%s, %d bytes) : %d (%s, %d bytes).\n",
     131             :                                        srctype, tds_prtype(srctype), srclen,
     132             :                                        desttype, tds_prtype(desttype), result);
     133           0 :                                 exit(1);
     134             :                         }
     135      516424 :                         continue;       /* don't attempt nonconvertible types */
     136             :                 }
     137             : 
     138        7864 :                 if (srctype == desttype)
     139         312 :                         continue;       /* don't attempt same types */
     140             : 
     141             :                 /* valid types should have a name ! */
     142        7552 :                 assert(tds_prtype(srctype)[0] != 0);
     143        7552 :                 assert(tds_prtype(desttype)[0] != 0);
     144             : 
     145        7552 :                 cr.n.precision = 8;
     146        7552 :                 cr.n.scale = 2;
     147             : 
     148        7552 :                 switch (srctype) {
     149        2536 :                 case SYBCHAR:
     150             :                 case SYBVARCHAR:
     151             :                 case SYBTEXT:
     152             :                 case SYBBINARY:
     153             :                 case SYBVARBINARY:
     154             :                 case SYBIMAGE:
     155             :                 case SYBLONGBINARY:
     156             :                 case XSYBBINARY:
     157             :                 case XSYBVARBINARY:
     158             :                 case XSYBCHAR:
     159             :                 case XSYBVARCHAR:
     160        2536 :                         switch (desttype) {
     161             :                         case SYBCHAR:
     162             :                         case SYBVARCHAR:
     163             :                         case SYBTEXT:
     164             :                         case SYBDATETIME:
     165             :                         case SYBDATETIME4:
     166             :                                 src = "Jan  1, 1999";
     167             :                                 break;
     168          80 :                         case SYBMSDATE:
     169             :                         case SYBDATE:
     170          80 :                                 src = "2012-11-27";
     171          80 :                                 break;
     172          40 :                         case SYBTIME:
     173          40 :                                 src = "15:27:12";
     174          40 :                                 break;
     175          80 :                         case SYBMSTIME:
     176             :                         case SYB5BIGTIME:
     177          80 :                                 src = "15:27:12.327862";
     178          80 :                                 break;
     179         120 :                         case SYBMSDATETIME2:
     180             :                         case SYBMSDATETIMEOFFSET:
     181             :                         case SYB5BIGDATETIME:
     182         120 :                                 src = "2015-09-12 21:48:12.638161";
     183         120 :                                 break;
     184         160 :                         case SYBBINARY:
     185             :                         case SYBIMAGE:
     186         160 :                                 src = "0xbeef";
     187         160 :                                 break;
     188         704 :                         case SYBINT1:
     189             :                         case SYBINT2:
     190             :                         case SYBINT4:
     191             :                         case SYBINT8:
     192             :                         case SYBUINT1:
     193             :                         case SYBUINT2:
     194             :                         case SYBUINT4:
     195             :                         case SYBUINT8:
     196         704 :                                 src = "255";
     197         704 :                                 break;
     198         432 :                         case SYBFLT8:
     199             :                         case SYBREAL:
     200             :                         case SYBNUMERIC:
     201             :                         case SYBDECIMAL:
     202             :                         case SYBMONEY:
     203             :                         case SYBMONEY4:
     204         432 :                                 src = "1999.25";
     205             :                                 cr.n.precision = 8;
     206             :                                 cr.n.scale = 2;
     207         432 :                                 break;
     208          40 :                         case SYBUNIQUE:
     209          40 :                                 src = "A8C60F70-5BD4-3E02-B769-7CCCCA585DCC";
     210          40 :                                 break;
     211         560 :                         case SYBBIT:
     212             :                         default:
     213         560 :                                 src = "1";
     214         560 :                                 break;
     215             :                         }
     216             :                         assert(src);
     217        2536 :                         srclen = strlen(src);
     218        2536 :                         break;
     219             :                 case SYBINT1:
     220             :                 case SYBUINT1:
     221             :                         src = (char *) &tds_tinyint;
     222             :                         srclen = sizeof(tds_tinyint);
     223             :                         break;
     224         208 :                 case SYBINT2:
     225         208 :                         src = (char *) &tds_smallint;
     226         208 :                         srclen = sizeof(tds_smallint);
     227         208 :                         break;
     228         208 :                 case SYBINT4:
     229         208 :                         src = (char *) &tds_int;
     230         208 :                         srclen = sizeof(tds_int);
     231         208 :                         break;
     232         208 :                 case SYBINT8:
     233         208 :                         src = (char *) &tds_int8;
     234         208 :                         srclen = sizeof(tds_int8);
     235         208 :                         break;
     236         208 :                 case SYBUINT2:
     237         208 :                         src = (char *) &tds_usmallint;
     238         208 :                         srclen = sizeof(tds_usmallint);
     239         208 :                         break;
     240         208 :                 case SYBUINT4:
     241         208 :                         src = (char *) &tds_uint;
     242         208 :                         srclen = sizeof(tds_uint);
     243         208 :                         break;
     244         208 :                 case SYBUINT8:
     245         208 :                         src = (char *) &tds_uint8;
     246         208 :                         srclen = sizeof(tds_uint8);
     247         208 :                         break;
     248         208 :                 case SYBFLT8:
     249         208 :                         tds_float = 3.14159;
     250         208 :                         src = (char *) &tds_float;
     251         208 :                         srclen = sizeof(tds_float);
     252         208 :                         break;
     253         208 :                 case SYBREAL:
     254         208 :                         tds_real = (TDS_REAL) 3.14159;
     255         208 :                         src = (char *) &tds_real;
     256         208 :                         srclen = sizeof(tds_real);
     257         208 :                         break;
     258         416 :                 case SYBNUMERIC:
     259             :                 case SYBDECIMAL:
     260         416 :                         src = (char *) &numeric;
     261         416 :                         srclen = sizeof(numeric);
     262         416 :                         break;
     263         208 :                 case SYBMONEY:
     264         208 :                         src = (char *) &money;
     265         208 :                         srclen = sizeof(money);
     266         208 :                         break;
     267         208 :                 case SYBMONEY4:
     268         208 :                         src = (char *) &money4;
     269         208 :                         srclen = sizeof(money4);
     270         208 :                         break;
     271         416 :                 case SYBBIT:
     272             :                 case SYBBITN:
     273         416 :                         src = (char *) &bit_input;
     274         416 :                         srclen = sizeof(bit_input);
     275         416 :                         break;
     276         160 :                 case SYBDATETIME:
     277         160 :                         src = (char *) &datetime;
     278         160 :                         srclen = sizeof(datetime);
     279         160 :                         break;
     280         160 :                 case SYBDATETIME4:
     281         160 :                         src = (char *) &datetime4;
     282         160 :                         srclen = sizeof(datetime4);
     283         160 :                         break;
     284         160 :                 case SYBDATE:
     285         160 :                         src = (char *) &date;
     286         160 :                         srclen = sizeof(date);
     287         160 :                         break;
     288         160 :                 case SYBTIME:
     289         160 :                         src = (char *) &time;
     290         160 :                         srclen = sizeof(time);
     291         160 :                         break;
     292         160 :                 case SYB5BIGTIME:
     293         160 :                         src = (char *) &bigtime;
     294         160 :                         srclen = sizeof(bigtime);
     295         160 :                         break;
     296         160 :                 case SYB5BIGDATETIME:
     297         160 :                         src = (char *) &bigdatetime;
     298         160 :                         srclen = sizeof(bigdatetime);
     299         160 :                         break;
     300          88 :                 case SYBUNIQUE:
     301          88 :                         src = (char *) &tds_unique;
     302          88 :                         srclen = sizeof(tds_unique);
     303          88 :                         break;
     304         640 :                 case SYBMSTIME:
     305             :                 case SYBMSDATE:
     306             :                 case SYBMSDATETIME2:
     307             :                 case SYBMSDATETIMEOFFSET:
     308         640 :                         src = (char *) &dta;
     309         640 :                         srclen = sizeof(dta);
     310         640 :                         break;
     311             :                 /*****  not defined yet
     312             :                         case SYBBOUNDARY:
     313             :                         case SYBSENSITIVITY:
     314             :                                 fprintf (stderr, "type %d not supported\n", srctype );
     315             :                                 continue;
     316             :                                 break;
     317             :                 *****/
     318           0 :                 default:
     319           0 :                         fprintf(stderr, "no such type %d (%s)\n", srctype, tds_prtype(srctype));
     320           0 :                         return -1;
     321             :                 }
     322             : 
     323             :                 /* 
     324             :                  * Now at last do the conversion
     325             :                  */
     326             : 
     327        7552 :                 result = tds_convert(ctx, srctype, src, srclen, desttype, &cr);
     328        7552 :                 if (result >= 0)
     329        7552 :                         free_convert(desttype, &cr);
     330             : 
     331        7552 :                 if (result < 0) {
     332           0 :                         if (result == TDS_CONVERT_NOAVAIL)      /* tds_willconvert returned true, but it lied. */
     333           0 :                                 fprintf(stderr, "Conversion not yet implemented:\n\t");
     334             : 
     335           0 :                         fprintf(stderr, "failed (%d) to convert %d (%s, %d bytes) : %d (%s).\n",
     336             :                                 result,
     337             :                                 srctype, tds_prtype(srctype), srclen,
     338             :                                 desttype, tds_prtype(desttype));
     339             : 
     340           0 :                         if (result == TDS_CONVERT_NOAVAIL)
     341           0 :                                 exit(1);
     342             :                 }
     343             : 
     344        7552 :                 printf("converted %d (%s, %d bytes) -> %d (%s, %d bytes).\n",
     345             :                        srctype, tds_prtype(srctype), srclen,
     346             :                        desttype, tds_prtype(desttype), result);
     347             : 
     348             :                 /* 
     349             :                  * In the first iteration, start with varchar -> others.  
     350             :                  * By saving the output, we initialize subsequent inputs.
     351             :                  */
     352             : 
     353        7552 :                 switch (desttype) {
     354         320 :                 case SYBNUMERIC:
     355             :                 case SYBDECIMAL:
     356         320 :                         numeric = cr.n;
     357         320 :                         break;
     358         208 :                 case SYBMONEY:
     359         208 :                         money = cr.m;
     360         208 :                         break;
     361         208 :                 case SYBMONEY4:
     362         208 :                         money4 = cr.m4;
     363         208 :                         break;
     364         112 :                 case SYBDATETIME:
     365         112 :                         datetime = cr.dt;
     366         112 :                         break;
     367         112 :                 case SYBDATETIME4:
     368         112 :                         datetime4 = cr.dt4;
     369         112 :                         break;
     370         112 :                 case SYBDATE:
     371         112 :                         date = cr.date;
     372         112 :                         break;
     373         112 :                 case SYBTIME:
     374         112 :                         time = cr.time;
     375         112 :                         break;
     376         112 :                 case SYBMSDATETIME2:
     377         112 :                         dta = cr.dta;
     378         112 :                         break;
     379         112 :                 case SYB5BIGTIME:
     380         112 :                         bigtime = cr.bigtime;
     381         112 :                         break;
     382         112 :                 case SYB5BIGDATETIME:
     383         112 :                         bigdatetime = cr.bigdatetime;
     384         112 :                         break;
     385         416 :                 case SYBINT1:
     386             :                 case SYBUINT1:
     387         416 :                         tds_tinyint = cr.ti;
     388         416 :                         break;
     389         208 :                 case SYBINT2:
     390         208 :                         tds_smallint = cr.si;
     391         208 :                         break;
     392         208 :                 case SYBINT4:
     393         208 :                         tds_int = cr.i;
     394         208 :                         break;
     395         208 :                 case SYBINT8:
     396         208 :                         tds_int8 = cr.bi;
     397         208 :                         break;
     398         208 :                 case SYBUINT2:
     399         208 :                         tds_usmallint = cr.usi;
     400         208 :                         break;
     401         208 :                 case SYBUINT4:
     402         208 :                         tds_uint = cr.ui;
     403         208 :                         break;
     404         208 :                 case SYBUINT8:
     405         208 :                         tds_uint8 = cr.ubi;
     406         208 :                         break;
     407          40 :                 case SYBUNIQUE:
     408          40 :                         tds_unique = cr.u;
     409          40 :                         break;
     410             :                 default:
     411             :                         break;
     412             :                 }
     413             : 
     414             :                 /*
     415             :                  * If an iteration count was passed on the command line (not by "make check")
     416             :                  * run the conversion N times and print the conversions per second.
     417             :                  */
     418        7552 :                 result = gettimeofday(&start, NULL);
     419        7552 :                 starttime = (double) start.tv_sec + (double) start.tv_usec * 0.000001;
     420             : 
     421        7552 :                 for (j = 0; result >= 0 && j < iterations; j++) {
     422           0 :                         result = tds_convert(ctx, srctype, src, srclen, desttype, &cr);
     423           0 :                         if (result >= 0)
     424           0 :                                 free_convert(desttype, &cr);
     425             :                 }
     426        7552 :                 if (result < 0)
     427           0 :                         continue;
     428             : 
     429        7552 :                 result = gettimeofday(&end, NULL);
     430        7552 :                 endtime = (double) end.tv_sec + (double) end.tv_usec * 0.000001;
     431             : 
     432        7552 :                 if (endtime != starttime && iterations) {
     433           0 :                         printf("%9.0f iterations/second converting %13s => %s.\n",
     434           0 :                                 j / (endtime - starttime), tds_prtype(srctype), tds_prtype(desttype));
     435             :                 }
     436             : 
     437             :         }
     438           8 :         tds_free_context(ctx);
     439             : 
     440           8 :         return g_result;
     441             : }

Generated by: LCOV version 1.13