aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/lib/ecpglib.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1998-08-11 18:33:37 +0000
committerBruce Momjian <bruce@momjian.us>1998-08-11 18:33:37 +0000
commitc6dd1e63a951ba4b529ed292f88fba28de70df78 (patch)
treefa342f405c3a3bacd02f038f6043b1f39d78f623 /src/interfaces/ecpg/lib/ecpglib.c
parent79c8d2e3a0966b49af2a2cab44628d2f963d46fd (diff)
downloadpostgresql-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.c426
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);
-}