1717#include <unistd.h>
1818#include <stdarg.h>
1919#include <string.h>
20+ #include <ctype.h>
2021
2122#include <libpq-fe.h>
2223#include <libpq/pqcomm.h>
@@ -78,6 +79,7 @@ struct statement
7879{
7980int lineno ;
8081char * command ;
82+ struct connection * connection ;
8183struct variable * inlist ;
8284struct variable * outlist ;
8385};
@@ -104,6 +106,21 @@ register_error(long code, char *fmt,...)
104106sqlca .sqlerrm .sqlerrml = strlen (sqlca .sqlerrm .sqlerrmc );
105107}
106108
109+ static struct connection *
110+ get_connection (const char * connection_name )
111+ {
112+ struct connection * con = all_connections ;;
113+
114+ if (connection_name == NULL || strcmp (connection_name ,"CURRENT" )== 0 )
115+ return actual_connection ;
116+
117+ for (;con && strcmp (connection_name ,con -> name )!= 0 ;con = con -> next );
118+ if (con )
119+ return con ;
120+ else
121+ return NULL ;
122+ }
123+
107124static void
108125ECPGfinish (struct connection * act )
109126{
@@ -145,7 +162,6 @@ ecpg_alloc(long size, int lineno)
145162
146163if (!new )
147164{
148- ECPGfinish (actual_connection );
149165ECPGlog ("out of memory\n" );
150166register_error (ECPG_OUT_OF_MEMORY ,"out of memory in line %d" ,lineno );
151167return NULL ;
@@ -162,7 +178,6 @@ ecpg_strdup(const char *string, int lineno)
162178
163179if (!new )
164180{
165- ECPGfinish (actual_connection );
166181ECPGlog ("out of memory\n" );
167182register_error (ECPG_OUT_OF_MEMORY ,"out of memory in line %d" ,lineno );
168183return NULL ;
@@ -238,9 +253,26 @@ quote_strings(char *arg, int lineno)
238253return res ;
239254}
240255
241- /* create a list of variables */
256+ /*
257+ * create a list of variables
258+ * The variables are listed with input variables preceeding outputvariables
259+ * The end of each group is marked by an end marker.
260+ * per variable we list:
261+ * type - as defined in ecpgtype.h
262+ * value - where to store the data
263+ * varcharsize - length of string in case we have a stringvariable, else 0
264+ * arraysize - 0 for pointer (we don't know the size of the array),
265+ * 1 for simple variable, size for arrays
266+ * offset - offset between ith and (i+1)th entry in an array,
267+ * normally that means sizeof(type)
268+ * ind_type - type of indicator variable
269+ * ind_value - pointer to indicator variable
270+ * ind_varcharsize - empty
271+ * ind_arraysize - arraysize of indicator array
272+ * ind_offset - indicator offset
273+ */
242274static bool
243- create_statement (int lineno ,struct statement * * stmt ,char * query ,va_list ap )
275+ create_statement (int lineno ,struct connection * connection , struct statement * * stmt ,char * query ,va_list ap )
244276{
245277struct variable * * list = & ((* stmt )-> inlist );
246278enum ECPGttype type ;
@@ -249,6 +281,7 @@ create_statement(int lineno, struct statement ** stmt, char *query, va_list ap)
249281return false;
250282
251283(* stmt )-> command = query ;
284+ (* stmt )-> connection = connection ;
252285(* stmt )-> lineno = lineno ;
253286
254287list = & ((* stmt )-> inlist );
@@ -278,7 +311,8 @@ create_statement(int lineno, struct statement ** stmt, char *query, va_list ap)
278311var -> ind_arrsize = va_arg (ap ,long );
279312var -> ind_offset = va_arg (ap ,long );
280313var -> next = NULL ;
281-
314+
315+ /* if variable is NULL, the statement hasn't been prepared */
282316if (var -> value == NULL )
283317{
284318ECPGlog ("create_statement: invalid statement name\n" );
@@ -564,27 +598,27 @@ ECPGexecute(struct statement * stmt)
564598
565599/* Now the request is built. */
566600
567- if (actual_connection -> committed && !no_auto_trans )
601+ if (stmt -> connection -> committed && !no_auto_trans )
568602{
569- if ((results = PQexec (actual_connection -> connection ,"begin transaction" ))== NULL )
603+ if ((results = PQexec (stmt -> connection -> connection ,"begin transaction" ))== NULL )
570604{
571605register_error (ECPG_TRANS ,"Error starting transaction line %d." ,stmt -> lineno );
572606return false;
573607}
574608PQclear (results );
575- actual_connection -> committed = false;
609+ stmt -> connection -> committed = false;
576610}
577611
578- ECPGlog ("ECPGexecute line %d: QUERY: %s\n" ,stmt -> lineno ,copiedquery );
579- results = PQexec (actual_connection -> connection ,copiedquery );
612+ ECPGlog ("ECPGexecute line %d: QUERY: %s on connection %s \n" ,stmt -> lineno ,copiedquery , stmt -> connection -> name );
613+ results = PQexec (stmt -> connection -> connection ,copiedquery );
580614free (copiedquery );
581615
582616if (results == NULL )
583617{
584618ECPGlog ("ECPGexecute line %d: error: %s" ,stmt -> lineno ,
585- PQerrorMessage (actual_connection -> connection ));
619+ PQerrorMessage (stmt -> connection -> connection ));
586620register_error (ECPG_PGSQL ,"Postgres error: %s line %d." ,
587- PQerrorMessage (actual_connection -> connection ),stmt -> lineno );
621+ PQerrorMessage (stmt -> connection -> connection ),stmt -> lineno );
588622}
589623else
590624{
@@ -642,6 +676,7 @@ ECPGexecute(struct statement * stmt)
642676status = false;
643677break ;
644678}
679+
645680for (act_tuple = 0 ;act_tuple < ntuples ;act_tuple ++ )
646681{
647682pval = PQgetvalue (results ,act_tuple ,act_field );
@@ -909,18 +944,18 @@ ECPGexecute(struct statement * stmt)
909944case PGRES_FATAL_ERROR :
910945case PGRES_BAD_RESPONSE :
911946ECPGlog ("ECPGexecute line %d: Error: %s" ,
912- stmt -> lineno ,PQerrorMessage (actual_connection -> connection ));
947+ stmt -> lineno ,PQerrorMessage (stmt -> connection -> connection ));
913948register_error (ECPG_PGSQL ,"Error: %s line %d." ,
914- PQerrorMessage (actual_connection -> connection ),stmt -> lineno );
949+ PQerrorMessage (stmt -> connection -> connection ),stmt -> lineno );
915950status = false;
916951break ;
917952case PGRES_COPY_OUT :
918953ECPGlog ("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n" ,stmt -> lineno );
919- PQendcopy (actual_connection -> connection );
954+ PQendcopy (stmt -> connection -> connection );
920955break ;
921956case PGRES_COPY_IN :
922957ECPGlog ("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n" ,stmt -> lineno );
923- PQendcopy (actual_connection -> connection );
958+ PQendcopy (stmt -> connection -> connection );
924959break ;
925960default :
926961ECPGlog ("ECPGexecute line %d: Got something else, postgres error.\n" ,
@@ -932,7 +967,7 @@ ECPGexecute(struct statement * stmt)
932967}
933968
934969/* check for asynchronous returns */
935- notify = PQnotifies (actual_connection -> connection );
970+ notify = PQnotifies (stmt -> connection -> connection );
936971if (notify )
937972{
938973ECPGlog ("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n" ,
@@ -944,20 +979,27 @@ ECPGexecute(struct statement * stmt)
944979}
945980
946981bool
947- ECPGdo (int lineno ,char * query ,...)
982+ ECPGdo (int lineno ,const char * connection_name , char * query ,...)
948983{
949984va_list args ;
950985struct statement * stmt ;
986+ struct connection * con = get_connection (connection_name );
951987
988+ if (con == NULL )
989+ {
990+ register_error (ECPG_NO_CONN ,"No such connection %s in line %d" ,connection_name ,lineno );
991+ return (false);
992+ }
993+
952994va_start (args ,query );
953- if (create_statement (lineno ,& stmt ,query ,args )== false)
995+ if (create_statement (lineno ,con , & stmt ,query ,args )== false)
954996return (false);
955997va_end (args );
956998
957999/* are we connected? */
958- if (actual_connection == NULL || actual_connection -> connection == NULL )
1000+ if (con == NULL || con -> connection == NULL )
9591001{
960- ECPGlog ("ECPGdo: not connected\n" );
1002+ ECPGlog ("ECPGdo: not connected to %s \n" , con -> name );
9611003register_error (ECPG_NOT_CONN ,"Not connected in line %d" ,lineno );
9621004return false;
9631005}
@@ -967,16 +1009,23 @@ ECPGdo(int lineno, char *query,...)
9671009
9681010
9691011bool
970- ECPGtrans (int lineno ,const char * transaction )
1012+ ECPGtrans (int lineno ,const char * connection_name , const char * transaction )
9711013{
9721014PGresult * res ;
1015+ struct connection * con = get_connection (connection_name );
1016+
1017+ if (con == NULL )
1018+ {
1019+ register_error (ECPG_NO_CONN ,"No such connection %s in line %d" ,connection_name ,lineno );
1020+ return (false);
1021+ }
9731022
974- ECPGlog ("ECPGtrans line %d action = %s\n" ,lineno ,transaction );
1023+ ECPGlog ("ECPGtrans line %d action = %s connection = %s \n" ,lineno ,transaction , con -> name );
9751024
9761025/* if we have no connection we just simulate the command */
977- if (actual_connection && actual_connection -> connection )
1026+ if (con && con -> connection )
9781027{
979- if ((res = PQexec (actual_connection -> connection ,transaction ))== NULL )
1028+ if ((res = PQexec (con -> connection ,transaction ))== NULL )
9801029{
9811030register_error (ECPG_TRANS ,"Error in transaction processing line %d." ,lineno );
9821031return FALSE;
@@ -987,7 +1036,7 @@ ECPGtrans(int lineno, const char *transaction)
9871036{
9881037struct prepared_statement * this ;
9891038
990- actual_connection -> committed = true;
1039+ con -> committed = true;
9911040
9921041/* deallocate all prepared statements */
9931042for (this = prep_stmts ;this != NULL ;this = this -> next )
@@ -1005,11 +1054,8 @@ ECPGtrans(int lineno, const char *transaction)
10051054bool
10061055ECPGsetconn (int lineno ,const char * connection_name )
10071056{
1008- struct connection * con = all_connections ;
1009-
1010- ECPGlog ("ECPGsetconn: setting actual connection to %s\n" ,connection_name );
1057+ struct connection * con = get_connection (connection_name );
10111058
1012- for (;con && strcmp (connection_name ,con -> name )!= 0 ;con = con -> next );
10131059if (con )
10141060{
10151061actual_connection = con ;
@@ -1070,9 +1116,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
10701116{
10711117struct connection * con ;
10721118
1073- if (strcmp (connection_name ,"CURRENT" )== 0 )
1074- ECPGfinish (actual_connection );
1075- else if (strcmp (connection_name ,"ALL" )== 0 )
1119+ if (strcmp (connection_name ,"ALL" )== 0 )
10761120{
10771121for (con = all_connections ;con ;)
10781122{
@@ -1084,7 +1128,8 @@ ECPGdisconnect(int lineno, const char *connection_name)
10841128}
10851129else
10861130{
1087- for (con = all_connections ;con && strcmp (con -> name ,connection_name )!= 0 ;con = con -> next );
1131+ con = get_connection (connection_name );
1132+
10881133if (con == NULL )
10891134{
10901135ECPGlog ("disconnect: not connected to connection %s\n" ,connection_name );
@@ -1136,6 +1181,21 @@ sqlprint(void)
11361181printf ("sql error %s\n" ,sqlca .sqlerrm .sqlerrmc );
11371182}
11381183
1184+ static bool
1185+ isvarchar (unsignedchar c )
1186+ {
1187+ if (isalnum (c ))
1188+ return true;
1189+
1190+ if (c == '_' || c == '>' || c == '-' || c == '.' )
1191+ return true;
1192+
1193+ if (c >=128 )
1194+ return true;
1195+
1196+ return (false);
1197+ }
1198+
11391199static void
11401200replace_variables (char * text )
11411201{
@@ -1150,7 +1210,7 @@ replace_variables(char *text)
11501210if (!string && * ptr == ':' )
11511211{
11521212ptr [0 ]= ptr [1 ]= ';' ;
1153- for (ptr += 2 ;* ptr && * ptr != ' ' ;ptr ++ )
1213+ for (ptr += 2 ;* ptr && isvarchar ( * ptr ) ;ptr ++ )
11541214* ptr = ' ' ;
11551215}
11561216}
@@ -1162,7 +1222,7 @@ ECPGprepare(int lineno, char *name, char *variable)
11621222{
11631223struct statement * stmt ;
11641224struct prepared_statement * this ;
1165-
1225+
11661226/* check if we already have prepared this statement */
11671227for (this = prep_stmts ;this != NULL && strcmp (this -> name ,name )!= 0 ;this = this -> next );
11681228if (this )
@@ -1186,6 +1246,7 @@ ECPGprepare(int lineno, char *name, char *variable)
11861246
11871247/* create statement */
11881248stmt -> lineno = lineno ;
1249+ stmt -> connection = NULL ;
11891250stmt -> command = ecpg_strdup (variable ,lineno );
11901251stmt -> inlist = stmt -> outlist = NULL ;
11911252