1/* src/interfaces/ecpg/ecpglib/error.c */
2
3#define POSTGRES_ECPG_INTERNAL
4#include "postgres_fe.h"
5
6#include "ecpgerrno.h"
7#include "ecpgtype.h"
8#include "ecpglib.h"
9#include "ecpglib_extern.h"
10#include "sqlca.h"
11
12void
13ecpg_raise(int line, int code, const char *sqlstate, const char *str)
14{
15 struct sqlca_t *sqlca = ECPGget_sqlca();
16
17 if (sqlca == NULL)
18 {
19 ecpg_log("out of memory");
20 ECPGfree_auto_mem();
21 return;
22 }
23
24 sqlca->sqlcode = code;
25 strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
26
27 switch (code)
28 {
29 case ECPG_NOT_FOUND:
30 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
31 /*------
32 translator: this string will be truncated at 149 characters expanded. */
33 ecpg_gettext("no data found on line %d"), line);
34 break;
35
36 case ECPG_OUT_OF_MEMORY:
37 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
38 /*------
39 translator: this string will be truncated at 149 characters expanded. */
40 ecpg_gettext("out of memory on line %d"), line);
41 break;
42
43 case ECPG_UNSUPPORTED:
44 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
45 /*------
46 translator: this string will be truncated at 149 characters expanded. */
47 ecpg_gettext("unsupported type \"%s\" on line %d"), str, line);
48 break;
49
50 case ECPG_TOO_MANY_ARGUMENTS:
51 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
52 /*------
53 translator: this string will be truncated at 149 characters expanded. */
54 ecpg_gettext("too many arguments on line %d"), line);
55 break;
56
57 case ECPG_TOO_FEW_ARGUMENTS:
58 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
59 /*------
60 translator: this string will be truncated at 149 characters expanded. */
61 ecpg_gettext("too few arguments on line %d"), line);
62 break;
63
64 case ECPG_INT_FORMAT:
65 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
66 /*------
67 translator: this string will be truncated at 149 characters expanded. */
68 ecpg_gettext("invalid input syntax for type int: \"%s\", on line %d"), str, line);
69 break;
70
71 case ECPG_UINT_FORMAT:
72 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
73 /*------
74 translator: this string will be truncated at 149 characters expanded. */
75 ecpg_gettext("invalid input syntax for type unsigned int: \"%s\", on line %d"), str, line);
76 break;
77
78 case ECPG_FLOAT_FORMAT:
79 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
80 /*------
81 translator: this string will be truncated at 149 characters expanded. */
82 ecpg_gettext("invalid input syntax for floating-point type: \"%s\", on line %d"), str, line);
83 break;
84
85 case ECPG_CONVERT_BOOL:
86 if (str)
87 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
88 /*------
89 translator: this string will be truncated at 149 characters expanded. */
90 ecpg_gettext("invalid syntax for type boolean: \"%s\", on line %d"), str, line);
91 else
92 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
93 /*------
94 translator: this string will be truncated at 149 characters expanded. */
95 ecpg_gettext("could not convert boolean value: size mismatch, on line %d"), line);
96 break;
97
98 case ECPG_EMPTY:
99 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
100 /*------
101 translator: this string will be truncated at 149 characters expanded. */
102 ecpg_gettext("empty query on line %d"), line);
103 break;
104
105 case ECPG_MISSING_INDICATOR:
106 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
107 /*------
108 translator: this string will be truncated at 149 characters expanded. */
109 ecpg_gettext("null value without indicator on line %d"), line);
110 break;
111
112 case ECPG_NO_ARRAY:
113 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
114 /*------
115 translator: this string will be truncated at 149 characters expanded. */
116 ecpg_gettext("variable does not have an array type on line %d"), line);
117 break;
118
119 case ECPG_DATA_NOT_ARRAY:
120 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
121 /*------
122 translator: this string will be truncated at 149 characters expanded. */
123 ecpg_gettext("data read from server is not an array on line %d"), line);
124 break;
125
126 case ECPG_ARRAY_INSERT:
127 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
128 /*------
129 translator: this string will be truncated at 149 characters expanded. */
130 ecpg_gettext("inserting an array of variables is not supported on line %d"), line);
131 break;
132
133 case ECPG_NO_CONN:
134 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
135 /*------
136 translator: this string will be truncated at 149 characters expanded. */
137 ecpg_gettext("connection \"%s\" does not exist on line %d"), str, line);
138 break;
139
140 case ECPG_NOT_CONN:
141 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
142 /*------
143 translator: this string will be truncated at 149 characters expanded. */
144 ecpg_gettext("not connected to connection \"%s\" on line %d"), str, line);
145 break;
146
147 case ECPG_INVALID_STMT:
148 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
149 /*------
150 translator: this string will be truncated at 149 characters expanded. */
151 ecpg_gettext("invalid statement name \"%s\" on line %d"), str, line);
152 break;
153
154 case ECPG_UNKNOWN_DESCRIPTOR:
155 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
156 /*------
157 translator: this string will be truncated at 149 characters expanded. */
158 ecpg_gettext("descriptor \"%s\" not found on line %d"), str, line);
159 break;
160
161 case ECPG_INVALID_DESCRIPTOR_INDEX:
162 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
163 /*------
164 translator: this string will be truncated at 149 characters expanded. */
165 ecpg_gettext("descriptor index out of range on line %d"), line);
166 break;
167
168 case ECPG_UNKNOWN_DESCRIPTOR_ITEM:
169 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
170 /*------
171 translator: this string will be truncated at 149 characters expanded. */
172 ecpg_gettext("unrecognized descriptor item \"%s\" on line %d"), str, line);
173 break;
174
175 case ECPG_VAR_NOT_NUMERIC:
176 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
177 /*------
178 translator: this string will be truncated at 149 characters expanded. */
179 ecpg_gettext("variable does not have a numeric type on line %d"), line);
180 break;
181
182 case ECPG_VAR_NOT_CHAR:
183 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
184 /*------
185 translator: this string will be truncated at 149 characters expanded. */
186 ecpg_gettext("variable does not have a character type on line %d"), line);
187 break;
188
189 case ECPG_TRANS:
190 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
191 /*------
192 translator: this string will be truncated at 149 characters expanded. */
193 ecpg_gettext("error in transaction processing on line %d"), line);
194 break;
195
196 case ECPG_CONNECT:
197 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
198 /*------
199 translator: this string will be truncated at 149 characters expanded. */
200 ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
201 break;
202
203 default:
204 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
205 /*------
206 translator: this string will be truncated at 149 characters expanded. */
207 ecpg_gettext("SQL error %d on line %d"), code, line);
208 break;
209 }
210
211 sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
212 ecpg_log("raising sqlcode %d on line %d: %s\n", code, line, sqlca->sqlerrm.sqlerrmc);
213
214 /* free all memory we have allocated for the user */
215 ECPGfree_auto_mem();
216}
217
218void
219ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat)
220{
221 struct sqlca_t *sqlca = ECPGget_sqlca();
222 char *sqlstate;
223 char *message;
224
225 if (sqlca == NULL)
226 {
227 ecpg_log("out of memory");
228 ECPGfree_auto_mem();
229 return;
230 }
231
232 if (result)
233 {
234 sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
235 if (sqlstate == NULL)
236 sqlstate = ECPG_SQLSTATE_ECPG_INTERNAL_ERROR;
237 message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
238 }
239 else
240 {
241 sqlstate = ECPG_SQLSTATE_ECPG_INTERNAL_ERROR;
242 message = PQerrorMessage(conn);
243 }
244
245 if (strcmp(sqlstate, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR) == 0)
246 {
247 /*
248 * we might get here if the connection breaks down, so let's check for
249 * this instead of giving just the generic internal error
250 */
251 if (PQstatus(conn) == CONNECTION_BAD)
252 {
253 sqlstate = "57P02";
254 message = ecpg_gettext("the connection to the server was lost");
255 }
256 }
257
258 /* copy error message */
259 snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "%s on line %d", message, line);
260 sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
261
262 /* copy SQLSTATE */
263 strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
264
265 /* assign SQLCODE for backward compatibility */
266 if (strncmp(sqlca->sqlstate, "23505", sizeof(sqlca->sqlstate)) == 0)
267 sqlca->sqlcode = INFORMIX_MODE(compat) ? ECPG_INFORMIX_DUPLICATE_KEY : ECPG_DUPLICATE_KEY;
268 else if (strncmp(sqlca->sqlstate, "21000", sizeof(sqlca->sqlstate)) == 0)
269 sqlca->sqlcode = INFORMIX_MODE(compat) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE : ECPG_SUBSELECT_NOT_ONE;
270 else
271 sqlca->sqlcode = ECPG_PGSQL;
272
273 /* %.*s is safe here as long as sqlstate is all-ASCII */
274 ecpg_log("raising sqlstate %.*s (sqlcode %ld): %s\n",
275 (int) sizeof(sqlca->sqlstate), sqlca->sqlstate, sqlca->sqlcode, sqlca->sqlerrm.sqlerrmc);
276
277 /* free all memory we have allocated for the user */
278 ECPGfree_auto_mem();
279}
280
281/* filter out all error codes */
282bool
283ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
284{
285 if (results == NULL)
286 {
287 ecpg_log("ecpg_check_PQresult on line %d: no result - %s", lineno, PQerrorMessage(connection));
288 ecpg_raise_backend(lineno, NULL, connection, compat);
289 return false;
290 }
291
292 switch (PQresultStatus(results))
293 {
294
295 case PGRES_TUPLES_OK:
296 return true;
297 break;
298 case PGRES_EMPTY_QUERY:
299 /* do nothing */
300 ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
301 PQclear(results);
302 return false;
303 break;
304 case PGRES_COMMAND_OK:
305 return true;
306 break;
307 case PGRES_NONFATAL_ERROR:
308 case PGRES_FATAL_ERROR:
309 case PGRES_BAD_RESPONSE:
310 ecpg_log("ecpg_check_PQresult on line %d: bad response - %s", lineno, PQresultErrorMessage(results));
311 ecpg_raise_backend(lineno, results, connection, compat);
312 PQclear(results);
313 return false;
314 break;
315 case PGRES_COPY_OUT:
316 return true;
317 break;
318 case PGRES_COPY_IN:
319 ecpg_log("ecpg_check_PQresult on line %d: COPY IN data transfer in progress\n", lineno);
320 PQendcopy(connection);
321 PQclear(results);
322 return false;
323 break;
324 default:
325 ecpg_log("ecpg_check_PQresult on line %d: unknown execution status type\n",
326 lineno);
327 ecpg_raise_backend(lineno, results, connection, compat);
328 PQclear(results);
329 return false;
330 break;
331 }
332}
333
334/* print out an error message */
335void
336sqlprint(void)
337{
338 struct sqlca_t *sqlca = ECPGget_sqlca();
339
340 if (sqlca == NULL)
341 {
342 ecpg_log("out of memory");
343 return;
344 }
345
346 sqlca->sqlerrm.sqlerrmc[sqlca->sqlerrm.sqlerrml] = '\0';
347 fprintf(stderr, ecpg_gettext("SQL error: %s\n"), sqlca->sqlerrm.sqlerrmc);
348}
349