1 /* Copyright comment */
3 * The aim is to get a simpler inteface to the database routines.
4 * All the tidieous messing around with tuples is supposed to be hidden
8 (actually most if the code is "borrowed" from the distribution and just
12 /* Taken over as part of PostgreSQL by Michael Meskes <meskes@debian.org>
23 #include <libpq/pqcomm.h>
28 /* variables visible to the programs */
31 static struct sqlca sqlca_init =
33 {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
37 {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
39 {0, 0, 0, 0, 0, 0, 0, 0},
40 {0, 0, 0, 0, 0, 0, 0, 0}
45 {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
49 {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
51 {0, 0, 0, 0, 0, 0, 0, 0},
52 {0, 0, 0, 0, 0, 0, 0, 0}
55 static struct connection
60 struct connection *next;
61 } *all_connections = NULL, *actual_connection = NULL;
71 enum ECPGttype ind_type;
76 struct variable *next;
83 struct connection *connection;
84 struct variable *inlist;
85 struct variable *outlist;
88 struct prepared_statement
91 struct statement *stmt;
92 struct prepared_statement *next;
98 struct auto_mem *next;
99 } *auto_allocs = NULL;
101 static int simple_debug = 0;
102 static FILE *debugstream = NULL;
105 register_error(long code, char *fmt,...)
110 sqlca.sqlcode = code;
112 vsprintf(sqlca.sqlerrm.sqlerrmc, fmt, args);
114 sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
116 /* free all memory we allocate for the user */
117 for (am = auto_allocs; am;)
119 struct auto_mem *act = am;
129 static struct connection *
130 get_connection(const char *connection_name)
132 struct connection *con = all_connections;;
134 if (connection_name == NULL || strcmp(connection_name, "CURRENT") == 0)
135 return actual_connection;
137 for (; con && strcmp(connection_name, con->name) != 0; con = con->next);
145 ECPGfinish(struct connection * act)
149 ECPGlog("ECPGfinish: finishing %s.\n", act->name);
150 PQfinish(act->connection);
151 /* remove act from the list */
152 if (act == all_connections)
154 all_connections = act->next;
160 struct connection *con;
162 for (con = all_connections; con->next && con->next != act; con = con->next);
165 con->next = act->next;
171 if (actual_connection == act)
172 actual_connection = all_connections;
175 ECPGlog("ECPGfinish: called an extra time.\n");
179 ecpg_alloc(long size, int lineno)
181 char *new = (char *) malloc(size);
185 ECPGlog("out of memory\n");
186 register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
190 memset(new, '\0', size);
195 ecpg_strdup(const char *string, int lineno)
197 char *new = strdup(string);
201 ECPGlog("out of memory\n");
202 register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
210 add_mem(void *ptr, int lineno)
212 struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno);
214 am->next = auto_allocs;
218 /* This function returns a newly malloced string that has the ' and \
219 in the argument quoted with \.
223 quote_postgres(char *arg, int lineno)
225 char *res = (char *) ecpg_alloc(2 * strlen(arg) + 1, lineno);
232 for (i = 0, ri = 0; arg[i]; i++, ri++)
250 /* This function returns a newly malloced string that has the \
251 in the strings inside the argument quoted with another \.
255 quote_strings(char *arg, int lineno)
257 char *res = (char *) ecpg_alloc(2 * strlen(arg) + 1, lineno);
265 for (i = 0, ri = 0; arg[i]; i++, ri++)
270 string = string ? false : true;
286 * create a list of variables
287 * The variables are listed with input variables preceeding outputvariables
288 * The end of each group is marked by an end marker.
289 * per variable we list:
290 * type - as defined in ecpgtype.h
291 * value - where to store the data
292 * varcharsize - length of string in case we have a stringvariable, else 0
293 * arraysize - 0 for pointer (we don't know the size of the array),
294 * 1 for simple variable, size for arrays
295 * offset - offset between ith and (i+1)th entry in an array,
296 * normally that means sizeof(type)
297 * ind_type - type of indicator variable
298 * ind_value - pointer to indicator variable
299 * ind_varcharsize - empty
300 * ind_arraysize - arraysize of indicator array
301 * ind_offset - indicator offset
304 create_statement(int lineno, struct connection *connection, struct statement ** stmt, char *query, va_list ap)
306 struct variable **list = &((*stmt)->inlist);
309 if (!(*stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
312 (*stmt)->command = query;
313 (*stmt)->connection = connection;
314 (*stmt)->lineno = lineno;
316 list = &((*stmt)->inlist);
318 type = va_arg(ap, enum ECPGttype);
320 while (type != ECPGt_EORT)
322 if (type == ECPGt_EOIT)
323 list = &((*stmt)->outlist);
326 struct variable *var,
329 if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
333 var->pointer = va_arg(ap, void *);
335 /* if variable is NULL, the statement hasn't been prepared */
336 if (var->pointer == NULL)
338 ECPGlog("create_statement: invalid statement name\n");
339 register_error(ECPG_INVALID_STMT, "Invalid statement name in line %d", lineno);
344 var->varcharsize = va_arg(ap, long);
345 var->arrsize = va_arg(ap, long);
346 var->offset = va_arg(ap, long);
348 if (var->arrsize == 0 || var->varcharsize == 0)
349 var->value = *((void **)(var->pointer));
351 var->value = var->pointer;
353 var->ind_type = va_arg(ap, enum ECPGttype);
354 var->ind_value = va_arg(ap, void *);
355 var->ind_varcharsize = va_arg(ap, long);
356 var->ind_arrsize = va_arg(ap, long);
357 var->ind_offset = va_arg(ap, long);
360 for (ptr = *list; ptr && ptr->next; ptr = ptr->next);
368 type = va_arg(ap, enum ECPGttype);
375 next_insert(char *text)
380 for (; ptr[1] != '\0' && (ptr[0] != ';' || ptr[1] != ';' || string); ptr++)
382 string = string ? false : true;
384 return (ptr[1] == '\0') ? NULL : ptr;
388 ECPGexecute(struct statement * stmt)
394 struct variable *var;
396 memcpy((char *) &sqlca, (char *) &sqlca_init, sizeof(sqlca));
398 copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
401 * Now, if the type is one of the fill in types then we take the
402 * argument and enter that in the string at the first %s position.
403 * Then if there are any more fill in types we fill in at the next and
410 char *mallocedval = NULL;
411 char *tobeinserted = NULL;
416 * Some special treatment is needed for records since we want
417 * their contents to arrive in a comma-separated list on insert (I
423 /* check for null value and set input buffer accordingly */
424 switch (var->ind_type)
427 case ECPGt_unsigned_short:
428 if (*(short *) var->ind_value < 0)
429 strcpy(buff, "null");
432 case ECPGt_unsigned_int:
433 if (*(int *) var->ind_value < 0)
434 strcpy(buff, "null");
437 case ECPGt_unsigned_long:
438 if (*(long *) var->ind_value < 0L)
439 strcpy(buff, "null");
451 sprintf(buff, "%d", *(int *) var->value);
455 case ECPGt_unsigned_short:
456 case ECPGt_unsigned_int:
457 sprintf(buff, "%d", *(unsigned int *) var->value);
462 sprintf(buff, "%ld", *(long *) var->value);
466 case ECPGt_unsigned_long:
467 sprintf(buff, "%ld", *(unsigned long *) var->value);
472 sprintf(buff, "%.14g", *(float *) var->value);
477 sprintf(buff, "%.14g", *(double *) var->value);
482 sprintf(buff, "'%c'", (*(char *) var->value ? 't' : 'f'));
487 case ECPGt_unsigned_char:
489 /* set slen to string length if type is char * */
490 int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize;
493 if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
496 strncpy(newcopy, (char *) var->value, slen);
497 newcopy[slen] = '\0';
499 if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
502 strcpy(mallocedval, "'");
503 tmp = quote_postgres(newcopy, stmt->lineno);
507 strcat(mallocedval, tmp);
508 strcat(mallocedval, "'");
512 tobeinserted = mallocedval;
515 case ECPGt_char_variable:
517 int slen = strlen((char *) var->value);
520 if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
523 strncpy(newcopy, (char *) var->value, slen);
524 newcopy[slen] = '\0';
525 if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 1, stmt->lineno)))
528 tmp = quote_strings(newcopy, stmt->lineno);
532 strcat(mallocedval, tmp);
535 tobeinserted = mallocedval;
540 struct ECPGgeneric_varchar *variable =
541 (struct ECPGgeneric_varchar *) (var->value);
544 if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, stmt->lineno)))
547 strncpy(newcopy, variable->arr, variable->len);
548 newcopy[variable->len] = '\0';
550 if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
553 strcpy(mallocedval, "'");
554 tmp = quote_postgres(newcopy, stmt->lineno);
558 strcat(mallocedval, tmp);
559 strcat(mallocedval, "'");
563 tobeinserted = mallocedval;
568 /* Not implemented yet */
569 register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.",
570 ECPGtype_name(var->type), stmt->lineno);
579 * Now tobeinserted points to an area that is to be inserted at
582 if (!(newcopy = (char *) ecpg_alloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
585 strcpy(newcopy, copiedquery);
586 if ((p = next_insert(newcopy)) == NULL)
590 * We have an argument but we dont have the matched up string
593 register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", stmt->lineno);
598 strcpy(p, tobeinserted);
601 * The strange thing in the second argument is the rest of the
602 * string from the old string
607 + sizeof(";;") - 1 /* don't count the '\0' */);
611 * Now everything is safely copied to the newcopy. Lets free the
612 * oldcopy and let the copiedquery get the var->value from the
615 if (mallocedval != NULL)
622 copiedquery = newcopy;
627 /* Check if there are unmatched things left. */
628 if (next_insert(copiedquery) != NULL)
630 register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno);
634 /* Now the request is built. */
636 if (stmt->connection->committed && !no_auto_trans)
638 if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL)
640 register_error(ECPG_TRANS, "Error starting transaction line %d.", stmt->lineno);
644 stmt->connection->committed = false;
647 ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name);
648 results = PQexec(stmt->connection->connection, copiedquery);
653 ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno,
654 PQerrorMessage(stmt->connection->connection));
655 register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
656 PQerrorMessage(stmt->connection->connection), stmt->lineno);
660 sqlca.sqlerrd[2] = 0;
662 switch (PQresultStatus(results))
669 case PGRES_TUPLES_OK:
670 nfields = PQnfields(results);
671 sqlca.sqlerrd[2] = ntuples = PQntuples(results);
676 ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n",
677 stmt->lineno, ntuples);
678 register_error(ECPG_NOT_FOUND, "Data not found line %d.", stmt->lineno);
683 for (act_field = 0; act_field < nfields && status; act_field++)
690 ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno);
691 register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno);
696 * if we don't have enough space, we cannot read all
699 if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
701 ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
702 stmt->lineno, ntuples, var->arrsize);
703 register_error(ECPG_TOO_MANY_MATCHES, "Too many matches line %d.", stmt->lineno);
709 * allocate memory for NULL pointers
711 if (var->arrsize == 0 || var->varcharsize == 0)
716 case ECPGt_unsigned_char:
717 if (var->value == NULL)
719 var->varcharsize = 0;
720 /* check strlen for each tuple */
721 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
723 int len = strlen(PQgetvalue(results, act_tuple, act_field));
725 if (len > var->varcharsize)
726 var->varcharsize = len;
728 var->offset *= var->varcharsize;
729 add_mem((void *)(var->value) = *((void **)(var->pointer)) = (void *) ecpg_alloc(var->offset * ntuples, stmt->lineno), stmt->lineno);
734 if (((struct ECPGgeneric_varchar *)var->value)->arr == NULL)
736 var->varcharsize = 0;
737 /* check strlen for each tuple */
738 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
740 int len = strlen(PQgetvalue(results, act_tuple, act_field));
742 if (len > var->varcharsize)
743 var->varcharsize = len;
745 ((struct ECPGgeneric_varchar *) ((long) var->value + var->offset * act_tuple))->arr = (char *) ecpg_alloc(len, stmt->lineno);
751 if (var->value == NULL)
752 add_mem((void *)(var->value) = *((void **)(var->pointer)) = (void *) ecpg_alloc(var->offset * ntuples, stmt->lineno), stmt->lineno);
757 for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
759 pval = PQgetvalue(results, act_tuple, act_field);
761 ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : "");
763 /* Now the pval is a pointer to the value. */
764 /* We will have to decode the value */
767 * check for null value and set indicator
770 switch (var->ind_type)
773 case ECPGt_unsigned_short:
774 ((short *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
777 case ECPGt_unsigned_int:
778 ((int *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
781 case ECPGt_unsigned_long:
782 ((long *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
799 res = strtol(pval, &scan_length, 10);
800 if (*scan_length != '\0') /* Garbage left */
802 register_error(ECPG_INT_FORMAT, "Not correctly formatted int type: %s line %d.",
815 ((short *) var->value)[act_tuple] = (short) res;
818 ((int *) var->value)[act_tuple] = (int) res;
821 ((long *) var->value)[act_tuple] = res;
829 case ECPGt_unsigned_short:
830 case ECPGt_unsigned_int:
831 case ECPGt_unsigned_long:
834 ures = strtoul(pval, &scan_length, 10);
835 if (*scan_length != '\0') /* Garbage left */
837 register_error(ECPG_UINT_FORMAT, "Not correctly formatted unsigned type: %s line %d.",
849 case ECPGt_unsigned_short:
850 ((unsigned short *) var->value)[act_tuple] = (unsigned short) ures;
852 case ECPGt_unsigned_int:
853 ((unsigned int *) var->value)[act_tuple] = (unsigned int) ures;
855 case ECPGt_unsigned_long:
856 ((unsigned long *) var->value)[act_tuple] = ures;
869 dres = strtod(pval, &scan_length);
870 if (*scan_length != '\0') /* Garbage left */
872 register_error(ECPG_FLOAT_FORMAT, "Not correctly formatted floating point type: %s line %d.",
885 ((float *) var->value)[act_tuple] = dres;
888 ((double *) var->value)[act_tuple] = dres;
899 if (pval[0] == 'f' && pval[1] == '\0')
901 ((char *) var->value)[act_tuple] = false;
904 else if (pval[0] == 't' && pval[1] == '\0')
906 ((char *) var->value)[act_tuple] = true;
911 register_error(ECPG_CONVERT_BOOL, "Unable to convert %s to bool on line %d.",
912 (pval ? pval : "NULL"),
918 case ECPGt_unsigned_char:
920 strncpy((char *) ((long) var->value + var->offset * act_tuple), pval, var->varcharsize);
921 if (var->varcharsize && var->varcharsize < strlen(pval))
924 switch (var->ind_type)
927 case ECPGt_unsigned_short:
928 ((short *) var->ind_value)[act_tuple] = var->varcharsize;
931 case ECPGt_unsigned_int:
932 ((int *) var->ind_value)[act_tuple] = var->varcharsize;
935 case ECPGt_unsigned_long:
936 ((long *) var->ind_value)[act_tuple] = var->varcharsize;
941 sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
948 struct ECPGgeneric_varchar *variable =
949 (struct ECPGgeneric_varchar *) ((long) var->value + var->offset * act_tuple);
951 if (var->varcharsize == 0)
952 strncpy(variable->arr, pval, strlen(pval));
954 strncpy(variable->arr, pval, var->varcharsize);
956 variable->len = strlen(pval);
957 if (var->varcharsize > 0 && variable->len > var->varcharsize)
960 switch (var->ind_type)
963 case ECPGt_unsigned_short:
964 ((short *) var->ind_value)[act_tuple] = var->varcharsize;
967 case ECPGt_unsigned_int:
968 ((int *) var->ind_value)[act_tuple] = var->varcharsize;
971 case ECPGt_unsigned_long:
972 ((long *) var->ind_value)[act_tuple] = var->varcharsize;
977 sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
979 variable->len = var->varcharsize;
985 register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", ECPGtype_name(var->type), stmt->lineno);
993 if (status && var != NULL)
995 register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", stmt->lineno);
1001 case PGRES_EMPTY_QUERY:
1003 register_error(ECPG_EMPTY, "Empty query line %d.", stmt->lineno);
1005 case PGRES_COMMAND_OK:
1007 sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
1008 ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, PQcmdStatus(results));
1010 case PGRES_NONFATAL_ERROR:
1011 case PGRES_FATAL_ERROR:
1012 case PGRES_BAD_RESPONSE:
1013 ECPGlog("ECPGexecute line %d: Error: %s",
1014 stmt->lineno, PQerrorMessage(stmt->connection->connection));
1015 register_error(ECPG_PGSQL, "Error: %s line %d.",
1016 PQerrorMessage(stmt->connection->connection), stmt->lineno);
1019 case PGRES_COPY_OUT:
1020 ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", stmt->lineno);
1021 PQendcopy(stmt->connection->connection);
1024 ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", stmt->lineno);
1025 PQendcopy(stmt->connection->connection);
1028 ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
1030 register_error(ECPG_PGSQL, "Postgres error line %d.", stmt->lineno);
1036 /* check for asynchronous returns */
1037 notify = PQnotifies(stmt->connection->connection);
1040 ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
1041 stmt->lineno, notify->relname, notify->be_pid);
1049 ECPGdo(int lineno, const char *connection_name, char *query,...)
1052 struct statement *stmt;
1053 struct connection *con = get_connection(connection_name);
1057 register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno);
1061 va_start(args, query);
1062 if (create_statement(lineno, con, &stmt, query, args) == false)
1066 /* are we connected? */
1067 if (con == NULL || con->connection == NULL)
1069 ECPGlog("ECPGdo: not connected to %s\n", con->name);
1070 register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno);
1074 return (ECPGexecute(stmt));
1079 ECPGtrans(int lineno, const char *connection_name, const char *transaction)
1082 struct connection *con = get_connection(connection_name);
1086 register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno);
1090 ECPGlog("ECPGtrans line %d action = %s connection = %s\n", lineno, transaction, con->name);
1092 /* if we have no connection we just simulate the command */
1093 if (con && con->connection)
1095 if ((res = PQexec(con->connection, transaction)) == NULL)
1097 register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno);
1102 if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0)
1104 struct prepared_statement *this;
1106 con->committed = true;
1108 /* deallocate all prepared statements */
1109 for (this = prep_stmts; this != NULL; this = this->next)
1111 bool b = ECPGdeallocate(lineno, this->name);
1122 ECPGsetconn(int lineno, const char *connection_name)
1124 struct connection *con = get_connection(connection_name);
1128 actual_connection = con;
1133 register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno);
1139 ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name)
1141 struct connection *this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno);
1146 if (dbname == NULL && connection_name == NULL)
1147 connection_name = "DEFAULT";
1149 /* add connection to our list */
1150 if (connection_name != NULL)
1151 this->name = ecpg_strdup(connection_name, lineno);
1153 this->name = ecpg_strdup(dbname, lineno);
1155 if (all_connections == NULL)
1158 this->next = all_connections;
1160 actual_connection = all_connections = this;
1162 ECPGlog("ECPGconnect: opening database %s %s%s\n", dbname ? dbname : "NULL", user ? "for user " : "", user ? user : "");
1166 this->connection = PQsetdbLogin(NULL, NULL, NULL, NULL, dbname, user, passwd);
1168 if (PQstatus(this->connection) == CONNECTION_BAD)
1171 ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "NULL", user ? "for user " : "", user ? user : "", lineno);
1172 register_error(ECPG_CONNECT, "connect: could not open database %s.", dbname ? dbname : "NULL");
1176 this->committed = true;
1182 ECPGdisconnect(int lineno, const char *connection_name)
1184 struct connection *con;
1186 if (strcmp(connection_name, "ALL") == 0)
1188 for (con = all_connections; con;)
1190 struct connection *f = con;
1198 con = get_connection(connection_name);
1202 ECPGlog("disconnect: not connected to connection %s\n", connection_name);
1203 register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno);
1214 ECPGdebug(int n, FILE *dbgs)
1218 ECPGlog("ECPGdebug: set to %d\n", simple_debug);
1222 ECPGlog(const char *format,...)
1228 char *f = (char *) malloc(strlen(format) + 100);
1233 sprintf(f, "[%d]: %s", (int) getpid(), format);
1235 va_start(ap, format);
1236 vfprintf(debugstream, f, ap);
1243 /* print out an error message */
1247 sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
1248 printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc);
1252 isvarchar(unsigned char c)
1257 if (c == '_' || c == '>' || c == '-' || c == '.')
1267 replace_variables(char *text)
1270 bool string = false;
1272 for (; *ptr != '\0'; ptr++)
1275 string = string ? false : true;
1277 if (!string && *ptr == ':')
1279 ptr[0] = ptr[1] = ';';
1280 for (ptr += 2; *ptr && isvarchar(*ptr); ptr++)
1286 /* handle the EXEC SQL PREPARE statement */
1288 ECPGprepare(int lineno, char *name, char *variable)
1290 struct statement *stmt;
1291 struct prepared_statement *this;
1293 /* check if we already have prepared this statement */
1294 for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
1297 bool b = ECPGdeallocate(lineno, name);
1303 this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
1307 stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
1314 /* create statement */
1315 stmt->lineno = lineno;
1316 stmt->connection = NULL;
1317 stmt->command = ecpg_strdup(variable, lineno);
1318 stmt->inlist = stmt->outlist = NULL;
1320 /* if we have C variables in our statment replace them with ';;' */
1321 replace_variables(stmt->command);
1323 /* add prepared statement to our list */
1324 this->name = ecpg_strdup(name, lineno);
1327 if (prep_stmts == NULL)
1330 this->next = prep_stmts;
1336 /* handle the EXEC SQL DEALLOCATE PREPARE statement */
1338 ECPGdeallocate(int lineno, char *name)
1340 struct prepared_statement *this, *prev;
1342 /* check if we really have prepared this statement */
1343 for (this = prep_stmts, prev = NULL; this != NULL && strcmp(this->name, name) != 0; prev = this, this = this->next);
1346 /* okay, free all the resources */
1348 free(this->stmt->command);
1351 prev->next = this->next;
1353 prep_stmts = this->next;
1357 ECPGlog("deallocate_prepare: invalid statement name %s\n", name);
1358 register_error(ECPG_INVALID_STMT, "Invalid statement name %s in line %d", name, lineno);
1362 /* return the prepared statement */
1364 ECPGprepared_statement(char *name)
1366 struct prepared_statement *this;
1368 for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
1369 return (this) ? this->stmt->command : NULL;