mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
@@ -6,13 +6,13 @@
|
||||
# Copyright (c) 1994, Regents of the University of California
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.40 1999/01/21 20:01:32 scrappy Exp $
|
||||
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.41 1999/02/20 07:00:53 scrappy Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
NAME= ecpg
|
||||
SO_MAJOR_VERSION= 2
|
||||
SO_MINOR_VERSION= 6.3
|
||||
SO_MINOR_VERSION= 7.0
|
||||
|
||||
SRCDIR= @top_srcdir@
|
||||
include $(SRCDIR)/Makefile.global
|
||||
|
||||
@@ -75,12 +75,19 @@ struct variable
|
||||
|
||||
struct statement
|
||||
{
|
||||
int lineno;
|
||||
int lineno;
|
||||
char *command;
|
||||
struct variable *inlist;
|
||||
struct variable *outlist;
|
||||
};
|
||||
|
||||
struct prepared_statement
|
||||
{
|
||||
char *name;
|
||||
struct statement *stmt;
|
||||
struct prepared_statement *next;
|
||||
} *prep_stmts = NULL;
|
||||
|
||||
static int simple_debug = 0;
|
||||
static FILE *debugstream = NULL;
|
||||
static int committed = true;
|
||||
@@ -196,6 +203,41 @@ quote_postgres(char *arg, int lineno)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* This function returns a newly malloced string that has the \
|
||||
in the strings inside the argument quoted with another \.
|
||||
*/
|
||||
static
|
||||
char *
|
||||
quote_strings(char *arg, int lineno)
|
||||
{
|
||||
char *res = (char *) ecpg_alloc(2 * strlen(arg) + 1, lineno);
|
||||
int i,
|
||||
ri;
|
||||
bool string = false;
|
||||
|
||||
if (!res)
|
||||
return (res);
|
||||
|
||||
for (i = 0, ri = 0; arg[i]; i++, ri++)
|
||||
{
|
||||
switch (arg[i])
|
||||
{
|
||||
case '\'':
|
||||
string = string ? false : true;
|
||||
break;
|
||||
case '\\':
|
||||
res[ri++] = '\\';
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
res[ri] = arg[i];
|
||||
}
|
||||
res[ri] = '\0';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* create a list of variables */
|
||||
static bool
|
||||
create_statement(int lineno, struct statement ** stmt, char *query, va_list ap)
|
||||
@@ -236,6 +278,14 @@ create_statement(int lineno, struct statement ** stmt, char *query, va_list ap)
|
||||
var->ind_arrsize = va_arg(ap, long);
|
||||
var->ind_offset = va_arg(ap, long);
|
||||
var->next = NULL;
|
||||
|
||||
if (var->value == NULL)
|
||||
{
|
||||
ECPGlog("create_statement: invalid statement name\n");
|
||||
register_error(ECPG_INVALID_STMT, "Invalid statement name in line %d", lineno);
|
||||
free(var);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ptr = *list; ptr && ptr->next; ptr = ptr->next);
|
||||
|
||||
@@ -251,6 +301,19 @@ create_statement(int lineno, struct statement ** stmt, char *query, va_list ap)
|
||||
return (true);
|
||||
}
|
||||
|
||||
static char *
|
||||
next_insert(char *text)
|
||||
{
|
||||
char *ptr = text;
|
||||
bool string = false;
|
||||
|
||||
for (; ptr[1] != '\0' && (ptr[0] != ';' || ptr[1] != ';' || string); ptr++)
|
||||
if (ptr[0] == '\'')
|
||||
string = string ? false : true;
|
||||
|
||||
return (ptr[1] == '\0') ? NULL : ptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
ECPGexecute(struct statement * stmt)
|
||||
{
|
||||
@@ -379,7 +442,30 @@ ECPGexecute(struct statement * stmt)
|
||||
tobeinserted = mallocedval;
|
||||
}
|
||||
break;
|
||||
case ECPGt_char_variable:
|
||||
{
|
||||
/* set slen to string length if type is char * */
|
||||
int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize;
|
||||
char *tmp;
|
||||
|
||||
if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
|
||||
return false;
|
||||
|
||||
strncpy(newcopy, (char *) var->value, slen);
|
||||
newcopy[slen] = '\0';
|
||||
if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 1, stmt->lineno)))
|
||||
return false;
|
||||
|
||||
tmp = quote_strings(newcopy, stmt->lineno);
|
||||
if (!tmp)
|
||||
return false;
|
||||
|
||||
strcat(mallocedval, tmp);
|
||||
free(newcopy);
|
||||
|
||||
tobeinserted = mallocedval;
|
||||
}
|
||||
break;
|
||||
case ECPGt_varchar:
|
||||
{
|
||||
struct ECPGgeneric_varchar *variable =
|
||||
@@ -428,7 +514,7 @@ ECPGexecute(struct statement * stmt)
|
||||
return false;
|
||||
|
||||
strcpy(newcopy, copiedquery);
|
||||
if ((p = strstr(newcopy, ";;")) == NULL)
|
||||
if ((p = next_insert(newcopy)) == NULL)
|
||||
{
|
||||
|
||||
/*
|
||||
@@ -449,7 +535,7 @@ ECPGexecute(struct statement * stmt)
|
||||
strcat(newcopy,
|
||||
copiedquery
|
||||
+ (p - newcopy)
|
||||
+ 2 /* Length of ;; */ );
|
||||
+ sizeof(";;") - 1 /* don't count the '\0' */);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -470,7 +556,7 @@ ECPGexecute(struct statement * stmt)
|
||||
}
|
||||
|
||||
/* Check if there are unmatched things left. */
|
||||
if (strstr(copiedquery, ";;") != NULL)
|
||||
if (next_insert(copiedquery) != NULL)
|
||||
{
|
||||
register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno);
|
||||
return false;
|
||||
@@ -898,7 +984,21 @@ ECPGtrans(int lineno, const char *transaction)
|
||||
PQclear(res);
|
||||
}
|
||||
if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0)
|
||||
{
|
||||
struct prepared_statement *this;
|
||||
|
||||
committed = 1;
|
||||
|
||||
/* deallocate all prepared statements */
|
||||
for (this = prep_stmts; this != NULL; this = this->next)
|
||||
{
|
||||
bool b = ECPGdeallocate(lineno, this->name);
|
||||
|
||||
if (!b)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1033,3 +1133,109 @@ sqlprint(void)
|
||||
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
|
||||
printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc);
|
||||
}
|
||||
|
||||
static void
|
||||
replace_variables(char *text)
|
||||
{
|
||||
char *ptr = text;
|
||||
bool string = false;
|
||||
|
||||
for (; *ptr != '\0'; ptr++)
|
||||
{
|
||||
if (*ptr == '\'')
|
||||
string = string ? false : true;
|
||||
|
||||
if (!string && *ptr == ':')
|
||||
{
|
||||
ptr[0] = ptr[1] = ';';
|
||||
for (ptr += 2; *ptr && *ptr != ' '; ptr++)
|
||||
*ptr = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* handle the EXEC SQL PREPARE statement */
|
||||
bool
|
||||
ECPGprepare(int lineno, char *name, char *variable)
|
||||
{
|
||||
struct statement *stmt;
|
||||
struct prepared_statement *this;
|
||||
|
||||
/* check if we already have prepared this statement */
|
||||
for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
|
||||
if (this)
|
||||
{
|
||||
bool b = ECPGdeallocate(lineno, name);
|
||||
|
||||
if (!b)
|
||||
return false;
|
||||
}
|
||||
|
||||
this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
|
||||
if (!this)
|
||||
return false;
|
||||
|
||||
stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
|
||||
if (!stmt)
|
||||
{
|
||||
free(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create statement */
|
||||
stmt->lineno = lineno;
|
||||
stmt->command = ecpg_strdup(variable, lineno);
|
||||
stmt->inlist = stmt->outlist = NULL;
|
||||
|
||||
/* if we have C variables in our statment replace them with ';;' */
|
||||
replace_variables(stmt->command);
|
||||
|
||||
/* add prepared statement to our list */
|
||||
this->name = ecpg_strdup(name, lineno);
|
||||
this->stmt = stmt;
|
||||
|
||||
if (prep_stmts == NULL)
|
||||
this->next = NULL;
|
||||
else
|
||||
this->next = prep_stmts;
|
||||
|
||||
prep_stmts = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* handle the EXEC SQL DEALLOCATE PREPARE statement */
|
||||
bool
|
||||
ECPGdeallocate(int lineno, char *name)
|
||||
{
|
||||
struct prepared_statement *this, *prev;
|
||||
|
||||
/* check if we really have prepared this statement */
|
||||
for (this = prep_stmts, prev = NULL; this != NULL && strcmp(this->name, name) != 0; prev = this, this = this->next);
|
||||
if (this)
|
||||
{
|
||||
/* okay, free all the resources */
|
||||
free(this->name);
|
||||
free(this->stmt->command);
|
||||
free(this->stmt);
|
||||
if (prev != NULL)
|
||||
prev->next = this->next;
|
||||
else
|
||||
prep_stmts = this->next;
|
||||
|
||||
return true;
|
||||
}
|
||||
ECPGlog("deallocate_prepare: invalid statement name %s\n", name);
|
||||
register_error(ECPG_INVALID_STMT, "Invalid statement name %s in line %d", name, lineno);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* return the prepared statement */
|
||||
char *
|
||||
ECPGprepared_statement(char *name)
|
||||
{
|
||||
struct prepared_statement *this;
|
||||
|
||||
for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
|
||||
return (this) ? this->stmt->command : NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ ECPGtype_name(enum ECPGttype typ)
|
||||
{
|
||||
switch (typ)
|
||||
{
|
||||
case ECPGt_char:
|
||||
case ECPGt_char:
|
||||
return "char";
|
||||
case ECPGt_unsigned_char:
|
||||
return "unsigned char";
|
||||
@@ -32,6 +32,8 @@ ECPGtype_name(enum ECPGttype typ)
|
||||
return "bool";
|
||||
case ECPGt_varchar:
|
||||
return "varchar";
|
||||
case ECPGt_char_variable:
|
||||
return "char";
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user