NCBI C++ ToolKit
error.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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/string.h>
39 #include "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 
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("", NULL)
163 };
164 
165 #undef ODBCERR
166 
168 {
169  char v3[6];
170  char v2[6];
171 };
172 
173 /* Map a v3 SQLSTATE to a v2 */
174 static const struct s_v3to2map v3to2map[] = {
175  {"01001", "01S03"},
176  {"01001", "01S04"},
177  {"HY019", "22003"},
178  {"22007", "22008"},
179  {"22018", "22005"},
180  {"07005", "24000"},
181  {"42000", "37000"},
182  {"HY018", "70100"},
183  {"42S01", "S0001"},
184  {"42S02", "S0002"},
185  {"42S11", "S0011"},
186  {"42S12", "S0012"},
187  {"42S21", "S0021"},
188  {"42S22", "S0022"},
189  {"42S23", "S0023"},
190  {"HY000", "S1000"},
191  {"HY001", "S1001"},
192  {"07009", "S1002"},
193  {"HY003", "S1003"},
194  {"HY004", "S1004"},
195  {"HY008", "S1008"},
196  {"HY009", "S1009"},
197  {"HY024", "S1009"},
198  {"HY007", "S1010"},
199  {"HY010", "S1010"},
200  {"HY011", "S1011"},
201  {"HY012", "S1012"},
202  {"HY090", "S1090"},
203  {"HY091", "S1091"},
204  {"HY092", "S1092"},
205 /* {"07009", "S1093"}, */
206  {"HY096", "S1096"},
207  {"HY097", "S1097"},
208  {"HY098", "S1098"},
209  {"HY099", "S1099"},
210  {"HY100", "S1100"},
211  {"HY101", "S1101"},
212  {"HY103", "S1103"},
213  {"HY104", "S1104"},
214  {"HY105", "S1105"},
215  {"HY106", "S1106"},
216  {"HY107", "S1107"},
217  {"HY108", "S1108"},
218  {"HY109", "S1109"},
219  {"HY110", "S1110"},
220  {"HY111", "S1111"},
221  {"HYC00", "S1C00"},
222  {"HYT00", "S1T00"},
223  {"08001", "S1000"},
224  {"IM007", "S1000"},
225  {"", ""}
226 };
227 
228 /*
229  * ODBC messages must be sorted by importance
230  * 1. Errors regarding the status of a transaction
231  * 2. Other errors (level ordered)
232  * 3. No-Data messages with a state class of 02 ??
233  * 4. Warning
234  * 5. Informational
235  */
236 static void
238 {
239  int settled, current, best;
240  struct _sql_error swapbuf;
241  char istrans;
242 
243  /* already ranked or nothing to rank */
244  if (errs->ranked != 0 || errs->num_errors <= 1) {
245  errs->ranked = 1;
246  return;
247  }
248 
249  /* Find the highest of all unranked errors until there are none left */
250  for (settled = 0; settled < errs->num_errors; settled++) {
251  best = settled;
252  for (current = settled; current < errs->num_errors; current++) {
253  /* always sort by rows */
254  if (errs->errs[best].row < errs->errs[current].row)
255  continue;
256  if (errs->errs[best].row > errs->errs[current].row) {
257  best = current;
258  continue;
259  }
260 
261  istrans = 0;
262  switch (errs->errs[current].native) {
263  case 1205:
264  case 1211:
265  case 2625:
266  case 3309:
267  case 7112:
268  case 266:
269  case 277:
270  case 611:
271  case 628:
272  case 3902:
273  case 3903:
274  case 3906:
275  case 3908:
276  case 6401:
277  istrans = 1;
278  break;
279  }
280 
281  if (istrans == 0) {
282  if (strcmp(errs->errs[current].state3,"25000") == 0)
283  istrans = 1;
284  else if (strcmp(errs->errs[current].state3,"S1012") == 0)
285  istrans = 1;
286  else if (strcmp(errs->errs[current].state3,"08007") == 0)
287  istrans = 1;
288  }
289 
290  /* Transaction errors are always best */
291  if (istrans == 1 && errs->errs[current].msgstate >= 10) {
292  best = current;
293  break;
294  }
295 
296  /* Non-terminating comparisons only below this point */
297  if (errs->errs[current].msgstate > errs->errs[best].msgstate)
298  best = current;
299  }
300 
301  /* swap settled position with best */
302  if (best != settled) {
303  swapbuf = errs->errs[settled];
304  errs->errs[settled] = errs->errs[best];
305  errs->errs[best] = swapbuf;
306  }
307  }
308  errs->ranked = 1;
309 }
310 
311 static const char *
312 odbc_get_msg(const char *sqlstate)
313 {
314  const struct s_SqlMsgMap *pmap = SqlMsgMap;
315 
316  /* TODO set flag and use pointers (no strdup) ?? */
317  while (pmap->msg) {
318  if (!strcasecmp(sqlstate, pmap->sqlstate)) {
319  return strdup(pmap->msg);
320  }
321  ++pmap;
322  }
323  return strdup("");
324 }
325 
326 static void
327 odbc_get_v2state(const char *sqlstate, char *dest_state)
328 {
329  const struct s_v3to2map *pmap = v3to2map;
330 
331  while (pmap->v3[0]) {
332  if (!strcasecmp(pmap->v3, sqlstate)) {
333  strlcpy(dest_state, pmap->v2, 6);
334  return;
335  }
336  ++pmap;
337  }
338  /* return the original if a v2 state is not found */
339  strlcpy(dest_state, sqlstate, 6);
340 }
341 
342 void
344 {
345  int i;
346 
347  if (errs->errs) {
348  for (i = 0; i < errs->num_errors; ++i) {
349  /* TODO see flags */
350  free((char *) errs->errs[i].msg);
351  free(errs->errs[i].server);
352  }
353  TDS_ZERO_FREE(errs->errs);
354  errs->num_errors = 0;
355  }
356  errs->lastrc = SQL_SUCCESS;
357  errs->ranked = 0;
358  assert(errs->num_errors == 0);
359 }
360 
361 /** Remove first element */
362 static void
364 {
365  if (!errs || !errs->errs || errs->num_errors <= 0)
366  return;
367 
368  if (errs->num_errors == 1) {
369  odbc_errs_reset(errs);
370  return;
371  }
372 
373  /* TODO see flags */
374  free((char *) errs->errs[0].msg);
375  free(errs->errs[0].server);
376 
377  --errs->num_errors;
378  memmove(&(errs->errs[0]), &(errs->errs[1]), errs->num_errors * sizeof(errs->errs[0]));
379 }
380 
381 void
382 odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
383 {
384  int n;
385 
386  assert(sqlstate);
387  if (!errs)
388  return;
389 
390  n = errs->num_errors;
391  if (!TDS_RESIZE(errs->errs, n + 1)) {
392  errs->lastrc = SQL_ERROR;
393  return;
394  }
395 
396  memset(&errs->errs[n], 0, sizeof(struct _sql_error));
397  errs->errs[n].native = 0;
398  strlcpy(errs->errs[n].state3, sqlstate, 6);
399  odbc_get_v2state(errs->errs[n].state3, errs->errs[n].state2);
400 
401  /* TODO why driver ?? -- freddy77 */
402  errs->errs[n].server = strdup("DRIVER");
403  errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
404  ++errs->num_errors;
405 
406  /* updated last error */
407  if (!strcmp(sqlstate, "01004") || !strcmp(sqlstate, "01S02")) {
408  if (errs->lastrc != SQL_ERROR)
410  } else {
411  errs->lastrc = SQL_ERROR;
412  }
413 
414  tdsdump_log(TDS_DBG_FUNC, "odbc_errs_add: \"%s\"\n", errs->errs[n].msg);
415 }
416 
417 /* TODO check if TDS_UINT is correct for native error */
418 void
419 odbc_errs_add_rdbms(struct _sql_errors *errs, TDS_UINT native, const char *sqlstate, const char *msg, int linenum, int msgstate,
420  const char *server, int row)
421 {
422  int n = errs->num_errors;
423 
424  if (!TDS_RESIZE(errs->errs, n + 1))
425  return;
426 
427  memset(&errs->errs[n], 0, sizeof(struct _sql_error));
428  errs->errs[n].row = row;
429  errs->errs[n].native = native;
430  if (sqlstate)
431  strlcpy(errs->errs[n].state2, sqlstate, 6);
432  else
433  errs->errs[n].state2[0] = '\0';
434  strcpy(errs->errs[n].state3, errs->errs[n].state2);
435  sqlstate2to3(errs->errs[n].state3);
436 
437  /* TODO why driver ?? -- freddy77 */
438  errs->errs[n].server = (server) ? strdup(server) : strdup("DRIVER");
439  errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
440  errs->errs[n].linenum = linenum;
441  errs->errs[n].msgstate = msgstate;
442  ++errs->num_errors;
443 }
444 
445 #define SQLS_MAP(v2,v3) if (strcmp(p,v2) == 0) {strcpy(p,v3); return;}
446 static void
448 {
449  char *p = state;
450 
451  if (p[0] == 'S' && p[1] == '0' && p[2] == '0') {
452  p[0] = '4';
453  p[1] = '2';
454  p[2] = 'S';
455  return;
456  }
457 
458  /* TODO optimize with a switch */
459  SQLS_MAP("01S03", "01001");
460  SQLS_MAP("01S04", "01001");
461  SQLS_MAP("22003", "HY019");
462  SQLS_MAP("22008", "22007");
463  SQLS_MAP("22005", "22018");
464  SQLS_MAP("24000", "07005");
465  SQLS_MAP("37000", "42000");
466  SQLS_MAP("70100", "HY018");
467  SQLS_MAP("S1000", "HY000");
468  SQLS_MAP("S1001", "HY001");
469  SQLS_MAP("S1002", "07009");
470  SQLS_MAP("S1003", "HY003");
471  SQLS_MAP("S1004", "HY004");
472  SQLS_MAP("S1008", "HY008");
473  SQLS_MAP("S1009", "HY009");
474  SQLS_MAP("S1010", "HY007");
475  SQLS_MAP("S1011", "HY011");
476  SQLS_MAP("S1012", "HY012");
477  SQLS_MAP("S1090", "HY090");
478  SQLS_MAP("S1091", "HY091");
479  SQLS_MAP("S1092", "HY092");
480  SQLS_MAP("S1093", "07009");
481  SQLS_MAP("S1096", "HY096");
482  SQLS_MAP("S1097", "HY097");
483  SQLS_MAP("S1098", "HY098");
484  SQLS_MAP("S1099", "HY099");
485  SQLS_MAP("S1100", "HY100");
486  SQLS_MAP("S1101", "HY101");
487  SQLS_MAP("S1103", "HY103");
488  SQLS_MAP("S1104", "HY104");
489  SQLS_MAP("S1105", "HY105");
490  SQLS_MAP("S1106", "HY106");
491  SQLS_MAP("S1107", "HY107");
492  SQLS_MAP("S1108", "HY108");
493  SQLS_MAP("S1109", "HY109");
494  SQLS_MAP("S1110", "HY110");
495  SQLS_MAP("S1111", "HY111");
496  SQLS_MAP("S1C00", "HYC00");
497  SQLS_MAP("S1T00", "HYT00");
498 }
499 
500 ODBC_FUNC(SQLGetDiagRec, (P(SQLSMALLINT,handleType), P(SQLHANDLE,handle), P(SQLSMALLINT,numRecord), PCHAR(szSqlState),
501  P(SQLINTEGER FAR *,pfNativeError), PCHAROUT(ErrorMsg,SQLSMALLINT) WIDE))
502 {
504  struct _sql_errors *errs;
505  const char *msg;
506  char *p;
507  TDS_DBC *dbc = NULL;
508 
509  static const char msgprefix[] = "[FreeTDS][SQL Server]";
510 
511  SQLINTEGER odbc_ver = SQL_OV_ODBC2;
512 
513  if (numRecord <= 0 || cbErrorMsgMax < 0)
514  return SQL_ERROR;
515 
516  if (!handle || ((TDS_CHK *) handle)->htype != handleType)
517  return SQL_INVALID_HANDLE;
518 
519  errs = &((TDS_CHK *) handle)->errs;
520  switch (handleType) {
521  case SQL_HANDLE_STMT:
522  dbc = ((TDS_STMT *) handle)->dbc;
523  odbc_ver = dbc->env->attr.odbc_version;
524  break;
525 
526  case SQL_HANDLE_DBC:
527  dbc = (TDS_DBC *) handle;
528  odbc_ver = dbc->env->attr.odbc_version;
529  break;
530 
531  case SQL_HANDLE_ENV:
532  odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version;
533  break;
534  case SQL_HANDLE_DESC:
535  dbc = desc_get_dbc((TDS_DESC *) handle);
536  odbc_ver = dbc->env->attr.odbc_version;
537  break;
538  default:
539  return SQL_INVALID_HANDLE;
540  }
541 
542  if (numRecord > errs->num_errors)
543  return SQL_NO_DATA_FOUND;
544  --numRecord;
545 
546  rank_errors(errs);
547 
548  if (szSqlState) {
549  const char *state =
550  (odbc_ver == SQL_OV_ODBC3) ? errs->errs[numRecord].state3 : errs->errs[numRecord].state2;
551  odbc_set_string(dbc, szSqlState, 24, (SQLSMALLINT *) NULL, state, -1);
552  }
553 
554  msg = errs->errs[numRecord].msg;
555 
556  if (asprintf(&p, "%s%s", msgprefix, msg) < 0)
557  return SQL_ERROR;
558 
559  tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec: \"%s\"\n", p);
560 
561  result = odbc_set_string(dbc, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1);
562  free(p);
563 
564  if (pfNativeError)
565  *pfNativeError = errs->errs[numRecord].native;
566 
567  return result;
568 }
569 
570 ODBC_FUNC(SQLError, (P(SQLHENV,henv), P(SQLHDBC,hdbc), P(SQLHSTMT,hstmt), PCHAR(szSqlState), P(SQLINTEGER FAR *,pfNativeError),
572 {
575  SQLHANDLE handle;
576 
577  if (hstmt) {
578  handle = hstmt;
580  } else if (hdbc) {
581  handle = hdbc;
583  } else if (henv) {
584  handle = henv;
586  } else
587  return SQL_INVALID_HANDLE;
588 
589  result = _SQLGetDiagRec(type, handle, 1, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg _wide);
590 
591  if (result == SQL_SUCCESS) {
592  /* remove first error */
593  odbc_errs_pop(&((TDS_CHK *) handle)->errs);
594  }
595 
596  return result;
597 }
598 
599 ODBC_FUNC(SQLGetDiagField, (P(SQLSMALLINT,handleType), P(SQLHANDLE,handle), P(SQLSMALLINT,numRecord),
600  P(SQLSMALLINT,diagIdentifier), P(SQLPOINTER,buffer), P(SQLSMALLINT,cbBuffer), P(SQLSMALLINT FAR *,pcbBuffer) WIDE))
601 {
603  struct _sql_errors *errs;
604  const char *msg;
605 
606  SQLINTEGER odbc_ver = SQL_OV_ODBC2;
607  int cplen;
608  TDS_STMT *stmt = NULL;
609  TDS_DBC *dbc = NULL;
610  TDS_ENV *env = NULL;
611  char tmp[16];
612 
613  if (cbBuffer < 0)
614  return SQL_ERROR;
615 
616  if (!handle || ((TDS_CHK *) handle)->htype != handleType)
617  return SQL_INVALID_HANDLE;
618 
619  switch (handleType) {
620  case SQL_HANDLE_STMT:
621  stmt = ((TDS_STMT *) handle);
622  dbc = stmt->dbc;
623  env = dbc->env;
624  break;
625 
626  case SQL_HANDLE_DBC:
627  dbc = ((TDS_DBC *) handle);
628  env = dbc->env;
629  break;
630 
631  case SQL_HANDLE_ENV:
632  env = ((TDS_ENV *) handle);
633  break;
634 
635  case SQL_HANDLE_DESC:
636  dbc = desc_get_dbc((TDS_DESC *) handle);
637  env = dbc->env;
638  break;
639 
640  default:
641  return SQL_INVALID_HANDLE;
642  }
643  errs = &((TDS_CHK *) handle)->errs;
644  odbc_ver = env->attr.odbc_version;
645 
646  /* header (numRecord ignored) */
647  switch (diagIdentifier) {
649  if (handleType != SQL_HANDLE_STMT)
650  return SQL_ERROR;
651 
652  /* TODO */
653  return odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "", 0);
654 
656  *(SQLINTEGER *) buffer = 0;
657  return SQL_SUCCESS;
658 
659  case SQL_DIAG_NUMBER:
660  *(SQLINTEGER *) buffer = errs->num_errors;
661  return SQL_SUCCESS;
662 
663  case SQL_DIAG_RETURNCODE:
664  *(SQLRETURN *) buffer = errs->lastrc;
665  return SQL_SUCCESS;
666 
668  if (handleType != SQL_HANDLE_STMT)
669  return SQL_ERROR;
670 
671  /* TODO */
672  *(SQLINTEGER *) buffer = 0;
673  return SQL_SUCCESS;
674 
675  case SQL_DIAG_ROW_COUNT:
676  if (handleType != SQL_HANDLE_STMT)
677  return SQL_ERROR;
678 
679  return _SQLRowCount((SQLHSTMT) handle, (SQLLEN FAR *) buffer);
680  }
681 
682  if (numRecord > errs->num_errors)
683  return SQL_NO_DATA_FOUND;
684 
685  if (numRecord <= 0)
686  return SQL_ERROR;
687  --numRecord;
688 
689  switch (diagIdentifier) {
690  case SQL_DIAG_ROW_NUMBER:
691  *(SQLINTEGER *) buffer =
692  errs->errs[numRecord].row > 0 ? errs->errs[numRecord].row : SQL_ROW_NUMBER_UNKNOWN;
693  break;
694 
697  if (odbc_ver == SQL_OV_ODBC2)
698  result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "ISO 9075", -1);
699  else
700  result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1);
701  break;
702 
705  break;
706 
708  if (errs->errs[numRecord].msgstate == 0)
709  return SQL_ERROR;
710  else
711  *(SQLINTEGER *) buffer = errs->errs[numRecord].msgstate;
712  break;
713 
714  case SQL_DIAG_SS_LINE:
715  if (errs->errs[numRecord].linenum == 0)
716  return SQL_ERROR;
717  else
718  *(SQLUSMALLINT *) buffer = errs->errs[numRecord].linenum;
719  break;
720 
722  if (dbc && dbc->tds_socket && dbc->tds_socket->conn->spid > 0)
723  cplen = sprintf(tmp, "%d", dbc->tds_socket->conn->spid);
724  else
725  cplen = 0;
726 
727  result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, tmp, cplen);
728  break;
729 
731  msg = errs->errs[numRecord].msg;
732  result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg, -1);
733  break;
734 
735  case SQL_DIAG_NATIVE:
736  *(SQLINTEGER *) buffer = errs->errs[numRecord].native;
737  break;
738 
740  msg = NULL;
741  switch (handleType) {
742  case SQL_HANDLE_ENV:
743  break;
744  case SQL_HANDLE_DBC:
745  if (dbc->tds_socket)
746  msg = dbc->tds_socket->conn->server;
747  break;
748  case SQL_HANDLE_STMT:
749  if (stmt->dbc->tds_socket)
750  msg = stmt->dbc->tds_socket->conn->server;
751  /*
752  * if dbc->server is not initialized, init it
753  * from the errs structure
754  */
755  if (!msg && errs->errs[numRecord].server) {
756  msg = errs->errs[numRecord].server;
757  }
758  break;
759  }
760  result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg ? msg : "", -1);
761  break;
762 
763  case SQL_DIAG_SQLSTATE:
764  if (odbc_ver == SQL_OV_ODBC3)
765  msg = errs->errs[numRecord].state3;
766  else
767  msg = errs->errs[numRecord].state2;
768 
769  result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg, 5);
770  break;
771 
772  default:
773  return SQL_ERROR;
774  }
775  return result;
776 }
777 
778 #include "error_export.h"
779 
static const struct s_v3to2map v3to2map[]
Definition: error.c:174
void odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
add an error to list
Definition: error.c:382
static void sqlstate2to3(char *state)
Definition: error.c:447
#define SQLS_MAP(v2, v3)
Definition: error.c:445
void odbc_errs_reset(struct _sql_errors *errs)
reset errors
Definition: error.c:343
static void odbc_errs_pop(struct _sql_errors *errs)
Remove first element.
Definition: error.c:363
void odbc_errs_add_rdbms(struct _sql_errors *errs, TDS_UINT native, const char *sqlstate, const char *msg, int linenum, int msgstate, const char *server, int row)
Add an error to list.
Definition: error.c:419
#define ODBCERR(s3, msg)
Definition: error.c:54
static const struct s_SqlMsgMap SqlMsgMap[]
Definition: error.c:55
static void rank_errors(struct _sql_errors *errs)
Definition: error.c:237
static SQLRETURN _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR *szSqlState, SQLINTEGER FAR *pfNativeError, SQLCHAR *szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR *pcbErrorMsg)
Definition: error.c:501
static void odbc_get_v2state(const char *sqlstate, char *dest_state)
Definition: error.c:327
static const char * odbc_get_msg(const char *sqlstate)
Definition: error.c:312
static int type
Definition: getdata.c:31
#define NULL
Definition: ncbistd.hpp:225
#define FAR
Definition: ncbistd.hpp:278
int i
if(yy_accept[yy_current_state])
yy_size_t n
#define P(a, b, c, d, k, s, t)
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
#define strdup
Definition: ncbi_ansi_ext.h:70
#define strcasecmp
switch(yytype)
Definition: newick.tab.cpp:737
static char tmp[2048]
Definition: utf8.c:42
#define odbc_set_string(dbc, buf, buf_len, out_len, s, s_len)
Definition: odbc.h:657
TDS_DBC * desc_get_dbc(TDS_DESC *desc)
Definition: descriptor.c:210
#define _wide
Definition: odbc.h:614
#define SQLLEN
Definition: odbc.h:52
SQLRETURN _SQLRowCount(SQLHSTMT hstmt, SQLINTEGER FAR *pcrow)
#define odbc_set_string_oct(dbc, buf, buf_len, out_len, s, s_len)
Definition: odbc.h:659
#define SQL_DIAG_SS_LINE
Definition: odbcss.h:32
#define SQL_DIAG_SS_MSGSTATE
Definition: odbcss.h:31
#define memmove(a, b, c)
static pcre_uint8 * buffer
Definition: pcretest.c:1051
static HSTMT stmt
Definition: rebindpar.c:12
#define asprintf
Definition: replacements.h:54
#define strlcpy(d, s, l)
Definition: replacements.h:80
SQLRETURN SQLError(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
SQLRETURN SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
#define SQL_HANDLE_STMT
Definition: sql.h:66
#define SQL_SUCCESS
Definition: sql.h:31
#define SQL_DIAG_DYNAMIC_FUNCTION_CODE
Definition: sql.h:128
SQLRETURN SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
Definition: error_export.h:168
#define SQL_DIAG_ROW_COUNT
Definition: sql.h:119
#define SQL_DIAG_CONNECTION_NAME
Definition: sql.h:126
#define SQL_DIAG_NUMBER
Definition: sql.h:118
#define SQL_DIAG_NATIVE
Definition: sql.h:121
#define SQL_DIAG_SQLSTATE
Definition: sql.h:120
#define SQL_DIAG_MESSAGE_TEXT
Definition: sql.h:122
#define SQL_HANDLE_ENV
Definition: sql.h:64
#define SQL_INVALID_HANDLE
Definition: sql.h:37
#define SQL_SUCCESS_WITH_INFO
Definition: sql.h:32
#define SQL_HANDLE_DESC
Definition: sql.h:67
#define SQL_DIAG_SERVER_NAME
Definition: sql.h:127
#define SQL_DIAG_RETURNCODE
Definition: sql.h:117
#define SQL_DIAG_CLASS_ORIGIN
Definition: sql.h:124
#define SQL_DIAG_SUBCLASS_ORIGIN
Definition: sql.h:125
#define SQL_HANDLE_DBC
Definition: sql.h:65
#define SQL_ERROR
Definition: sql.h:36
#define SQL_DIAG_DYNAMIC_FUNCTION
Definition: sql.h:123
#define SQL_OV_ODBC3
Definition: sqlext.h:98
#define SQL_NO_DATA_FOUND
Definition: sqlext.h:64
#define SQL_ROW_NUMBER_UNKNOWN
Definition: sqlext.h:607
#define SQL_DIAG_COLUMN_NUMBER
Definition: sqlext.h:422
#define SQL_DIAG_CURSOR_ROW_COUNT
Definition: sqlext.h:420
#define SQL_COLUMN_NUMBER_UNKNOWN
Definition: sqlext.h:608
#define SQL_OV_ODBC2
Definition: sqlext.h:97
#define SQL_DIAG_ROW_NUMBER
Definition: sqlext.h:421
SQLHANDLE SQLHENV
Definition: sqltypes.h:214
unsigned short SQLUSMALLINT
Definition: sqltypes.h:202
void * SQLPOINTER
Definition: sqltypes.h:195
SQLHANDLE SQLHDBC
Definition: sqltypes.h:215
long SQLINTEGER
Definition: sqltypes.h:176
SQLHANDLE SQLHSTMT
Definition: sqltypes.h:216
void * SQLHANDLE
Definition: sqltypes.h:213
signed short int SQLSMALLINT
Definition: sqltypes.h:201
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:210
#define ODBC_FUNC(name, params)
Definition: sqlwparams.h:23
#define PCHAROUT(n, t)
Definition: sqlwparams.h:21
#define WIDE
Definition: sqlwparams.h:15
#define PCHAR(a)
Definition: sqlwparams.h:16
#define assert(x)
Definition: srv_diag.hpp:58
Definition: odbc.h:233
Definition: odbc.h:282
Definition: odbc.h:205
Definition: odbc.h:242
Definition: odbc.h:390
char state2[6]
Definition: odbc.h:97
int linenum
Definition: odbc.h:101
const char * msg
Definition: odbc.h:96
int msgstate
Definition: odbc.h:102
char * server
Definition: odbc.h:100
int row
Definition: odbc.h:103
char state3[6]
Definition: odbc.h:98
TDS_UINT native
Definition: odbc.h:99
int num_errors
Definition: odbc.h:109
char ranked
Definition: odbc.h:111
SQLRETURN lastrc
Definition: odbc.h:110
struct _sql_error * errs
Definition: odbc.h:108
const char * msg
Definition: error.c:49
char sqlstate[6]
Definition: error.c:50
char v2[6]
Definition: error.c:170
char v3[6]
Definition: error.c:169
Definition: type.c:6
#define tdsdump_log
Definition: tds.h:1561
#define TDS_RESIZE(p, n_elem)
Definition: tds.h:1390
#define TDS_ZERO_FREE(x)
Definition: tds.h:359
tds_sysdep_uint32_type TDS_UINT
Definition: tds.h:150
#define TDS_DBG_FUNC
Definition: tds.h:898
else result
Definition: token2.c:20
static HENV env
Definition: transaction2.c:38
static HDBC dbc
Definition: transaction2.c:39
void free(voidpf ptr)
Modified on Tue Feb 27 05:54:23 2024 by modify_doxy.py rev. 669887