LCOV - code coverage report
Current view: top level - src/odbc - error.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 175 281 62.3 %
Date: 2024-04-18 20:40:06 Functions: 9 11 81.8 %

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

Generated by: LCOV version 1.13