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 : 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 1089546 : while (pmap->msg) {
320 1089546 : if (!strcasecmp(sqlstate, pmap->sqlstate)) {
321 : return pmap->msg;
322 : }
323 1064178 : ++pmap;
324 : }
325 : return "";
326 : }
327 :
328 : static void
329 26992 : odbc_get_v2state(const char *sqlstate, char *dest_state)
330 : {
331 26992 : const struct s_v3to2map *pmap = v3to2map;
332 :
333 965178 : while (pmap->v3[0]) {
334 925750 : if (!strcasecmp(pmap->v3, sqlstate)) {
335 14556 : strlcpy(dest_state, pmap->v2, 6);
336 14556 : return;
337 : }
338 911194 : ++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 203801 : odbc_errs_reset(struct _sql_errors *errs)
346 : {
347 : int i;
348 :
349 203801 : if (errs->errs) {
350 31466 : for (i = 0; i < errs->num_errors; ++i) {
351 31466 : if (!errs->errs[i].msg_is_static)
352 6098 : free((char *) errs->errs[i].msg);
353 31466 : free(errs->errs[i].server);
354 : }
355 5190 : TDS_ZERO_FREE(errs->errs);
356 5190 : errs->num_errors = 0;
357 : }
358 203801 : errs->lastrc = SQL_SUCCESS;
359 203801 : errs->ranked = 0;
360 203801 : assert(errs->num_errors == 0);
361 203801 : }
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 0 : if (!errs->errs[0].msg_is_static)
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 26992 : odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
385 : {
386 : int n;
387 :
388 26992 : assert(sqlstate);
389 26992 : if (!errs)
390 : return;
391 :
392 26992 : n = errs->num_errors;
393 26992 : if (!TDS_RESIZE(errs->errs, n + 1)) {
394 0 : errs->lastrc = SQL_ERROR;
395 0 : return;
396 : }
397 :
398 26992 : memset(&errs->errs[n], 0, sizeof(struct _sql_error));
399 26992 : errs->errs[n].native = 0;
400 26992 : strlcpy(errs->errs[n].state3, sqlstate, 6);
401 26992 : odbc_get_v2state(errs->errs[n].state3, errs->errs[n].state2);
402 :
403 : /* TODO why driver ?? -- freddy77 */
404 26992 : errs->errs[n].server = strdup("DRIVER");
405 53984 : errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
406 26992 : errs->errs[n].msg_is_static = (msg == NULL);
407 26992 : ++errs->num_errors;
408 :
409 : /* updated last error */
410 26992 : if (!strcmp(sqlstate, "01004") || !strcmp(sqlstate, "01S02")) {
411 1572 : if (errs->lastrc != SQL_ERROR)
412 1572 : errs->lastrc = SQL_SUCCESS_WITH_INFO;
413 : } else {
414 25420 : errs->lastrc = SQL_ERROR;
415 : }
416 :
417 26992 : tdsdump_log(TDS_DBG_FUNC, "odbc_errs_add: \"%s\"\n", errs->errs[n].msg);
418 : }
419 :
420 : /* TODO check if TDS_UINT is correct for native error */
421 : void
422 4474 : odbc_errs_add_rdbms(struct _sql_errors *errs, TDS_UINT native, const char *sqlstate, const char *msg, int linenum, int msgstate,
423 : const char *server, int row)
424 : {
425 4474 : int n = errs->num_errors;
426 :
427 4474 : if (!TDS_RESIZE(errs->errs, n + 1))
428 : return;
429 :
430 4474 : memset(&errs->errs[n], 0, sizeof(struct _sql_error));
431 4474 : errs->errs[n].row = row;
432 4474 : errs->errs[n].native = native;
433 4474 : if (sqlstate)
434 4474 : strlcpy(errs->errs[n].state2, sqlstate, 6);
435 : else
436 0 : errs->errs[n].state2[0] = '\0';
437 4474 : strcpy(errs->errs[n].state3, errs->errs[n].state2);
438 4474 : sqlstate2to3(errs->errs[n].state3);
439 :
440 : /* TODO why driver ?? -- freddy77 */
441 4474 : errs->errs[n].server = (server) ? strdup(server) : strdup("DRIVER");
442 8948 : errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
443 4474 : errs->errs[n].msg_is_static = (msg == NULL);
444 4474 : errs->errs[n].linenum = linenum;
445 4474 : errs->errs[n].msgstate = msgstate;
446 4474 : ++errs->num_errors;
447 : }
448 :
449 : #define SQLS_MAP(v2,v3) if (strcmp(p,v2) == 0) {strcpy(p,v3); return;}
450 : static void
451 4474 : sqlstate2to3(char *state)
452 : {
453 4474 : char *p = state;
454 :
455 4474 : if (p[0] == 'S' && p[1] == '0' && p[2] == '0') {
456 140 : p[0] = '4';
457 140 : p[1] = '2';
458 140 : p[2] = 'S';
459 140 : return;
460 : }
461 :
462 : /* TODO optimize with a switch */
463 4334 : SQLS_MAP("01S03", "01001");
464 4334 : SQLS_MAP("01S04", "01001");
465 4334 : SQLS_MAP("22003", "HY019");
466 3938 : SQLS_MAP("22008", "22007");
467 3918 : SQLS_MAP("22005", "22018");
468 3914 : SQLS_MAP("24000", "07005");
469 3914 : SQLS_MAP("37000", "42000");
470 3904 : SQLS_MAP("70100", "HY018");
471 3904 : SQLS_MAP("S1000", "HY000");
472 3903 : SQLS_MAP("S1001", "HY001");
473 3903 : SQLS_MAP("S1002", "07009");
474 3903 : SQLS_MAP("S1003", "HY003");
475 3903 : SQLS_MAP("S1004", "HY004");
476 3903 : SQLS_MAP("S1008", "HY008");
477 3903 : SQLS_MAP("S1009", "HY009");
478 3903 : SQLS_MAP("S1010", "HY007");
479 3903 : SQLS_MAP("S1011", "HY011");
480 3903 : SQLS_MAP("S1012", "HY012");
481 3903 : SQLS_MAP("S1090", "HY090");
482 3903 : SQLS_MAP("S1091", "HY091");
483 3903 : SQLS_MAP("S1092", "HY092");
484 3903 : SQLS_MAP("S1093", "07009");
485 3903 : SQLS_MAP("S1096", "HY096");
486 3903 : SQLS_MAP("S1097", "HY097");
487 3903 : SQLS_MAP("S1098", "HY098");
488 3903 : SQLS_MAP("S1099", "HY099");
489 3903 : SQLS_MAP("S1100", "HY100");
490 3903 : SQLS_MAP("S1101", "HY101");
491 3903 : SQLS_MAP("S1103", "HY103");
492 3903 : SQLS_MAP("S1104", "HY104");
493 3903 : SQLS_MAP("S1105", "HY105");
494 3903 : SQLS_MAP("S1106", "HY106");
495 3903 : SQLS_MAP("S1107", "HY107");
496 3903 : SQLS_MAP("S1108", "HY108");
497 3903 : SQLS_MAP("S1109", "HY109");
498 3903 : SQLS_MAP("S1110", "HY110");
499 3903 : SQLS_MAP("S1111", "HY111");
500 3903 : SQLS_MAP("S1C00", "HYC00");
501 3903 : SQLS_MAP("S1T00", "HYT00");
502 : }
503 :
504 1379 : ODBC_FUNC(SQLGetDiagRec, (P(SQLSMALLINT,handleType), P(SQLHANDLE,handle), P(SQLSMALLINT,numRecord), PCHAR(szSqlState),
505 : P(SQLINTEGER FAR *,pfNativeError), PCHAROUT(ErrorMsg,SQLSMALLINT) WIDE))
506 : {
507 : SQLRETURN result;
508 : struct _sql_errors *errs;
509 : const char *msg;
510 : char *p;
511 1379 : TDS_DBC *dbc = NULL;
512 :
513 : static const char msgprefix[] = "[FreeTDS][SQL Server]";
514 :
515 1379 : SQLINTEGER odbc_ver = SQL_OV_ODBC2;
516 :
517 1379 : if (numRecord <= 0 || cbErrorMsgMax < 0)
518 : return SQL_ERROR;
519 :
520 1379 : if (!handle || ((TDS_CHK *) handle)->htype != handleType)
521 : return SQL_INVALID_HANDLE;
522 :
523 1379 : errs = &((TDS_CHK *) handle)->errs;
524 1379 : switch (handleType) {
525 1347 : case SQL_HANDLE_STMT:
526 1347 : dbc = ((TDS_STMT *) handle)->dbc;
527 1347 : odbc_ver = dbc->env->attr.odbc_version;
528 1347 : break;
529 :
530 32 : case SQL_HANDLE_DBC:
531 32 : dbc = (TDS_DBC *) handle;
532 32 : odbc_ver = dbc->env->attr.odbc_version;
533 32 : break;
534 :
535 0 : case SQL_HANDLE_ENV:
536 0 : odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version;
537 0 : break;
538 0 : case SQL_HANDLE_DESC:
539 0 : dbc = desc_get_dbc((TDS_DESC *) handle);
540 0 : odbc_ver = dbc->env->attr.odbc_version;
541 0 : break;
542 : default:
543 : return SQL_INVALID_HANDLE;
544 : }
545 :
546 1379 : if (numRecord > errs->num_errors)
547 : return SQL_NO_DATA_FOUND;
548 1261 : --numRecord;
549 :
550 1261 : rank_errors(errs);
551 :
552 1261 : if (szSqlState) {
553 2498 : const char *state =
554 1249 : (odbc_ver == SQL_OV_ODBC3) ? errs->errs[numRecord].state3 : errs->errs[numRecord].state2;
555 1249 : odbc_set_string(dbc, szSqlState, 24, (SQLSMALLINT *) NULL, state, -1);
556 : }
557 :
558 1261 : msg = errs->errs[numRecord].msg;
559 :
560 1261 : if (asprintf(&p, "%s%s", msgprefix, msg) < 0)
561 : return SQL_ERROR;
562 :
563 1261 : tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec: \"%s\"\n", p);
564 :
565 1261 : result = odbc_set_string(dbc, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1);
566 1261 : free(p);
567 :
568 1261 : if (pfNativeError)
569 180 : *pfNativeError = errs->errs[numRecord].native;
570 :
571 : return result;
572 : }
573 :
574 0 : ODBC_FUNC(SQLError, (P(SQLHENV,henv), P(SQLHDBC,hdbc), P(SQLHSTMT,hstmt), PCHAR(szSqlState), P(SQLINTEGER FAR *,pfNativeError),
575 : PCHAROUT(ErrorMsg,SQLSMALLINT) WIDE))
576 : {
577 : SQLRETURN result;
578 : SQLSMALLINT type;
579 : SQLHANDLE handle;
580 :
581 0 : if (hstmt) {
582 : handle = hstmt;
583 : type = SQL_HANDLE_STMT;
584 0 : } else if (hdbc) {
585 : handle = hdbc;
586 : type = SQL_HANDLE_DBC;
587 0 : } else if (henv) {
588 : handle = henv;
589 : type = SQL_HANDLE_ENV;
590 : } else
591 : return SQL_INVALID_HANDLE;
592 :
593 0 : result = odbc_SQLGetDiagRec(type, handle, 1, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg _wide);
594 :
595 0 : if (result == SQL_SUCCESS) {
596 : /* remove first error */
597 0 : odbc_errs_pop(&((TDS_CHK *) handle)->errs);
598 : }
599 :
600 : return result;
601 : }
602 :
603 732 : ODBC_FUNC(SQLGetDiagField, (P(SQLSMALLINT,handleType), P(SQLHANDLE,handle), P(SQLSMALLINT,numRecord),
604 : P(SQLSMALLINT,diagIdentifier), P(SQLPOINTER,buffer), P(SQLSMALLINT,cbBuffer), P(SQLSMALLINT FAR *,pcbBuffer) WIDE))
605 : {
606 732 : SQLRETURN result = SQL_SUCCESS;
607 : struct _sql_errors *errs;
608 : const char *msg;
609 :
610 732 : SQLINTEGER odbc_ver = SQL_OV_ODBC2;
611 : int cplen;
612 732 : TDS_STMT *stmt = NULL;
613 732 : TDS_DBC *dbc = NULL;
614 732 : TDS_ENV *env = NULL;
615 : char tmp[16];
616 :
617 732 : if (cbBuffer < 0)
618 : return SQL_ERROR;
619 :
620 732 : if (!handle || ((TDS_CHK *) handle)->htype != handleType)
621 : return SQL_INVALID_HANDLE;
622 :
623 732 : switch (handleType) {
624 732 : case SQL_HANDLE_STMT:
625 732 : stmt = ((TDS_STMT *) handle);
626 732 : dbc = stmt->dbc;
627 732 : env = dbc->env;
628 732 : break;
629 :
630 0 : case SQL_HANDLE_DBC:
631 0 : dbc = ((TDS_DBC *) handle);
632 0 : env = dbc->env;
633 0 : break;
634 :
635 : case SQL_HANDLE_ENV:
636 : env = ((TDS_ENV *) handle);
637 : break;
638 :
639 0 : case SQL_HANDLE_DESC:
640 0 : dbc = desc_get_dbc((TDS_DESC *) handle);
641 0 : env = dbc->env;
642 0 : break;
643 :
644 : default:
645 : return SQL_INVALID_HANDLE;
646 : }
647 732 : errs = &((TDS_CHK *) handle)->errs;
648 732 : odbc_ver = env->attr.odbc_version;
649 :
650 : /* header (numRecord ignored) */
651 732 : switch (diagIdentifier) {
652 0 : case SQL_DIAG_DYNAMIC_FUNCTION:
653 0 : if (handleType != SQL_HANDLE_STMT)
654 : return SQL_ERROR;
655 :
656 : /* TODO */
657 0 : return odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "", 0);
658 :
659 0 : case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
660 0 : *(SQLINTEGER *) buffer = 0;
661 0 : return SQL_SUCCESS;
662 :
663 0 : case SQL_DIAG_NUMBER:
664 0 : *(SQLINTEGER *) buffer = errs->num_errors;
665 0 : return SQL_SUCCESS;
666 :
667 0 : case SQL_DIAG_RETURNCODE:
668 0 : *(SQLRETURN *) buffer = errs->lastrc;
669 0 : return SQL_SUCCESS;
670 :
671 0 : case SQL_DIAG_CURSOR_ROW_COUNT:
672 0 : if (handleType != SQL_HANDLE_STMT)
673 : return SQL_ERROR;
674 :
675 : /* TODO */
676 0 : *(SQLINTEGER *) buffer = 0;
677 0 : return SQL_SUCCESS;
678 :
679 0 : case SQL_DIAG_ROW_COUNT:
680 0 : if (handleType != SQL_HANDLE_STMT)
681 : return SQL_ERROR;
682 :
683 0 : return odbc_SQLRowCount((SQLHSTMT) handle, (SQLLEN FAR *) buffer);
684 : }
685 :
686 732 : if (numRecord > errs->num_errors)
687 : return SQL_NO_DATA_FOUND;
688 :
689 732 : if (numRecord <= 0)
690 : return SQL_ERROR;
691 732 : --numRecord;
692 :
693 732 : switch (diagIdentifier) {
694 732 : case SQL_DIAG_ROW_NUMBER:
695 732 : *(SQLINTEGER *) buffer =
696 732 : errs->errs[numRecord].row > 0 ? errs->errs[numRecord].row : SQL_ROW_NUMBER_UNKNOWN;
697 732 : break;
698 :
699 0 : case SQL_DIAG_CLASS_ORIGIN:
700 : case SQL_DIAG_SUBCLASS_ORIGIN:
701 0 : if (odbc_ver == SQL_OV_ODBC2)
702 0 : result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "ISO 9075", -1);
703 : else
704 0 : result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1);
705 : break;
706 :
707 0 : case SQL_DIAG_COLUMN_NUMBER:
708 0 : *(SQLINTEGER *) buffer = SQL_COLUMN_NUMBER_UNKNOWN;
709 0 : break;
710 :
711 0 : case SQL_DIAG_SS_MSGSTATE:
712 0 : if (errs->errs[numRecord].msgstate == 0)
713 : return SQL_ERROR;
714 : else
715 0 : *(SQLINTEGER *) buffer = errs->errs[numRecord].msgstate;
716 0 : break;
717 :
718 0 : case SQL_DIAG_SS_LINE:
719 0 : if (errs->errs[numRecord].linenum == 0)
720 : return SQL_ERROR;
721 : else
722 0 : *(SQLUSMALLINT *) buffer = errs->errs[numRecord].linenum;
723 0 : break;
724 :
725 0 : case SQL_DIAG_CONNECTION_NAME:
726 0 : if (dbc && dbc->tds_socket && dbc->tds_socket->conn->spid > 0)
727 0 : cplen = sprintf(tmp, "%d", dbc->tds_socket->conn->spid);
728 : else
729 : cplen = 0;
730 :
731 0 : result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, tmp, cplen);
732 0 : break;
733 :
734 0 : case SQL_DIAG_MESSAGE_TEXT:
735 0 : msg = errs->errs[numRecord].msg;
736 0 : result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg, -1);
737 0 : break;
738 :
739 0 : case SQL_DIAG_NATIVE:
740 0 : *(SQLINTEGER *) buffer = errs->errs[numRecord].native;
741 0 : break;
742 :
743 0 : case SQL_DIAG_SERVER_NAME:
744 0 : msg = NULL;
745 0 : switch (handleType) {
746 : case SQL_HANDLE_ENV:
747 : break;
748 0 : case SQL_HANDLE_DBC:
749 0 : if (dbc->tds_socket)
750 0 : msg = dbc->tds_socket->conn->server;
751 : break;
752 0 : case SQL_HANDLE_STMT:
753 0 : if (stmt->dbc->tds_socket)
754 0 : msg = stmt->dbc->tds_socket->conn->server;
755 : /*
756 : * if dbc->server is not initialized, init it
757 : * from the errs structure
758 : */
759 0 : if (!msg && errs->errs[numRecord].server) {
760 0 : msg = errs->errs[numRecord].server;
761 : }
762 : break;
763 : }
764 0 : result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg ? msg : "", -1);
765 0 : break;
766 :
767 0 : case SQL_DIAG_SQLSTATE:
768 0 : if (odbc_ver == SQL_OV_ODBC3)
769 0 : msg = errs->errs[numRecord].state3;
770 : else
771 0 : msg = errs->errs[numRecord].state2;
772 :
773 0 : result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg, 5);
774 0 : break;
775 :
776 : default:
777 : return SQL_ERROR;
778 : }
779 : return result;
780 : }
781 :
782 : #include "error_export.h"
783 :
|