4 * The aim is to get a simpler inteface to the database routines.
5 * All the tidieous messing around with tuples is supposed to be hidden
9 (actually most if the code is "borrowed" from the distribution and just
13 /* Taken over as part of PostgreSQL by Michael Meskes <meskes@postgresql.org>
16 #define POSTGRES_ECPG_INTERNAL
17 #include "postgres_fe.h"
25 #include "ecpgerrno.h"
28 #include "sql3types.h"
29 #include "pgtypes_numeric.h"
30 #include "pgtypes_date.h"
31 #include "pgtypes_timestamp.h"
32 #include "pgtypes_interval.h"
35 * This function returns a newly malloced string that has ' and \
39 quote_postgres(char *arg
, bool quote
, int lineno
)
47 * if quote is false we just need to store things in a descriptor they
48 * will be quoted once they are inserted in a statement
55 buffer_len
= 2 * length
+ 1;
56 res
= (char *) ecpg_alloc(buffer_len
+ 3, lineno
);
59 escaped_len
= PQescapeString(res
+ 1, arg
, buffer_len
);
60 if (length
== escaped_len
)
62 res
[0] = res
[escaped_len
+ 1] = '\'';
63 res
[escaped_len
+ 2] = '\0';
68 * We don't know if the target database is using
69 * standard_conforming_strings, so we always use E'' strings.
71 memmove(res
+ 2, res
+ 1, escaped_len
);
72 res
[0] = ESCAPE_STRING_SYNTAX
;
73 res
[1] = res
[escaped_len
+ 2] = '\'';
74 res
[escaped_len
+ 3] = '\0';
82 free_variable(struct variable
* var
)
84 struct variable
*var_next
;
100 free_statement(struct statement
* stmt
)
104 free_variable(stmt
->inlist
);
105 free_variable(stmt
->outlist
);
106 ecpg_free(stmt
->command
);
107 ecpg_free(stmt
->name
);
112 next_insert(char *text
, int pos
, bool questionmarks
)
117 for (; text
[p
] != '\0'; p
++)
119 if (text
[p
] == '\\') /* escape character */
121 else if (text
[p
] == '\'')
122 string
= string
? false : true;
125 if (text
[p
] == '$' && isdigit((unsigned char) text
[p
+ 1]))
127 /* this can be either a dollar quote or a variable */
130 for (i
= p
+ 1; isdigit((unsigned char) text
[i
]); i
++)
131 /* empty loop body */ ;
132 if (!isalpha((unsigned char) text
[i
]) &&
133 isascii((unsigned char) text
[i
]) && text
[i
] != '_')
134 /* not dollar delimited quote */
137 else if (questionmarks
&& text
[p
] == '?')
139 /* also allow old style placeholders */
149 ecpg_type_infocache_push(struct ECPGtype_information_cache
** cache
, int oid
, bool isarray
, int lineno
)
151 struct ECPGtype_information_cache
*new_entry
152 = (struct ECPGtype_information_cache
*) ecpg_alloc(sizeof(struct ECPGtype_information_cache
), lineno
);
154 if (new_entry
== NULL
)
157 new_entry
->oid
= oid
;
158 new_entry
->isarray
= isarray
;
159 new_entry
->next
= *cache
;
164 static enum ARRAY_TYPE
165 ecpg_is_type_an_array(int type
, const struct statement
* stmt
, const struct variable
* var
)
168 enum ARRAY_TYPE isarray
= ECPG_ARRAY_NOT_SET
;
170 struct ECPGtype_information_cache
*cache_entry
;
172 if ((stmt
->connection
->cache_head
) == NULL
)
175 * Text like types are not an array for ecpg, but postgres counts them
176 * as an array. This define reminds you to not 'correct' these values.
178 #define not_an_array_in_ecpg ECPG_ARRAY_NONE
180 /* populate cache with well known types to speed things up */
181 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), BOOLOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
182 return (ECPG_ARRAY_ERROR
);
183 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), BYTEAOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
184 return (ECPG_ARRAY_ERROR
);
185 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), CHAROID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
186 return (ECPG_ARRAY_ERROR
);
187 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), NAMEOID
, not_an_array_in_ecpg
, stmt
->lineno
))
188 return (ECPG_ARRAY_ERROR
);
189 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), INT8OID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
190 return (ECPG_ARRAY_ERROR
);
191 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), INT2OID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
192 return (ECPG_ARRAY_ERROR
);
193 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), INT2VECTOROID
, ECPG_ARRAY_VECTOR
, stmt
->lineno
))
194 return (ECPG_ARRAY_ERROR
);
195 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), INT4OID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
196 return (ECPG_ARRAY_ERROR
);
197 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), REGPROCOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
198 return (ECPG_ARRAY_ERROR
);
199 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), TEXTOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
200 return (ECPG_ARRAY_ERROR
);
201 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), OIDOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
202 return (ECPG_ARRAY_ERROR
);
203 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), TIDOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
204 return (ECPG_ARRAY_ERROR
);
205 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), XIDOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
206 return (ECPG_ARRAY_ERROR
);
207 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), CIDOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
208 return (ECPG_ARRAY_ERROR
);
209 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), OIDVECTOROID
, ECPG_ARRAY_VECTOR
, stmt
->lineno
))
210 return (ECPG_ARRAY_ERROR
);
211 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), POINTOID
, ECPG_ARRAY_VECTOR
, stmt
->lineno
))
212 return (ECPG_ARRAY_ERROR
);
213 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), LSEGOID
, ECPG_ARRAY_VECTOR
, stmt
->lineno
))
214 return (ECPG_ARRAY_ERROR
);
215 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), PATHOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
216 return (ECPG_ARRAY_ERROR
);
217 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), BOXOID
, ECPG_ARRAY_VECTOR
, stmt
->lineno
))
218 return (ECPG_ARRAY_ERROR
);
219 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), POLYGONOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
220 return (ECPG_ARRAY_ERROR
);
221 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), LINEOID
, ECPG_ARRAY_VECTOR
, stmt
->lineno
))
222 return (ECPG_ARRAY_ERROR
);
223 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), FLOAT4OID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
224 return (ECPG_ARRAY_ERROR
);
225 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), FLOAT8OID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
226 return (ECPG_ARRAY_ERROR
);
227 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), ABSTIMEOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
228 return (ECPG_ARRAY_ERROR
);
229 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), RELTIMEOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
230 return (ECPG_ARRAY_ERROR
);
231 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), TINTERVALOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
232 return (ECPG_ARRAY_ERROR
);
233 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), UNKNOWNOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
234 return (ECPG_ARRAY_ERROR
);
235 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), CIRCLEOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
236 return (ECPG_ARRAY_ERROR
);
237 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), CASHOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
238 return (ECPG_ARRAY_ERROR
);
239 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), INETOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
240 return (ECPG_ARRAY_ERROR
);
241 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), CIDROID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
242 return (ECPG_ARRAY_ERROR
);
243 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), BPCHAROID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
244 return (ECPG_ARRAY_ERROR
);
245 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), VARCHAROID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
246 return (ECPG_ARRAY_ERROR
);
247 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), DATEOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
248 return (ECPG_ARRAY_ERROR
);
249 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), TIMEOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
250 return (ECPG_ARRAY_ERROR
);
251 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), TIMESTAMPOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
252 return (ECPG_ARRAY_ERROR
);
253 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), TIMESTAMPTZOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
254 return (ECPG_ARRAY_ERROR
);
255 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), INTERVALOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
256 return (ECPG_ARRAY_ERROR
);
257 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), TIMETZOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
258 return (ECPG_ARRAY_ERROR
);
259 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), ZPBITOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
260 return (ECPG_ARRAY_ERROR
);
261 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), VARBITOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
262 return (ECPG_ARRAY_ERROR
);
263 if (!ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), NUMERICOID
, ECPG_ARRAY_NONE
, stmt
->lineno
))
264 return (ECPG_ARRAY_ERROR
);
267 for (cache_entry
= (stmt
->connection
->cache_head
); cache_entry
!= NULL
; cache_entry
= cache_entry
->next
)
269 if (cache_entry
->oid
== type
)
270 return cache_entry
->isarray
;
273 array_query
= (char *) ecpg_alloc(strlen("select typlen from pg_type where oid= and typelem<>0") + 11, stmt
->lineno
);
274 if (array_query
== NULL
)
275 return (ECPG_ARRAY_ERROR
);
277 sprintf(array_query
, "select typlen from pg_type where oid=%d and typelem<>0", type
);
278 query
= PQexec(stmt
->connection
->connection
, array_query
);
279 ecpg_free(array_query
);
280 if (!ecpg_check_PQresult(query
, stmt
->lineno
, stmt
->connection
->connection
, stmt
->compat
))
281 return (ECPG_ARRAY_ERROR
);
282 else if (PQresultStatus(query
) == PGRES_TUPLES_OK
)
284 if (PQntuples(query
) == 0)
285 isarray
= ECPG_ARRAY_NONE
;
288 isarray
= (atol((char *) PQgetvalue(query
, 0, 0)) == -1) ? ECPG_ARRAY_ARRAY
: ECPG_ARRAY_VECTOR
;
289 if (ecpg_dynamic_type(type
) == SQL3_CHARACTER
||
290 ecpg_dynamic_type(type
) == SQL3_CHARACTER_VARYING
)
293 * arrays of character strings are not yet implemented
295 isarray
= ECPG_ARRAY_NONE
;
301 return (ECPG_ARRAY_ERROR
);
303 ecpg_type_infocache_push(&(stmt
->connection
->cache_head
), type
, isarray
, stmt
->lineno
);
304 ecpg_log("ecpg_is_type_an_array on line %d: type (%d); C (%d); array (%s)\n", stmt
->lineno
, type
, var
->type
, isarray
? _("yes") : _("no"));
310 ecpg_store_result(const PGresult
*results
, int act_field
,
311 const struct statement
* stmt
, struct variable
* var
)
313 enum ARRAY_TYPE isarray
;
315 ntuples
= PQntuples(results
);
318 if ((isarray
= ecpg_is_type_an_array(PQftype(results
, act_field
), stmt
, var
)) == ECPG_ARRAY_ERROR
)
320 ecpg_raise(stmt
->lineno
, ECPG_OUT_OF_MEMORY
, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
, NULL
);
324 if (isarray
== ECPG_ARRAY_NONE
)
327 * if we don't have enough space, we cannot read all tuples
329 if ((var
->arrsize
> 0 && ntuples
> var
->arrsize
) || (var
->ind_arrsize
> 0 && ntuples
> var
->ind_arrsize
))
331 ecpg_log("ecpg_store_result on line %d: incorrect number of matches; %d don't fit into array of %d\n",
332 stmt
->lineno
, ntuples
, var
->arrsize
);
333 ecpg_raise(stmt
->lineno
, INFORMIX_MODE(stmt
->compat
) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE
: ECPG_TOO_MANY_MATCHES
, ECPG_SQLSTATE_CARDINALITY_VIOLATION
, NULL
);
340 * since we read an array, the variable has to be an array too
342 if (var
->arrsize
== 0)
344 ecpg_raise(stmt
->lineno
, ECPG_NO_ARRAY
, ECPG_SQLSTATE_DATATYPE_MISMATCH
, NULL
);
350 * allocate memory for NULL pointers
352 if ((var
->arrsize
== 0 || var
->varcharsize
== 0) && var
->value
== NULL
)
359 case ECPGt_unsigned_char
:
360 if (!var
->varcharsize
&& !var
->arrsize
)
362 /* special mode for handling char**foo=0 */
363 for (act_tuple
= 0; act_tuple
< ntuples
; act_tuple
++)
364 len
+= strlen(PQgetvalue(results
, act_tuple
, act_field
)) + 1;
365 len
*= var
->offset
; /* should be 1, but YMNK */
366 len
+= (ntuples
+ 1) * sizeof(char *);
370 var
->varcharsize
= 0;
371 /* check strlen for each tuple */
372 for (act_tuple
= 0; act_tuple
< ntuples
; act_tuple
++)
374 int len
= strlen(PQgetvalue(results
, act_tuple
, act_field
)) + 1;
376 if (len
> var
->varcharsize
)
377 var
->varcharsize
= len
;
379 var
->offset
*= var
->varcharsize
;
380 len
= var
->offset
* ntuples
;
384 len
= ntuples
* (var
->varcharsize
+ sizeof(int));
387 len
= var
->offset
* ntuples
;
390 ecpg_log("ecpg_store_result on line %d: allocating memory for %d tuples\n", stmt
->lineno
, ntuples
);
391 var
->value
= (char *) ecpg_alloc(len
, stmt
->lineno
);
394 *((char **) var
->pointer
) = var
->value
;
395 ecpg_add_mem(var
->value
, stmt
->lineno
);
398 /* allocate indicator variable if needed */
399 if ((var
->ind_arrsize
== 0 || var
->ind_varcharsize
== 0) && var
->ind_value
== NULL
&& var
->ind_pointer
!= NULL
)
401 int len
= var
->ind_offset
* ntuples
;
403 var
->ind_value
= (char *) ecpg_alloc(len
, stmt
->lineno
);
406 *((char **) var
->ind_pointer
) = var
->ind_value
;
407 ecpg_add_mem(var
->ind_value
, stmt
->lineno
);
410 /* fill the variable with the tuple(s) */
411 if (!var
->varcharsize
&& !var
->arrsize
&&
412 (var
->type
== ECPGt_char
|| var
->type
== ECPGt_unsigned_char
))
414 /* special mode for handling char**foo=0 */
416 /* filling the array of (char*)s */
417 char **current_string
= (char **) var
->value
;
419 /* storing the data (after the last array element) */
420 char *current_data_location
= (char *) ¤t_string
[ntuples
+ 1];
422 for (act_tuple
= 0; act_tuple
< ntuples
&& status
; act_tuple
++)
424 int len
= strlen(PQgetvalue(results
, act_tuple
, act_field
)) + 1;
426 if (!ecpg_get_data(results
, act_tuple
, act_field
, stmt
->lineno
,
427 var
->type
, var
->ind_type
, current_data_location
,
428 var
->ind_value
, len
, 0, var
->ind_offset
, isarray
, stmt
->compat
, stmt
->force_indicator
))
432 *current_string
= current_data_location
;
433 current_data_location
+= len
;
438 /* terminate the list */
439 *current_string
= NULL
;
443 for (act_tuple
= 0; act_tuple
< ntuples
&& status
; act_tuple
++)
445 if (!ecpg_get_data(results
, act_tuple
, act_field
, stmt
->lineno
,
446 var
->type
, var
->ind_type
, var
->value
,
447 var
->ind_value
, var
->varcharsize
, var
->offset
, var
->ind_offset
, isarray
, stmt
->compat
, stmt
->force_indicator
))
455 ecpg_store_input(const int lineno
, const bool force_indicator
, const struct variable
* var
,
456 char **tobeinserted_p
, bool quote
)
458 char *mallocedval
= NULL
;
459 char *newcopy
= NULL
;
462 * arrays are not possible unless the attribute is an array too FIXME: we
463 * do not know if the attribute is an array here
466 if (var
->arrsize
> 1 &&...)
468 ecpg_raise(lineno
, ECPG_ARRAY_INSERT
, ECPG_SQLSTATE_DATATYPE_MISMATCH
, NULL
);
474 * Some special treatment is needed for records since we want their
475 * contents to arrive in a comma-separated list on insert (I think).
478 *tobeinserted_p
= "";
480 /* check for null value and set input buffer accordingly */
481 switch (var
->ind_type
)
484 case ECPGt_unsigned_short
:
485 if (*(short *) var
->ind_value
< 0)
486 *tobeinserted_p
= NULL
;
489 case ECPGt_unsigned_int
:
490 if (*(int *) var
->ind_value
< 0)
491 *tobeinserted_p
= NULL
;
494 case ECPGt_unsigned_long
:
495 if (*(long *) var
->ind_value
< 0L)
496 *tobeinserted_p
= NULL
;
498 #ifdef HAVE_LONG_LONG_INT_64
499 case ECPGt_long_long
:
500 case ECPGt_unsigned_long_long
:
501 if (*(long long int *) var
->ind_value
< (long long) 0)
502 *tobeinserted_p
= NULL
;
504 #endif /* HAVE_LONG_LONG_INT_64 */
505 case ECPGt_NO_INDICATOR
:
506 if (force_indicator
== false)
508 if (ECPGis_noind_null(var
->type
, var
->value
))
509 *tobeinserted_p
= NULL
;
515 if (*tobeinserted_p
!= NULL
)
517 int asize
= var
->arrsize
? var
->arrsize
: 1;
524 if (!(mallocedval
= ecpg_alloc(asize
* 20, lineno
)))
529 strcpy(mallocedval
, "array [");
531 for (element
= 0; element
< asize
; element
++)
532 sprintf(mallocedval
+ strlen(mallocedval
), "%hd,", ((short *) var
->value
)[element
]);
534 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
537 sprintf(mallocedval
, "%hd", *((short *) var
->value
));
539 *tobeinserted_p
= mallocedval
;
543 if (!(mallocedval
= ecpg_alloc(asize
* 20, lineno
)))
548 strcpy(mallocedval
, "{");
550 for (element
= 0; element
< asize
; element
++)
551 sprintf(mallocedval
+ strlen(mallocedval
), "%d,", ((int *) var
->value
)[element
]);
553 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "}");
556 sprintf(mallocedval
, "%d", *((int *) var
->value
));
558 *tobeinserted_p
= mallocedval
;
561 case ECPGt_unsigned_short
:
562 if (!(mallocedval
= ecpg_alloc(asize
* 20, lineno
)))
567 strcpy(mallocedval
, "array [");
569 for (element
= 0; element
< asize
; element
++)
570 sprintf(mallocedval
+ strlen(mallocedval
), "%hu,", ((unsigned short *) var
->value
)[element
]);
572 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
575 sprintf(mallocedval
, "%hu", *((unsigned short *) var
->value
));
577 *tobeinserted_p
= mallocedval
;
580 case ECPGt_unsigned_int
:
581 if (!(mallocedval
= ecpg_alloc(asize
* 20, lineno
)))
586 strcpy(mallocedval
, "array [");
588 for (element
= 0; element
< asize
; element
++)
589 sprintf(mallocedval
+ strlen(mallocedval
), "%u,", ((unsigned int *) var
->value
)[element
]);
591 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
594 sprintf(mallocedval
, "%u", *((unsigned int *) var
->value
));
596 *tobeinserted_p
= mallocedval
;
600 if (!(mallocedval
= ecpg_alloc(asize
* 20, lineno
)))
605 strcpy(mallocedval
, "array [");
607 for (element
= 0; element
< asize
; element
++)
608 sprintf(mallocedval
+ strlen(mallocedval
), "%ld,", ((long *) var
->value
)[element
]);
610 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
613 sprintf(mallocedval
, "%ld", *((long *) var
->value
));
615 *tobeinserted_p
= mallocedval
;
618 case ECPGt_unsigned_long
:
619 if (!(mallocedval
= ecpg_alloc(asize
* 20, lineno
)))
624 strcpy(mallocedval
, "array [");
626 for (element
= 0; element
< asize
; element
++)
627 sprintf(mallocedval
+ strlen(mallocedval
), "%lu,", ((unsigned long *) var
->value
)[element
]);
629 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
632 sprintf(mallocedval
, "%lu", *((unsigned long *) var
->value
));
634 *tobeinserted_p
= mallocedval
;
636 #ifdef HAVE_LONG_LONG_INT_64
637 case ECPGt_long_long
:
638 if (!(mallocedval
= ecpg_alloc(asize
* 30, lineno
)))
643 strcpy(mallocedval
, "array [");
645 for (element
= 0; element
< asize
; element
++)
646 sprintf(mallocedval
+ strlen(mallocedval
), "%lld,", ((long long *) var
->value
)[element
]);
648 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
651 sprintf(mallocedval
, "%lld", *((long long *) var
->value
));
653 *tobeinserted_p
= mallocedval
;
656 case ECPGt_unsigned_long_long
:
657 if (!(mallocedval
= ecpg_alloc(asize
* 30, lineno
)))
662 strcpy(mallocedval
, "array [");
664 for (element
= 0; element
< asize
; element
++)
665 sprintf(mallocedval
+ strlen(mallocedval
), "%llu,", ((unsigned long long *) var
->value
)[element
]);
667 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
670 sprintf(mallocedval
, "%llu", *((unsigned long long *) var
->value
));
672 *tobeinserted_p
= mallocedval
;
674 #endif /* HAVE_LONG_LONG_INT_64 */
676 if (!(mallocedval
= ecpg_alloc(asize
* 25, lineno
)))
681 strcpy(mallocedval
, "array [");
683 for (element
= 0; element
< asize
; element
++)
684 sprintf(mallocedval
+ strlen(mallocedval
), "%.14g,", ((float *) var
->value
)[element
]);
686 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
689 sprintf(mallocedval
, "%.14g", *((float *) var
->value
));
691 *tobeinserted_p
= mallocedval
;
695 if (!(mallocedval
= ecpg_alloc(asize
* 25, lineno
)))
700 strcpy(mallocedval
, "array [");
702 for (element
= 0; element
< asize
; element
++)
703 sprintf(mallocedval
+ strlen(mallocedval
), "%.14g,", ((double *) var
->value
)[element
]);
705 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
708 sprintf(mallocedval
, "%.14g", *((double *) var
->value
));
710 *tobeinserted_p
= mallocedval
;
714 if (!(mallocedval
= ecpg_alloc(var
->arrsize
+ sizeof("array []"), lineno
)))
717 if (var
->arrsize
> 1)
719 strcpy(mallocedval
, "array [");
721 if (var
->offset
== sizeof(char))
722 for (element
= 0; element
< var
->arrsize
; element
++)
723 sprintf(mallocedval
+ strlen(mallocedval
), "%c,", (((char *) var
->value
)[element
]) ? 't' : 'f');
726 * this is necessary since sizeof(C++'s bool)==sizeof(int)
728 else if (var
->offset
== sizeof(int))
729 for (element
= 0; element
< var
->arrsize
; element
++)
730 sprintf(mallocedval
+ strlen(mallocedval
), "%c,", (((int *) var
->value
)[element
]) ? 't' : 'f');
732 ecpg_raise(lineno
, ECPG_CONVERT_BOOL
, ECPG_SQLSTATE_DATATYPE_MISMATCH
, _("different size"));
734 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
738 if (var
->offset
== sizeof(char))
739 sprintf(mallocedval
, "%c", (*((char *) var
->value
)) ? 't' : 'f');
740 else if (var
->offset
== sizeof(int))
741 sprintf(mallocedval
, "%c", (*((int *) var
->value
)) ? 't' : 'f');
743 ecpg_raise(lineno
, ECPG_CONVERT_BOOL
, ECPG_SQLSTATE_DATATYPE_MISMATCH
, _("different size"));
746 *tobeinserted_p
= mallocedval
;
750 case ECPGt_unsigned_char
:
752 /* set slen to string length if type is char * */
753 int slen
= (var
->varcharsize
== 0) ? strlen((char *) var
->value
) : var
->varcharsize
;
755 if (!(newcopy
= ecpg_alloc(slen
+ 1, lineno
)))
758 strncpy(newcopy
, (char *) var
->value
, slen
);
759 newcopy
[slen
] = '\0';
761 mallocedval
= quote_postgres(newcopy
, quote
, lineno
);
765 *tobeinserted_p
= mallocedval
;
769 case ECPGt_char_variable
:
771 int slen
= strlen((char *) var
->value
);
773 if (!(mallocedval
= ecpg_alloc(slen
+ 1, lineno
)))
776 strncpy(mallocedval
, (char *) var
->value
, slen
);
777 mallocedval
[slen
] = '\0';
779 *tobeinserted_p
= mallocedval
;
784 struct ECPGgeneric_varchar
*variable
=
785 (struct ECPGgeneric_varchar
*) (var
->value
);
787 if (!(newcopy
= (char *) ecpg_alloc(variable
->len
+ 1, lineno
)))
790 strncpy(newcopy
, variable
->arr
, variable
->len
);
791 newcopy
[variable
->len
] = '\0';
793 mallocedval
= quote_postgres(newcopy
, quote
, lineno
);
797 *tobeinserted_p
= mallocedval
;
808 if (var
->arrsize
> 1)
810 for (element
= 0; element
< var
->arrsize
; element
++)
812 nval
= PGTYPESnumeric_new();
816 if (var
->type
== ECPGt_numeric
)
817 PGTYPESnumeric_copy((numeric
*) ((var
+ var
->offset
* element
)->value
), nval
);
819 PGTYPESnumeric_from_decimal((decimal
*) ((var
+ var
->offset
* element
)->value
), nval
);
821 str
= PGTYPESnumeric_to_asc(nval
, nval
->dscale
);
823 PGTYPESnumeric_free(nval
);
825 if (!(mallocedval
= ecpg_realloc(mallocedval
, strlen(mallocedval
) + slen
+ sizeof("array [] "), lineno
)))
832 strcpy(mallocedval
, "array [");
834 strncpy(mallocedval
+ strlen(mallocedval
), str
, slen
+ 1);
835 strcpy(mallocedval
+ strlen(mallocedval
), ",");
838 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
842 nval
= PGTYPESnumeric_new();
846 if (var
->type
== ECPGt_numeric
)
847 PGTYPESnumeric_copy((numeric
*) (var
->value
), nval
);
849 PGTYPESnumeric_from_decimal((decimal
*) (var
->value
), nval
);
851 str
= PGTYPESnumeric_to_asc(nval
, nval
->dscale
);
853 PGTYPESnumeric_free(nval
);
855 if (!(mallocedval
= ecpg_alloc(slen
+ 1, lineno
)))
861 strncpy(mallocedval
, str
, slen
);
862 mallocedval
[slen
] = '\0';
866 *tobeinserted_p
= mallocedval
;
875 if (var
->arrsize
> 1)
877 for (element
= 0; element
< var
->arrsize
; element
++)
879 str
= quote_postgres(PGTYPESinterval_to_asc((interval
*) ((var
+ var
->offset
* element
)->value
)), quote
, lineno
);
884 if (!(mallocedval
= ecpg_realloc(mallocedval
, strlen(mallocedval
) + slen
+ sizeof("array [],interval "), lineno
)))
891 strcpy(mallocedval
, "array [");
893 strncpy(mallocedval
+ strlen(mallocedval
), str
, slen
+ 1);
894 strcpy(mallocedval
+ strlen(mallocedval
), ",");
897 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
901 str
= quote_postgres(PGTYPESinterval_to_asc((interval
*) (var
->value
)), quote
, lineno
);
906 if (!(mallocedval
= ecpg_alloc(slen
+ sizeof("interval ") + 1, lineno
)))
912 /* also copy trailing '\0' */
913 strncpy(mallocedval
+ strlen(mallocedval
), str
, slen
+ 1);
917 *tobeinserted_p
= mallocedval
;
926 if (var
->arrsize
> 1)
928 for (element
= 0; element
< var
->arrsize
; element
++)
930 str
= quote_postgres(PGTYPESdate_to_asc(*(date
*) ((var
+ var
->offset
* element
)->value
)), quote
, lineno
);
935 if (!(mallocedval
= ecpg_realloc(mallocedval
, strlen(mallocedval
) + slen
+ sizeof("array [],date "), lineno
)))
942 strcpy(mallocedval
, "array [");
944 strncpy(mallocedval
+ strlen(mallocedval
), str
, slen
+ 1);
945 strcpy(mallocedval
+ strlen(mallocedval
), ",");
948 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
952 str
= quote_postgres(PGTYPESdate_to_asc(*(date
*) (var
->value
)), quote
, lineno
);
957 if (!(mallocedval
= ecpg_alloc(slen
+ sizeof("date ") + 1, lineno
)))
963 /* also copy trailing '\0' */
964 strncpy(mallocedval
+ strlen(mallocedval
), str
, slen
+ 1);
968 *tobeinserted_p
= mallocedval
;
972 case ECPGt_timestamp
:
977 if (var
->arrsize
> 1)
979 for (element
= 0; element
< var
->arrsize
; element
++)
981 str
= quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp
*) ((var
+ var
->offset
* element
)->value
)), quote
, lineno
);
987 if (!(mallocedval
= ecpg_realloc(mallocedval
, strlen(mallocedval
) + slen
+ sizeof("array [], timestamp "), lineno
)))
994 strcpy(mallocedval
, "array [");
996 strncpy(mallocedval
+ strlen(mallocedval
), str
, slen
+ 1);
997 strcpy(mallocedval
+ strlen(mallocedval
), ",");
1000 strcpy(mallocedval
+ strlen(mallocedval
) - 1, "]");
1004 str
= quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp
*) (var
->value
)), quote
, lineno
);
1009 if (!(mallocedval
= ecpg_alloc(slen
+ sizeof("timestamp") + 1, lineno
)))
1015 /* also copy trailing '\0' */
1016 strncpy(mallocedval
+ strlen(mallocedval
), str
, slen
+ 1);
1020 *tobeinserted_p
= mallocedval
;
1024 case ECPGt_descriptor
:
1028 /* Not implemented yet */
1029 ecpg_raise(lineno
, ECPG_UNSUPPORTED
, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
, (char *) ecpg_type_name(var
->type
));
1038 free_params(const char **paramValues
, int nParams
, bool print
, int lineno
)
1042 for (n
= 0; n
< nParams
; n
++)
1045 ecpg_log("free_params on line %d: parameter %d = %s\n", lineno
, n
+ 1, paramValues
[n
] ? paramValues
[n
] : _("null"));
1046 ecpg_free((void *) (paramValues
[n
]));
1048 ecpg_free(paramValues
);
1053 insert_tobeinserted(int position
, int ph_len
, struct statement
* stmt
, char *tobeinserted
)
1057 if (!(newcopy
= (char *) ecpg_alloc(strlen(stmt
->command
)
1058 + strlen(tobeinserted
)
1059 + 1, stmt
->lineno
)))
1061 ecpg_free(tobeinserted
);
1065 strcpy(newcopy
, stmt
->command
);
1066 strcpy(newcopy
+ position
- 1, tobeinserted
);
1069 * The strange thing in the second argument is the rest of the
1070 * string from the old string
1077 ecpg_free(stmt
->command
);
1078 stmt
->command
= newcopy
;
1080 ecpg_free((char *) tobeinserted
);
1085 ecpg_execute(struct statement
* stmt
)
1087 bool status
= false;
1091 struct variable
*var
;
1092 int desc_counter
= 0;
1093 const char **paramValues
= NULL
;
1096 struct sqlca_t
*sqlca
= ECPGget_sqlca();
1097 bool clear_result
= true;
1100 * If the type is one of the fill in types then we take the argument and
1101 * enter it to our parameter array at the first position. Then if there
1102 * are any more fill in types we add more parameters.
1110 tobeinserted
= NULL
;
1113 * A descriptor is a special case since it contains many variables but
1114 * is listed only once.
1116 if (var
->type
== ECPGt_descriptor
)
1119 * We create an additional variable list here, so the same logic
1122 struct variable desc_inlist
;
1123 struct descriptor
*desc
;
1124 struct descriptor_item
*desc_item
;
1126 desc
= ecpg_find_desc(stmt
->lineno
, var
->pointer
);
1131 for (desc_item
= desc
->items
; desc_item
; desc_item
= desc_item
->next
)
1133 if (desc_item
->num
== desc_counter
)
1135 desc_inlist
.type
= ECPGt_char
;
1136 desc_inlist
.value
= desc_item
->data
;
1137 desc_inlist
.pointer
= &(desc_item
->data
);
1138 desc_inlist
.varcharsize
= strlen(desc_item
->data
);
1139 desc_inlist
.arrsize
= 1;
1140 desc_inlist
.offset
= 0;
1141 if (!desc_item
->indicator
)
1143 desc_inlist
.ind_type
= ECPGt_NO_INDICATOR
;
1144 desc_inlist
.ind_value
= desc_inlist
.ind_pointer
= NULL
;
1145 desc_inlist
.ind_varcharsize
= desc_inlist
.ind_arrsize
= desc_inlist
.ind_offset
= 0;
1149 desc_inlist
.ind_type
= ECPGt_int
;
1150 desc_inlist
.ind_value
= &(desc_item
->indicator
);
1151 desc_inlist
.ind_pointer
= &(desc_inlist
.ind_value
);
1152 desc_inlist
.ind_varcharsize
= desc_inlist
.ind_arrsize
= 1;
1153 desc_inlist
.ind_offset
= 0;
1155 if (!ecpg_store_input(stmt
->lineno
, stmt
->force_indicator
, &desc_inlist
, &tobeinserted
, false))
1161 if (desc
->count
== desc_counter
)
1166 if (!ecpg_store_input(stmt
->lineno
, stmt
->force_indicator
, var
, &tobeinserted
, false))
1171 * now tobeinserted points to an area that contains the next parameter
1172 * now find the positin in the string where it belongs
1174 if ((position
= next_insert(stmt
->command
, position
, stmt
->questionmarks
) + 1) == 0)
1177 * We have an argument but we dont have the matched up
1178 * placeholder in the string
1180 ecpg_raise(stmt
->lineno
, ECPG_TOO_MANY_ARGUMENTS
,
1181 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS
,
1183 free_params(paramValues
, nParams
, false, stmt
->lineno
);
1188 * if var->type=ECPGt_char_variable we have a dynamic cursor we have
1189 * to simulate a dynamic cursor because there is no backend
1190 * functionality for it
1192 if (var
->type
== ECPGt_char_variable
)
1194 int ph_len
= (stmt
->command
[position
] == '?') ? strlen("?") : strlen("$1");
1196 if (!insert_tobeinserted(position
, ph_len
, stmt
, tobeinserted
))
1198 free_params(paramValues
, nParams
, false, stmt
->lineno
);
1201 tobeinserted
= NULL
;
1204 * if the placeholder is '$0' we have to replace it on the client side
1205 * this is for places we want to support variables at that are not supported in the backend
1207 else if (stmt
->command
[position
] == '0' )
1209 if (!insert_tobeinserted(position
, 2, stmt
, tobeinserted
))
1211 free_params(paramValues
, nParams
, false, stmt
->lineno
);
1214 tobeinserted
= NULL
;
1219 if (!(paramValues
= (const char **) ecpg_realloc(paramValues
, sizeof(const char *) * nParams
, stmt
->lineno
)))
1221 ecpg_free(paramValues
);
1225 paramValues
[nParams
- 1] = tobeinserted
;
1227 /* let's see if this was an old style placeholder */
1228 if (stmt
->command
[position
] == '?')
1230 /* yes, replace with new style */
1231 int buffersize
= sizeof(int) * CHAR_BIT
* 10 / 3; /* a rough guess of the
1234 if (!(tobeinserted
= (char *) ecpg_alloc(buffersize
, stmt
->lineno
)))
1236 free_params(paramValues
, nParams
, false, stmt
->lineno
);
1240 snprintf(tobeinserted
, buffersize
, "$%d", counter
++);
1242 if (!insert_tobeinserted(position
, 2, stmt
, tobeinserted
))
1244 free_params(paramValues
, nParams
, false, stmt
->lineno
);
1247 tobeinserted
= NULL
;
1251 if (desc_counter
== 0)
1255 /* Check if there are unmatched things left. */
1256 if (next_insert(stmt
->command
, position
, stmt
->questionmarks
) >= 0)
1258 ecpg_raise(stmt
->lineno
, ECPG_TOO_FEW_ARGUMENTS
,
1259 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS
, NULL
);
1260 free_params(paramValues
, nParams
, false, stmt
->lineno
);
1264 /* The request has been build. */
1266 if (stmt
->connection
->committed
&& !stmt
->connection
->autocommit
)
1268 results
= PQexec(stmt
->connection
->connection
, "begin transaction");
1269 if (!ecpg_check_PQresult(results
, stmt
->lineno
, stmt
->connection
->connection
, stmt
->compat
))
1271 free_params(paramValues
, nParams
, false, stmt
->lineno
);
1275 stmt
->connection
->committed
= false;
1278 ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt
->lineno
, stmt
->command
, nParams
, stmt
->connection
->name
);
1279 if (stmt
->statement_type
== ECPGst_execute
)
1281 results
= PQexecPrepared(stmt
->connection
->connection
, stmt
->name
, nParams
, paramValues
, NULL
, NULL
, 0);
1282 ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt
->lineno
, stmt
->command
);
1288 results
= PQexec(stmt
->connection
->connection
, stmt
->command
);
1289 ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt
->lineno
);
1293 results
= PQexecParams(stmt
->connection
->connection
, stmt
->command
, nParams
, NULL
, paramValues
, NULL
, NULL
, 0);
1294 ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt
->lineno
);
1298 free_params(paramValues
, nParams
, true, stmt
->lineno
);
1300 if (!ecpg_check_PQresult(results
, stmt
->lineno
, stmt
->connection
->connection
, stmt
->compat
))
1303 var
= stmt
->outlist
;
1304 switch (PQresultStatus(results
))
1310 case PGRES_TUPLES_OK
:
1311 nfields
= PQnfields(results
);
1312 sqlca
->sqlerrd
[2] = ntuples
= PQntuples(results
);
1313 ecpg_log("ecpg_execute on line %d: correctly got %d tuples with %d fields\n", stmt
->lineno
, ntuples
, nfields
);
1319 ecpg_log("ecpg_execute on line %d: incorrect number of matches (%d)\n",
1320 stmt
->lineno
, ntuples
);
1321 ecpg_raise(stmt
->lineno
, ECPG_NOT_FOUND
, ECPG_SQLSTATE_NO_DATA
, NULL
);
1326 if (var
!= NULL
&& var
->type
== ECPGt_descriptor
)
1328 struct descriptor
*desc
= ecpg_find_desc(stmt
->lineno
, var
->pointer
);
1335 PQclear(desc
->result
);
1336 desc
->result
= results
;
1337 clear_result
= false;
1338 ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into descriptor %s\n",
1339 stmt
->lineno
, PQntuples(results
), (const char *) var
->pointer
);
1344 for (act_field
= 0; act_field
< nfields
&& status
; act_field
++)
1348 status
= ecpg_store_result(results
, act_field
, stmt
, var
);
1351 else if (!INFORMIX_MODE(stmt
->compat
))
1353 ecpg_raise(stmt
->lineno
, ECPG_TOO_FEW_ARGUMENTS
, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS
, NULL
);
1358 if (status
&& var
!= NULL
)
1360 ecpg_raise(stmt
->lineno
, ECPG_TOO_MANY_ARGUMENTS
, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS
, NULL
);
1365 case PGRES_COMMAND_OK
:
1367 cmdstat
= PQcmdStatus(results
);
1368 sqlca
->sqlerrd
[1] = PQoidValue(results
);
1369 sqlca
->sqlerrd
[2] = atol(PQcmdTuples(results
));
1370 ecpg_log("ecpg_execute on line %d: OK: %s\n", stmt
->lineno
, cmdstat
);
1371 if (stmt
->compat
!= ECPG_COMPAT_INFORMIX_SE
&&
1372 !sqlca
->sqlerrd
[2] &&
1373 (!strncmp(cmdstat
, "UPDATE", 6)
1374 || !strncmp(cmdstat
, "INSERT", 6)
1375 || !strncmp(cmdstat
, "DELETE", 6)))
1376 ecpg_raise(stmt
->lineno
, ECPG_NOT_FOUND
, ECPG_SQLSTATE_NO_DATA
, NULL
);
1378 case PGRES_COPY_OUT
:
1383 ecpg_log("ecpg_execute on line %d: COPY OUT data transfer in progress\n", stmt
->lineno
);
1384 while ((res
= PQgetCopyData(stmt
->connection
->connection
,
1387 printf("%s", buffer
);
1394 results
= PQgetResult(stmt
->connection
->connection
);
1395 if (PQresultStatus(results
) == PGRES_COMMAND_OK
)
1396 ecpg_log("ecpg_execute on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt
->lineno
);
1398 ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", PQresultErrorMessage(results
));
1405 * execution should never reach this code because it is already
1406 * handled in ECPGcheck_PQresult()
1408 ecpg_log("ecpg_execute on line %d: unknown execution status type\n",
1410 ecpg_raise_backend(stmt
->lineno
, results
, stmt
->connection
->connection
, stmt
->compat
);
1417 /* check for asynchronous returns */
1418 notify
= PQnotifies(stmt
->connection
->connection
);
1421 ecpg_log("ecpg_execute on line %d: asynchronous notification of \"%s\" from backend pid %d received\n",
1422 stmt
->lineno
, notify
->relname
, notify
->be_pid
);
1430 ECPGdo(const int lineno
, const int compat
, const int force_indicator
, const char *connection_name
, const bool questionmarks
, const int st
, const char *query
,...)
1433 struct statement
*stmt
;
1434 struct connection
*con
;
1437 enum ECPGttype type
;
1438 struct variable
**list
;
1439 enum ECPG_statement_type statement_type
= (enum ECPG_statement_type
) st
;
1444 ecpg_raise(lineno
, ECPG_EMPTY
, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
, NULL
);
1448 /* Make sure we do NOT honor the locale for numeric input/output */
1449 /* since the database wants the standard decimal point */
1450 oldlocale
= ecpg_strdup(setlocale(LC_NUMERIC
, NULL
), lineno
);
1451 setlocale(LC_NUMERIC
, "C");
1453 #ifdef ENABLE_THREAD_SAFETY
1454 ecpg_pthreads_init();
1457 con
= ecpg_get_connection(connection_name
);
1459 if (!ecpg_init(con
, connection_name
, lineno
))
1461 setlocale(LC_NUMERIC
, oldlocale
);
1462 ecpg_free(oldlocale
);
1466 /* construct statement in our own structure */
1467 va_start(args
, query
);
1470 * create a list of variables The variables are listed with input
1471 * variables preceding outputvariables The end of each group is marked by
1472 * an end marker. per variable we list: type - as defined in ecpgtype.h
1473 * value - where to store the data varcharsize - length of string in case
1474 * we have a stringvariable, else 0 arraysize - 0 for pointer (we don't
1475 * know the size of the array), 1 for simple variable, size for arrays
1476 * offset - offset between ith and (i+1)th entry in an array, normally
1477 * that means sizeof(type) ind_type - type of indicator variable ind_value
1478 * - pointer to indicator variable ind_varcharsize - empty ind_arraysize -
1479 * arraysize of indicator array ind_offset - indicator offset
1481 if (!(stmt
= (struct statement
*) ecpg_alloc(sizeof(struct statement
), lineno
)))
1483 setlocale(LC_NUMERIC
, oldlocale
);
1484 ecpg_free(oldlocale
);
1490 * If statement type is ECPGst_prepnormal we are supposed to prepare the
1491 * statement before executing them
1493 if (statement_type
== ECPGst_prepnormal
)
1495 if (!ecpg_auto_prepare(lineno
, connection_name
, compat
, questionmarks
, &prepname
, query
))
1499 * statement is now prepared, so instead of the query we have to
1502 stmt
->command
= prepname
;
1503 statement_type
= ECPGst_execute
;
1506 stmt
->command
= ecpg_strdup(query
, lineno
);
1510 if (statement_type
== ECPGst_execute
)
1512 /* if we have an EXECUTE command, only the name is send */
1513 char *command
= ecpg_prepared(stmt
->command
, con
, lineno
);
1517 stmt
->name
= stmt
->command
;
1518 stmt
->command
= ecpg_strdup(command
, lineno
);
1521 ecpg_raise(lineno
, ECPG_INVALID_STMT
, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME
, stmt
->command
);
1524 stmt
->connection
= con
;
1525 stmt
->lineno
= lineno
;
1526 stmt
->compat
= compat
;
1527 stmt
->force_indicator
= force_indicator
;
1528 stmt
->questionmarks
= questionmarks
;
1529 stmt
->statement_type
= statement_type
;
1531 list
= &(stmt
->inlist
);
1533 type
= va_arg(args
, enum ECPGttype
);
1535 while (type
!= ECPGt_EORT
)
1537 if (type
== ECPGt_EOIT
)
1538 list
= &(stmt
->outlist
);
1541 struct variable
*var
,
1544 if (!(var
= (struct variable
*) ecpg_alloc(sizeof(struct variable
), lineno
)))
1546 setlocale(LC_NUMERIC
, oldlocale
);
1547 ecpg_free(oldlocale
);
1548 free_statement(stmt
);
1554 var
->pointer
= va_arg(args
, char *);
1556 var
->varcharsize
= va_arg(args
, long);
1557 var
->arrsize
= va_arg(args
, long);
1558 var
->offset
= va_arg(args
, long);
1560 if (var
->arrsize
== 0 || var
->varcharsize
== 0)
1561 var
->value
= *((char **) (var
->pointer
));
1563 var
->value
= var
->pointer
;
1566 * negative values are used to indicate an array without given
1569 /* reset to zero for us */
1570 if (var
->arrsize
< 0)
1572 if (var
->varcharsize
< 0)
1573 var
->varcharsize
= 0;
1577 var
->ind_type
= va_arg(args
, enum ECPGttype
);
1578 var
->ind_pointer
= va_arg(args
, char *);
1579 var
->ind_varcharsize
= va_arg(args
, long);
1580 var
->ind_arrsize
= va_arg(args
, long);
1581 var
->ind_offset
= va_arg(args
, long);
1583 if (var
->ind_type
!= ECPGt_NO_INDICATOR
1584 && (var
->ind_arrsize
== 0 || var
->ind_varcharsize
== 0))
1585 var
->ind_value
= *((char **) (var
->ind_pointer
));
1587 var
->ind_value
= var
->ind_pointer
;
1590 * negative values are used to indicate an array without given
1593 /* reset to zero for us */
1594 if (var
->ind_arrsize
< 0)
1595 var
->ind_arrsize
= 0;
1596 if (var
->ind_varcharsize
< 0)
1597 var
->ind_varcharsize
= 0;
1599 /* if variable is NULL, the statement hasn't been prepared */
1600 if (var
->pointer
== NULL
)
1602 ecpg_raise(lineno
, ECPG_INVALID_STMT
, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME
, NULL
);
1604 setlocale(LC_NUMERIC
, oldlocale
);
1605 ecpg_free(oldlocale
);
1606 free_statement(stmt
);
1611 for (ptr
= *list
; ptr
&& ptr
->next
; ptr
= ptr
->next
);
1619 type
= va_arg(args
, enum ECPGttype
);
1624 /* are we connected? */
1625 if (con
== NULL
|| con
->connection
== NULL
)
1627 free_statement(stmt
);
1628 ecpg_raise(lineno
, ECPG_NOT_CONN
, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
, (con
) ? con
->name
: _("<empty>"));
1629 setlocale(LC_NUMERIC
, oldlocale
);
1630 ecpg_free(oldlocale
);
1634 /* initialize auto_mem struct */
1635 ecpg_clear_auto_mem();
1637 status
= ecpg_execute(stmt
);
1638 free_statement(stmt
);
1640 /* and reset locale value so our application is not affected */
1641 setlocale(LC_NUMERIC
, oldlocale
);
1642 ecpg_free(oldlocale
);
1647 /* old descriptor interface */
1649 ECPGdo_descriptor(int line
, const char *connection
,
1650 const char *descriptor
, const char *query
)
1652 return ECPGdo(line
, ECPG_COMPAT_PGSQL
, true, connection
, '\0', 0, (char *) query
, ECPGt_EOIT
,
1653 ECPGt_descriptor
, descriptor
, 0L, 0L, 0L,
1654 ECPGt_NO_INDICATOR
, NULL
, 0L, 0L, 0L, ECPGt_EORT
);