LTP GCOV extension - code coverage report
Current view: directory - odbc - error.c
Test: FreeTDS coverage
Date: 2008-11-21 Instrumented lines: 291
Code covered: 52.2 % Executed lines: 152

       1                 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2                 :  * Copyright (C) 1998-1999  Brian Bruns
       3                 :  * Copyright (C) 2003, 2004, 2005  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                 : #include <stdio.h>
      26                 : 
      27                 : #if HAVE_STDLIB_H
      28                 : #include <stdlib.h>
      29                 : #endif /* HAVE_STDLIB_H */
      30                 : 
      31                 : #if HAVE_STRING_H
      32                 : #include <string.h>
      33                 : #endif /* HAVE_STRING_H */
      34                 : 
      35                 : #include <assert.h>
      36                 : 
      37                 : #include "tdsodbc.h"
      38                 : #include "tdsstring.h"
      39                 : #include "replacements.h"
      40                 : 
      41                 : #if HAVE_ODBCSS_H
      42                 : #include <odbcss.h>
      43                 : #endif
      44                 : 
      45                 : #ifdef DMALLOC
      46                 : #include <dmalloc.h>
      47                 : #endif
      48                 : 
      49                 : TDS_RCSID(var, "$Id: error.c,v 1.43 2005/07/17 07:48:10 freddy77 Exp $");
      50                 : 
      51                 : static void odbc_errs_pop(struct _sql_errors *errs);
      52                 : static const char *odbc_get_msg(const char *sqlstate);
      53                 : static void odbc_get_v2state(const char *sqlstate, char *dest_state);
      54                 : static void sqlstate2to3(char *state);
      55                 : 
      56                 : struct s_SqlMsgMap
      57                 : {
      58                 :         const char *msg;
      59                 :         char sqlstate[6];
      60                 : };
      61                 : 
      62                 : /* This list contains both v2 and v3 messages */
      63                 : #define ODBCERR(s3,msg) { msg, s3 }
      64                 : static const struct s_SqlMsgMap SqlMsgMap[] = {
      65                 :         ODBCERR("IM007", "No data source or driver specified"),
      66                 :         ODBCERR("01000", "Warning"),
      67                 :         ODBCERR("01002", "Disconnect error"),
      68                 :         ODBCERR("01004", "Data truncated"),
      69                 :         ODBCERR("01504", "The UPDATE or DELETE statement does not include a WHERE clause"),
      70                 :         ODBCERR("01508", "Statement disqualified for blocking"),
      71                 :         ODBCERR("01S00", "Invalid connection string attribute"),
      72                 :         ODBCERR("01S01", "Error in row"),
      73                 :         ODBCERR("01S02", "Option value changed"),
      74                 :         ODBCERR("01S06", "Attempt to fetch before the result set returned the first rowset"),
      75                 :         ODBCERR("01S07", "Fractional truncation"),
      76                 :         ODBCERR("07001", "Wrong number of parameters"),
      77                 :         ODBCERR("07002", "Too many columns"),
      78                 :         ODBCERR("07005", "The statement did not return a result set"),
      79                 :         ODBCERR("07006", "Invalid conversion"),
      80                 :         ODBCERR("07009", "Invalid descriptor index"),
      81                 :         ODBCERR("08001", "Unable to connect to data source"),
      82                 :         ODBCERR("08002", "Connection in use"),
      83                 :         ODBCERR("08003", "Connection is closed"),
      84                 :         ODBCERR("08004", "The application server rejected establishment of the connection"),
      85                 :         ODBCERR("08007", "Connection failure during transaction"),
      86                 :         ODBCERR("08S01", "Communication link failure"),
      87                 :         ODBCERR("0F001", "The LOB token variable does not currently represent any value"),
      88                 :         ODBCERR("21S01", "Insert value list does not match column list"),
      89                 :         ODBCERR("22001", "String data right truncation"),
      90                 :         ODBCERR("22002", "Invalid output or indicator buffer specified"),
      91                 :         ODBCERR("22003", "Numeric value out of range"),
      92                 :         ODBCERR("22005", "Error in assignment"),
      93                 :         ODBCERR("22007", "Invalid datetime format"),
      94                 :         ODBCERR("22008", "Datetime field overflow"),
      95                 :         ODBCERR("22011", "A substring error occurred"),
      96                 :         ODBCERR("22012", "Division by zero is invalid"),
      97                 :         ODBCERR("22015", "Interval field overflow"),
      98                 :         ODBCERR("22018", "Invalid character value for cast specification"),
      99                 :         ODBCERR("22019", "Invalid escape character"),
     100                 :         ODBCERR("22025", "Invalid escape sequence"),
     101                 :         ODBCERR("22026", "String data, length mismatch"),
     102                 :         ODBCERR("23000", "Integrity constraint violation"),
     103                 :         ODBCERR("24000", "Invalid cursor state"),
     104                 :         ODBCERR("24504", "The cursor identified in the UPDATE, DELETE, SET, or GET statement is not positioned on a row"),
     105                 :         ODBCERR("25501", "Invalid transaction state"),
     106                 :         ODBCERR("28000", "Invalid authorization specification"),
     107                 :         ODBCERR("34000", "Invalid cursor name"),
     108                 :         ODBCERR("37000", "Invalid SQL syntax"),
     109                 :         ODBCERR("40001", "Serialization failure"),
     110                 :         ODBCERR("40003", "Statement completion unknown"),
     111                 :         ODBCERR("42000", "Syntax error or access violation"),
     112                 :         ODBCERR("42601", "PARMLIST syntax error"),
     113                 :         ODBCERR("42818", "The operands of an operator or function are not compatible"),
     114                 :         ODBCERR("42895", "The value of a host variable in the EXECUTE or OPEN statement cannot be used because of its data type"),
     115                 :         ODBCERR("428A1", "Unable to access a file referenced by a host file variable"),
     116                 :         ODBCERR("44000", "Integrity constraint violation"),
     117                 :         ODBCERR("54028", "The maximum number of concurrent LOB handles has been reached"),
     118                 :         ODBCERR("56084", "LOB data is not supported in DRDA"),
     119                 :         ODBCERR("58004", "Unexpected system failure"),
     120                 :         ODBCERR("HY000", "General driver error"),
     121                 :         ODBCERR("HY001", "Memory allocation failure"),
     122                 :         ODBCERR("HY002", "Invalid column number"),
     123                 :         ODBCERR("HY003", "Program type out of range"),
     124                 :         ODBCERR("HY004", "Invalid data type"),
     125                 :         ODBCERR("HY007", "Associated statement is not prepared"),
     126                 :         ODBCERR("HY008", "Operation was cancelled"),
     127                 :         ODBCERR("HY009", "Invalid argument value"),
     128                 :         ODBCERR("HY010", "Function sequence error"),
     129                 :         ODBCERR("HY011", "Operation invalid at this time"),
     130                 :         ODBCERR("HY012", "Invalid transaction code"),
     131                 :         ODBCERR("HY013", "Unexpected memory handling error"),
     132                 :         ODBCERR("HY014", "No more handles"),
     133                 :         ODBCERR("HY016", "Cannot modify an implementation row descriptor"),
     134                 :         ODBCERR("HY017", "Invalid use of an automatically allocated descriptor handle"),
     135                 :         ODBCERR("HY018", "Server declined cancel request"),
     136                 :         ODBCERR("HY021", "Inconsistent descriptor information"),
     137                 :         ODBCERR("HY024", "Invalid attribute value"),
     138                 :         ODBCERR("HY090", "Invalid string or buffer length"),
     139                 :         ODBCERR("HY091", "Descriptor type out of range"),
     140                 :         ODBCERR("HY092", "Invalid option"),
     141                 :         ODBCERR("HY093", "Invalid parameter number"),
     142                 :         ODBCERR("HY094", "Invalid scale value"),
     143                 :         ODBCERR("HY096", "Information type out of range"),
     144                 :         ODBCERR("HY097", "Column type out of range"),
     145                 :         ODBCERR("HY098", "Scope type out of range"),
     146                 :         ODBCERR("HY099", "Nullable type out of range"),
     147                 :         ODBCERR("HY100", "Uniqueness option type out of range"),
     148                 :         ODBCERR("HY101", "Accuracy option type out of range"),
     149                 :         ODBCERR("HY103", "Direction option out of range"),
     150                 :         ODBCERR("HY104", "Invalid precision value"),
     151                 :         ODBCERR("HY105", "Invalid parameter type"),
     152                 :         ODBCERR("HY106", "Fetch type out of range"),
     153                 :         ODBCERR("HY107", "Row value out of range"),
     154                 :         ODBCERR("HY109", "Invalid cursor position"),
     155                 :         ODBCERR("HY110", "Invalid driver completion"),
     156                 :         ODBCERR("HY111", "Invalid bookmark value"),
     157                 :         ODBCERR("HY501", "Invalid data source name"),
     158                 :         ODBCERR("HY503", "Invalid file name length"),
     159                 :         ODBCERR("HY506", "Error closing a file"),
     160                 :         ODBCERR("HY509", "Error deleting a file"),
     161                 :         ODBCERR("HYC00", "Driver not capable"),
     162                 :         ODBCERR("HYT00", "Timeout expired"),
     163                 :         ODBCERR("HYT01", "Connection timeout expired"),
     164                 :         ODBCERR("S0001", "Database object already exists"),
     165                 :         ODBCERR("S0002", "Database object does not exist"),
     166                 :         ODBCERR("S0011", "Index already exists"),
     167                 :         ODBCERR("S0012", "Index not found"),
     168                 :         ODBCERR("S0021", "Column already exists"),
     169                 :         ODBCERR("S0022", "Column not found"),
     170                 :         ODBCERR("", NULL)
     171                 : };
     172                 : 
     173                 : #undef ODBCERR
     174                 : 
     175                 : struct s_v3to2map
     176                 : {
     177                 :         char v3[6];
     178                 :         char v2[6];
     179                 : };
     180                 : 
     181                 : /* Map a v3 SQLSTATE to a v2 */
     182                 : static const struct s_v3to2map v3to2map[] = {
     183                 :         {"01001", "01S03"},
     184                 :         {"01001", "01S04"},
     185                 :         {"HY019", "22003"},
     186                 :         {"22007", "22008"},
     187                 :         {"22018", "22005"},
     188                 :         {"07005", "24000"},
     189                 :         {"42000", "37000"},
     190                 :         {"HY018", "70100"},
     191                 :         {"42S01", "S0001"},
     192                 :         {"42S02", "S0002"},
     193                 :         {"42S11", "S0011"},
     194                 :         {"42S12", "S0012"},
     195                 :         {"42S21", "S0021"},
     196                 :         {"42S22", "S0022"},
     197                 :         {"42S23", "S0023"},
     198                 :         {"HY000", "S1000"},
     199                 :         {"HY001", "S1001"},
     200                 :         {"07009", "S1002"},
     201                 :         {"HY003", "S1003"},
     202                 :         {"HY004", "S1004"},
     203                 :         {"HY008", "S1008"},
     204                 :         {"HY009", "S1009"},
     205                 :         {"HY024", "S1009"},
     206                 :         {"HY007", "S1010"},
     207                 :         {"HY010", "S1010"},
     208                 :         {"HY011", "S1011"},
     209                 :         {"HY012", "S1012"},
     210                 :         {"HY090", "S1090"},
     211                 :         {"HY091", "S1091"},
     212                 :         {"HY092", "S1092"},
     213                 : /*      {"07009", "S1093"}, */
     214                 :         {"HY096", "S1096"},
     215                 :         {"HY097", "S1097"},
     216                 :         {"HY098", "S1098"},
     217                 :         {"HY099", "S1099"},
     218                 :         {"HY100", "S1100"},
     219                 :         {"HY101", "S1101"},
     220                 :         {"HY103", "S1103"},
     221                 :         {"HY104", "S1104"},
     222                 :         {"HY105", "S1105"},
     223                 :         {"HY106", "S1106"},
     224                 :         {"HY107", "S1107"},
     225                 :         {"HY108", "S1108"},
     226                 :         {"HY109", "S1109"},
     227                 :         {"HY110", "S1110"},
     228                 :         {"HY111", "S1111"},
     229                 :         {"HYC00", "S1C00"},
     230                 :         {"HYT00", "S1T00"},
     231                 :         {"08001", "S1000"},
     232                 :         {"IM007", "S1000"},
     233                 :         {"", ""}
     234                 : };
     235                 : 
     236                 : /* 
     237                 :  * ODBC messages must be sorted by importance
     238                 :  * 1. Errors regarding the status of a transaction
     239                 :  * 2. Other errors (level ordered)
     240                 :  * 3. No-Data messages with a state class of 02 ??
     241                 :  * 4. Warning
     242                 :  * 5. Informational
     243                 :  */
     244                 : static void
     245                 : rank_errors(struct _sql_errors *errs)
     246              40 : {
     247                 :         int settled, current, best;
     248                 :         struct _sql_error swapbuf;
     249                 :         char istrans;
     250                 : 
     251              40 :         if (errs->ranked == 0 && errs->num_errors > 1) {
     252                 :                 /* Find the highest of all unranked errors until there are none left */
     253              12 :                 for (settled = 0; settled < errs->num_errors; settled++) {
     254               8 :                         best = -1;
     255              20 :                         for (current = settled; current < errs->num_errors; current++) {
     256              12 :                                 istrans = 0;
     257              12 :                                 switch (errs->errs[current].native) {
     258                 :                                 case 1205:
     259                 :                                 case 1211:
     260                 :                                 case 2625:
     261                 :                                 case 3309:
     262                 :                                 case 7112:
     263                 :                                 case 266:
     264                 :                                 case 277:
     265                 :                                 case 611:
     266                 :                                 case 628:
     267                 :                                 case 3902:
     268                 :                                 case 3903:
     269                 :                                 case 3906:
     270                 :                                 case 3908:
     271                 :                                 case 6401:
     272               0 :                                         istrans = 1;
     273                 :                                         break;
     274                 :                                 }
     275                 : 
     276              12 :                                 if (istrans == 0) {
     277              12 :                                         if (strcmp(errs->errs[current].state3,"25000") == 0)
     278               0 :                                                 istrans = 1;
     279              12 :                                         else if (strcmp(errs->errs[current].state3,"S1012") == 0)
     280               0 :                                                 istrans = 1;
     281              12 :                                         else if (strcmp(errs->errs[current].state3,"08007") == 0)
     282               0 :                                                 istrans = 1;
     283                 :                                 }
     284                 : 
     285                 :                                 /* Transaction errors are always best */
     286              12 :                                 if (istrans == 1 && errs->errs[current].msgstate >= 10)   {
     287               0 :                                         best = current;
     288               0 :                                         break;
     289                 :                                 }
     290                 : 
     291              12 :                                 if (best == -1)
     292               8 :                                         best = current;
     293                 : 
     294                 :                                 /* Non-terminating comparisons only below this point */
     295              12 :                                 if (errs->errs[current].msgstate > errs->errs[best].msgstate)
     296               0 :                                         best = current;
     297                 :                         }
     298                 : 
     299                 :                         /* swap settled position with best */
     300               8 :                         if (best != settled) {
     301               0 :                                 swapbuf = errs->errs[settled];
     302               0 :                                 errs->errs[settled] = errs->errs[best];
     303               0 :                                 errs->errs[best] = swapbuf;
     304                 :                         }
     305                 :                 }
     306                 :         }
     307              40 :         errs->ranked = 1;
     308              40 : }
     309                 : 
     310                 : static const char *
     311                 : odbc_get_msg(const char *sqlstate)
     312             119 : {
     313             119 :         const struct s_SqlMsgMap *pmap = SqlMsgMap;
     314                 : 
     315                 :         /* TODO set flag and use pointers (no strdup) ?? */
     316            7288 :         while (pmap->msg) {
     317            7169 :                 if (!strcasecmp(sqlstate, pmap->sqlstate)) {
     318             119 :                         return strdup(pmap->msg);
     319                 :                 }
     320            7050 :                 ++pmap;
     321                 :         }
     322               0 :         return strdup("");
     323                 : }
     324                 : 
     325                 : static void
     326                 : odbc_get_v2state(const char *sqlstate, char *dest_state)
     327             125 : {
     328             125 :         const struct s_v3to2map *pmap = v3to2map;
     329                 : 
     330            5833 :         while (pmap->v3[0]) {
     331            5609 :                 if (!strcasecmp(pmap->v3, sqlstate)) {
     332              26 :                         tds_strlcpy(dest_state, pmap->v2, 6);
     333              26 :                         return;
     334                 :                 }
     335            5583 :                 ++pmap;
     336                 :         }
     337                 :         /* return the original if a v2 state is not found */
     338              99 :         tds_strlcpy(dest_state, sqlstate, 6);
     339                 : }
     340                 : 
     341                 : void
     342                 : odbc_errs_reset(struct _sql_errors *errs)
     343            7070 : {
     344                 :         int i;
     345                 : 
     346            7070 :         if (errs->errs) {
     347             981 :                 for (i = 0; i < errs->num_errors; ++i) {
     348                 :                         /* TODO see flags */
     349             596 :                         if (errs->errs[i].msg)
     350             596 :                                 free((char *) errs->errs[i].msg);
     351             596 :                         if (errs->errs[i].server)
     352             596 :                                 free(errs->errs[i].server);
     353                 :                 }
     354             385 :                 TDS_ZERO_FREE(errs->errs);
     355             385 :                 errs->num_errors = 0;
     356                 :         }
     357            7070 :         errs->lastrc = SQL_SUCCESS;
     358            7070 :         errs->ranked = 0;
     359            7070 :         assert(errs->num_errors == 0);
     360            7070 : }
     361                 : 
     362                 : /** Remove first element */
     363                 : static void
     364                 : odbc_errs_pop(struct _sql_errors *errs)
     365               0 : {
     366               0 :         if (!errs || !errs->errs || errs->num_errors <= 0)
     367               0 :                 return;
     368                 : 
     369               0 :         if (errs->num_errors == 1) {
     370               0 :                 odbc_errs_reset(errs);
     371               0 :                 return;
     372                 :         }
     373                 : 
     374                 :         /* TODO see flags */
     375               0 :         if (errs->errs[0].msg)
     376               0 :                 free((char *) errs->errs[0].msg);
     377               0 :         if (errs->errs[0].server)
     378               0 :                 free(errs->errs[0].server);
     379                 : 
     380               0 :         --errs->num_errors;
     381               0 :         memmove(&(errs->errs[0]), &(errs->errs[1]), errs->num_errors * sizeof(errs->errs[0]));
     382                 : }
     383                 : 
     384                 : void
     385                 : odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
     386             125 : {
     387                 :         struct _sql_error *p;
     388             125 :         int n = errs->num_errors;
     389                 : 
     390             125 :         assert(sqlstate);
     391                 : 
     392             125 :         if (errs->errs)
     393               2 :                 p = (struct _sql_error *) realloc(errs->errs, sizeof(struct _sql_error) * (n + 1));
     394                 :         else
     395             123 :                 p = (struct _sql_error *) malloc(sizeof(struct _sql_error));
     396             125 :         if (!p)
     397               0 :                 return;
     398             125 :         errs->errs = p;
     399                 : 
     400             125 :         memset(&errs->errs[n], 0, sizeof(struct _sql_error));
     401             125 :         errs->errs[n].native = 0;
     402             125 :         tds_strlcpy(errs->errs[n].state3, sqlstate, 6);
     403             125 :         odbc_get_v2state(errs->errs[n].state3, errs->errs[n].state2);
     404                 : 
     405                 :         /* TODO why driver ?? -- freddy77 */
     406             125 :         errs->errs[n].server = strdup("DRIVER");
     407             125 :         errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
     408             125 :         ++errs->num_errors;
     409                 : }
     410                 : 
     411                 : /* TODO check if TDS_UINT is correct for native error */
     412                 : void
     413                 : odbc_errs_add_rdbms(struct _sql_errors *errs, TDS_UINT native, const char *sqlstate, const char *msg, int linenum, int msgstate,
     414                 :                     const char *server)
     415             471 : {
     416                 :         struct _sql_error *p;
     417             471 :         int n = errs->num_errors;
     418                 : 
     419             471 :         if (errs->errs)
     420             209 :                 p = (struct _sql_error *) realloc(errs->errs, sizeof(struct _sql_error) * (n + 1));
     421                 :         else
     422             262 :                 p = (struct _sql_error *) malloc(sizeof(struct _sql_error));
     423             471 :         if (!p)
     424               0 :                 return;
     425             471 :         errs->errs = p;
     426                 : 
     427             471 :         memset(&errs->errs[n], 0, sizeof(struct _sql_error));
     428             471 :         errs->errs[n].native = native;
     429             471 :         if (sqlstate)
     430             471 :                 tds_strlcpy(errs->errs[n].state2, sqlstate, 6);
     431                 :         else
     432               0 :                 errs->errs[n].state2[0] = '\0';
     433             471 :         strcpy(errs->errs[n].state3, errs->errs[n].state2);
     434             471 :         sqlstate2to3(errs->errs[n].state3);
     435                 : 
     436                 :         /* TODO why driver ?? -- freddy77 */
     437             471 :         errs->errs[n].server = (server) ? strdup(server) : strdup("DRIVER");
     438             471 :         errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
     439             471 :         errs->errs[n].linenum = linenum;
     440             471 :         errs->errs[n].msgstate = msgstate;
     441             471 :         ++errs->num_errors;
     442                 : }
     443                 : 
     444                 : #define SQLS_MAP(v2,v3) if (strcmp(p,v2) == 0) {strcpy(p,v3); return;}
     445                 : static void
     446                 : sqlstate2to3(char *state)
     447             471 : {
     448             471 :         char *p = state;
     449                 : 
     450             471 :         if (p[0] == 'S' && p[1] == '0' && p[2] == '0') {
     451              39 :                 p[0] = '4';
     452              39 :                 p[1] = '2';
     453              39 :                 p[2] = 'S';
     454              39 :                 return;
     455                 :         }
     456                 : 
     457                 :         /* TODO optimize with a switch */
     458             432 :         SQLS_MAP("01S03", "01001");
     459             432 :         SQLS_MAP("01S04", "01001");
     460             432 :         SQLS_MAP("22003", "HY019");
     461             392 :         SQLS_MAP("22008", "22007");
     462             388 :         SQLS_MAP("22005", "22018");
     463             386 :         SQLS_MAP("24000", "07005");
     464             386 :         SQLS_MAP("37000", "42000");
     465             386 :         SQLS_MAP("70100", "HY018");
     466             386 :         SQLS_MAP("S1000", "HY000");
     467             386 :         SQLS_MAP("S1001", "HY001");
     468             386 :         SQLS_MAP("S1002", "07009");
     469             386 :         SQLS_MAP("S1003", "HY003");
     470             386 :         SQLS_MAP("S1004", "HY004");
     471             386 :         SQLS_MAP("S1008", "HY008");
     472             386 :         SQLS_MAP("S1009", "HY009");
     473             386 :         SQLS_MAP("S1010", "HY007");
     474             386 :         SQLS_MAP("S1011", "HY011");
     475             386 :         SQLS_MAP("S1012", "HY012");
     476             386 :         SQLS_MAP("S1090", "HY090");
     477             386 :         SQLS_MAP("S1091", "HY091");
     478             386 :         SQLS_MAP("S1092", "HY092");
     479             386 :         SQLS_MAP("S1093", "07009");
     480             386 :         SQLS_MAP("S1096", "HY096");
     481             386 :         SQLS_MAP("S1097", "HY097");
     482             386 :         SQLS_MAP("S1098", "HY098");
     483             386 :         SQLS_MAP("S1099", "HY099");
     484             386 :         SQLS_MAP("S1100", "HY100");
     485             386 :         SQLS_MAP("S1101", "HY101");
     486             386 :         SQLS_MAP("S1103", "HY103");
     487             386 :         SQLS_MAP("S1104", "HY104");
     488             386 :         SQLS_MAP("S1105", "HY105");
     489             386 :         SQLS_MAP("S1106", "HY106");
     490             386 :         SQLS_MAP("S1107", "HY107");
     491             386 :         SQLS_MAP("S1108", "HY108");
     492             386 :         SQLS_MAP("S1109", "HY109");
     493             386 :         SQLS_MAP("S1110", "HY110");
     494             386 :         SQLS_MAP("S1111", "HY111");
     495             386 :         SQLS_MAP("S1C00", "HYC00");
     496             386 :         SQLS_MAP("S1T00", "HYT00");
     497                 : }
     498                 : 
     499                 : static SQLRETURN
     500                 : _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR FAR * szSqlState,
     501                 :                SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
     502              40 : {
     503                 :         SQLRETURN result;
     504              40 :         struct _sql_errors *errs = NULL;
     505                 :         const char *msg;
     506                 :         char *p;
     507                 : 
     508                 :         static const char msgprefix[] = "[FreeTDS][SQL Server]";
     509                 : 
     510              40 :         SQLINTEGER odbc_ver = SQL_OV_ODBC2;
     511                 : 
     512              40 :         if (numRecord <= 0 || cbErrorMsgMax < 0)
     513               0 :                 return SQL_ERROR;
     514                 : 
     515              40 :         if (!handle)
     516               0 :                 return SQL_INVALID_HANDLE;
     517                 : 
     518              40 :         switch (handleType) {
     519                 :         case SQL_HANDLE_STMT:
     520              38 :                 odbc_ver = ((TDS_STMT *) handle)->dbc->env->attr.odbc_version;
     521              38 :                 errs = &((TDS_STMT *) handle)->errs;
     522              38 :                 break;
     523                 : 
     524                 :         case SQL_HANDLE_DBC:
     525               2 :                 odbc_ver = ((TDS_DBC *) handle)->env->attr.odbc_version;
     526               2 :                 errs = &((TDS_DBC *) handle)->errs;
     527               2 :                 break;
     528                 : 
     529                 :         case SQL_HANDLE_ENV:
     530               0 :                 odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version;
     531               0 :                 errs = &((TDS_ENV *) handle)->errs;
     532               0 :                 break;
     533                 : 
     534                 :         default:
     535               0 :                 return SQL_INVALID_HANDLE;
     536                 :         }
     537                 : 
     538              40 :         if (numRecord > errs->num_errors)
     539               0 :                 return SQL_NO_DATA_FOUND;
     540              40 :         --numRecord;
     541                 : 
     542              40 :         rank_errors(errs);
     543                 : 
     544              40 :         if (szSqlState) {
     545              16 :                 if (odbc_ver == SQL_OV_ODBC3)
     546               2 :                         strcpy((char *) szSqlState, errs->errs[numRecord].state3);
     547                 :                 else
     548              14 :                         strcpy((char *) szSqlState, errs->errs[numRecord].state2);
     549                 :         }
     550                 : 
     551              40 :         msg = errs->errs[numRecord].msg;
     552                 : 
     553              40 :         if (asprintf(&p, "%s%s", msgprefix, msg) < 0)
     554               0 :                 return SQL_ERROR;
     555              40 :         result = odbc_set_string(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1);
     556              40 :         free(p);
     557                 : 
     558              40 :         if (pfNativeError)
     559               4 :                 *pfNativeError = errs->errs[numRecord].native;
     560                 : 
     561              40 :         return result;
     562                 : }
     563                 : 
     564                 : SQLRETURN SQL_API
     565                 : SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, SQLINTEGER FAR * pfNativeError,
     566                 :          SQLCHAR FAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
     567               0 : {
     568                 :         SQLRETURN result;
     569               0 :         struct _sql_errors *errs = NULL;
     570                 :         SQLSMALLINT type;
     571                 :         SQLHANDLE handle;
     572                 : 
     573               0 :         if (hstmt) {
     574               0 :                 errs = &((TDS_STMT *) hstmt)->errs;
     575               0 :                 handle = hstmt;
     576               0 :                 type = SQL_HANDLE_STMT;
     577               0 :         } else if (hdbc) {
     578               0 :                 errs = &((TDS_DBC *) hdbc)->errs;
     579               0 :                 handle = hdbc;
     580               0 :                 type = SQL_HANDLE_DBC;
     581               0 :         } else if (henv) {
     582               0 :                 errs = &((TDS_ENV *) henv)->errs;
     583               0 :                 handle = henv;
     584               0 :                 type = SQL_HANDLE_ENV;
     585                 :         } else
     586               0 :                 return SQL_INVALID_HANDLE;
     587                 : 
     588               0 :         rank_errors(errs);
     589                 : 
     590               0 :         result = _SQLGetDiagRec(type, handle, 1, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
     591                 : 
     592               0 :         if (result == SQL_SUCCESS) {
     593                 :                 /* remove first error */
     594               0 :                 odbc_errs_pop(errs);
     595                 :         }
     596                 : 
     597               0 :         return result;
     598                 : }
     599                 : 
     600                 : #if (ODBCVER >= 0x0300)
     601                 : SQLRETURN SQL_API
     602                 : SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR FAR * szSqlState,
     603                 :               SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
     604              40 : {
     605              40 :         return _SQLGetDiagRec(handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
     606                 : }
     607                 : 
     608                 : SQLRETURN SQL_API
     609                 : SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLSMALLINT diagIdentifier, SQLPOINTER buffer,
     610                 :                 SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer)
     611               0 : {
     612               0 :         SQLRETURN result = SQL_SUCCESS;
     613               0 :         struct _sql_errors *errs = NULL;
     614                 :         const char *msg;
     615                 : 
     616               0 :         SQLINTEGER odbc_ver = SQL_OV_ODBC2;
     617                 :         int cplen;
     618               0 :         TDS_STMT *stmt = NULL;
     619               0 :         TDS_DBC *dbc = NULL;
     620               0 :         TDS_ENV *env = NULL;
     621                 :         char tmp[16];
     622                 : 
     623               0 :         if (cbBuffer < 0)
     624               0 :                 return SQL_ERROR;
     625                 : 
     626               0 :         if (!handle)
     627               0 :                 return SQL_INVALID_HANDLE;
     628                 : 
     629               0 :         switch (handleType) {
     630                 :         case SQL_HANDLE_STMT:
     631               0 :                 stmt = ((TDS_STMT *) handle);
     632               0 :                 dbc = stmt->dbc;
     633               0 :                 env = dbc->env;
     634               0 :                 errs = &stmt->errs;
     635               0 :                 break;
     636                 : 
     637                 :         case SQL_HANDLE_DBC:
     638               0 :                 dbc = ((TDS_DBC *) handle);
     639               0 :                 env = dbc->env;
     640               0 :                 errs = &dbc->errs;
     641               0 :                 break;
     642                 : 
     643                 :         case SQL_HANDLE_ENV:
     644               0 :                 env = ((TDS_ENV *) handle);
     645               0 :                 errs = &env->errs;
     646               0 :                 break;
     647                 : 
     648                 :         default:
     649               0 :                 return SQL_INVALID_HANDLE;
     650                 :         }
     651               0 :         odbc_ver = env->attr.odbc_version;
     652                 : 
     653                 :         /* header (numRecord ignored) */
     654               0 :         switch (diagIdentifier) {
     655                 :         case SQL_DIAG_DYNAMIC_FUNCTION:
     656               0 :                 if (handleType != SQL_HANDLE_STMT)
     657               0 :                         return SQL_ERROR;
     658                 : 
     659                 :                 /* TODO */
     660               0 :                 return odbc_set_string(buffer, cbBuffer, pcbBuffer, "", 0);
     661                 : 
     662                 :         case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
     663               0 :                 *(SQLINTEGER *) buffer = 0;
     664               0 :                 return SQL_SUCCESS;
     665                 : 
     666                 :         case SQL_DIAG_NUMBER:
     667               0 :                 *(SQLINTEGER *) buffer = errs->num_errors;
     668               0 :                 return SQL_SUCCESS;
     669                 : 
     670                 :         case SQL_DIAG_RETURNCODE:
     671               0 :                 *(SQLRETURN *) buffer = errs->lastrc;
     672               0 :                 return SQL_SUCCESS;
     673                 : 
     674                 :         case SQL_DIAG_CURSOR_ROW_COUNT:
     675               0 :                 if (handleType != SQL_HANDLE_STMT)
     676               0 :                         return SQL_ERROR;
     677                 : 
     678                 :                 /* TODO */
     679               0 :                 *(SQLINTEGER *) buffer = 0;
     680               0 :                 return SQL_SUCCESS;
     681                 : 
     682                 :         case SQL_DIAG_ROW_COUNT:
     683               0 :                 if (handleType != SQL_HANDLE_STMT)
     684               0 :                         return SQL_ERROR;
     685                 : 
     686               0 :                 return _SQLRowCount((SQLHSTMT) handle, (SQLLEN FAR *) buffer);
     687                 :         }
     688                 : 
     689               0 :         if (numRecord > errs->num_errors)
     690               0 :                 return SQL_NO_DATA_FOUND;
     691                 : 
     692               0 :         if (numRecord <= 0)
     693               0 :                 return SQL_ERROR;
     694               0 :         --numRecord;
     695                 : 
     696               0 :         switch (diagIdentifier) {
     697                 :         case SQL_DIAG_ROW_NUMBER:
     698               0 :                 *(SQLINTEGER *) buffer = SQL_ROW_NUMBER_UNKNOWN;
     699               0 :                 break;
     700                 : 
     701                 :         case SQL_DIAG_CLASS_ORIGIN:
     702                 :         case SQL_DIAG_SUBCLASS_ORIGIN:
     703               0 :                 if (odbc_ver == SQL_OV_ODBC2)
     704               0 :                         result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ISO 9075", -1);
     705                 :                 else
     706               0 :                         result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1);
     707               0 :                 break;
     708                 : 
     709                 :         case SQL_DIAG_COLUMN_NUMBER:
     710               0 :                 *(SQLINTEGER *) buffer = SQL_COLUMN_NUMBER_UNKNOWN;
     711               0 :                 break;
     712                 : 
     713                 : #ifdef SQL_DIAG_SS_MSGSTATE
     714                 :         case SQL_DIAG_SS_MSGSTATE:
     715                 :                 if (errs->errs[numRecord].msgstate == 0)
     716                 :                         return SQL_ERROR;
     717                 :                 else
     718                 :                         *(SQLINTEGER *) buffer = errs->errs[numRecord].msgstate;
     719                 :                 break;
     720                 : #endif
     721                 : 
     722                 : #ifdef SQL_DIAG_SS_LINE
     723                 :         case SQL_DIAG_SS_LINE:
     724                 :                 if (errs->errs[numRecord].linenum == 0)
     725                 :                         return SQL_ERROR;
     726                 :                 else
     727                 :                         *(SQLUSMALLINT *) buffer = errs->errs[numRecord].linenum;
     728                 :                 break;
     729                 : #endif
     730                 : 
     731                 :         case SQL_DIAG_CONNECTION_NAME:
     732               0 :                 if (dbc && dbc->tds_socket && dbc->tds_socket->spid > 0)
     733               0 :                         cplen = sprintf(tmp, "%d", dbc->tds_socket->spid);
     734                 :                 else
     735               0 :                         cplen = 0;
     736                 : 
     737               0 :                 result = odbc_set_string(buffer, cbBuffer, pcbBuffer, tmp, cplen);
     738               0 :                 break;
     739                 : 
     740                 :         case SQL_DIAG_MESSAGE_TEXT:
     741               0 :                 msg = errs->errs[numRecord].msg;
     742               0 :                 result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1);
     743               0 :                 break;
     744                 : 
     745                 :         case SQL_DIAG_NATIVE:
     746               0 :                 *(SQLINTEGER *) buffer = errs->errs[numRecord].native;
     747               0 :                 break;
     748                 : 
     749                 :         case SQL_DIAG_SERVER_NAME:
     750               0 :                 msg = "";
     751               0 :                 switch (handleType) {
     752                 :                 case SQL_HANDLE_ENV:
     753               0 :                         break;
     754                 :                 case SQL_HANDLE_DBC:
     755               0 :                         msg = tds_dstr_cstr(&dbc->server);
     756               0 :                         break;
     757                 :                 case SQL_HANDLE_STMT:
     758               0 :                         msg = tds_dstr_cstr(&stmt->dbc->server);
     759                 :                         /*
     760                 :                          * if dbc->server is not initialized, init it
     761                 :                          * from the errs structure
     762                 :                          */
     763               0 :                         if (!msg[0] && errs->errs[numRecord].server) {
     764               0 :                                 tds_dstr_copy(&stmt->dbc->server, errs->errs[numRecord].server);
     765               0 :                                 msg = errs->errs[numRecord].server;
     766                 :                         }
     767                 :                         break;
     768                 :                 }
     769               0 :                 result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1);
     770               0 :                 break;
     771                 : 
     772                 :         case SQL_DIAG_SQLSTATE:
     773               0 :                 if (odbc_ver == SQL_OV_ODBC3)
     774               0 :                         msg = errs->errs[numRecord].state3;
     775                 :                 else
     776               0 :                         msg = errs->errs[numRecord].state2;
     777                 : 
     778               0 :                 result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, 5);
     779               0 :                 break;
     780                 : 
     781                 :         default:
     782               0 :                 return SQL_ERROR;
     783                 :         }
     784               0 :         return result;
     785                 : }
     786                 : #endif

Generated by: LTP GCOV extension version 1.6