mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	postgres_fdw tended to say "unknown error" if it tried to execute a command on an already-dead connection, because some paths in libpq just return a null PGresult for such cases. Out-of-memory might result in that, too. To fix, pass the PGconn to pgfdw_report_error, and look at its PQerrorMessage() string if we can't get anything out of the PGresult. Also, fix the transaction-exit logic to reliably drop a dead connection. It was attempting to do that already, but it assumed that only connection cache entries with xact_depth > 0 needed to be examined. The folly in that is that if we fail while issuing START TRANSACTION, we'll not have bumped xact_depth. (At least for the case I was testing, this fix masks the other problem; but it still seems like a good idea to have the PGconn fallback logic.) Per investigation of bug #9087 from Craig Lucas. Backpatch to 9.3 where this code was introduced.
		
			
				
	
	
		
			77 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*-------------------------------------------------------------------------
 | |
|  *
 | |
|  * postgres_fdw.h
 | |
|  *		  Foreign-data wrapper for remote PostgreSQL servers
 | |
|  *
 | |
|  * Portions Copyright (c) 2012-2013, PostgreSQL Global Development Group
 | |
|  *
 | |
|  * IDENTIFICATION
 | |
|  *		  contrib/postgres_fdw/postgres_fdw.h
 | |
|  *
 | |
|  *-------------------------------------------------------------------------
 | |
|  */
 | |
| #ifndef POSTGRES_FDW_H
 | |
| #define POSTGRES_FDW_H
 | |
| 
 | |
| #include "foreign/foreign.h"
 | |
| #include "lib/stringinfo.h"
 | |
| #include "nodes/relation.h"
 | |
| #include "utils/rel.h"
 | |
| 
 | |
| #include "libpq-fe.h"
 | |
| 
 | |
| /* in postgres_fdw.c */
 | |
| extern int	set_transmission_modes(void);
 | |
| extern void reset_transmission_modes(int nestlevel);
 | |
| 
 | |
| /* in connection.c */
 | |
| extern PGconn *GetConnection(ForeignServer *server, UserMapping *user,
 | |
| 			  bool will_prep_stmt);
 | |
| extern void ReleaseConnection(PGconn *conn);
 | |
| extern unsigned int GetCursorNumber(PGconn *conn);
 | |
| extern unsigned int GetPrepStmtNumber(PGconn *conn);
 | |
| extern void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn,
 | |
| 				   bool clear, const char *sql);
 | |
| 
 | |
| /* in option.c */
 | |
| extern int ExtractConnectionOptions(List *defelems,
 | |
| 						 const char **keywords,
 | |
| 						 const char **values);
 | |
| 
 | |
| /* in deparse.c */
 | |
| extern void classifyConditions(PlannerInfo *root,
 | |
| 				   RelOptInfo *baserel,
 | |
| 				   List **remote_conds,
 | |
| 				   List **local_conds);
 | |
| extern bool is_foreign_expr(PlannerInfo *root,
 | |
| 				RelOptInfo *baserel,
 | |
| 				Expr *expr);
 | |
| extern void deparseSelectSql(StringInfo buf,
 | |
| 				 PlannerInfo *root,
 | |
| 				 RelOptInfo *baserel,
 | |
| 				 Bitmapset *attrs_used,
 | |
| 				 List **retrieved_attrs);
 | |
| extern void appendWhereClause(StringInfo buf,
 | |
| 				  PlannerInfo *root,
 | |
| 				  RelOptInfo *baserel,
 | |
| 				  List *exprs,
 | |
| 				  bool is_first,
 | |
| 				  List **params);
 | |
| extern void deparseInsertSql(StringInfo buf, PlannerInfo *root,
 | |
| 				 Index rtindex, Relation rel,
 | |
| 				 List *targetAttrs, List *returningList,
 | |
| 				 List **retrieved_attrs);
 | |
| extern void deparseUpdateSql(StringInfo buf, PlannerInfo *root,
 | |
| 				 Index rtindex, Relation rel,
 | |
| 				 List *targetAttrs, List *returningList,
 | |
| 				 List **retrieved_attrs);
 | |
| extern void deparseDeleteSql(StringInfo buf, PlannerInfo *root,
 | |
| 				 Index rtindex, Relation rel,
 | |
| 				 List *returningList,
 | |
| 				 List **retrieved_attrs);
 | |
| extern void deparseAnalyzeSizeSql(StringInfo buf, Relation rel);
 | |
| extern void deparseAnalyzeSql(StringInfo buf, Relation rel,
 | |
| 				  List **retrieved_attrs);
 | |
| 
 | |
| #endif   /* POSTGRES_FDW_H */
 |