diff options
author | Bruce Momjian <bruce@momjian.us> | 1998-08-11 18:33:37 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1998-08-11 18:33:37 +0000 |
commit | c6dd1e63a951ba4b529ed292f88fba28de70df78 (patch) | |
tree | fa342f405c3a3bacd02f038f6043b1f39d78f623 /src/interfaces/ecpg/lib/ecpglib.c | |
parent | 79c8d2e3a0966b49af2a2cab44628d2f963d46fd (diff) | |
download | postgresql-c6dd1e63a951ba4b529ed292f88fba28de70df78.tar.gz postgresql-c6dd1e63a951ba4b529ed292f88fba28de70df78.zip |
This one cleans the cursor problems ecpg had so far. It is now able
to understand cursors with variables.
Michael
Diffstat (limited to 'src/interfaces/ecpg/lib/ecpglib.c')
-rw-r--r-- | src/interfaces/ecpg/lib/ecpglib.c | 426 |
1 files changed, 225 insertions, 201 deletions
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index 86021d6ee46..0d3d4fa0e6a 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -33,6 +33,29 @@ static struct connection struct connection *next; } *all_connections = NULL, *actual_connection = NULL; +struct variable +{ + enum ECPGttype type; + void *value; + long varcharsize; + long arrsize; + long offset; + enum ECPGttype ind_type; + void *ind_value; + long ind_varcharsize; + long ind_arrsize; + long ind_offset; + struct variable *next; +}; + +struct statement +{ + int lineno; + char *command; + struct variable *inlist; + struct variable *outlist; +}; + static int simple_debug = 0; static FILE *debugstream = NULL; static int committed = true; @@ -116,27 +139,87 @@ ECPGfinish(struct connection *act) ECPGlog("ECPGfinish: called an extra time.\n"); } -bool -ECPGdo(int lineno, char *query,...) +/* create a list of variables */ +static bool +create_statement(int lineno, struct statement **stmt, char *query, va_list ap) +{ + struct variable **list = &((*stmt)->inlist); + enum ECPGttype type; + + *stmt = calloc(sizeof(struct statement), 1); + + if (!*stmt) + { + ECPGfinish(actual_connection); + ECPGlog("out of memory\n"); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + return false; + } + + (*stmt)->command = query; + (*stmt)->lineno = lineno; + + list = &((*stmt)->inlist); + + type = va_arg(ap, enum ECPGttype); + + while (type != ECPGt_EORT) + { + if (type == ECPGt_EOIT) + { + list = &((*stmt)->outlist); + } + else + { + struct variable *var, *ptr; + + var = malloc(sizeof(struct variable)); + if (!var) + { + ECPGfinish(actual_connection); + ECPGlog("out of memory\n"); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + return false; + } + + var->type = type; + var->value = va_arg(ap, void *); + var->varcharsize = va_arg(ap, long); + var->arrsize = va_arg(ap, long); + var->offset = va_arg(ap, long); + var->ind_type = va_arg(ap, enum ECPGttype); + var->ind_value = va_arg(ap, void *); + var->ind_varcharsize = va_arg(ap, long); + var->ind_arrsize = va_arg(ap, long); + var->ind_offset = va_arg(ap, long); + var->next = NULL; + + for (ptr = *list; ptr && ptr->next; ptr=ptr->next); + + if (ptr == NULL) + *list = var; + else + ptr->next = var; + } + + type = va_arg(ap, enum ECPGttype); + } + + return(true); +} + +static bool +ECPGexecute(struct statement *stmt) { - va_list ap; bool status = false; char *copiedquery; PGresult *results; PGnotify *notify; - enum ECPGttype type; - void *value = NULL, *ind_value; - long varcharsize, ind_varcharsize; - long arrsize, ind_arrsize; - long offset, ind_offset; - enum ECPGttype ind_type; + struct variable *var; memset((char *) &sqlca, 0, sizeof (sqlca)); - va_start(ap, query); - copiedquery = strdup(query); - - type = va_arg(ap, enum ECPGttype); + copiedquery = strdup(stmt->command); /* * Now, if the type is one of the fill in types then we take the @@ -144,7 +227,8 @@ ECPGdo(int lineno, char *query,...) * Then if there are any more fill in types we fill in at the next and * so on. */ - while (type != ECPGt_EOIT) + var = stmt->inlist; + while (var) { char *newcopy; char *mallocedval = NULL; @@ -158,34 +242,24 @@ ECPGdo(int lineno, char *query,...) * think). */ - value = va_arg(ap, void *); - varcharsize = va_arg(ap, long); - arrsize = va_arg(ap, long); - offset = va_arg(ap, long); - ind_type = va_arg(ap, enum ECPGttype); - ind_value = va_arg(ap, void *); - ind_varcharsize = va_arg(ap, long); - ind_arrsize = va_arg(ap, long); - ind_offset = va_arg(ap, long); - buff[0] = '\0'; /* check for null value and set input buffer accordingly */ - switch (ind_type) + switch (var->ind_type) { case ECPGt_short: case ECPGt_unsigned_short: - if (*(short *) ind_value < 0) + if (*(short *) var->ind_value < 0) strcpy(buff, "null"); break; case ECPGt_int: case ECPGt_unsigned_int: - if (*(int *) ind_value < 0) + if (*(int *) var->ind_value < 0) strcpy(buff, "null"); break; case ECPGt_long: case ECPGt_unsigned_long: - if (*(long *) ind_value < 0L) + if (*(long *) var->ind_value < 0L) strcpy(buff, "null"); break; default: @@ -194,42 +268,42 @@ ECPGdo(int lineno, char *query,...) if (*buff == '\0') { - switch (type) + switch (var->type) { case ECPGt_short: case ECPGt_int: - sprintf(buff, "%d", *(int *) value); + sprintf(buff, "%d", *(int *) var->value); tobeinserted = buff; break; case ECPGt_unsigned_short: case ECPGt_unsigned_int: - sprintf(buff, "%d", *(unsigned int *) value); + sprintf(buff, "%d", *(unsigned int *) var->value); tobeinserted = buff; break; case ECPGt_long: - sprintf(buff, "%ld", *(long *) value); + sprintf(buff, "%ld", *(long *) var->value); tobeinserted = buff; break; case ECPGt_unsigned_long: - sprintf(buff, "%ld", *(unsigned long *) value); + sprintf(buff, "%ld", *(unsigned long *) var->value); tobeinserted = buff; break; case ECPGt_float: - sprintf(buff, "%.14g", *(float *) value); + sprintf(buff, "%.14g", *(float *) var->value); tobeinserted = buff; break; case ECPGt_double: - sprintf(buff, "%.14g", *(double *) value); + sprintf(buff, "%.14g", *(double *) var->value); tobeinserted = buff; break; case ECPGt_bool: - sprintf(buff, "'%c'", (*(char *) value ? 't' : 'f')); + sprintf(buff, "'%c'", (*(char *) var->value ? 't' : 'f')); tobeinserted = buff; break; @@ -237,7 +311,7 @@ ECPGdo(int lineno, char *query,...) case ECPGt_unsigned_char: { /* set slen to string length if type is char * */ - int slen = (varcharsize == 0) ? strlen((char *) value) : varcharsize; + int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize; char * tmp; newcopy = (char *) malloc(slen + 1); @@ -245,11 +319,11 @@ ECPGdo(int lineno, char *query,...) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno); return false; } - strncpy(newcopy, (char *) value, slen); + strncpy(newcopy, (char *) var->value, slen); newcopy[slen] = '\0'; mallocedval = (char *) malloc(2 * strlen(newcopy) + 3); @@ -257,7 +331,7 @@ ECPGdo(int lineno, char *query,...) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno); return false; } @@ -267,7 +341,7 @@ ECPGdo(int lineno, char *query,...) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno); return false; } @@ -282,28 +356,28 @@ ECPGdo(int lineno, char *query,...) case ECPGt_varchar: { - struct ECPGgeneric_varchar *var = - (struct ECPGgeneric_varchar *) value; + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var->value); char *tmp; - newcopy = (char *) malloc(var->len + 1); + newcopy = (char *) malloc(variable->len + 1); if (!newcopy) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno); return false; } - strncpy(newcopy, var->arr, var->len); - newcopy[var->len] = '\0'; + strncpy(newcopy, variable->arr, variable->len); + newcopy[variable->len] = '\0'; mallocedval = (char *) malloc(2 * strlen(newcopy) + 3); if (!mallocedval) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno); return false; } @@ -313,7 +387,7 @@ ECPGdo(int lineno, char *query,...) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno); return false; } @@ -329,7 +403,7 @@ ECPGdo(int lineno, char *query,...) default: /* Not implemented yet */ register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", - ECPGtype_name(type), lineno); + ECPGtype_name(var->type), stmt->lineno); return false; break; } @@ -348,7 +422,7 @@ ECPGdo(int lineno, char *query,...) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno); return false; } @@ -360,7 +434,7 @@ ECPGdo(int lineno, char *query,...) * We have an argument but we dont have the matched up string * in the string */ - register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", lineno); + register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", stmt->lineno); return false; } else @@ -379,7 +453,7 @@ ECPGdo(int lineno, char *query,...) /* * Now everything is safely copied to the newcopy. Lets free the - * oldcopy and let the copiedquery get the value from the newcopy. + * oldcopy and let the copiedquery get the var->value from the newcopy. */ if (mallocedval != NULL) { @@ -390,13 +464,13 @@ ECPGdo(int lineno, char *query,...) free(copiedquery); copiedquery = newcopy; - type = va_arg(ap, enum ECPGttype); + var = var->next; } /* Check if there are unmatched things left. */ if (strstr(copiedquery, ";;") != NULL) { - register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", lineno); + register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno); return false; } @@ -406,27 +480,28 @@ ECPGdo(int lineno, char *query,...) { if ((results = PQexec(actual_connection->connection, "begin transaction")) == NULL) { - register_error(ECPG_TRANS, "Error starting transaction line %d.", lineno); + register_error(ECPG_TRANS, "Error starting transaction line %d.", stmt->lineno); return false; } PQclear(results); committed = 0; } - ECPGlog("ECPGdo line %d: QUERY: %s\n", lineno, copiedquery); + ECPGlog("ECPGexecute line %d: QUERY: %s\n", stmt->lineno, copiedquery); results = PQexec(actual_connection->connection, copiedquery); free(copiedquery); if (results == NULL) { - ECPGlog("ECPGdo line %d: error: %s", lineno, + ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, PQerrorMessage(actual_connection->connection)); register_error(ECPG_PGSQL, "Postgres error: %s line %d.", - PQerrorMessage(actual_connection->connection), lineno); + PQerrorMessage(actual_connection->connection), stmt->lineno); } else { sqlca.sqlerrd[2] = 0; + var = stmt->outlist; switch (PQresultStatus(results)) { int nfields, ntuples, act_tuple, act_field; @@ -445,9 +520,9 @@ ECPGdo(int lineno, char *query,...) if (ntuples < 1) { - ECPGlog("ECPGdo line %d: Incorrect number of matches: %d\n", - lineno, ntuples); - register_error(ECPG_NOT_FOUND, "Data not found line %d.", lineno); + ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n", + stmt->lineno, ntuples); + register_error(ECPG_NOT_FOUND, "Data not found line %d.", stmt->lineno); status = false; break; } @@ -457,23 +532,19 @@ ECPGdo(int lineno, char *query,...) char *pval; char *scan_length; - type = va_arg(ap, enum ECPGttype); - value = va_arg(ap, void *); - varcharsize = va_arg(ap, long); - arrsize = va_arg(ap, long); - offset = va_arg(ap, long); - ind_type = va_arg(ap, enum ECPGttype); - ind_value = va_arg(ap, void *); - ind_varcharsize = va_arg(ap, long); - ind_arrsize = va_arg(ap, long); - ind_offset = va_arg(ap, long); - + if (var == NULL) + { + ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno); + register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno); + return(false); + } + /* if we don't have enough space, we cannot read all tuples */ - if ((arrsize > 0 && ntuples > arrsize) || (ind_arrsize > 0 && ntuples > ind_arrsize)) + if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize)) { - ECPGlog("ECPGdo line %d: Incorrect number of matches: %d don't fit into array of %d\n", - lineno, ntuples, arrsize); - register_error(ECPG_TOO_MANY_MATCHES, "Too many matches line %d.", lineno); + ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n", + stmt->lineno, ntuples, var->arrsize); + register_error(ECPG_TOO_MANY_MATCHES, "Too many matches line %d.", stmt->lineno); status = false; break; } @@ -481,31 +552,31 @@ ECPGdo(int lineno, char *query,...) { pval = PQgetvalue(results, act_tuple, act_field); - ECPGlog("ECPGdo line %d: RESULT: %s\n", lineno, pval ? pval : ""); + ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : ""); - /* Now the pval is a pointer to the value. */ - /* We will have to decode the value */ + /* Now the pval is a pointer to the var->value. */ + /* We will have to decode the var->value */ - /* check for null value and set indicator accordingly */ - switch (ind_type) + /* check for null var->value and set indicator accordingly */ + switch (var->ind_type) { case ECPGt_short: case ECPGt_unsigned_short: - ((short *) ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); + ((short *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); break; case ECPGt_int: case ECPGt_unsigned_int: - ((int *) ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); + ((int *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); break; case ECPGt_long: case ECPGt_unsigned_long: - ((long *) ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); + ((long *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); break; default: break; } - switch (type) + switch (var->type) { long res; unsigned long ures; @@ -520,7 +591,7 @@ ECPGdo(int lineno, char *query,...) if (*scan_length != '\0') /* Garbage left */ { register_error(ECPG_INT_FORMAT, "Not correctly formatted int type: %s line %d.", - pval, lineno); + pval, stmt->lineno); status = false; res = 0L; } @@ -529,16 +600,16 @@ ECPGdo(int lineno, char *query,...) res = 0L; /* Again?! Yes */ - switch (type) + switch (var->type) { case ECPGt_short: - ((short *) value)[act_tuple] = (short) res; + ((short *) var->value)[act_tuple] = (short) res; break; case ECPGt_int: - ((int *) value)[act_tuple] = (int) res; + ((int *) var->value)[act_tuple] = (int) res; break; case ECPGt_long: - ((long *) value)[act_tuple] = res; + ((long *) var->value)[act_tuple] = res; break; default: /* Cannot happen */ @@ -555,7 +626,7 @@ ECPGdo(int lineno, char *query,...) if (*scan_length != '\0') /* Garbage left */ { register_error(ECPG_UINT_FORMAT, "Not correctly formatted unsigned type: %s line %d.", - pval, lineno); + pval, stmt->lineno); status = false; ures = 0L; } @@ -564,16 +635,16 @@ ECPGdo(int lineno, char *query,...) ures = 0L; /* Again?! Yes */ - switch (type) + switch (var->type) { case ECPGt_unsigned_short: - ((unsigned short *) value)[act_tuple] = (unsigned short) ures; + ((unsigned short *) var->value)[act_tuple] = (unsigned short) ures; break; case ECPGt_unsigned_int: - ((unsigned int *) value)[act_tuple] = (unsigned int) ures; + ((unsigned int *) var->value)[act_tuple] = (unsigned int) ures; break; case ECPGt_unsigned_long: - ((unsigned long *) value)[act_tuple] = ures; + ((unsigned long *) var->value)[act_tuple] = ures; break; default: /* Cannot happen */ @@ -590,7 +661,7 @@ ECPGdo(int lineno, char *query,...) if (*scan_length != '\0') /* Garbage left */ { register_error(ECPG_FLOAT_FORMAT, "Not correctly formatted floating point type: %s line %d.", - pval, lineno); + pval, stmt->lineno); status = false; dres = 0.0; } @@ -599,13 +670,13 @@ ECPGdo(int lineno, char *query,...) dres = 0.0; /* Again?! Yes */ - switch (type) + switch (var->type) { case ECPGt_float: - ((float *) value)[act_tuple] = dres; + ((float *) var->value)[act_tuple] = dres; break; case ECPGt_double: - ((double *) value)[act_tuple] = dres; + ((double *) var->value)[act_tuple] = dres; break; default: /* Cannot happen */ @@ -618,50 +689,50 @@ ECPGdo(int lineno, char *query,...) { if (pval[0] == 'f' && pval[1] == '\0') { - ((char *) value)[act_tuple] = false; + ((char *) var->value)[act_tuple] = false; break; } else if (pval[0] == 't' && pval[1] == '\0') { - ((char *) value)[act_tuple] = true; + ((char *) var->value)[act_tuple] = true; break; } } register_error(ECPG_CONVERT_BOOL, "Unable to convert %s to bool on line %d.", (pval ? pval : "NULL"), - lineno); + stmt->lineno); status = false; break; case ECPGt_char: case ECPGt_unsigned_char: { - if (varcharsize == 0) + if (var->varcharsize == 0) { /* char* */ - strncpy(((char **) value)[act_tuple], pval, strlen(pval)); - (((char **) value)[act_tuple])[strlen(pval)] = '\0'; + strncpy(((char **) var->value)[act_tuple], pval, strlen(pval)); + (((char **) var->value)[act_tuple])[strlen(pval)] = '\0'; } else { - strncpy((char *) (value + offset * act_tuple), pval, varcharsize); - if (varcharsize < strlen(pval)) + strncpy((char *) (var->value + var->offset * act_tuple), pval, var->varcharsize); + if (var->varcharsize < strlen(pval)) { /* truncation */ - switch (ind_type) + switch (var->ind_type) { case ECPGt_short: case ECPGt_unsigned_short: - ((short *) ind_value)[act_tuple] = varcharsize; + ((short *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_int: case ECPGt_unsigned_int: - ((int *) ind_value)[act_tuple] = varcharsize; + ((int *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_long: case ECPGt_unsigned_long: - ((long *) ind_value)[act_tuple] = varcharsize; + ((long *) var->ind_value)[act_tuple] = var->varcharsize; break; default: break; @@ -674,62 +745,55 @@ ECPGdo(int lineno, char *query,...) case ECPGt_varchar: { - struct ECPGgeneric_varchar *var = - (struct ECPGgeneric_varchar *) (value + offset * act_tuple); + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var->value + var->offset * act_tuple); - if (varcharsize == 0) - strncpy(var->arr, pval, strlen(pval)); + if (var->varcharsize == 0) + strncpy(variable->arr, pval, strlen(pval)); else - strncpy(var->arr, pval, varcharsize); + strncpy(variable->arr, pval, var->varcharsize); - var->len = strlen(pval); - if (varcharsize > 0 && var->len > varcharsize) + variable->len = strlen(pval); + if (var->varcharsize > 0 && variable->len > var->varcharsize) { /* truncation */ - switch (ind_type) + switch (var->ind_type) { case ECPGt_short: case ECPGt_unsigned_short: - ((short *) ind_value)[act_tuple] = varcharsize; + ((short *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_int: case ECPGt_unsigned_int: - ((int *) ind_value)[act_tuple] = varcharsize; + ((int *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_long: case ECPGt_unsigned_long: - ((long *) ind_value)[act_tuple] = varcharsize; + ((long *) var->ind_value)[act_tuple] = var->varcharsize; break; default: break; } sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; - var->len = varcharsize; + variable->len = var->varcharsize; } } break; - case ECPGt_EORT: - ECPGlog("ECPGdo line %d: Too few arguments.\n", lineno); - register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", lineno); - status = false; - break; - default: register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", - ECPGtype_name(type), lineno); + ECPGtype_name(var->type), stmt->lineno); status = false; break; } } + var = var->next; } - type = va_arg(ap, enum ECPGttype); - - if (status && type != ECPGt_EORT) + if (status && var != NULL) { - register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", lineno); + register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", stmt->lineno); status = false; } @@ -737,35 +801,34 @@ ECPGdo(int lineno, char *query,...) break; case PGRES_EMPTY_QUERY: /* do nothing */ - register_error(ECPG_EMPTY, "Empty query line %d.", lineno); + register_error(ECPG_EMPTY, "Empty query line %d.", stmt->lineno); break; case PGRES_COMMAND_OK: status = true; sqlca.sqlerrd[2] = atol(PQcmdTuples(results)); - ECPGlog("TEST: %s\n", PQcmdTuples(results)); - ECPGlog("ECPGdo line %d Ok: %s\n", lineno, PQcmdStatus(results)); + ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, PQcmdStatus(results)); break; case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: case PGRES_BAD_RESPONSE: - ECPGlog("ECPGdo line %d: Error: %s", - lineno, PQerrorMessage(actual_connection->connection)); + ECPGlog("ECPGexecute line %d: Error: %s", + stmt->lineno, PQerrorMessage(actual_connection->connection)); register_error(ECPG_PGSQL, "Error: %s line %d.", - PQerrorMessage(actual_connection->connection), lineno); + PQerrorMessage(actual_connection->connection), stmt->lineno); status = false; break; case PGRES_COPY_OUT: - ECPGlog("ECPGdo line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno); + ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", stmt->lineno); PQendcopy(results->conn); break; case PGRES_COPY_IN: - ECPGlog("ECPGdo line %d: Got PGRES_COPY_IN ... tossing.\n", lineno); + ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", stmt->lineno); PQendcopy(results->conn); break; default: - ECPGlog("ECPGdo line %d: Got something else, postgres error.\n", - lineno); - register_error(ECPG_PGSQL, "Postgres error line %d.", lineno); + ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n", + stmt->lineno); + register_error(ECPG_PGSQL, "Postgres error line %d.", stmt->lineno); status = false; break; } @@ -775,8 +838,8 @@ ECPGdo(int lineno, char *query,...) notify = PQnotifies(actual_connection->connection); if (notify) { - ECPGlog("ECPGdo line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n", - lineno, notify->relname, notify->be_pid); + ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n", + stmt->lineno, notify->relname, notify->be_pid); free(notify); } @@ -784,6 +847,20 @@ ECPGdo(int lineno, char *query,...) return status; } +bool +ECPGdo(int lineno, char *query, ...) +{ + va_list args; + struct statement *stmt; + + va_start(args, query); + if (create_statement(lineno, &stmt, query, args) == false) + return(false); + va_end(args); + + return(ECPGexecute(stmt)); +} + bool ECPGtrans(int lineno, const char * transaction) @@ -940,56 +1017,3 @@ sqlprint(void) sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0'; printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc); } - -/* keep a list of cursors */ -struct cursor *cur = NULL; - -bool ECPGdeclare(int lineno, const char *name, char *command) -{ - struct cursor *ptr; - - for (ptr = cur; ptr != NULL; ptr = ptr->next) - { - if (strcmp(name, ptr->name) == 0) - { - /* re-definition */ - free(ptr->command); - ptr->command = command; - break; - } - } - - if (ptr == NULL) - { - struct cursor *this = (struct cursor *) malloc(sizeof(struct cursor)); - - if (!this) - { - ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); - return false; - } - /* initial definition */ - this->next = cur; - this->name = name; - this->command = command; - cur = this; - } - - return(true); -} - -bool ECPGopen(int lineno, const char *name) -{ - struct cursor *ptr; - - for (ptr = cur; ptr != NULL; ptr=ptr->next) - { - if (strcmp(ptr->name, name) == 0) - return(ECPGdo(lineno, ptr->command, ECPGt_EOIT, ECPGt_EORT)); - } - - ECPGlog("trying to open undeclared cursor %s\n", name); - register_error(ECPG_UNDECLARED_CURSOR, "trying to open undeclared cursor %s in line %d", name, lineno); - return(false); -} |