1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +03:00
+
+ Son Feb 21 14:10:47 CET 1999
+
+       - Fixed variable detection in libecpg.
+
+ Mon Feb 22 19:47:45 CET 1999
+
+       - Added 'at <db_connection>' option to all commands it is apllicable
+         to. Due to changing the API of some libecpg functions this
+         requires me to increase the major version number.
+       - Synced pgc.l with scan.l.
+       - Added support for unions.
+       - Set library version to 3.0.0
+       - Set ecpg version to 3.0.0
This commit is contained in:
Marc G. Fournier
1999-02-23 12:57:03 +00:00
parent e17d8448f2
commit fa9db42a6e
18 changed files with 240 additions and 98 deletions

View File

@@ -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.42 1999/02/21 03:02:35 scrappy Exp $
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.43 1999/02/23 12:56:55 scrappy Exp $
#
#-------------------------------------------------------------------------
NAME= ecpg
SO_MAJOR_VERSION= 2
SO_MINOR_VERSION= 7.1
SO_MAJOR_VERSION= 3
SO_MINOR_VERSION= 0.0
SRCDIR= @top_srcdir@
include $(SRCDIR)/Makefile.global

View File

@@ -17,6 +17,7 @@
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <libpq-fe.h>
#include <libpq/pqcomm.h>
@@ -78,6 +79,7 @@ struct statement
{
int lineno;
char *command;
struct connection *connection;
struct variable *inlist;
struct variable *outlist;
};
@@ -104,6 +106,21 @@ register_error(long code, char *fmt,...)
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
}
static struct connection *
get_connection(const char *connection_name)
{
struct connection *con = all_connections;;
if (connection_name == NULL || strcmp(connection_name, "CURRENT") == 0)
return actual_connection;
for (; con && strcmp(connection_name, con->name) != 0; con = con->next);
if (con)
return con;
else
return NULL;
}
static void
ECPGfinish(struct connection * act)
{
@@ -145,7 +162,6 @@ ecpg_alloc(long size, int lineno)
if (!new)
{
ECPGfinish(actual_connection);
ECPGlog("out of memory\n");
register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
return NULL;
@@ -162,7 +178,6 @@ ecpg_strdup(const char *string, int lineno)
if (!new)
{
ECPGfinish(actual_connection);
ECPGlog("out of memory\n");
register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
return NULL;
@@ -238,9 +253,26 @@ quote_strings(char *arg, int lineno)
return res;
}
/* create a list of variables */
/*
* create a list of variables
* The variables are listed with input variables preceeding outputvariables
* The end of each group is marked by an end marker.
* per variable we list:
* type - as defined in ecpgtype.h
* value - where to store the data
* varcharsize - length of string in case we have a stringvariable, else 0
* arraysize - 0 for pointer (we don't know the size of the array),
* 1 for simple variable, size for arrays
* offset - offset between ith and (i+1)th entry in an array,
* normally that means sizeof(type)
* ind_type - type of indicator variable
* ind_value - pointer to indicator variable
* ind_varcharsize - empty
* ind_arraysize - arraysize of indicator array
* ind_offset - indicator offset
*/
static bool
create_statement(int lineno, struct statement ** stmt, char *query, va_list ap)
create_statement(int lineno, struct connection *connection, struct statement ** stmt, char *query, va_list ap)
{
struct variable **list = &((*stmt)->inlist);
enum ECPGttype type;
@@ -249,6 +281,7 @@ create_statement(int lineno, struct statement ** stmt, char *query, va_list ap)
return false;
(*stmt)->command = query;
(*stmt)->connection = connection;
(*stmt)->lineno = lineno;
list = &((*stmt)->inlist);
@@ -278,7 +311,8 @@ 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 variable is NULL, the statement hasn't been prepared */
if (var->value == NULL)
{
ECPGlog("create_statement: invalid statement name\n");
@@ -564,27 +598,27 @@ ECPGexecute(struct statement * stmt)
/* Now the request is built. */
if (actual_connection->committed && !no_auto_trans)
if (stmt->connection->committed && !no_auto_trans)
{
if ((results = PQexec(actual_connection->connection, "begin transaction")) == NULL)
if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL)
{
register_error(ECPG_TRANS, "Error starting transaction line %d.", stmt->lineno);
return false;
}
PQclear(results);
actual_connection->committed = false;
stmt->connection->committed = false;
}
ECPGlog("ECPGexecute line %d: QUERY: %s\n", stmt->lineno, copiedquery);
results = PQexec(actual_connection->connection, copiedquery);
ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name);
results = PQexec(stmt->connection->connection, copiedquery);
free(copiedquery);
if (results == NULL)
{
ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno,
PQerrorMessage(actual_connection->connection));
PQerrorMessage(stmt->connection->connection));
register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
PQerrorMessage(actual_connection->connection), stmt->lineno);
PQerrorMessage(stmt->connection->connection), stmt->lineno);
}
else
{
@@ -642,6 +676,7 @@ ECPGexecute(struct statement * stmt)
status = false;
break;
}
for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
{
pval = PQgetvalue(results, act_tuple, act_field);
@@ -909,18 +944,18 @@ ECPGexecute(struct statement * stmt)
case PGRES_FATAL_ERROR:
case PGRES_BAD_RESPONSE:
ECPGlog("ECPGexecute line %d: Error: %s",
stmt->lineno, PQerrorMessage(actual_connection->connection));
stmt->lineno, PQerrorMessage(stmt->connection->connection));
register_error(ECPG_PGSQL, "Error: %s line %d.",
PQerrorMessage(actual_connection->connection), stmt->lineno);
PQerrorMessage(stmt->connection->connection), stmt->lineno);
status = false;
break;
case PGRES_COPY_OUT:
ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", stmt->lineno);
PQendcopy(actual_connection->connection);
PQendcopy(stmt->connection->connection);
break;
case PGRES_COPY_IN:
ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", stmt->lineno);
PQendcopy(actual_connection->connection);
PQendcopy(stmt->connection->connection);
break;
default:
ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
@@ -932,7 +967,7 @@ ECPGexecute(struct statement * stmt)
}
/* check for asynchronous returns */
notify = PQnotifies(actual_connection->connection);
notify = PQnotifies(stmt->connection->connection);
if (notify)
{
ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
@@ -944,20 +979,27 @@ ECPGexecute(struct statement * stmt)
}
bool
ECPGdo(int lineno, char *query,...)
ECPGdo(int lineno, const char *connection_name, char *query,...)
{
va_list args;
struct statement *stmt;
struct connection *con = get_connection(connection_name);
if (con == NULL)
{
register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno);
return (false);
}
va_start(args, query);
if (create_statement(lineno, &stmt, query, args) == false)
if (create_statement(lineno, con, &stmt, query, args) == false)
return (false);
va_end(args);
/* are we connected? */
if (actual_connection == NULL || actual_connection->connection == NULL)
if (con == NULL || con->connection == NULL)
{
ECPGlog("ECPGdo: not connected\n");
ECPGlog("ECPGdo: not connected to %s\n", con->name);
register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno);
return false;
}
@@ -967,16 +1009,23 @@ ECPGdo(int lineno, char *query,...)
bool
ECPGtrans(int lineno, const char *transaction)
ECPGtrans(int lineno, const char *connection_name, const char *transaction)
{
PGresult *res;
struct connection *con = get_connection(connection_name);
if (con == NULL)
{
register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno);
return (false);
}
ECPGlog("ECPGtrans line %d action = %s\n", lineno, transaction);
ECPGlog("ECPGtrans line %d action = %s connection = %s\n", lineno, transaction, con->name);
/* if we have no connection we just simulate the command */
if (actual_connection && actual_connection->connection)
if (con && con->connection)
{
if ((res = PQexec(actual_connection->connection, transaction)) == NULL)
if ((res = PQexec(con->connection, transaction)) == NULL)
{
register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno);
return FALSE;
@@ -987,7 +1036,7 @@ ECPGtrans(int lineno, const char *transaction)
{
struct prepared_statement *this;
actual_connection->committed = true;
con->committed = true;
/* deallocate all prepared statements */
for (this = prep_stmts; this != NULL; this = this->next)
@@ -1005,11 +1054,8 @@ ECPGtrans(int lineno, const char *transaction)
bool
ECPGsetconn(int lineno, const char *connection_name)
{
struct connection *con = all_connections;
struct connection *con = get_connection(connection_name);
ECPGlog("ECPGsetconn: setting actual connection to %s\n", connection_name);
for (; con && strcmp(connection_name, con->name) != 0; con = con->next);
if (con)
{
actual_connection = con;
@@ -1070,9 +1116,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
{
struct connection *con;
if (strcmp(connection_name, "CURRENT") == 0)
ECPGfinish(actual_connection);
else if (strcmp(connection_name, "ALL") == 0)
if (strcmp(connection_name, "ALL") == 0)
{
for (con = all_connections; con;)
{
@@ -1084,7 +1128,8 @@ ECPGdisconnect(int lineno, const char *connection_name)
}
else
{
for (con = all_connections; con && strcmp(con->name, connection_name) != 0; con = con->next);
con = get_connection(connection_name);
if (con == NULL)
{
ECPGlog("disconnect: not connected to connection %s\n", connection_name);
@@ -1136,6 +1181,21 @@ sqlprint(void)
printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc);
}
static bool
isvarchar(unsigned char c)
{
if (isalnum(c))
return true;
if (c == '_' || c == '>' || c == '-' || c == '.')
return true;
if (c >= 128)
return true;
return(false);
}
static void
replace_variables(char *text)
{
@@ -1150,7 +1210,7 @@ replace_variables(char *text)
if (!string && *ptr == ':')
{
ptr[0] = ptr[1] = ';';
for (ptr += 2; *ptr && *ptr != ' '; ptr++)
for (ptr += 2; *ptr && isvarchar(*ptr); ptr++)
*ptr = ' ';
}
}
@@ -1162,7 +1222,7 @@ 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)
@@ -1186,6 +1246,7 @@ ECPGprepare(int lineno, char *name, char *variable)
/* create statement */
stmt->lineno = lineno;
stmt->connection = NULL;
stmt->command = ecpg_strdup(variable, lineno);
stmt->inlist = stmt->outlist = NULL;