aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/ecpglib/execute.c
diff options
context:
space:
mode:
authorMichael Meskes <meskes@postgresql.org>2004-06-30 15:01:58 +0000
committerMichael Meskes <meskes@postgresql.org>2004-06-30 15:01:58 +0000
commit90326c01c9c116a888998e2744eeca9d3afa6242 (patch)
tree1aa62a4173d5352644b59db72f37021ae4e816cc /src/interfaces/ecpg/ecpglib/execute.c
parentc7beffcc1dd157d26239d75d307ccface07740e9 (diff)
downloadpostgresql-90326c01c9c116a888998e2744eeca9d3afa6242.tar.gz
postgresql-90326c01c9c116a888998e2744eeca9d3afa6242.zip
Added SET DESCRIPTOR command.
Note that this still has some bugs. The functionality is there though, it's just a matter of fixing the bugs now. Cleaned up error handling in preprocessor.
Diffstat (limited to 'src/interfaces/ecpg/ecpglib/execute.c')
-rw-r--r--src/interfaces/ecpg/ecpglib/execute.c146
1 files changed, 101 insertions, 45 deletions
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index c91e96d3a1a..d99f9584458 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.34 2004/06/27 12:28:40 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.35 2004/06/30 15:01:56 meskes Exp $ */
/*
* The aim is to get a simpler inteface to the database routines.
@@ -1026,6 +1026,9 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
free(str);
}
break;
+
+ case ECPGt_descriptor:
+ break;
default:
/* Not implemented yet */
@@ -1046,6 +1049,7 @@ ECPGexecute(struct statement * stmt)
PGresult *results;
PGnotify *notify;
struct variable *var;
+ int desc_counter = 0;
copiedquery = ECPGstrdup(stmt->command, stmt->lineno);
@@ -1056,64 +1060,116 @@ ECPGexecute(struct statement * stmt)
* so on.
*/
var = stmt->inlist;
+
while (var)
{
char *newcopy = NULL;
- const char *tobeinserted = NULL;
+ const char *tobeinserted;
char *p;
- bool malloced = FALSE;
- int hostvarl = 0;
-
- if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
- return false;
+ bool malloced = FALSE;
+ int hostvarl = 0;
- /*
- * Now tobeinserted points to an area that is to be inserted at
- * the first %s
- */
- if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
- return false;
-
- strcpy(newcopy, copiedquery);
- if ((p = next_insert(newcopy + hostvarl)) == NULL)
+ tobeinserted = NULL;
+ /* A descriptor is a special case since it contains many variables but is listed only once. */
+ if (var->type == ECPGt_descriptor)
{
- /*
- * We have an argument but we dont have the matched up string
- * in the string
- */
- ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
- return false;
+ /* We create an additional variable list here, so the same logic applies. */
+ struct variable desc_inlist;
+ struct descriptor *desc;
+ struct descriptor_item *desc_item;
+ for (desc = all_descriptors; desc; desc = desc->next)
+ {
+ if (strcmp(var->pointer, desc->name) == 0)
+ break;
+ }
+
+ if (desc == NULL)
+ {
+ ECPGraise(stmt->lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, var->pointer);
+ return false;
+ }
+
+ desc_counter++;
+ for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
+ {
+ if (desc_item->num == desc_counter)
+ {
+ desc_inlist.type = ECPGt_char;
+ desc_inlist.value = desc_item->data;
+ desc_inlist.pointer = &(desc_item->data);
+ desc_inlist.varcharsize = strlen(desc_item->data);
+ desc_inlist.arrsize = 1;
+ desc_inlist.offset = 0;
+ desc_inlist.ind_type = ECPGt_NO_INDICATOR;
+ desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
+ desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
+
+ if (!ECPGstore_input(stmt, &desc_inlist, &tobeinserted, &malloced))
+ return false;
+
+ break;
+ }
+ }
+
+ if (!desc_item) /* no more entries found in descriptor */
+ desc_counter = 0;
}
else
{
- strcpy(p, tobeinserted);
- hostvarl = strlen(newcopy);
-
+ if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
+ return false;
+ }
+ if (tobeinserted)
+ {
/*
- * The strange thing in the second argument is the rest of the
- * string from the old string
+ * Now tobeinserted points to an area that is to be inserted at
+ * the first %s
*/
- strcat(newcopy,
- copiedquery
- + (p - newcopy)
- + sizeof("?") - 1 /* don't count the '\0' */ );
- }
+ if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
+ return false;
- /*
- * Now everything is safely copied to the newcopy. Lets free the
- * oldcopy and let the copiedquery get the var->value from the
- * newcopy.
- */
- if (malloced)
- {
- ECPGfree((char *) tobeinserted);
- tobeinserted = NULL;
- }
+ strcpy(newcopy, copiedquery);
+ if ((p = next_insert(newcopy + hostvarl)) == NULL)
+ {
+ /*
+ * We have an argument but we dont have the matched up string
+ * in the string
+ */
+ ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
+ return false;
+ }
+ else
+ {
+ strcpy(p, tobeinserted);
+ hostvarl = strlen(newcopy);
+
+ /*
+ * The strange thing in the second argument is the rest of the
+ * string from the old string
+ */
+ strcat(newcopy,
+ copiedquery
+ + (p - newcopy)
+ + sizeof("?") - 1 /* don't count the '\0' */ );
+ }
- ECPGfree(copiedquery);
- copiedquery = newcopy;
+ /*
+ * Now everything is safely copied to the newcopy. Lets free the
+ * oldcopy and let the copiedquery get the var->value from the
+ * newcopy.
+ */
+ if (malloced)
+ {
+ ECPGfree((char *) tobeinserted);
+ tobeinserted = NULL;
+ }
- var = var->next;
+ ECPGfree(copiedquery);
+ copiedquery = newcopy;
+ }
+
+ if (desc_counter == 0)
+ var = var->next;
}
/* Check if there are unmatched things left. */