@ -301,11 +301,12 @@ dblink_open(PG_FUNCTION_ARGS)
char * curname = NULL ;
char * curname = NULL ;
char * sql = NULL ;
char * sql = NULL ;
char * conname = NULL ;
char * conname = NULL ;
StringInfo str = makeStringInfo ( ) ;
StringInfoData buf ;
remoteConn * rconn = NULL ;
remoteConn * rconn = NULL ;
bool fail = true ; /* default to backward compatible behavior */
bool fail = true ; /* default to backward compatible behavior */
DBLINK_INIT ;
DBLINK_INIT ;
initStringInfo ( & buf ) ;
if ( PG_NARGS ( ) = = 2 )
if ( PG_NARGS ( ) = = 2 )
{
{
@ -361,8 +362,8 @@ dblink_open(PG_FUNCTION_ARGS)
if ( rconn - > newXactForCursor )
if ( rconn - > newXactForCursor )
( rconn - > openCursorCount ) + + ;
( rconn - > openCursorCount ) + + ;
appendStringInfo ( str , " DECLARE %s CURSOR FOR %s " , curname , sql ) ;
appendStringInfo ( & buf , " DECLARE %s CURSOR FOR %s " , curname , sql ) ;
res = PQexec ( conn , str - > data ) ;
res = PQexec ( conn , buf . data ) ;
if ( ! res | | PQresultStatus ( res ) ! = PGRES_COMMAND_OK )
if ( ! res | | PQresultStatus ( res ) ! = PGRES_COMMAND_OK )
{
{
if ( fail )
if ( fail )
@ -389,12 +390,13 @@ dblink_close(PG_FUNCTION_ARGS)
PGresult * res = NULL ;
PGresult * res = NULL ;
char * curname = NULL ;
char * curname = NULL ;
char * conname = NULL ;
char * conname = NULL ;
StringInfo str = makeStringInfo ( ) ;
StringInfoData buf ;
char * msg ;
char * msg ;
remoteConn * rconn = NULL ;
remoteConn * rconn = NULL ;
bool fail = true ; /* default to backward compatible behavior */
bool fail = true ; /* default to backward compatible behavior */
DBLINK_INIT ;
DBLINK_INIT ;
initStringInfo ( & buf ) ;
if ( PG_NARGS ( ) = = 1 )
if ( PG_NARGS ( ) = = 1 )
{
{
@ -432,10 +434,10 @@ dblink_close(PG_FUNCTION_ARGS)
else
else
conn = rconn - > conn ;
conn = rconn - > conn ;
appendStringInfo ( str , " CLOSE %s " , curname ) ;
appendStringInfo ( & buf , " CLOSE %s " , curname ) ;
/* close the cursor */
/* close the cursor */
res = PQexec ( conn , str - > data ) ;
res = PQexec ( conn , buf . data ) ;
if ( ! res | | PQresultStatus ( res ) ! = PGRES_COMMAND_OK )
if ( ! res | | PQresultStatus ( res ) ! = PGRES_COMMAND_OK )
{
{
if ( fail )
if ( fail )
@ -493,7 +495,7 @@ dblink_fetch(PG_FUNCTION_ARGS)
if ( SRF_IS_FIRSTCALL ( ) )
if ( SRF_IS_FIRSTCALL ( ) )
{
{
PGconn * conn = NULL ;
PGconn * conn = NULL ;
StringInfo str = makeStringInfo ( ) ;
StringInfoData buf ;
char * curname = NULL ;
char * curname = NULL ;
int howmany = 0 ;
int howmany = 0 ;
bool fail = true ; /* default to backward compatible */
bool fail = true ; /* default to backward compatible */
@ -542,6 +544,9 @@ dblink_fetch(PG_FUNCTION_ARGS)
if ( ! conn )
if ( ! conn )
DBLINK_CONN_NOT_AVAIL ;
DBLINK_CONN_NOT_AVAIL ;
initStringInfo ( & buf ) ;
appendStringInfo ( & buf , " FETCH %d FROM %s " , howmany , curname ) ;
/* create a function context for cross-call persistence */
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT ( ) ;
funcctx = SRF_FIRSTCALL_INIT ( ) ;
@ -550,9 +555,7 @@ dblink_fetch(PG_FUNCTION_ARGS)
*/
*/
oldcontext = MemoryContextSwitchTo ( funcctx - > multi_call_memory_ctx ) ;
oldcontext = MemoryContextSwitchTo ( funcctx - > multi_call_memory_ctx ) ;
appendStringInfo ( str , " FETCH %d FROM %s " , howmany , curname ) ;
res = PQexec ( conn , buf . data ) ;
res = PQexec ( conn , str - > data ) ;
if ( ! res | |
if ( ! res | |
( PQresultStatus ( res ) ! = PGRES_COMMAND_OK & &
( PQresultStatus ( res ) ! = PGRES_COMMAND_OK & &
PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) )
PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) )
@ -1547,13 +1550,14 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
HeapTuple tuple ;
HeapTuple tuple ;
TupleDesc tupdesc ;
TupleDesc tupdesc ;
int natts ;
int natts ;
StringInfo str = makeStringInfo ( ) ;
StringInfoData buf ;
char * sql ;
char * val ;
char * val ;
int16 key ;
int16 key ;
int i ;
int i ;
bool needComma ;
bool needComma ;
initStringInfo ( & buf ) ;
/* get relation name including any needed schema prefix and quoting */
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name ( relid ) ;
relname = generate_relation_name ( relid ) ;
@ -1570,7 +1574,7 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
( errcode ( ERRCODE_CARDINALITY_VIOLATION ) ,
( errcode ( ERRCODE_CARDINALITY_VIOLATION ) ,
errmsg ( " source row not found " ) ) ) ;
errmsg ( " source row not found " ) ) ) ;
appendStringInfo ( str , " INSERT INTO %s( " , relname ) ;
appendStringInfo ( & buf , " INSERT INTO %s( " , relname ) ;
needComma = false ;
needComma = false ;
for ( i = 0 ; i < natts ; i + + )
for ( i = 0 ; i < natts ; i + + )
@ -1579,14 +1583,14 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
continue ;
continue ;
if ( needComma )
if ( needComma )
appendStringInfo ( str , " , " ) ;
appendStringInfo ( & buf , " , " ) ;
appendStringInfo ( str , " %s " ,
appendStringInfoString ( & buf ,
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ i ] - > attname ) ) ) ;
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ i ] - > attname ) ) ) ;
needComma = true ;
needComma = true ;
}
}
appendStringInfo ( str , " ) VALUES( " ) ;
appendStringInfo ( & buf , " ) VALUES( " ) ;
/*
/*
* remember attvals are 1 based
* remember attvals are 1 based
@ -1598,7 +1602,7 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
continue ;
continue ;
if ( needComma )
if ( needComma )
appendStringInfo ( str , " , " ) ;
appendStringInfo ( & buf , " , " ) ;
if ( tgt_pkattvals ! = NULL )
if ( tgt_pkattvals ! = NULL )
key = get_attnum_pk_pos ( pkattnums , pknumatts , i + 1 ) ;
key = get_attnum_pk_pos ( pkattnums , pknumatts , i + 1 ) ;
@ -1612,21 +1616,17 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
if ( val ! = NULL )
if ( val ! = NULL )
{
{
appendStringInfo ( str , " %s " , quote_literal_cstr ( val ) ) ;
appendStringInfoString ( & buf , quote_literal_cstr ( val ) ) ;
pfree ( val ) ;
pfree ( val ) ;
}
}
else
else
appendStringInfo ( str , " NULL " ) ;
appendStringInfo ( & buf , " NULL " ) ;
needComma = true ;
needComma = true ;
}
}
appendStringInfo ( str , " ) " ) ;
appendStringInfo ( & buf , " ) " ) ;
sql = pstrdup ( str - > data ) ;
pfree ( str - > data ) ;
pfree ( str ) ;
relation_close ( rel , AccessShareLock ) ;
relation_close ( rel , AccessShareLock ) ;
return ( buf . data ) ;
return ( sql ) ;
}
}
static char *
static char *
@ -1636,10 +1636,11 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
char * relname ;
char * relname ;
TupleDesc tupdesc ;
TupleDesc tupdesc ;
int natts ;
int natts ;
StringInfo str = makeStringInfo ( ) ;
StringInfoData buf ;
char * sql ;
int i ;
int i ;
initStringInfo ( & buf ) ;
/* get relation name including any needed schema prefix and quoting */
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name ( relid ) ;
relname = generate_relation_name ( relid ) ;
@ -1650,15 +1651,15 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
tupdesc = rel - > rd_att ;
tupdesc = rel - > rd_att ;
natts = tupdesc - > natts ;
natts = tupdesc - > natts ;
appendStringInfo ( str , " DELETE FROM %s WHERE " , relname ) ;
appendStringInfo ( & buf , " DELETE FROM %s WHERE " , relname ) ;
for ( i = 0 ; i < pknumatts ; i + + )
for ( i = 0 ; i < pknumatts ; i + + )
{
{
int16 pkattnum = pkattnums - > values [ i ] ;
int16 pkattnum = pkattnums - > values [ i ] ;
if ( i > 0 )
if ( i > 0 )
appendStringInfo ( str , " AND " ) ;
appendStringInfo ( & buf , " AND " ) ;
appendStringInfo ( str , " %s " ,
appendStringInfoString ( & buf ,
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ pkattnum - 1 ] - > attname ) ) ) ;
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ pkattnum - 1 ] - > attname ) ) ) ;
if ( tgt_pkattvals = = NULL )
if ( tgt_pkattvals = = NULL )
@ -1666,18 +1667,14 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
elog ( ERROR , " target key array must not be NULL " ) ;
elog ( ERROR , " target key array must not be NULL " ) ;
if ( tgt_pkattvals [ i ] ! = NULL )
if ( tgt_pkattvals [ i ] ! = NULL )
appendStringInfo ( str , " = %s " ,
appendStringInfo ( & buf , " = %s " ,
quote_literal_cstr ( tgt_pkattvals [ i ] ) ) ;
quote_literal_cstr ( tgt_pkattvals [ i ] ) ) ;
else
else
appendStringInfo ( str , " IS NULL " ) ;
appendStringInfo ( & buf , " IS NULL " ) ;
}
}
sql = pstrdup ( str - > data ) ;
pfree ( str - > data ) ;
pfree ( str ) ;
relation_close ( rel , AccessShareLock ) ;
relation_close ( rel , AccessShareLock ) ;
return ( buf . data ) ;
return ( sql ) ;
}
}
static char *
static char *
@ -1688,13 +1685,14 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
HeapTuple tuple ;
HeapTuple tuple ;
TupleDesc tupdesc ;
TupleDesc tupdesc ;
int natts ;
int natts ;
StringInfo str = makeStringInfo ( ) ;
StringInfoData buf ;
char * sql ;
char * val ;
char * val ;
int16 key ;
int16 key ;
int i ;
int i ;
bool needComma ;
bool needComma ;
initStringInfo ( & buf ) ;
/* get relation name including any needed schema prefix and quoting */
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name ( relid ) ;
relname = generate_relation_name ( relid ) ;
@ -1711,7 +1709,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
( errcode ( ERRCODE_CARDINALITY_VIOLATION ) ,
( errcode ( ERRCODE_CARDINALITY_VIOLATION ) ,
errmsg ( " source row not found " ) ) ) ;
errmsg ( " source row not found " ) ) ) ;
appendStringInfo ( str , " UPDATE %s SET " , relname ) ;
appendStringInfo ( & buf , " UPDATE %s SET " , relname ) ;
needComma = false ;
needComma = false ;
for ( i = 0 ; i < natts ; i + + )
for ( i = 0 ; i < natts ; i + + )
@ -1720,9 +1718,9 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
continue ;
continue ;
if ( needComma )
if ( needComma )
appendStringInfo ( str , " , " ) ;
appendStringInfo ( & buf , " , " ) ;
appendStringInfo ( str , " %s = " ,
appendStringInfo ( & buf , " %s = " ,
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ i ] - > attname ) ) ) ;
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ i ] - > attname ) ) ) ;
if ( tgt_pkattvals ! = NULL )
if ( tgt_pkattvals ! = NULL )
@ -1737,24 +1735,24 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
if ( val ! = NULL )
if ( val ! = NULL )
{
{
appendStringInfo ( str , " %s " , quote_literal_cstr ( val ) ) ;
appendStringInfoString ( & buf , quote_literal_cstr ( val ) ) ;
pfree ( val ) ;
pfree ( val ) ;
}
}
else
else
appendStringInfo ( str , " NULL " ) ;
appendStringInfoString ( & buf , " NULL " ) ;
needComma = true ;
needComma = true ;
}
}
appendStringInfo ( str , " WHERE " ) ;
appendStringInfo ( & buf , " WHERE " ) ;
for ( i = 0 ; i < pknumatts ; i + + )
for ( i = 0 ; i < pknumatts ; i + + )
{
{
int16 pkattnum = pkattnums - > values [ i ] ;
int16 pkattnum = pkattnums - > values [ i ] ;
if ( i > 0 )
if ( i > 0 )
appendStringInfo ( str , " AND " ) ;
appendStringInfo ( & buf , " AND " ) ;
appendStringInfo ( str , " %s " ,
appendStringInfo ( & buf , " %s " ,
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ pkattnum - 1 ] - > attname ) ) ) ;
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ pkattnum - 1 ] - > attname ) ) ) ;
if ( tgt_pkattvals ! = NULL )
if ( tgt_pkattvals ! = NULL )
@ -1764,19 +1762,15 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
if ( val ! = NULL )
if ( val ! = NULL )
{
{
appendStringInfo ( str , " = %s " , quote_literal_cstr ( val ) ) ;
appendStringInfo ( & buf , " = %s " , quote_literal_cstr ( val ) ) ;
pfree ( val ) ;
pfree ( val ) ;
}
}
else
else
appendStringInfo ( str , " IS NULL " ) ;
appendStringInfo ( & buf , " IS NULL " ) ;
}
}
sql = pstrdup ( str - > data ) ;
pfree ( str - > data ) ;
pfree ( str ) ;
relation_close ( rel , AccessShareLock ) ;
relation_close ( rel , AccessShareLock ) ;
return ( buf . data ) ;
return ( sql ) ;
}
}
/*
/*
@ -1836,12 +1830,13 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
Relation rel ;
Relation rel ;
char * relname ;
char * relname ;
TupleDesc tupdesc ;
TupleDesc tupdesc ;
StringInfo str = makeStringInfo ( ) ;
StringInfoData buf ;
char * sql = NULL ;
int ret ;
int ret ;
HeapTuple tuple ;
HeapTuple tuple ;
int i ;
int i ;
initStringInfo ( & buf ) ;
/* get relation name including any needed schema prefix and quoting */
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name ( relid ) ;
relname = generate_relation_name ( relid ) ;
@ -1863,34 +1858,30 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
* Build sql statement to look up tuple of interest Use src_pkattvals as
* Build sql statement to look up tuple of interest Use src_pkattvals as
* the criteria .
* the criteria .
*/
*/
appendStringInfo ( str , " SELECT * FROM %s WHERE " , relname ) ;
appendStringInfo ( & buf , " SELECT * FROM %s WHERE " , relname ) ;
for ( i = 0 ; i < pknumatts ; i + + )
for ( i = 0 ; i < pknumatts ; i + + )
{
{
int16 pkattnum = pkattnums - > values [ i ] ;
int16 pkattnum = pkattnums - > values [ i ] ;
if ( i > 0 )
if ( i > 0 )
appendStringInfo ( str , " AND " ) ;
appendStringInfo ( & buf , " AND " ) ;
appendStringInfo ( str , " %s " ,
appendStringInfoString ( & buf ,
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ pkattnum - 1 ] - > attname ) ) ) ;
quote_ident_cstr ( NameStr ( tupdesc - > attrs [ pkattnum - 1 ] - > attname ) ) ) ;
if ( src_pkattvals [ i ] ! = NULL )
if ( src_pkattvals [ i ] ! = NULL )
appendStringInfo ( str , " = %s " ,
appendStringInfo ( & buf , " = %s " ,
quote_literal_cstr ( src_pkattvals [ i ] ) ) ;
quote_literal_cstr ( src_pkattvals [ i ] ) ) ;
else
else
appendStringInfo ( str , " IS NULL " ) ;
appendStringInfo ( & buf , " IS NULL " ) ;
}
}
sql = pstrdup ( str - > data ) ;
pfree ( str - > data ) ;
pfree ( str ) ;
/*
/*
* Retrieve the desired tuple
* Retrieve the desired tuple
*/
*/
ret = SPI_exec ( sql , 0 ) ;
ret = SPI_exec ( buf . data , 0 ) ;
pfree ( sql ) ;
pfree ( buf . data ) ;
/*
/*
* Only allow one qualifying tuple
* Only allow one qualifying tuple