MODULE_big = postgresql_fdw
PG_CPPFLAGS = -I$(libpq_srcdir)
-OBJS = postgresql_fdw.o
+OBJS = postgresql_fdw.o fsconnection.o
SHLIB_LINK = $(libpq)
DATA_built = postgresql_fdw.sql
#include "utils/builtins.h"
#include "utils/catcache.h"
+#include "fsconnection.h"
extern Datum pg_foreign_connections(PG_FUNCTION_ARGS);
--- /dev/null
+/*
+ * fsconnection.h
+ *
+ * Cache connections to foreign PostgreSQL servers.
+ *
+ * contrib/postgresql_fdw/postgresql_fdw.h
+ * Copyright (c) 2010, PostgreSQL Global Development Group
+ * ALL RIGHTS RESERVED;
+ *
+ */
+
+#ifndef FSCONNECTION_H
+#define FSCONNECTION_H
+
+/* foreign server connections */
+extern FSConnection *ConnectToForeignServer(FdwRoutine *routine,
+ ForeignServer *server, UserMapping *user, const char *conname);
+extern void RegisterFSConnection(FSConnection *conn, FdwRoutine *routine,
+ const char *conname);
+extern FSConnection *GetFSConnectionByName(const char *conname, FdwRoutine **routine);
+extern bool DisconnectForeignServer(const char *conname);
+extern void DisconnectAllForeignServers(void);
+
+#endif /* FSCONNECTION_H */
#include "utils/syscache.h"
#include "postgresql_fdw.h"
+#include "fsconnection.h"
PG_MODULE_MAGIC;
AS 'MODULE_PATHNAME','postgresql_fdw_handler'
LANGUAGE C STRICT;
+CREATE OR REPLACE FUNCTION pg_foreign_connections(conname OUT text, serverid OUT oid, userid OUT oid)
+ RETURNS SETOF record
+ AS 'MODULE_PATHNAME','pg_foreign_connections'
+ LANGUAGE C STRICT;
+
+CREATE OR REPLACE VIEW pg_foreign_connections AS
+ SELECT c.conname as conname,
+ s.srvname as srvname,
+ a.rolname as usename
+ FROM pg_foreign_connections() c
+ JOIN pg_foreign_server s ON (s.oid = c.serverid)
+ JOIN pg_authid a ON (a.oid = c.userid);
+
+GRANT EXECUTE ON FUNCTION pg_foreign_connections(conname OUT text, serverid OUT oid, userid OUT oid) TO public;
+GRANT SELECT ON pg_foreign_connections TO public;
+
set search_path = public;
DROP FUNCTION postgresql_fdw_handler ();
+DROP VIEW pg_foreign_connections;
+DROP FUNCTION pg_foreign_connections(conname OUT text, serverid OUT oid, userid OUT oid);
<entry>open cursors</entry>
</row>
- <row>
- <entry><link linkend="view-pg-foreign-connections"><structname>pg_foreign_connections</structname></link></entry>
- <entry>established foreign connections</entry>
- </row>
-
<row>
<entry><link linkend="view-pg-group"><structname>pg_group</structname></link></entry>
<entry>groups of database users</entry>
</sect1>
- <sect1 id="view-pg-foreign-connections">
- <title><structname>pg_foreign_connections</structname></title>
-
- <indexterm zone="view-pg-foreign-connections">
- <primary>pg_foreign_connections</primary>
- </indexterm>
-
- <para>
- The <structname>pg_foreign_connections</structname> view lists
- the foreign connections that are currently available.
- Foreign connections are established in several ways:
- <itemizedlist>
- <listitem>
- <para>
- via the query for a foreign table
- </para>
- </listitem>
-
- <listitem>
- <para>
- via the use of dblink functions, see <xref linkend="dblink">
- </para>
- </listitem>
- </itemizedlist>
-
- The <structname>pg_foreign_connections</structname> view displays
- foreign connections created by any of these means.
- Foreign connections only exist for the duration
- of the backend lifetime which established the connection,
- and cannot be used from other backends.
- Use <command>DISCARD ALL</command> command to close all foreign
- connections.
- </para>
-
- <table>
- <title><structname>pg_foreign_connections</> Columns</title>
-
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Name</entry>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry><structfield>conname</structfield></entry>
- <entry><type>text</type></entry>
- <entry>The name of the connection</entry>
- </row>
-
- <row>
- <entry><structfield>srvname</structfield></entry>
- <entry><type>name</type></entry>
- <entry>The name of the foreign server which was used to
- establish the connection</entry>
- </row>
-
- <row>
- <entry><structfield>usename</structfield></entry>
- <entry><type>name</type></entry>
- <entry>The name of the local user which was used to
- establish the connection</entry>
- </row>
-
- <row>
- <entry><structfield>fdwname</structfield></entry>
- <entry><type>name</type></entry>
- <entry>The name of the foreign-data wrapper which was
- used to establish the connection</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- The <structname>pg_cursors</structname> view is read only.
- </para>
-
- </sect1>
-
<sect1 id="view-pg-group">
<title><structname>pg_group</structname></title>
CREATE VIEW pg_timezone_names AS
SELECT * FROM pg_timezone_names();
-CREATE VIEW pg_foreign_connections AS
- SELECT C.connection_name AS conname,
- S.srvname AS srvname,
- U.rolname AS usename,
- D.fdwname AS fdwname
- FROM pg_foreign_connections() AS C
- LEFT JOIN pg_authid U ON C.userid = U.oid
- LEFT JOIN pg_foreign_server S ON C.serverid = S.oid
- LEFT JOIN pg_foreign_data_wrapper D ON S.srvfdw = D.oid;
-
-- Statistics views
CREATE VIEW pg_stat_all_tables AS
LockReleaseAll(USER_LOCKMETHOD, true);
ResetPlanCache();
ResetTempTableNamespace();
- DisconnectAllForeignServers();
}
scanstate->routine = GetFdwRoutine(scanstate->wrapper->fdwhandler);
/* connect to the foreign server and prepare to execute scan */
- scanstate->conn = ConnectToForeignServer(scanstate->routine,
- scanstate->server,
- scanstate->user,
- scanstate->server->servername);
+ scanstate->conn = scanstate->routine->ConnectServer(scanstate->server,
+ scanstate->user);
scanstate->routine->Open(scanstate);
return scanstate;
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
-OBJS= foreign.o fsconnection.o csv_fdw.o
+OBJS= foreign.o csv_fdw.o
include $(top_srcdir)/src/backend/common.mk
AssertArg(OidIsValid(userid));
OuterUserId = userid;
- /* Discard all foreign server connections */
- if (CurrentUserId != userid)
- DisconnectAllForeignServers();
-
/* We force the effective user ID to match, too */
CurrentUserId = userid;
}
SessionUserIsSuperuser = is_superuser;
SetRoleIsActive = false;
- /* Discard all foreign server connections */
- if (CurrentUserId != userid)
- DisconnectAllForeignServers();
-
/* We force the effective user IDs to match, too */
OuterUserId = userid;
CurrentUserId = userid;
DESCR("get the channels that the current backend listens to");
DATA(insert OID = 3036 ( pg_notify PGNSP PGUID 12 1 0 0 f f f f f v 2 0 2278 "25 25" _null_ _null_ _null_ _null_ pg_notify _null_ _null_ _null_ ));
DESCR("send a notification event");
-DATA(insert OID = 3539 ( pg_foreign_connections PGNSP PGUID 12 1 1000 0 f f f t t s 0 0 2249 "" "{25,26,26}" "{o,o,o}" "{connection_name,serverid,userid}" _null_ pg_foreign_connections _null_ _null_ _null_ ));
-DESCR("get the foreign server connections for this session");
/* non-persistent series generator */
DATA(insert OID = 1066 ( generate_series PGNSP PGUID 12 1 1000 0 f f f t t i 3 0 23 "23 23 23" _null_ _null_ _null_ _null_ generate_series_step_int4 _null_ _null_ _null_ ));
extern void ATExecGenericOptions(Relation rel, List *options);
extern bool is_libpq_connection_option(const char *option);
-/* foreign server connections */
-extern FSConnection *ConnectToForeignServer(FdwRoutine *routine,
- ForeignServer *server, UserMapping *user, const char *conname);
-extern void RegisterFSConnection(FSConnection *conn, FdwRoutine *routine,
- const char *conname);
-extern FSConnection *GetFSConnectionByName(const char *conname, FdwRoutine **routine);
-extern bool DisconnectForeignServer(const char *conname);
-extern void DisconnectAllForeignServers(void);
-
#endif /* FOREIGN_H */
-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
pg_cursors | SELECT c.name, c.statement, c.is_holdable, c.is_binary, c.is_scrollable, c.creation_time FROM pg_cursor() c(name, statement, is_holdable, is_binary, is_scrollable, creation_time);
- pg_foreign_connections | SELECT c.connection_name AS conname, s.srvname, u.rolname AS usename, d.fdwname FROM (((pg_foreign_connections() c(connection_name, serverid, userid) LEFT JOIN pg_authid u ON ((c.userid = u.oid))) LEFT JOIN pg_foreign_server s ON ((c.serverid = s.oid))) LEFT JOIN pg_foreign_data_wrapper d ON ((s.srvfdw = d.oid)));
pg_group | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
pg_indexes | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, t.spcname AS tablespace, pg_get_indexdef(i.oid) AS indexdef FROM ((((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
pg_locks | SELECT l.locktype, l.database, l.relation, l.page, l.tuple, l.virtualxid, l.transactionid, l.classid, l.objid, l.objsubid, l.virtualtransaction, l.pid, l.mode, l.granted FROM pg_lock_status() l(locktype, database, relation, page, tuple, virtualxid, transactionid, classid, objid, objsubid, virtualtransaction, pid, mode, granted);
shoelace_obsolete | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color))));
street | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath);
toyemp | SELECT emp.name, emp.age, emp.location, (12 * emp.salary) AS annualsal FROM emp;
-(57 rows)
+(56 rows)
SELECT tablename, rulename, definition FROM pg_rules
ORDER BY tablename, rulename;