LTP GCOV extension - code coverage report
Current view: directory - odbc - odbc_util.c
Test: FreeTDS coverage
Date: 2008-11-21 Instrumented lines: 344
Code covered: 73.8 % Executed lines: 254

       1                 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2                 :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
       3                 :  * Copyright (C) 2005, 2006 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                 : #if HAVE_CONFIG_H
      22                 : #include <config.h>
      23                 : #endif /* HAVE_CONFIG_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                 : 
      35                 : #include "tdsodbc.h"
      36                 : 
      37                 : #ifdef DMALLOC
      38                 : #include <dmalloc.h>
      39                 : #endif
      40                 : 
      41                 : TDS_RCSID(var, "$Id: odbc_util.c,v 1.85.2.1 2007/12/21 11:19:02 freddy77 Exp $");
      42                 : 
      43                 : /**
      44                 :  * \ingroup odbc_api
      45                 :  * \defgroup odbc_util ODBC utility
      46                 :  * Functions called within \c ODBC driver.
      47                 :  */
      48                 : 
      49                 : /**
      50                 :  * \addtogroup odbc_util
      51                 :  *  \@{ 
      52                 :  */
      53                 : 
      54                 : static int
      55                 : odbc_set_stmt(TDS_STMT * stmt, char **dest, const char *sql, int sql_len)
      56             800 : {
      57                 :         char *p;
      58                 : 
      59             800 :         assert(dest == &stmt->prepared_query || dest == &stmt->query);
      60                 : 
      61             800 :         if (sql_len == SQL_NTS)
      62             724 :                 sql_len = strlen(sql);
      63              76 :         else if (sql_len <= 0)
      64               0 :                 return SQL_ERROR;
      65                 : 
      66                 :         /* TODO already NULL ?? */
      67             800 :         tds_free_param_results(stmt->params);
      68             800 :         stmt->params = NULL;
      69             800 :         stmt->param_num = 0;
      70             800 :         stmt->param_count = 0;
      71             800 :         stmt->prepared_query_is_func = 0;
      72             800 :         stmt->prepared_query_is_rpc = 0;
      73             800 :         stmt->prepared_pos = NULL;
      74             800 :         stmt->curr_param_row = 0;
      75                 : 
      76             800 :         if (stmt->prepared_query)
      77              71 :                 TDS_ZERO_FREE(stmt->prepared_query);
      78                 : 
      79             800 :         if (stmt->query)
      80             608 :                 TDS_ZERO_FREE(stmt->query);
      81                 : 
      82             800 :         *dest = p = (char *) malloc(sql_len + 1);
      83             800 :         if (!p)
      84               0 :                 return SQL_ERROR;
      85                 : 
      86             800 :         if (sql) {
      87             800 :                 memcpy(p, sql, sql_len);
      88             800 :                 p[sql_len] = 0;
      89                 :         } else {
      90               0 :                 p[0] = 0;
      91                 :         }
      92                 : 
      93             800 :         return SQL_SUCCESS;
      94                 : }
      95                 : 
      96                 : int
      97                 : odbc_set_stmt_query(TDS_STMT * stmt, const char *sql, int sql_len)
      98             703 : {
      99             703 :         return odbc_set_stmt(stmt, &stmt->query, sql, sql_len);
     100                 : }
     101                 : 
     102                 : 
     103                 : int
     104                 : odbc_set_stmt_prepared_query(TDS_STMT * stmt, const char *sql, int sql_len)
     105              97 : {
     106              97 :         return odbc_set_stmt(stmt, &stmt->prepared_query, sql, sql_len);
     107                 : }
     108                 : 
     109                 : 
     110                 : void
     111                 : odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
     112              98 : {
     113              98 :         TDSSOCKET *tds = stmt->dbc->tds_socket;
     114              98 :         TDSCONTEXT *context = stmt->dbc->env->tds_ctx;
     115                 : 
     116                 :         /* TODO handle different type results (functions) on mssql2k */
     117              98 :         if (stmt->prepared_query_is_func && tds->has_status) {
     118                 :                 struct _drecord *drec;
     119                 :                 int len;
     120              16 :                 const TDS_DESC* axd = stmt->apd;
     121                 :                 TDS_INTPTR len_offset;
     122                 :                 char *data_ptr;
     123                 : 
     124              16 :                 if (axd->header.sql_desc_count < 1)
     125               0 :                         return;
     126              16 :                 drec = &axd->records[0];
     127              16 :                 data_ptr = drec->sql_desc_data_ptr;
     128                 : 
     129              16 :                 if (axd->header.sql_desc_bind_type != SQL_BIND_BY_COLUMN) {
     130               0 :                         len_offset = axd->header.sql_desc_bind_type * n_row;
     131               0 :                         if (axd->header.sql_desc_bind_offset_ptr)
     132               0 :                                 len_offset += *axd->header.sql_desc_bind_offset_ptr;
     133               0 :                         data_ptr += len_offset;
     134                 :                 } else {
     135              16 :                         len_offset = sizeof(SQLLEN) * n_row;
     136              16 :                         data_ptr += sizeof(SQLINTEGER) * n_row;
     137                 :                 }
     138                 : #define LEN(ptr) *((SQLLEN*)(((char*)(ptr)) + len_offset))
     139                 : 
     140              16 :                 len = convert_tds2sql(context, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
     141                 :                                       drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
     142              16 :                 if (TDS_FAIL == len)
     143               0 :                         return /* SQL_ERROR */ ;
     144              16 :                 if (drec->sql_desc_indicator_ptr)
     145              16 :                         LEN(drec->sql_desc_indicator_ptr) = 0;
     146              16 :                 if (drec->sql_desc_octet_length_ptr)
     147              16 :                         LEN(drec->sql_desc_octet_length_ptr) = len;
     148                 :         }
     149                 : #undef LEN
     150                 : }
     151                 : 
     152                 : void
     153                 : odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
     154              24 : {
     155              24 :         TDSSOCKET *tds = stmt->dbc->tds_socket;
     156              24 :         TDSPARAMINFO *info = tds->current_results;
     157              24 :         TDSCONTEXT *context = stmt->dbc->env->tds_ctx;
     158                 : 
     159              24 :         int i_begin = stmt->prepared_query_is_func ? 1 : 0;
     160                 :         int i;
     161              24 :         int nparam = i_begin;
     162                 : 
     163                 :         /* I don't understand why but this happen -- freddy77 */
     164                 :         /* TODO check why, put an assert ? */
     165              24 :         if (!info)
     166               0 :                 return;
     167                 : 
     168              56 :         for (i = 0; i < info->num_cols; ++i) {
     169              32 :                 const TDS_DESC* axd = stmt->apd;
     170                 :                 const struct _drecord *drec_apd, *drec_ipd;
     171              32 :                 TDSCOLUMN *colinfo = info->columns[i];
     172                 :                 TDS_CHAR *src;
     173                 :                 int srclen;
     174                 :                 SQLINTEGER len;
     175                 :                 int c_type;
     176                 :                 char *data_ptr;
     177                 :                 TDS_INTPTR len_offset;
     178                 : 
     179                 :                 /* find next output parameter */
     180                 :                 for (;;) {
     181              44 :                         drec_apd = NULL;
     182                 :                         /* TODO best way to stop */
     183              44 :                         if (nparam >= axd->header.sql_desc_count || nparam >= stmt->ipd->header.sql_desc_count)
     184               0 :                                 return;
     185              44 :                         drec_apd = &axd->records[nparam];
     186              44 :                         drec_ipd = &stmt->ipd->records[nparam];
     187              44 :                         if (stmt->ipd->records[nparam++].sql_desc_parameter_type != SQL_PARAM_INPUT)
     188              32 :                                 break;
     189              12 :                 }
     190                 : 
     191              32 :                 data_ptr = drec_apd->sql_desc_data_ptr;
     192              32 :                 if (axd->header.sql_desc_bind_type != SQL_BIND_BY_COLUMN) {
     193               0 :                         len_offset = axd->header.sql_desc_bind_type * n_row;
     194               0 :                         if (axd->header.sql_desc_bind_offset_ptr)
     195               0 :                                 len_offset += *axd->header.sql_desc_bind_offset_ptr;
     196               0 :                         data_ptr += len_offset;
     197                 :                 } else {
     198              32 :                         len_offset = sizeof(SQLLEN) * n_row;
     199              32 :                         data_ptr += odbc_get_octet_len(drec_apd->sql_desc_concise_type, drec_apd) * n_row;
     200                 :                 }
     201                 : #define LEN(ptr) *((SQLLEN*)(((char*)(ptr)) + len_offset))
     202                 : 
     203                 :                 /* null parameter ? */
     204              32 :                 if (colinfo->column_cur_size < 0) {
     205                 :                         /* FIXME error if NULL */
     206               0 :                         if (drec_apd->sql_desc_indicator_ptr)
     207               0 :                                 LEN(drec_apd->sql_desc_indicator_ptr) = SQL_NULL_DATA;
     208               0 :                         continue;
     209                 :                 }
     210                 : 
     211              32 :                 src = (TDS_CHAR *) & info->current_row[colinfo->column_offset];
     212              32 :                 if (is_blob_type(colinfo->column_type))
     213               0 :                         src = ((TDSBLOB *) src)->textvalue;
     214              32 :                 srclen = colinfo->column_cur_size;
     215              32 :                 c_type = drec_apd->sql_desc_concise_type;
     216              32 :                 if (c_type == SQL_C_DEFAULT)
     217               0 :                         c_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
     218                 :                 /* 
     219                 :                  * TODO why IPD ?? perhaps SQLBindParameter it's not correct ??
     220                 :                  * Or tests are wrong ??
     221                 :                  */
     222              32 :                 len = convert_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size), src, srclen,
     223                 :                                       c_type, (void *) data_ptr, drec_apd->sql_desc_octet_length, drec_ipd);
     224                 :                 /* TODO error handling */
     225              32 :                 if (len < 0)
     226               0 :                         return /* SQL_ERROR */ ;
     227              32 :                 if (drec_apd->sql_desc_indicator_ptr)
     228              32 :                         LEN(drec_apd->sql_desc_indicator_ptr) = 0;
     229              32 :                 if (drec_apd->sql_desc_octet_length_ptr)
     230              32 :                         LEN(drec_apd->sql_desc_octet_length_ptr) = len;
     231                 : #undef LEN
     232                 :         }
     233                 : }
     234                 : 
     235                 : int
     236                 : odbc_get_string_size(int size, SQLCHAR * str)
     237             357 : {
     238             357 :         if (str) {
     239             337 :                 if (size == SQL_NTS)
     240             266 :                         return strlen((const char *) str);
     241              71 :                 if (size >= 0)
     242              71 :                         return size;
     243                 :         }
     244                 :         /* SQL_NULL_DATA or any other strange value */
     245              20 :         return 0;
     246                 : }
     247                 : 
     248                 : /**
     249                 :  * Convert type from database to ODBC
     250                 :  */
     251                 : SQLSMALLINT
     252                 : odbc_server_to_sql_type(int col_type, int col_size)
     253            1386 : {
     254                 :         /* FIXME finish */
     255            1386 :         switch ((TDS_SERVER_TYPE) col_type) {
     256                 :         case XSYBCHAR:
     257                 :         case SYBCHAR:
     258              15 :                 return SQL_CHAR;
     259                 :         case XSYBVARCHAR:
     260                 :         case SYBVARCHAR:
     261             420 :                 return SQL_VARCHAR;
     262                 :         case SYBTEXT:
     263              14 :                 return SQL_LONGVARCHAR;
     264                 :         case SYBBIT:
     265                 :         case SYBBITN:
     266              20 :                 return SQL_BIT;
     267                 : #if (ODBCVER >= 0x0300)
     268                 :         case SYBINT8:
     269                 :                 /* TODO return numeric for odbc2 and convert bigint to numeric */
     270               0 :                 return SQL_BIGINT;
     271                 : #endif
     272                 :         case SYBINT4:
     273             136 :                 return SQL_INTEGER;
     274                 :         case SYBINT2:
     275             142 :                 return SQL_SMALLINT;
     276                 :         case SYBINT1:
     277               4 :                 return SQL_TINYINT;
     278                 :         case SYBINTN:
     279             502 :                 switch (col_size) {
     280                 :                 case 1:
     281               9 :                         return SQL_TINYINT;
     282                 :                 case 2:
     283             352 :                         return SQL_SMALLINT;
     284                 :                 case 4:
     285             141 :                         return SQL_INTEGER;
     286                 : #if (ODBCVER >= 0x0300)
     287                 :                 case 8:
     288               0 :                         return SQL_BIGINT;
     289                 : #endif
     290                 :                 }
     291               0 :                 break;
     292                 :         case SYBREAL:
     293               5 :                 return SQL_REAL;
     294                 :         case SYBFLT8:
     295              23 :                 return SQL_DOUBLE;
     296                 :         case SYBFLTN:
     297              18 :                 switch (col_size) {
     298                 :                 case 4:
     299               5 :                         return SQL_REAL;
     300                 :                 case 8:
     301              13 :                         return SQL_DOUBLE;
     302                 :                 }
     303               0 :                 break;
     304                 :         case SYBMONEY:
     305               1 :                 return SQL_DOUBLE;
     306                 :         case SYBMONEY4:
     307               1 :                 return SQL_DOUBLE;
     308                 :         case SYBMONEYN:
     309               8 :                 return SQL_DOUBLE;
     310                 :         case SYBDATETIME:
     311                 :         case SYBDATETIME4:
     312                 :         case SYBDATETIMN:
     313                 : #if (ODBCVER >= 0x0300)
     314              38 :                 return SQL_TYPE_TIMESTAMP;
     315                 : #else
     316                 :                 return SQL_TIMESTAMP;
     317                 : #endif
     318                 :         case XSYBBINARY:
     319                 :         case SYBBINARY:
     320               3 :                 return SQL_BINARY;
     321                 :         case SYBLONGBINARY:
     322                 :         case SYBIMAGE:
     323               4 :                 return SQL_LONGVARBINARY;
     324                 :         case XSYBVARBINARY:
     325                 :         case SYBVARBINARY:
     326               3 :                 return SQL_VARBINARY;
     327                 :         case SYBNUMERIC:
     328                 :         case SYBDECIMAL:
     329              25 :                 return SQL_NUMERIC;
     330                 :                 /* TODO this is ODBC 3.5 */
     331                 :         case SYBNTEXT:
     332                 :         case SYBNVARCHAR:
     333                 :         case XSYBNVARCHAR:
     334                 :         case XSYBNCHAR:
     335               0 :                 break;
     336                 : #if (ODBCVER >= 0x0300)
     337                 :         case SYBUNIQUE:
     338                 : #ifdef SQL_GUID
     339               4 :                 return SQL_GUID;
     340                 : #else
     341                 :                 return SQL_CHAR;
     342                 : #endif
     343                 :         case SYBVARIANT:
     344                 :                 break;
     345                 : #endif
     346                 :                 /* TODO what should I do with these types ?? */
     347                 :         case SYBVOID:
     348                 :         case SYBSINT1:
     349                 :         case SYBUINT2:
     350                 :         case SYBUINT4:
     351                 :         case SYBUINT8:
     352                 :                 break;
     353                 :         }
     354               0 :         return SQL_UNKNOWN_TYPE;
     355                 : }
     356                 : 
     357                 : /**
     358                 :  * Pass this an SQL_C_* type and get a SYB* type which most closely corresponds
     359                 :  * to the SQL_C_* type.
     360                 :  */
     361                 : int
     362                 : odbc_c_to_server_type(int c_type)
     363            1809 : {
     364            1809 :         switch (c_type) {
     365                 :                 /* FIXME this should be dependent on size of data !!! */
     366                 :         case SQL_C_BINARY:
     367              59 :                 return SYBBINARY;
     368                 :                 /* TODO what happen if varchar is more than 255 characters long */
     369                 :         case SQL_C_CHAR:
     370             924 :                 return SYBVARCHAR;
     371                 :         case SQL_C_FLOAT:
     372              16 :                 return SYBREAL;
     373                 :         case SQL_C_DOUBLE:
     374              16 :                 return SYBFLT8;
     375                 :         case SQL_C_BIT:
     376               8 :                 return SYBBIT;
     377                 : #if (ODBCVER >= 0x0300)
     378                 :         case SQL_C_SBIGINT:
     379                 :         case SQL_C_UBIGINT:
     380               0 :                 return SYBINT8;
     381                 : #ifdef SQL_C_GUID
     382                 :         case SQL_C_GUID:
     383               6 :                 return SYBUNIQUE;
     384                 : #endif
     385                 : #endif
     386                 :         case SQL_C_LONG:
     387                 :         case SQL_C_SLONG:
     388                 :         case SQL_C_ULONG:
     389             486 :                 return SYBINT4;
     390                 :         case SQL_C_SHORT:
     391                 :         case SQL_C_SSHORT:
     392                 :         case SQL_C_USHORT:
     393             258 :                 return SYBINT2;
     394                 :         case SQL_C_TINYINT:
     395                 :         case SQL_C_STINYINT:
     396                 :         case SQL_C_UTINYINT:
     397               4 :                 return SYBINT1;
     398                 :                 /* ODBC date formats are completely differect from SQL one */
     399                 :         case SQL_C_DATE:
     400                 :         case SQL_C_TIME:
     401                 :         case SQL_C_TIMESTAMP:
     402                 :         case SQL_C_TYPE_DATE:
     403                 :         case SQL_C_TYPE_TIME:
     404                 :         case SQL_C_TYPE_TIMESTAMP:
     405              14 :                 return SYBDATETIME;
     406                 :                 /* ODBC numeric/decimal formats are completely differect from tds one */
     407                 :         case SQL_C_NUMERIC:
     408              18 :                 return SYBNUMERIC;
     409                 :                 /* not supported */
     410                 :         case SQL_C_INTERVAL_YEAR:
     411                 :         case SQL_C_INTERVAL_MONTH:
     412                 :         case SQL_C_INTERVAL_DAY:
     413                 :         case SQL_C_INTERVAL_HOUR:
     414                 :         case SQL_C_INTERVAL_MINUTE:
     415                 :         case SQL_C_INTERVAL_SECOND:
     416                 :         case SQL_C_INTERVAL_YEAR_TO_MONTH:
     417                 :         case SQL_C_INTERVAL_DAY_TO_HOUR:
     418                 :         case SQL_C_INTERVAL_DAY_TO_MINUTE:
     419                 :         case SQL_C_INTERVAL_DAY_TO_SECOND:
     420                 :         case SQL_C_INTERVAL_HOUR_TO_MINUTE:
     421                 :         case SQL_C_INTERVAL_HOUR_TO_SECOND:
     422                 :         case SQL_C_INTERVAL_MINUTE_TO_SECOND:
     423                 : #ifdef SQL_C_WCHAR
     424                 :         case SQL_C_WCHAR:
     425                 : #endif
     426                 :                 break;
     427                 :         }
     428               0 :         return TDS_FAIL;
     429                 : }
     430                 : 
     431                 : void
     432                 : odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec)
     433            1386 : {
     434                 : #define SET_INFO(type, prefix, suffix) \
     435                 :         drec->sql_desc_literal_prefix = prefix; \
     436                 :         drec->sql_desc_literal_suffix = suffix; \
     437                 :         drec->sql_desc_type_name = type; \
     438                 :         return;
     439                 : 
     440                 :         /* FIXME finish, support for N type (nvarchar) */
     441            1386 :         switch (tds_get_conversion_type(col->column_type, col->column_size)) {
     442                 :         case XSYBCHAR:
     443                 :         case SYBCHAR:
     444              15 :                 SET_INFO("char", "'", "'");
     445                 :         case XSYBVARCHAR:
     446                 :         case SYBVARCHAR:
     447             420 :                 SET_INFO("varchar", "'", "'");
     448                 :         case SYBTEXT:
     449              14 :                 SET_INFO("text", "'", "'");
     450                 :         case SYBBIT:
     451                 :         case SYBBITN:
     452              20 :                 SET_INFO("bit", "", "");
     453                 : #if (ODBCVER >= 0x0300)
     454                 :         case SYBINT8:
     455                 :                 /* TODO return numeric for odbc2 and convert bigint to numeric */
     456               0 :                 SET_INFO("bigint", "", "");
     457                 : #endif
     458                 :         case SYBINT4:
     459             277 :                 SET_INFO("int", "", "");
     460                 :         case SYBINT2:
     461             494 :                 SET_INFO("smallint", "", "");
     462                 :         case SYBINT1:
     463              13 :                 SET_INFO("tinyint", "", "");
     464                 :         case SYBREAL:
     465              10 :                 SET_INFO("real", "", "");
     466                 :         case SYBFLT8:
     467              36 :                 SET_INFO("float", "", "");
     468                 :         case SYBMONEY:
     469                 :         case SYBMONEY4:
     470              10 :                 SET_INFO("money", "$", "");
     471                 :         case SYBDATETIME:
     472                 :         case SYBDATETIME4:
     473              38 :                 SET_INFO("datetime", "'", "'");
     474                 :         case SYBBINARY:
     475                 :                 /* handle TIMESTAMP using usertype */
     476               3 :                 if (col->column_usertype == 80)
     477               1 :                         SET_INFO("timestamp", "0x", "");
     478                 :                 SET_INFO("binary", "0x", "");
     479                 :         case SYBIMAGE:
     480               4 :                 SET_INFO("image", "0x", "");
     481                 :         case SYBVARBINARY:
     482               3 :                 SET_INFO("varbinary", "0x", "");
     483                 :         case SYBNUMERIC:
     484              21 :                 SET_INFO("numeric", "", "");
     485                 :         case SYBDECIMAL:
     486               4 :                 SET_INFO("decimal", "", "");
     487                 :         case SYBINTN:
     488                 :         case SYBDATETIMN:
     489                 :         case SYBFLTN:
     490                 :         case SYBMONEYN:
     491               0 :                 assert(0);
     492                 :         case SYBVOID:
     493                 :         case SYBNTEXT:
     494                 :         case SYBNVARCHAR:
     495                 :         case XSYBNVARCHAR:
     496                 :         case XSYBNCHAR:
     497               0 :                 break;
     498                 : #if (ODBCVER >= 0x0300)
     499                 :         case SYBUNIQUE:
     500                 :                 /* FIXME for Sybase ?? */
     501               4 :                 SET_INFO("uniqueidentifier", "'", "'");
     502                 :         case SYBVARIANT:
     503                 :                 /* SET_INFO("sql_variant", "", ""); */
     504                 :                 break;
     505                 : #endif
     506                 :         }
     507               0 :         SET_INFO("", "", "");
     508                 : #undef SET_INFO
     509                 : }
     510                 : 
     511                 : SQLINTEGER
     512                 : odbc_sql_to_displaysize(int sqltype, int column_size, int column_prec)
     513            1386 : {
     514            1386 :         SQLINTEGER size = 0;
     515                 : 
     516            1386 :         switch (sqltype) {
     517                 :         case SQL_CHAR:
     518                 :         case SQL_VARCHAR:
     519                 :         case SQL_LONGVARCHAR:
     520             449 :                 size = column_size;
     521             449 :                 break;
     522                 :         case SQL_BIGINT:
     523               0 :                 size = 20;
     524               0 :                 break;
     525                 :         case SQL_INTEGER:
     526             277 :                 size = 11;      /* -1000000000 */
     527             277 :                 break;
     528                 :         case SQL_SMALLINT:
     529             494 :                 size = 6;       /* -10000 */
     530             494 :                 break;
     531                 :         case SQL_TINYINT:
     532              13 :                 size = 3;       /* 255 */
     533              13 :                 break;
     534                 :         case SQL_DECIMAL:
     535                 :         case SQL_NUMERIC:
     536              25 :                 size = column_prec + 2;
     537              25 :                 break;
     538                 :         case SQL_DATE:
     539                 :                 /* FIXME check always yyyy-mm-dd ?? */
     540               0 :                 size = 19;
     541               0 :                 break;
     542                 :         case SQL_TIME:
     543                 :                 /* FIXME check always hh:mm:ss[.fff] */
     544               0 :                 size = 19;
     545               0 :                 break;
     546                 :         case SQL_TYPE_TIMESTAMP:
     547                 :         case SQL_TIMESTAMP:
     548                 :                 /* TODO dependent on precision (decimal second digits) */
     549                 :                 /* FIXME check, always format yyyy-mm-dd hh:mm:ss[.fff] ?? */
     550              38 :                 size = 24;
     551                 :                 /* spinellia@acm.org: int token.c it is 30 should we comply? */
     552              38 :                 break;
     553                 :         case SQL_FLOAT:
     554                 :         case SQL_REAL:
     555                 :         case SQL_DOUBLE:
     556              56 :                 size = 24;      /* FIXME -- what should the correct size be? */
     557              56 :                 break;
     558                 : #ifdef SQL_GUID
     559                 :         case SQL_GUID:
     560               4 :                 size = 36;
     561               4 :                 break;
     562                 : #endif
     563                 :         default:
     564                 :                 /* FIXME TODO finish, should support ALL types (interval, binary) */
     565              30 :                 size = 40;
     566              30 :                 tdsdump_log(TDS_DBG_INFO1, "odbc_sql_to_displaysize: unknown sql type %d\n", (int) sqltype);
     567                 :                 break;
     568                 :         }
     569            1386 :         return size;
     570                 : }
     571                 : 
     572                 : int
     573                 : odbc_sql_to_c_type_default(int sql_type)
     574               0 : {
     575                 : 
     576               0 :         switch (sql_type) {
     577                 : 
     578                 :         case SQL_CHAR:
     579                 :         case SQL_VARCHAR:
     580                 :         case SQL_LONGVARCHAR:
     581               0 :                 return SQL_C_CHAR;
     582                 :                 /* for compatibility numeric are converted to CHAR, not to structure */
     583                 :         case SQL_DECIMAL:
     584                 :         case SQL_NUMERIC:
     585               0 :                 return SQL_C_CHAR;
     586                 : #ifdef SQL_GUID
     587                 :         case SQL_GUID:
     588                 :                 /* TODO return SQL_C_CHAR for Sybase ?? */
     589               0 :                 return SQL_C_GUID;
     590                 : #endif
     591                 :         case SQL_BIT:
     592               0 :                 return SQL_C_BIT;
     593                 :         case SQL_TINYINT:
     594               0 :                 return SQL_C_UTINYINT;
     595                 :         case SQL_SMALLINT:
     596               0 :                 return SQL_C_SSHORT;
     597                 :         case SQL_INTEGER:
     598               0 :                 return SQL_C_SLONG;
     599                 :         case SQL_BIGINT:
     600               0 :                 return SQL_C_SBIGINT;
     601                 :         case SQL_REAL:
     602               0 :                 return SQL_C_FLOAT;
     603                 :         case SQL_FLOAT:
     604                 :         case SQL_DOUBLE:
     605               0 :                 return SQL_C_DOUBLE;
     606                 :         case SQL_DATE:
     607                 :         case SQL_TYPE_DATE:
     608               0 :                 return SQL_C_TYPE_DATE;
     609                 :         case SQL_TIME:
     610                 :         case SQL_TYPE_TIME:
     611               0 :                 return SQL_C_TYPE_TIME;
     612                 :         case SQL_TIMESTAMP:
     613                 :         case SQL_TYPE_TIMESTAMP:
     614               0 :                 return SQL_C_TYPE_TIMESTAMP;
     615                 :         case SQL_BINARY:
     616                 :         case SQL_VARBINARY:
     617                 :         case SQL_LONGVARBINARY:
     618               0 :                 return SQL_C_BINARY;
     619                 :                 /* TODO interval types */
     620                 :         default:
     621               0 :                 return 0;
     622                 :         }
     623                 : }
     624                 : 
     625                 : int
     626                 : odbc_sql_to_server_type(TDSSOCKET * tds, int sql_type)
     627             432 : {
     628                 : 
     629             432 :         switch (sql_type) {
     630                 : 
     631                 :         case SQL_CHAR:
     632               1 :                 return SYBCHAR;
     633                 :         case SQL_VARCHAR:
     634             186 :                 return SYBVARCHAR;
     635                 :         case SQL_LONGVARCHAR:
     636              10 :                 return SYBTEXT;
     637                 :         case SQL_DECIMAL:
     638               2 :                 return SYBDECIMAL;
     639                 :         case SQL_NUMERIC:
     640               6 :                 return SYBNUMERIC;
     641                 : #ifdef SQL_GUID
     642                 :         case SQL_GUID:
     643               3 :                 if (IS_TDS7_PLUS(tds))
     644               3 :                         return SYBUNIQUE;
     645               0 :                 return 0;
     646                 : #endif
     647                 :         case SQL_BIT:
     648               4 :                 if (IS_TDS7_PLUS(tds))
     649               2 :                         return SYBBITN;
     650               2 :                 return SYBBIT;
     651                 :         case SQL_TINYINT:
     652               2 :                 return SYBINT1;
     653                 :         case SQL_SMALLINT:
     654               0 :                 return SYBINT2;
     655                 :         case SQL_INTEGER:
     656             187 :                 return SYBINT4;
     657                 :         case SQL_BIGINT:
     658               0 :                 return SYBINT8;
     659                 :         case SQL_REAL:
     660               8 :                 return SYBREAL;
     661                 :         case SQL_FLOAT:
     662                 :         case SQL_DOUBLE:
     663               8 :                 return SYBFLT8;
     664                 :                 /* ODBC version 2 */
     665                 :         case SQL_DATE:
     666                 :         case SQL_TIME:
     667                 :         case SQL_TIMESTAMP:
     668                 :                 /* ODBC version 3 */
     669                 :         case SQL_TYPE_DATE:
     670                 :         case SQL_TYPE_TIME:
     671                 :         case SQL_TYPE_TIMESTAMP:
     672              10 :                 return SYBDATETIME;
     673                 :         case SQL_BINARY:
     674               0 :                 return SYBBINARY;
     675                 :         case SQL_VARBINARY:
     676               0 :                 return SYBVARBINARY;
     677                 :         case SQL_LONGVARBINARY:
     678               5 :                 return SYBIMAGE;
     679                 :                 /* TODO interval types */
     680                 :         default:
     681               0 :                 return 0;
     682                 :         }
     683                 : }
     684                 : 
     685                 : /**
     686                 :  * Copy a string to client setting size according to ODBC convenction
     687                 :  * @param buffer    client buffer
     688                 :  * @param cbBuffer  client buffer size (in bytes)
     689                 :  * @param pcbBuffer pointer to SQLSMALLINT to hold string size
     690                 :  * @param s         string to copy
     691                 :  * @param len       len of string to copy. <0 null terminated
     692                 :  */
     693                 : SQLRETURN
     694                 : odbc_set_string(SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len)
     695             739 : {
     696             739 :         SQLRETURN result = SQL_SUCCESS;
     697                 : 
     698             739 :         if (len < 0)
     699             731 :                 len = strlen(s);
     700                 : 
     701             739 :         if (pcbBuffer)
     702             699 :                 *pcbBuffer = len;
     703             739 :         if (len >= cbBuffer) {
     704               0 :                 len = cbBuffer - 1;
     705               0 :                 result = SQL_SUCCESS_WITH_INFO;
     706                 :         }
     707             739 :         if (buffer && len >= 0) {
     708                 :                 /* buffer can overlap, use memmove, thanks to Valgrind */
     709             739 :                 memmove((char *) buffer, s, len);
     710             739 :                 ((char *) buffer)[len] = 0;
     711                 :         }
     712             739 :         return result;
     713                 : }
     714                 : 
     715                 : SQLRETURN
     716                 : odbc_set_string_i(SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len)
     717               0 : {
     718               0 :         SQLRETURN result = SQL_SUCCESS;
     719                 : 
     720               0 :         if (len < 0)
     721               0 :                 len = strlen(s);
     722                 : 
     723               0 :         if (pcbBuffer)
     724               0 :                 *pcbBuffer = len;
     725               0 :         if (len >= cbBuffer) {
     726               0 :                 len = cbBuffer - 1;
     727               0 :                 result = SQL_SUCCESS_WITH_INFO;
     728                 :         }
     729               0 :         if (buffer && len >= 0) {
     730                 :                 /* buffer can overlap, use memmove, thanks to Valgrind */
     731               0 :                 memmove((char *) buffer, s, len);
     732               0 :                 ((char *) buffer)[len] = 0;
     733                 :         }
     734               0 :         return result;
     735                 : }
     736                 : 
     737                 : /** Returns the version of the RDBMS in the ODBC format */
     738                 : void
     739                 : odbc_rdbms_version(TDSSOCKET * tds, char *pversion_string)
     740               4 : {
     741               4 :         sprintf(pversion_string, "%.02d.%.02d.%.04d", (int) ((tds->product_version & 0x7F000000) >> 24),
     742                 :                 (int) ((tds->product_version & 0x00FF0000) >> 16), (int) (tds->product_version & 0x0000FFFF));
     743               4 : }
     744                 : 
     745                 : /** Return length of parameter from parameter information */
     746                 : SQLINTEGER
     747                 : odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row)
     748             385 : {
     749                 :         SQLINTEGER len;
     750                 :         int size;
     751                 :         TDS_INTPTR len_offset;
     752                 : 
     753             385 :         if (axd->header.sql_desc_bind_type != SQL_BIND_BY_COLUMN) {
     754               0 :                 len_offset = axd->header.sql_desc_bind_type * n_row;
     755               0 :                 if (axd->header.sql_desc_bind_offset_ptr)
     756               0 :                         len_offset += *axd->header.sql_desc_bind_offset_ptr;
     757                 :         } else {
     758             385 :                 len_offset = sizeof(SQLLEN) * n_row;
     759                 :         }
     760                 : #define LEN(ptr) *((SQLLEN*)(((char*)(ptr)) + len_offset))
     761                 : 
     762             385 :         if (drec_axd->sql_desc_indicator_ptr && LEN(drec_axd->sql_desc_indicator_ptr) == SQL_NULL_DATA)
     763               0 :                 len = SQL_NULL_DATA;
     764             385 :         else if (drec_axd->sql_desc_octet_length_ptr)
     765             379 :                 len = LEN(drec_axd->sql_desc_octet_length_ptr);
     766                 :         else {
     767               6 :                 len = 0;
     768                 :                 /* TODO add XML if defined */
     769                 :                 /* FIXME, other types available */
     770              10 :                 if (drec_axd->sql_desc_concise_type == SQL_C_CHAR || drec_axd->sql_desc_concise_type == SQL_C_BINARY) {
     771               4 :                         len = SQL_NTS;
     772                 :                 } else {
     773               2 :                         int type = drec_axd->sql_desc_concise_type;
     774                 : 
     775               2 :                         if (type == SQL_C_DEFAULT)
     776               0 :                                 type = odbc_sql_to_c_type_default(drec_ixd->sql_desc_concise_type);
     777               2 :                         type = odbc_c_to_server_type(type);
     778                 : 
     779                 :                         /* FIXME check what happen to DATE/TIME types */
     780               2 :                         size = tds_get_size_by_type(type);
     781               2 :                         if (size > 0)
     782               2 :                                 len = size;
     783                 :                 }
     784                 :         }
     785             385 :         return len;
     786                 : #undef LEN
     787                 : }
     788                 : 
     789                 : #ifdef SQL_GUID
     790                 : # define TYPE_NORMAL_SQL_GUID TYPE_NORMAL(SQL_GUID)
     791                 : #else
     792                 : # define TYPE_NORMAL_SQL_GUID
     793                 : #endif
     794                 : #define SQL_TYPES \
     795                 :         TYPE_NORMAL(SQL_BIT) \
     796                 :         TYPE_NORMAL(SQL_SMALLINT) \
     797                 :         TYPE_NORMAL(SQL_TINYINT) \
     798                 :         TYPE_NORMAL(SQL_INTEGER) \
     799                 :         TYPE_NORMAL(SQL_BIGINT) \
     800                 : \
     801                 :         TYPE_NORMAL_SQL_GUID \
     802                 : \
     803                 :         TYPE_NORMAL(SQL_BINARY) \
     804                 :         TYPE_NORMAL(SQL_VARBINARY) \
     805                 :         TYPE_NORMAL(SQL_LONGVARBINARY) \
     806                 : \
     807                 :         TYPE_NORMAL(SQL_CHAR) \
     808                 :         TYPE_NORMAL(SQL_VARCHAR) \
     809                 :         TYPE_NORMAL(SQL_LONGVARCHAR) \
     810                 : \
     811                 :         TYPE_NORMAL(SQL_DECIMAL) \
     812                 :         TYPE_NORMAL(SQL_NUMERIC) \
     813                 : \
     814                 :         TYPE_NORMAL(SQL_FLOAT) \
     815                 :         TYPE_NORMAL(SQL_REAL) \
     816                 :         TYPE_NORMAL(SQL_DOUBLE)\
     817                 : \
     818                 :         TYPE_VERBOSE_START(SQL_DATETIME) \
     819                 :         TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_TIMESTAMP, SQL_TYPE_TIMESTAMP, SQL_TIMESTAMP) \
     820                 :         TYPE_VERBOSE_END(SQL_DATETIME)
     821                 : 
     822                 : SQLSMALLINT
     823                 : odbc_get_concise_sql_type(SQLSMALLINT type, SQLSMALLINT interval)
     824           50910 : {
     825                 : #define TYPE_NORMAL(t) case t: return type;
     826                 : #define TYPE_VERBOSE_START(t) \
     827                 :         case t: switch (interval) {
     828                 : #define TYPE_VERBOSE_DATE(t, interval, concise, old) \
     829                 :         case interval: return concise;
     830                 : #define TYPE_VERBOSE_END(t) \
     831                 :         }
     832                 : 
     833           50910 :         switch (type) {
     834             232 :                 SQL_TYPES;
     835                 :         }
     836               0 :         return 0;
     837                 : #undef TYPE_NORMAL
     838                 : #undef TYPE_VERBOSE_START
     839                 : #undef TYPE_VERBOSE_DATE
     840                 : #undef TYPE_VERBOSE_END
     841                 : }
     842                 : 
     843                 : /**
     844                 :  * Set concise type and all cascading field.
     845                 :  * @param concise_type concise type to set
     846                 :  * @param drec         record to set. NULL to test error without setting
     847                 :  * @param check_only   it <>0 (true) check only, do not set type
     848                 :  */
     849                 : SQLRETURN
     850                 : odbc_set_concise_sql_type(SQLSMALLINT concise_type, struct _drecord * drec, int check_only)
     851            1719 : {
     852            1719 :         SQLSMALLINT type = concise_type, interval_code = 0;
     853                 : 
     854                 : #define TYPE_NORMAL(t) case t: break;
     855                 : #define TYPE_VERBOSE_START(t)
     856                 : #define TYPE_VERBOSE_DATE(t, interval, concise, old) \
     857                 :         case old: concise_type = concise; \
     858                 :         case concise: type = t; interval_code = interval; break;
     859                 : #define TYPE_VERBOSE_END(t)
     860                 : 
     861            1719 :         switch (type) {
     862              26 :                 SQL_TYPES;
     863                 :         default:
     864              52 :                 return SQL_ERROR;
     865                 :         }
     866            1667 :         if (!check_only) {
     867            1667 :                 drec->sql_desc_concise_type = concise_type;
     868            1667 :                 drec->sql_desc_type = type;
     869            1667 :                 drec->sql_desc_datetime_interval_code = interval_code;
     870                 : 
     871            1667 :                 switch (drec->sql_desc_type) {
     872                 :                 case SQL_NUMERIC:
     873                 :                 case SQL_DECIMAL:
     874              37 :                         drec->sql_desc_precision = 38;
     875              37 :                         drec->sql_desc_scale = 0;
     876                 :                         break;
     877                 :                         /* TODO finish */
     878                 :                 }
     879                 :         }
     880            1667 :         return SQL_SUCCESS;
     881                 : #undef TYPE_NORMAL
     882                 : #undef TYPE_VERBOSE_START
     883                 : #undef TYPE_VERBOSE_DATE
     884                 : #undef TYPE_VERBOSE_END
     885                 : }
     886                 : 
     887                 : #ifdef SQL_C_GUID
     888                 : # define TYPE_NORMAL_SQL_C_GUID TYPE_NORMAL(SQL_C_GUID)
     889                 : #else
     890                 : # define TYPE_NORMAL_SQL_C_GUID
     891                 : #endif
     892                 : #define C_TYPES \
     893                 :         TYPE_NORMAL(SQL_C_BIT) \
     894                 :         TYPE_NORMAL(SQL_C_SHORT) \
     895                 :         TYPE_NORMAL(SQL_C_TINYINT) \
     896                 :         TYPE_NORMAL(SQL_C_UTINYINT) \
     897                 :         TYPE_NORMAL(SQL_C_STINYINT) \
     898                 :         TYPE_NORMAL(SQL_C_LONG) \
     899                 :         TYPE_NORMAL(SQL_C_SBIGINT) \
     900                 :         TYPE_NORMAL(SQL_C_UBIGINT) \
     901                 :         TYPE_NORMAL(SQL_C_SSHORT) \
     902                 :         TYPE_NORMAL(SQL_C_SLONG) \
     903                 :         TYPE_NORMAL(SQL_C_USHORT) \
     904                 :         TYPE_NORMAL(SQL_C_ULONG) \
     905                 : \
     906                 :         TYPE_NORMAL_SQL_C_GUID \
     907                 :         TYPE_NORMAL(SQL_C_DEFAULT) \
     908                 : \
     909                 :         TYPE_NORMAL(SQL_C_BINARY) \
     910                 : \
     911                 :         TYPE_NORMAL(SQL_C_CHAR) \
     912                 : \
     913                 :         TYPE_NORMAL(SQL_C_NUMERIC) \
     914                 : \
     915                 :         TYPE_NORMAL(SQL_C_FLOAT) \
     916                 :         TYPE_NORMAL(SQL_C_DOUBLE)\
     917                 : \
     918                 :         TYPE_VERBOSE_START(SQL_DATETIME) \
     919                 :         TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_DATE, SQL_C_TYPE_DATE, SQL_C_DATE) \
     920                 :         TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_TIME, SQL_C_TYPE_TIME, SQL_C_TIME) \
     921                 :         TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_TIMESTAMP, SQL_C_TYPE_TIMESTAMP, SQL_C_TIMESTAMP) \
     922                 :         TYPE_VERBOSE_END(SQL_DATETIME) \
     923                 : \
     924                 :         TYPE_VERBOSE_START(SQL_INTERVAL) \
     925                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY, SQL_C_INTERVAL_DAY) \
     926                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY_TO_HOUR, SQL_C_INTERVAL_DAY_TO_HOUR) \
     927                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY_TO_MINUTE, SQL_C_INTERVAL_DAY_TO_MINUTE) \
     928                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY_TO_SECOND, SQL_C_INTERVAL_DAY_TO_SECOND) \
     929                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_HOUR, SQL_C_INTERVAL_HOUR) \
     930                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_HOUR_TO_MINUTE, SQL_C_INTERVAL_HOUR_TO_MINUTE) \
     931                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_HOUR_TO_SECOND, SQL_C_INTERVAL_HOUR_TO_SECOND) \
     932                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_MINUTE, SQL_C_INTERVAL_MINUTE) \
     933                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_MINUTE_TO_SECOND, SQL_C_INTERVAL_MINUTE_TO_SECOND) \
     934                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_MONTH, SQL_C_INTERVAL_MONTH) \
     935                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_SECOND, SQL_C_INTERVAL_SECOND) \
     936                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_YEAR, SQL_C_INTERVAL_YEAR) \
     937                 :         TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_YEAR_TO_MONTH, SQL_C_INTERVAL_YEAR_TO_MONTH) \
     938                 :         TYPE_VERBOSE_END(SQL_INTERVAL)
     939                 : 
     940                 : SQLSMALLINT
     941                 : odbc_get_concise_c_type(SQLSMALLINT type, SQLSMALLINT interval)
     942           11180 : {
     943                 : #define TYPE_NORMAL(t) case t: return type;
     944                 : #define TYPE_VERBOSE_START(t) \
     945                 :         case t: switch (interval) {
     946                 : #define TYPE_VERBOSE(t, interval, concise) \
     947                 :         case interval: return concise;
     948                 : #define TYPE_VERBOSE_DATE(t, interval, concise, old) \
     949                 :         case interval: return concise;
     950                 : #define TYPE_VERBOSE_END(t) \
     951                 :         }
     952                 : 
     953           11180 :         switch (type) {
     954              84 :                 C_TYPES;
     955                 :         }
     956               0 :         return 0;
     957                 : #undef TYPE_NORMAL
     958                 : #undef TYPE_VERBOSE_START
     959                 : #undef TYPE_VERBOSE
     960                 : #undef TYPE_VERBOSE_DATE
     961                 : #undef TYPE_VERBOSE_END
     962                 : }
     963                 : 
     964                 : /**
     965                 :  * Set concise type and all cascading field.
     966                 :  * @param concise_type concise type to set
     967                 :  * @param drec         record to set. NULL to test error without setting
     968                 :  * @param check_only   it <>0 (true) check only, do not set type
     969                 :  */
     970                 : SQLRETURN
     971                 : odbc_set_concise_c_type(SQLSMALLINT concise_type, struct _drecord * drec, int check_only)
     972             459 : {
     973             459 :         SQLSMALLINT type = concise_type, interval_code = 0;
     974                 : 
     975                 : #define TYPE_NORMAL(t) case t: break;
     976                 : #define TYPE_VERBOSE_START(t)
     977                 : #define TYPE_VERBOSE(t, interval, concise) \
     978                 :         case concise: type = t; interval_code = interval; break;
     979                 : #define TYPE_VERBOSE_DATE(t, interval, concise, old) \
     980                 :         case concise: type = t; interval_code = interval; break; \
     981                 :         case old: concise_type = concise; type = t; interval_code = interval; break;
     982                 : #define TYPE_VERBOSE_END(t)
     983                 : 
     984             459 :         switch (type) {
     985              10 :                 C_TYPES;
     986                 :         default:
     987              28 :                 return SQL_ERROR;
     988                 :         }
     989             431 :         if (!check_only) {
     990             431 :                 drec->sql_desc_concise_type = concise_type;
     991             431 :                 drec->sql_desc_type = type;
     992             431 :                 drec->sql_desc_datetime_interval_code = interval_code;
     993                 : 
     994             431 :                 switch (drec->sql_desc_type) {
     995                 :                 case SQL_C_NUMERIC:
     996              14 :                         drec->sql_desc_precision = 38;
     997              14 :                         drec->sql_desc_scale = 0;
     998                 :                         break;
     999                 :                         /* TODO finish */
    1000                 :                 }
    1001                 :         }
    1002             431 :         return SQL_SUCCESS;
    1003                 : #undef TYPE_NORMAL
    1004                 : #undef TYPE_VERBOSE_START
    1005                 : #undef TYPE_VERBOSE
    1006                 : #undef TYPE_VERBOSE_DATE
    1007                 : #undef TYPE_VERBOSE_END
    1008                 : }
    1009                 : 
    1010                 : SQLLEN
    1011                 : odbc_get_octet_len(int c_type, const struct _drecord *drec)
    1012             196 : {
    1013                 :         SQLLEN len;
    1014                 : 
    1015                 :         /* this shit is mine -- freddy77 */
    1016             196 :         switch (c_type) {
    1017                 :         case SQL_C_CHAR:
    1018                 :         case SQL_C_BINARY:
    1019              96 :                 len = drec->sql_desc_octet_length;
    1020              96 :                 break;
    1021                 :         case SQL_C_DATE:
    1022                 :         case SQL_C_TYPE_DATE:
    1023               0 :                 len = sizeof(DATE_STRUCT);
    1024               0 :                 break;
    1025                 :         case SQL_C_TIME:
    1026                 :         case SQL_C_TYPE_TIME:
    1027               0 :                 len = sizeof(TIME_STRUCT);
    1028               0 :                 break;
    1029                 :         case SQL_C_TIMESTAMP:
    1030                 :         case SQL_C_TYPE_TIMESTAMP:
    1031               0 :                 len = sizeof(TIMESTAMP_STRUCT);
    1032               0 :                 break;
    1033                 :         case SQL_C_NUMERIC:
    1034               6 :                 len = sizeof(SQL_NUMERIC_STRUCT);
    1035               6 :                 break;
    1036                 :         default:
    1037              94 :                 len = tds_get_size_by_type(odbc_c_to_server_type(c_type));
    1038                 :                 break;
    1039                 :         }
    1040             196 :         return len;
    1041                 : }
    1042                 : 
    1043                 : /** \@} */

Generated by: LTP GCOV extension version 1.6