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 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 233337 : odbc_errs_reset(struct _sql_errors *errs)
346 : {
347 : int i;
348 :
349 233337 : if (errs->errs) {
350 31226 : for (i = 0; i < errs->num_errors; ++i) {
351 : /* TODO see flags */
352 31226 : free((char *) errs->errs[i].msg);
353 31226 : free(errs->errs[i].server);
354 : }
355 4966 : TDS_ZERO_FREE(errs->errs);
356 4966 : errs->num_errors = 0;
357 : }
358 233337 : errs->lastrc = SQL_SUCCESS;
359 233337 : errs->ranked = 0;
360 233337 : assert(errs->num_errors == 0);
361 233337 : }
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 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 26992 : errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
406 26992 : ++errs->num_errors;
407 :
408 : /* updated last error */
409 26992 : 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 25420 : errs->lastrc = SQL_ERROR;
414 : }
415 :
416 26992 : 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 :
|