-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.197 2009/02/09 20:57:59 alvherre Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.198 2009/02/24 10:06:31 petere Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
</row>
<row>
- <entry><structfield>fdwlibrary</structfield></entry>
- <entry><type>text</type></entry>
- <entry></entry>
- <entry>File name of the library implementing this foreign-data wrapper</entry>
+ <entry><structfield>fdwvalidator</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
+ <entry>
+ References a validator function that is responsible for
+ checking the validity of the generic options given to the
+ foreign-data wrapper, as well as to foreign servers and user
+ mappings using the foreign-data wrapper. Zero if no validator
+ is provided.
+ </entry>
</row>
<row>
-<!-- $PostgreSQL: pgsql/doc/src/sgml/keywords.sgml,v 2.22 2008/12/19 16:25:16 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/keywords.sgml,v 2.23 2009/02/24 10:06:31 petere Exp $ -->
<appendix id="sql-keywords-appendix">
<title><acronym>SQL</acronym> Key Words</title>
<entry>reserved</entry>
<entry>reserved</entry>
</row>
- <row>
- <entry><token>LIBRARY</token></entry>
- <entry>non-reserved</entry>
- <entry>non-reserved</entry>
- <entry>non-reserved</entry>
- <entry></entry>
- <entry></entry>
- </row>
<row>
<entry><token>LIKE</token></entry>
<entry>reserved (can be function or type)</entry>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml,v 1.1 2008/12/19 16:25:16 petere Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml,v 1.2 2009/02/24 10:06:32 petere Exp $
PostgreSQL documentation
-->
<refsynopsisdiv>
<synopsis>
ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
- [ LIBRARY '<replaceable class="parameter">libraryname</replaceable>' ]
+ [ VALIDATOR <replaceable class="parameter">valfunction</replaceable> | NO VALIDATOR ]
[ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ]) ]
ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
</synopsis>
</varlistentry>
<varlistentry>
- <term><replaceable class="parameter">libraryname</replaceable></term>
+ <term><literal>VALIDATOR <replaceable class="parameter">valfunction</replaceable></literal></term>
<listitem>
<para>
- New name of the foreign-data wrapper library.
+ Specifies a new foreign-data wrapper validator function.
</para>
<para>
- Note that it is possible that after changing the library, the
+ Note that it is possible that after changing the validator the
options to the foreign-data wrapper, servers, and user mappings
have become invalid. It is up to the user to make sure that
these options are correct before using the foreign-data
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>NO VALIDATOR</literal></term>
+ <listitem>
+ <para>
+ This is used to specify that the foreign-data wrapper should no
+ longer have a validator function.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] )</literal></term>
<listitem>
</para>
<para>
- Change the foreign-data wrapper <literal>dbi</> library
- to <literal>/home/bob/mylibrary.so</>:
+ Change the foreign-data wrapper <literal>dbi</> validator
+ to <literal>bob.myvalidator</>:
<programlisting>
-ALTER FOREIGN DATA WRAPPER dbi LIBRARY '/home/bob/mylibrary.so';
+ALTER FOREIGN DATA WRAPPER dbi VALIDATOR bob.myvalidator;
</programlisting>
</para>
</refsect1>
<para>
<command>ALTER FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
- 9075-9 (SQL/MED). The standard does not specify the <literal>OWNER
- TO</> variant of the command.
+ 9075-9 (SQL/MED). The standard does not specify the <literal>
+ VALIDATOR</literal> and <literal>OWNER TO</> variants of the
+ command.
</para>
</refsect1>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_foreign_data_wrapper.sgml,v 1.1 2008/12/19 16:25:16 petere Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_foreign_data_wrapper.sgml,v 1.2 2009/02/24 10:06:32 petere Exp $
PostgreSQL documentation
-->
<refsynopsisdiv>
<synopsis>
CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
- LIBRARY '<replaceable class="parameter">libraryname</replaceable>'
- LANGUAGE C
+ [ VALIDATOR <replaceable class="parameter">valfunction</replaceable> | NO VALIDATOR ]
[ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ]
</synopsis>
</refsynopsisdiv>
</varlistentry>
<varlistentry>
- <term><replaceable class="parameter">libraryname</replaceable></term>
+ <term><literal>VALIDATOR <replaceable class="parameter">valfunction</replaceable></literal></term>
<listitem>
<para>
- The name of the shared library implementing the foreign-data
- wrapper. The file name is specified in the same way as for
- shared library names in <xref linkend="sql-createfunction"
- endterm="sql-createfunction-title">; in particular, one can rely
- on a search path and automatic addition of the system's standard
- shared library file name extension.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><literal>LANGUAGE C</literal></term>
- <listitem>
- <para>
- Currently, only the C programming language is supported for
- implementing foreign-data wrappers.
+ <replaceable class="parameter">valfunction</replaceable> is the
+ name of a previously registered function that will be called to
+ check the generic options given to the foreign-data wrapper, as
+ well as to foreign servers and user mappings using the
+ foreign-data wrapper. If no validator function or <literal>NO
+ VALIDATOR</literal> is specified, then options will not be
+ checked at creation time. (Foreign-data wrappers will possibly
+ ignore or reject invalid option specifications at run time,
+ depending on the implementation.) The validator function must
+ take two arguments: one of type <type>text[]</type>, which will
+ contain the array of options as stored in the system catalogs,
+ and one of type <type>oid</type>, which will be the OID of the
+ system catalog containing the options, or zero if the context is
+ not known. The return type is ignored; the function should
+ indicate invalid options using
+ the <function>ereport()</function> function.
</para>
</listitem>
</varlistentry>
</para>
<para>
- The C language API for foreign-data wrappers is currently not
- documented, stable, or complete. Would-be authors of functionality
- interfacing with the SQL/MED functionality are advised to contact
- the PostgreSQL developers.
- </para>
-
- <para>
- There are currently two foreign-data wrapper libraries
- provided: <filename>dummy_fdw</filename>, which does nothing and
- could be useful for testing,
- and <filename>postgresql_fdw</filename>, which accepts options
- corresponding to <application>libpq</> connection parameters.
+ There is currently one foreign-data wrapper validator function
+ provided:
+ <filename>postgresql_fdw_validator</filename>, which accepts
+ options corresponding to <application>libpq</> connection
+ parameters.
</para>
</refsect1>
<title>Examples</title>
<para>
- Create a foreign-data wrapper <literal>dummy</> with
- library <literal>dummy_fdw</>:
+ Create a foreign-data wrapper <literal>dummy</>:
<programlisting>
-CREATE FOREIGN DATA WRAPPER dummy LIBRARY 'dummy_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER dummy;
</programlisting>
</para>
<para>
Create a foreign-data wrapper <literal>postgresql</> with
- library <literal>postgresql_fdw</>:
+ validator function <literal>postgresql_fdw_validator</>:
<programlisting>
-CREATE FOREIGN DATA WRAPPER postgresql LIBRARY 'postgresql_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
</programlisting>
</para>
<para>
- Create a foreign-data wrapper <literal>mywrapper</> with library
- <literal>/home/bob/mywrapper.so</> and some options:
+ Create a foreign-data wrapper <literal>mywrapper</> with some
+ options:
<programlisting>
CREATE FOREIGN DATA WRAPPER mywrapper
- LIBRARY '/home/bob/mywrapper.so'
- LANGUAGE C
OPTIONS (debug 'true');
</programlisting>
</para>
<para>
<command>CREATE FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
9075-9 (SQL/MED), with the exception that
- the <literal>LIBRARY</literal> clause is not optional in
- PostgreSQL.
+ the <literal>VALIDATOR</literal> clause is an extension and the
+ clauses <literal>LIBRARY</literal> and <literal>LANGUAGE</literal>
+ are not yet implemented in PostgreSQL.
</para>
<para>
#
# Copyright (c) 1994, Regents of the University of California
#
-# $PostgreSQL: pgsql/src/Makefile,v 1.44 2008/12/19 16:25:16 petere Exp $
+# $PostgreSQL: pgsql/src/Makefile,v 1.45 2009/02/24 10:06:32 petere Exp $
#
#-------------------------------------------------------------------------
$(MAKE) -C backend $@
$(MAKE) -C backend/utils/mb/conversion_procs $@
$(MAKE) -C backend/snowball $@
- $(MAKE) -C backend/foreign $@-fdw
$(MAKE) -C include $@
$(MAKE) -C interfaces $@
$(MAKE) -C bin $@
*
* Copyright (c) 2003-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.52 2009/02/14 20:48:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.53 2009/02/24 10:06:32 petere Exp $
*/
/*
CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
CAST(fdwname AS sql_identifier) AS foreign_data_wrapper_name,
CAST(u.rolname AS sql_identifier) AS authorization_identifier,
- CAST(fdwlibrary AS character_data) AS library_name,
CAST('c' AS character_data) AS foreign_data_wrapper_language
FROM pg_foreign_data_wrapper w, pg_authid u
WHERE u.oid = w.fdwowner
SELECT foreign_data_wrapper_catalog,
foreign_data_wrapper_name,
authorization_identifier,
- library_name,
+ CAST(NULL AS character_data) AS library_name,
foreign_data_wrapper_language
FROM _pg_foreign_data_wrappers w;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/foreigncmds.c,v 1.5 2009/01/20 09:10:20 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/foreigncmds.c,v 1.6 2009/02/24 10:06:32 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include "catalog/indexing.h"
#include "catalog/pg_foreign_data_wrapper.h"
#include "catalog/pg_foreign_server.h"
+#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "catalog/pg_user_mapping.h"
#include "commands/defrem.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
+#include "parser/parse_func.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
List *optionDefList,
GenericOptionFlags flags,
ForeignDataWrapper *fdw,
- OptionListValidatorFunc validateOptionList)
+ Oid fdwvalidator)
{
List *resultOptions = untransformRelOptions(oldOptions);
ListCell *optcell;
+ Datum result;
foreach(optcell, optionDefList)
{
}
}
- if (validateOptionList)
- validateOptionList(fdw, flags, resultOptions);
+ result = optionListToArray(resultOptions);
- return optionListToArray(resultOptions);
+ if (fdwvalidator)
+ OidFunctionCall2(fdwvalidator, result, 0);
+
+ return result;
}
}
+/*
+ * Convert a validator function name passed from the parser to an Oid.
+ */
+static Oid
+lookup_fdw_validator_func(List *validator)
+{
+ Oid funcargtypes[2];
+
+ funcargtypes[0] = TEXTARRAYOID;
+ funcargtypes[1] = OIDOID;
+ return LookupFuncName(validator, 2, funcargtypes, false);
+ /* return value is ignored, so we don't check the type */
+}
+
+
/*
* Create a foreign-data wrapper
*/
bool nulls[Natts_pg_foreign_data_wrapper];
HeapTuple tuple;
Oid fdwId;
+ Oid fdwvalidator;
Datum fdwoptions;
Oid ownerId;
- ForeignDataWrapperLibrary *fdwlib;
/* Must be super user */
if (!superuser())
values[Anum_pg_foreign_data_wrapper_fdwname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->fdwname));
values[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(ownerId);
- values[Anum_pg_foreign_data_wrapper_fdwlibrary - 1] = CStringGetTextDatum(stmt->library);
- nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
- /*
- * See if the FDW library loads at all. We also might want to use it
- * later for validating the options.
- */
- fdwlib = GetForeignDataWrapperLibrary(stmt->library);
+ if (stmt->validator)
+ fdwvalidator = lookup_fdw_validator_func(stmt->validator);
+ else
+ fdwvalidator = InvalidOid;
+
+ values[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = fdwvalidator;
+
+ nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
fdwoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
FdwOpt, NULL,
- fdwlib->validateOptionList);
+ fdwvalidator);
if (PointerIsValid(DatumGetPointer(fdwoptions)))
values[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = fdwoptions;
heap_freetuple(tuple);
+ if (fdwvalidator)
+ {
+ ObjectAddress myself;
+ ObjectAddress referenced;
+
+ myself.classId = ForeignDataWrapperRelationId;
+ myself.objectId = fdwId;
+ myself.objectSubId = 0;
+
+ referenced.classId = ProcedureRelationId;
+ referenced.objectId = fdwvalidator;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+ }
+
recordDependencyOnOwner(ForeignDataWrapperRelationId, fdwId, ownerId);
heap_close(rel, NoLock);
Oid fdwId;
bool isnull;
Datum datum;
- ForeignDataWrapperLibrary *fdwlib;
+ Oid fdwvalidator;
/* Must be super user */
if (!superuser())
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
- if (stmt->library)
+ if (stmt->change_validator)
{
- /*
- * New library specified -- load to see if valid.
- */
- fdwlib = GetForeignDataWrapperLibrary(stmt->library);
-
- repl_val[Anum_pg_foreign_data_wrapper_fdwlibrary - 1] = CStringGetTextDatum(stmt->library);
- repl_repl[Anum_pg_foreign_data_wrapper_fdwlibrary - 1] = true;
+ fdwvalidator = stmt->validator ? lookup_fdw_validator_func(stmt->validator) : InvalidOid;
+ repl_val[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = ObjectIdGetDatum(fdwvalidator);
+ repl_repl[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = true;
/*
* It could be that the options for the FDW, SERVER and USER MAPPING
- * are no longer valid with the new library. Warn about this.
+ * are no longer valid with the new validator. Warn about this.
*/
- ereport(WARNING,
- (errmsg("changing the foreign-data wrapper library can cause "
- "the options for dependent objects to become invalid")));
+ if (stmt->validator)
+ ereport(WARNING,
+ (errmsg("changing the foreign-data wrapper validator can cause "
+ "the options for dependent objects to become invalid")));
}
else
{
/*
- * No LIBRARY clause specified, but we need to load it for validating
+ * Validator is not changed, but we need it for validating
* options.
*/
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
tp,
- Anum_pg_foreign_data_wrapper_fdwlibrary,
+ Anum_pg_foreign_data_wrapper_fdwvalidator,
&isnull);
Assert(!isnull);
- fdwlib = GetForeignDataWrapperLibrary(TextDatumGetCString(datum));
+ fdwvalidator = DatumGetObjectId(datum);
}
/*
/* Transform the options */
datum = transformGenericOptions(datum, stmt->options, FdwOpt,
- NULL, fdwlib->validateOptionList);
+ NULL, fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = datum;
/* Add server options */
srvoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
ServerOpt, fdw,
- fdw->lib->validateOptionList);
+ fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(srvoptions)))
values[Anum_pg_foreign_server_srvoptions - 1] = srvoptions;
/* Prepare the options array */
datum = transformGenericOptions(datum, stmt->options, ServerOpt,
- fdw, fdw->lib->validateOptionList);
+ fdw, fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_server_srvoptions - 1] = datum;
/* Add user options */
useoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
UserMappingOpt,
- fdw, fdw->lib->validateOptionList);
+ fdw, fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(useoptions)))
values[Anum_pg_user_mapping_umoptions - 1] = useoptions;
/* Prepare the options array */
datum = transformGenericOptions(datum, stmt->options, UserMappingOpt,
- fdw, fdw->lib->validateOptionList);
+ fdw, fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_user_mapping_umoptions - 1] = datum;
# Makefile for foreign
#
# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/foreign/Makefile,v 1.1 2008/12/19 16:25:17 petere Exp $
+# $PostgreSQL: pgsql/src/backend/foreign/Makefile,v 1.2 2009/02/24 10:06:32 petere Exp $
#
#-------------------------------------------------------------------------
OBJS= foreign.o
include $(top_srcdir)/src/backend/common.mk
-
-FDW = dummy postgresql
-
-$(addsuffix -fdw,all install installdirs uninstall distprep):
- for dir in $(FDW); do $(MAKE) -C $$dir `echo $@ | sed 's/-fdw$$//'` || exit; done
-
-clean distclean maintainer-clean:
- for dir in $(FDW); do $(MAKE) -C $$dir $@ || exit; done
+++ /dev/null
-#-------------------------------------------------------------------------
-#
-# Makefile--
-# Makefile for dummy foreign-data wrapper
-#
-# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/foreign/dummy/Makefile,v 1.1 2008/12/19 16:25:17 petere Exp $
-#
-#-------------------------------------------------------------------------
-
-subdir = src/backend/foreign/dummy
-top_builddir = ../../../..
-include $(top_builddir)/src/Makefile.global
-
-NAME = dummy_fdw
-OBJS = dummy_fdw.o
-
-include $(top_srcdir)/src/Makefile.shlib
-
-all: all-shared-lib
-
-install: all install-lib
-
-installdirs: installdirs-lib
-
-clean distclean maintainer-clean: clean-lib
- rm -f $(OBJS)
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * dummy_fdw.c
- * "dummy" foreign-data wrapper
- *
- * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/foreign/dummy/dummy_fdw.c,v 1.2 2009/01/01 17:23:42 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "fmgr.h"
-#include "foreign/foreign.h"
-
-PG_MODULE_MAGIC;
-
-/*
- * This looks like a complete waste right now, but it is useful for
- * testing, and will become more interesting as more parts of the
- * interface are implemented.
- */
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/foreign/foreign.c,v 1.2 2009/01/01 17:23:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/foreign/foreign.c,v 1.3 2009/02/24 10:06:32 petere Exp $
*
*-------------------------------------------------------------------------
*/
extern Datum pg_options_to_table(PG_FUNCTION_ARGS);
+extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS);
-/* list of currently loaded foreign-data wrapper interfaces */
-static List *loaded_fdw_interfaces = NIL;
-
-
-/*
- * GetForeignDataWrapperLibrary - return the named FDW library. If it
- * is already loaded, use that. Otherwise allocate, initialize, and
- * store in cache.
- */
-ForeignDataWrapperLibrary *
-GetForeignDataWrapperLibrary(const char *libname)
-{
- MemoryContext oldcontext;
- void *libhandle = NULL;
- ForeignDataWrapperLibrary *fdwl = NULL;
- ListCell *cell;
-
- /* See if we have the FDW library is already loaded */
- foreach (cell, loaded_fdw_interfaces)
- {
- fdwl = lfirst(cell);
- if (strcmp(fdwl->libname, libname) == 0)
- return fdwl;
- }
-
- /*
- * We don't have it yet, so load and add. Attempt a load_file()
- * first to filter out any missing or unloadable libraries.
- */
- load_file(libname, false);
-
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
-
- fdwl = palloc(sizeof(*fdwl));
- fdwl->libname = pstrdup(libname);
- loaded_fdw_interfaces = lappend(loaded_fdw_interfaces, fdwl);
-
- MemoryContextSwitchTo(oldcontext);
-
- /*
- * Now look up the foreign data wrapper functions.
- */
-#define LOOKUP_FUNCTION(name) \
- (void *)(libhandle ? \
- lookup_external_function(libhandle, name) \
- : load_external_function(fdwl->libname, name, false, &libhandle))
-
- fdwl->validateOptionList = LOOKUP_FUNCTION("_pg_validateOptionList");
-
- return fdwl;
-}
-
/*
* GetForeignDataWrapper - look up the foreign-data wrapper by OID.
- *
- * Here we also deal with loading the FDW library and looking up the
- * actual functions.
*/
ForeignDataWrapper *
GetForeignDataWrapper(Oid fdwid)
fdw->fdwid = fdwid;
fdw->owner = fdwform->fdwowner;
fdw->fdwname = pstrdup(NameStr(fdwform->fdwname));
-
- /* Extract library name */
- datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
- tp,
- Anum_pg_foreign_data_wrapper_fdwlibrary,
- &isnull);
- fdw->fdwlibrary = pstrdup(TextDatumGetCString(datum));
-
- fdw->lib = GetForeignDataWrapperLibrary(fdw->fdwlibrary);
+ fdw->fdwvalidator = fdwform->fdwvalidator;
/* Extract the options */
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
return (Datum) 0;
}
+
+
+/*
+ * Describes the valid options for postgresql FDW, server, and user mapping.
+ */
+struct ConnectionOption {
+ const char *optname;
+ Oid optcontext; /* Oid of catalog in which option may appear */
+};
+
+/*
+ * Copied from fe-connect.c PQconninfoOptions.
+ *
+ * The list is small - don't bother with bsearch if it stays so.
+ */
+static struct ConnectionOption libpq_conninfo_options[] = {
+ { "authtype", ForeignServerRelationId },
+ { "service", ForeignServerRelationId },
+ { "user", UserMappingRelationId },
+ { "password", UserMappingRelationId },
+ { "connect_timeout", ForeignServerRelationId },
+ { "dbname", ForeignServerRelationId },
+ { "host", ForeignServerRelationId },
+ { "hostaddr", ForeignServerRelationId },
+ { "port", ForeignServerRelationId },
+ { "tty", ForeignServerRelationId },
+ { "options", ForeignServerRelationId },
+ { "requiressl", ForeignServerRelationId },
+ { "sslmode", ForeignServerRelationId },
+ { "gsslib", ForeignServerRelationId },
+ { NULL, InvalidOid }
+};
+
+
+/*
+ * Check if the provided option is one of libpq conninfo options.
+ * context is the Oid of the catalog the option came from, or 0 if we
+ * don't care.
+ */
+static bool
+is_conninfo_option(const char *option, Oid context)
+{
+ struct ConnectionOption *opt;
+
+ for (opt = libpq_conninfo_options; opt->optname; opt++)
+ if ((context == opt->optcontext || context == InvalidOid) && strcmp(opt->optname, option) == 0)
+ return true;
+ return false;
+}
+
+
+/*
+ * Validate the generic option given to SERVER or USER MAPPING.
+ * Raise an ERROR if the option or its value is considered
+ * invalid.
+ *
+ * Valid server options are all libpq conninfo options except
+ * user and password -- these may only appear in USER MAPPING options.
+ */
+Datum
+postgresql_fdw_validator(PG_FUNCTION_ARGS)
+{
+ List* options_list = untransformRelOptions(PG_GETARG_DATUM(0));
+ Oid catalog = PG_GETARG_OID(1);
+
+ ListCell *cell;
+
+ foreach (cell, options_list)
+ {
+ DefElem *def = lfirst(cell);
+
+ if (!is_conninfo_option(def->defname, catalog))
+ {
+ struct ConnectionOption *opt;
+ StringInfoData buf;
+
+ /*
+ * Unknown option specified, complain about it. Provide a hint
+ * with list of valid options for the object.
+ */
+ initStringInfo(&buf);
+ for (opt = libpq_conninfo_options; opt->optname; opt++)
+ if (catalog == InvalidOid || catalog == opt->optcontext)
+ appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
+ opt->optname);
+
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("invalid option \"%s\"", def->defname),
+ errhint("Valid options in this context are: %s", buf.data)));
+
+ PG_RETURN_BOOL(false);
+ }
+ }
+
+ PG_RETURN_BOOL(true);
+}
+++ /dev/null
-#-------------------------------------------------------------------------
-#
-# Makefile--
-# Makefile for postgresql foreign-data wrapper
-#
-# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/foreign/postgresql/Makefile,v 1.1 2008/12/19 16:25:17 petere Exp $
-#
-#-------------------------------------------------------------------------
-
-subdir = src/backend/foreign/postgresql
-top_builddir = ../../../..
-include $(top_builddir)/src/Makefile.global
-
-NAME = postgresql_fdw
-OBJS = postgresql_fdw.o
-
-include $(top_srcdir)/src/Makefile.shlib
-
-all: all-shared-lib
-
-install: all install-lib
-
-installdirs: installdirs-lib
-
-clean distclean maintainer-clean: clean-lib
- rm -f $(OBJS)
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * postgresql_fdw.c
- * foreign-data wrapper for postgresql (libpq) connections.
- *
- * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/foreign/postgresql/postgresql_fdw.c,v 1.2 2009/01/01 17:23:42 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "fmgr.h"
-#include "lib/stringinfo.h"
-#include "nodes/value.h"
-#include "nodes/parsenodes.h"
-#include "nodes/makefuncs.h"
-#include "foreign/foreign.h"
-
-PG_MODULE_MAGIC;
-
-
-/*
- * Describes the valid options for postgresql FDW, server and user mapping.
- */
-typedef struct ConnectionOptions {
- const char *optname; /* Option name */
- GenericOptionFlags optflags; /* Option usage bitmap */
-} ConnectionOptions;
-
-/*
- * Copied from fe-connect.c PQconninfoOptions.
- *
- * The list is small - don't bother with bsearch if it stays so.
- */
-static ConnectionOptions libpq_conninfo_options[] = {
- { "authtype", ServerOpt },
- { "service", ServerOpt },
- { "user", UserMappingOpt },
- { "password", UserMappingOpt },
- { "connect_timeout", ServerOpt },
- { "dbname", ServerOpt },
- { "host", ServerOpt },
- { "hostaddr", ServerOpt },
- { "port", ServerOpt },
- { "tty", ServerOpt },
- { "options", ServerOpt },
- { "requiressl", ServerOpt },
- { "sslmode", ServerOpt },
- { "gsslib", ServerOpt },
- { NULL, InvalidOpt }
-};
-
-void _PG_fini(void);
-
-
-/*
- * Check if the provided option is one of libpq conninfo options.
- * We look at only options with matching flags.
- */
-static bool
-is_conninfo_option(const char *option, GenericOptionFlags flags)
-{
- ConnectionOptions *opt;
-
- for (opt = libpq_conninfo_options; opt->optname != NULL; opt++)
- if (flags & opt->optflags && strcmp(opt->optname, option) == 0)
- return true;
- return false;
-}
-
-/*
- * Validate the generic option given to SERVER or USER MAPPING.
- * Raise an ERROR if the option or its value is considered
- * invalid.
- *
- * Valid server options are all libpq conninfo options except
- * user and password -- these may only appear in USER MAPPING options.
- */
-void
-_pg_validateOptionList(ForeignDataWrapper *fdw, GenericOptionFlags flags,
- List *options)
-{
- ListCell *cell;
-
- foreach (cell, options)
- {
- DefElem *def = lfirst(cell);
-
- if (!is_conninfo_option(def->defname, flags))
- {
- ConnectionOptions *opt;
- StringInfoData buf;
- const char *objtype;
-
- /*
- * Unknown option specified, complain about it. Provide a hint
- * with list of valid options for the object.
- */
- initStringInfo(&buf);
- for (opt = libpq_conninfo_options; opt->optname != NULL; opt++)
- if (flags & opt->optflags)
- appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
- opt->optname);
-
- if (flags & ServerOpt)
- objtype = "server";
- else if (flags & UserMappingOpt)
- objtype = "user mapping";
- else if (flags & FdwOpt)
- objtype = "foreign-data wrapper";
- else
- objtype = "???";
-
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("invalid option \"%s\" to %s", def->defname, objtype),
- errhint("valid %s options are: %s", objtype, buf.data)));
- }
- }
-}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.423 2009/02/06 23:43:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.424 2009/02/24 10:06:32 petere Exp $
*
*-------------------------------------------------------------------------
*/
CreateFdwStmt *newnode = makeNode(CreateFdwStmt);
COPY_STRING_FIELD(fdwname);
- COPY_STRING_FIELD(library);
+ COPY_NODE_FIELD(validator);
COPY_NODE_FIELD(options);
return newnode;
AlterFdwStmt *newnode = makeNode(AlterFdwStmt);
COPY_STRING_FIELD(fdwname);
- COPY_STRING_FIELD(library);
+ COPY_NODE_FIELD(validator);
+ COPY_SCALAR_FIELD(change_validator);
COPY_NODE_FIELD(options);
return newnode;
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.347 2009/02/02 19:31:39 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.348 2009/02/24 10:06:32 petere Exp $
*
*-------------------------------------------------------------------------
*/
_equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b)
{
COMPARE_STRING_FIELD(fdwname);
- COMPARE_STRING_FIELD(library);
+ COMPARE_NODE_FIELD(validator);
COMPARE_NODE_FIELD(options);
return true;
_equalAlterFdwStmt(AlterFdwStmt *a, AlterFdwStmt *b)
{
COMPARE_STRING_FIELD(fdwname);
- COMPARE_STRING_FIELD(library);
+ COMPARE_NODE_FIELD(validator);
+ COMPARE_SCALAR_FIELD(change_validator);
COMPARE_NODE_FIELD(options);
return true;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.658 2009/02/11 21:11:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.659 2009/02/24 10:06:33 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
index_name name file_name cluster_index_specification
%type <list> func_name handler_name qual_Op qual_all_Op subquery_Op
- opt_class opt_validator
+ opt_class opt_validator validator_clause
%type <range> qualified_name OptConstrFromTable
KEY
LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
- LIBRARY LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
+ LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
LOCK_P LOGIN_P
MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
| name attrs { $$ = lcons(makeString($1), $2); }
;
-opt_validator:
+validator_clause:
VALIDATOR handler_name { $$ = $2; }
+ | NO VALIDATOR { $$ = NIL; }
+ ;
+
+opt_validator:
+ validator_clause { $$ = $1; }
| /*EMPTY*/ { $$ = NIL; }
;
/*****************************************************************************
*
* QUERY:
- * CREATE FOREIGN DATA WRAPPER name LIBRARY 'library_name' LANGUAGE C
+ * CREATE FOREIGN DATA WRAPPER name [ VALIDATOR name ]
*
*****************************************************************************/
-CreateFdwStmt: CREATE FOREIGN DATA_P WRAPPER name LIBRARY Sconst LANGUAGE ColId create_generic_options
+CreateFdwStmt: CREATE FOREIGN DATA_P WRAPPER name opt_validator create_generic_options
{
CreateFdwStmt *n = makeNode(CreateFdwStmt);
n->fdwname = $5;
- n->library = $7;
- n->options = $10;
+ n->validator = $6;
+ n->options = $7;
$$ = (Node *) n;
-
- if (pg_strcasecmp($9, "C") != 0)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("language for foreign-data wrapper must be C"),
- scanner_errposition(@9)));
}
;
*
****************************************************************************/
-AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name LIBRARY Sconst alter_generic_options
+AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name validator_clause alter_generic_options
{
AlterFdwStmt *n = makeNode(AlterFdwStmt);
n->fdwname = $5;
- n->library = $7;
- n->options = $8;
+ n->validator = $6;
+ n->change_validator = true;
+ n->options = $7;
$$ = (Node *) n;
}
- | ALTER FOREIGN DATA_P WRAPPER name LIBRARY Sconst
+ | ALTER FOREIGN DATA_P WRAPPER name validator_clause
{
AlterFdwStmt *n = makeNode(AlterFdwStmt);
n->fdwname = $5;
- n->library = $7;
+ n->validator = $6;
+ n->change_validator = true;
$$ = (Node *) n;
}
| ALTER FOREIGN DATA_P WRAPPER name alter_generic_options
| INVOKER
| ISOLATION
| KEY
- | LIBRARY
| LANCOMPILER
| LANGUAGE
| LARGE_P
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.209 2009/01/01 17:23:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.210 2009/02/24 10:06:33 petere Exp $
*
*-------------------------------------------------------------------------
*/
{"least", LEAST, COL_NAME_KEYWORD},
{"left", LEFT, TYPE_FUNC_NAME_KEYWORD},
{"level", LEVEL, UNRESERVED_KEYWORD},
- {"library", LIBRARY, UNRESERVED_KEYWORD},
{"like", LIKE, TYPE_FUNC_NAME_KEYWORD},
{"limit", LIMIT, RESERVED_KEYWORD},
{"listen", LISTEN, UNRESERVED_KEYWORD},
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.524 2009/02/18 12:07:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.525 2009/02/24 10:06:33 petere Exp $
*
*-------------------------------------------------------------------------
*/
int i_oid;
int i_fdwname;
int i_rolname;
- int i_fdwlibrary;
+ int i_fdwvalidator;
int i_fdwacl;
int i_fdwoptions;
selectSourceSchema("pg_catalog");
appendPQExpBuffer(query, "SELECT oid, fdwname, "
- "(%s fdwowner) AS rolname, fdwlibrary, fdwacl,"
+ "(%s fdwowner) AS rolname, fdwvalidator::pg_catalog.regproc, fdwacl,"
"array_to_string(ARRAY("
" SELECT option_name || ' ' || quote_literal(option_value) "
" FROM pg_options_to_table(fdwoptions)), ', ') AS fdwoptions "
i_oid = PQfnumber(res, "oid");
i_fdwname = PQfnumber(res, "fdwname");
i_rolname = PQfnumber(res, "rolname");
- i_fdwlibrary = PQfnumber(res, "fdwlibrary");
+ i_fdwvalidator = PQfnumber(res, "fdwvalidator");
i_fdwacl = PQfnumber(res, "fdwacl");
i_fdwoptions = PQfnumber(res, "fdwoptions");
fdwinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_fdwname));
fdwinfo[i].dobj.namespace = NULL;
fdwinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
- fdwinfo[i].fdwlibrary = strdup(PQgetvalue(res, i, i_fdwlibrary));
+ fdwinfo[i].fdwvalidator = strdup(PQgetvalue(res, i, i_fdwvalidator));
fdwinfo[i].fdwoptions = strdup(PQgetvalue(res, i, i_fdwoptions));
fdwinfo[i].fdwacl = strdup(PQgetvalue(res, i, i_fdwacl));
q = createPQExpBuffer();
delq = createPQExpBuffer();
- appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s LIBRARY '%s' LANGUAGE C",
- fmtId(fdwinfo->dobj.name), fdwinfo->fdwlibrary);
+ appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
+ fmtId(fdwinfo->dobj.name));
+
+ if (fdwinfo->fdwvalidator && strcmp(fdwinfo->fdwvalidator, "-") != 0)
+ appendPQExpBuffer(q, " VALIDATOR %s",
+ fdwinfo->fdwvalidator);
+
if (fdwinfo->fdwoptions && strlen(fdwinfo->fdwoptions) > 0)
appendPQExpBuffer(q, " OPTIONS (%s)", fdwinfo->fdwoptions);
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.152 2009/02/18 12:07:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.153 2009/02/24 10:06:34 petere Exp $
*
*-------------------------------------------------------------------------
*/
{
DumpableObject dobj;
char *rolname;
- char *fdwlibrary;
+ char *fdwvalidator;
char *fdwoptions;
char *fdwacl;
} FdwInfo;
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.200 2009/02/23 15:59:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.201 2009/02/24 10:06:34 petere Exp $
*/
#include "postgres_fe.h"
printfPQExpBuffer(&buf,
"SELECT fdwname AS \"%s\",\n"
" pg_catalog.pg_get_userbyid(fdwowner) AS \"%s\",\n"
- " fdwlibrary AS \"%s\"",
+ " fdwvalidator::pg_catalog.regproc AS \"%s\"",
gettext_noop("Name"),
gettext_noop("Owner"),
- gettext_noop("Library"));
+ gettext_noop("Validator"));
if (verbose)
{
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.179 2009/01/01 17:23:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.180 2009/02/24 10:06:34 petere Exp $
*/
/*----------------------------------------------------------------------
pg_strcasecmp(prev2_wd, "WRAPPER") == 0)
{
static const char *const list_ALTER_FDW[] =
- {"LIBRARY", "OPTIONS", "OWNER TO", NULL};
+ {"VALIDATOR", "OPTIONS", "OWNER TO", NULL};
COMPLETE_WITH_LIST(list_ALTER_FDW);
}
pg_strcasecmp(prev4_wd, "FOREIGN") == 0 &&
pg_strcasecmp(prev3_wd, "DATA") == 0 &&
pg_strcasecmp(prev2_wd, "WRAPPER") == 0)
- COMPLETE_WITH_CONST("LIBRARY");
-
- else if (pg_strcasecmp(prev5_wd, "DATA") == 0 &&
- pg_strcasecmp(prev4_wd, "WRAPPER") == 0 &&
- pg_strcasecmp(prev2_wd, "LIBRARY") == 0)
- COMPLETE_WITH_CONST("LANGUAGE C");
+ COMPLETE_WITH_CONST("VALIDATOR");
/* CREATE INDEX */
/* First off we complete CREATE UNIQUE with "INDEX" */
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.523 2009/02/09 21:18:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.524 2009/02/24 10:06:34 petere Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200902092
+#define CATALOG_VERSION_NO 200902242
#endif
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_foreign_data_wrapper.h,v 1.2 2009/01/01 17:23:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_foreign_data_wrapper.h,v 1.3 2009/02/24 10:06:34 petere Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
{
NameData fdwname; /* foreign-data wrapper name */
Oid fdwowner; /* FDW owner */
+ Oid fdwvalidator; /* optional validation function */
/* VARIABLE LENGTH FIELDS start here. */
- text fdwlibrary; /* FDW shared library location */
aclitem fdwacl[1]; /* access permissions */
text fdwoptions[1]; /* FDW options */
} FormData_pg_foreign_data_wrapper;
#define Natts_pg_foreign_data_wrapper 5
#define Anum_pg_foreign_data_wrapper_fdwname 1
#define Anum_pg_foreign_data_wrapper_fdwowner 2
-#define Anum_pg_foreign_data_wrapper_fdwlibrary 3
+#define Anum_pg_foreign_data_wrapper_fdwvalidator 3
#define Anum_pg_foreign_data_wrapper_fdwacl 4
#define Anum_pg_foreign_data_wrapper_fdwoptions 5
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.536 2009/02/06 21:15:11 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.537 2009/02/24 10:06:34 petere Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
DATA(insert OID = 2288 ( pg_size_pretty PGNSP PGUID 12 1 0 0 f f f t f v 1 0 25 "20" _null_ _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ ));
DESCR("convert a long int to a human readable text using size units");
+DATA(insert OID = 2316 ( postgresql_fdw_validator PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "1009 26" _null_ _null_ _null_ _null_ postgresql_fdw_validator _null_ _null_ _null_));
+
DATA(insert OID = 2290 ( record_in PGNSP PGUID 12 1 0 0 f f f t f v 3 0 2249 "2275 26 23" _null_ _null_ _null_ _null_ record_in _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 2291 ( record_out PGNSP PGUID 12 1 0 0 f f f t f v 1 0 2275 "2249" _null_ _null_ _null_ _null_ record_out _null_ _null_ _null_ ));
*
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/foreign/foreign.h,v 1.2 2009/01/01 17:23:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/foreign/foreign.h,v 1.3 2009/02/24 10:06:35 petere Exp $
*
*-------------------------------------------------------------------------
*/
FdwOpt = 4, /* options for FOREIGN DATA WRAPPER */
} GenericOptionFlags;
-typedef struct ForeignDataWrapperLibrary ForeignDataWrapperLibrary;
-
typedef struct ForeignDataWrapper
{
Oid fdwid; /* FDW Oid */
Oid owner; /* FDW owner user Oid */
char *fdwname; /* Name of the FDW */
- char *fdwlibrary; /* Library name */
+ Oid fdwvalidator;
List *options; /* fdwoptions as DefElem list */
-
- ForeignDataWrapperLibrary *lib; /* interface to the FDW functions */
} ForeignDataWrapper;
typedef struct ForeignServer
} UserMapping;
-/*
- * Foreign-data wrapper library function types.
- */
-typedef void (*OptionListValidatorFunc)(ForeignDataWrapper *,
- GenericOptionFlags,
- List *);
-
-/*
- * Interface functions to the foreign-data wrapper. This is decoupled
- * from the FDW as there maybe several FDW-s accessing the same library.
- */
-struct ForeignDataWrapperLibrary
-{
- char *libname; /* name of the library file */
-
- OptionListValidatorFunc validateOptionList;
-};
-
-
extern ForeignServer *GetForeignServer(Oid serverid);
extern ForeignServer *GetForeignServerByName(const char *name, bool missing_ok);
extern Oid GetForeignServerOidByName(const char *name, bool missing_ok);
extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name,
bool missing_ok);
extern Oid GetForeignDataWrapperOidByName(const char *name, bool missing_ok);
-extern ForeignDataWrapperLibrary *GetForeignDataWrapperLibrary(const char *libname);
/* Foreign data wrapper interface functions */
extern void _pg_validateOptionList(ForeignDataWrapper *fdw,
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.391 2009/02/11 21:11:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.392 2009/02/24 10:06:35 petere Exp $
*
*-------------------------------------------------------------------------
*/
{
NodeTag type;
char *fdwname; /* foreign-data wrapper name */
- char *library; /* libray name */
+ List *validator; /* optional validator function (qual. name) */
List *options; /* generic options to FDW */
} CreateFdwStmt;
{
NodeTag type;
char *fdwname; /* foreign-data wrapper name */
- char *library; /* libray name */
+ List *validator; /* optional validator function (qual. name) */
+ bool change_validator;
List *options; /* generic options to FDW */
} AlterFdwStmt;
CREATE ROLE regress_test_role_super SUPERUSER;
CREATE ROLE regress_test_indirect;
CREATE ROLE unprivileged_role;
-CREATE FOREIGN DATA WRAPPER dummy LIBRARY 'dummy_fdw' LANGUAGE C;
-CREATE FOREIGN DATA WRAPPER postgresql LIBRARY 'postgresql_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER dummy;
+CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
-- At this point we should have 2 built-in wrappers and no servers.
-SELECT fdwname, fdwlibrary, fdwoptions FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3;
- fdwname | fdwlibrary | fdwoptions
-------------+----------------+------------
- dummy | dummy_fdw |
- postgresql | postgresql_fdw |
+SELECT fdwname, fdwvalidator::regproc, fdwoptions FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3;
+ fdwname | fdwvalidator | fdwoptions
+------------+--------------------------+------------
+ dummy | - |
+ postgresql | postgresql_fdw_validator |
(2 rows)
SELECT srvname, srvoptions FROM pg_foreign_server;
(0 rows)
-- CREATE FOREIGN DATA WRAPPER
-CREATE FOREIGN DATA WRAPPER foo LIBRARY '' LANGUAGE C; -- ERROR
-ERROR: could not access file "": No such file or directory
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql' LANGUAGE C;
-DROP FOREIGN DATA WRAPPER foo;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER foo VALIDATOR bar; -- ERROR
+ERROR: function bar(text[], oid) does not exist
+CREATE FOREIGN DATA WRAPPER foo;
\dew
- List of foreign-data wrappers
- Name | Owner | Library
-------------+-------------------+----------------
- dummy | foreign_data_user | dummy_fdw
- foo | foreign_data_user | dummy_fdw
- postgresql | foreign_data_user | postgresql_fdw
+ List of foreign-data wrappers
+ Name | Owner | Validator
+------------+-------------------+--------------------------
+ dummy | foreign_data_user | -
+ foo | foreign_data_user | -
+ postgresql | foreign_data_user | postgresql_fdw_validator
(3 rows)
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C; -- duplicate
+CREATE FOREIGN DATA WRAPPER foo; -- duplicate
ERROR: foreign-data wrapper "foo" already exists
-CREATE FOREIGN DATA WRAPPER "Foo" LIBRARY 'dummy_fdw' LANGUAGE C;
-DROP FOREIGN DATA WRAPPER "Foo";
DROP FOREIGN DATA WRAPPER foo;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (testing '1');
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1');
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+-------------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | | {testing=1}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+-------------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | | {testing=1}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
DROP FOREIGN DATA WRAPPER foo;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (testing '1', testing '2'); -- ERROR
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', testing '2'); -- ERROR
ERROR: option "testing" provided more than once
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (testing '1', another '2');
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', another '2');
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+-----------------------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | | {testing=1,another=2}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+-----------------------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | | {testing=1,another=2}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
DROP FOREIGN DATA WRAPPER foo;
SET ROLE regress_test_role;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C; -- ERROR
+CREATE FOREIGN DATA WRAPPER foo; -- ERROR
ERROR: permission denied to create foreign-data wrapper "foo"
HINT: Must be superuser to create a foreign-data wrapper.
RESET ROLE;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'postgresql_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator;
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+---------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | postgresql_fdw | |
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+---------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | postgresql_fdw_validator | |
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
-- ALTER FOREIGN DATA WRAPPER
-ALTER FOREIGN DATA WRAPPER foo LIBRARY ''; -- ERROR
-ERROR: could not access file "": No such file or directory
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql';
-WARNING: changing the foreign-data wrapper library can cause the options for dependent objects to become invalid
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw';
-WARNING: changing the foreign-data wrapper library can cause the options for dependent objects to become invalid
+ALTER FOREIGN DATA WRAPPER foo; -- ERROR
+ERROR: syntax error at or near ";"
+LINE 1: ALTER FOREIGN DATA WRAPPER foo;
+ ^
+ALTER FOREIGN DATA WRAPPER foo VALIDATOR bar; -- ERROR
+ERROR: function bar(text[], oid) does not exist
+ALTER FOREIGN DATA WRAPPER foo NO VALIDATOR;
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+---------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | |
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+---------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | |
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2');
ERROR: option "c" not found
ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD x '1', DROP x);
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+-----------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | | {a=1,b=2}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+-----------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | | {a=1,b=2}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP a, SET b '3', ADD c '4');
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+-----------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | | {b=3,c=4}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+-----------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | | {b=3,c=4}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '2');
ALTER FOREIGN DATA WRAPPER foo OPTIONS (b '4'); -- ERROR
ERROR: option "b" provided more than once
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+---------------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | | {b=3,c=4,a=2}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+---------------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | | {b=3,c=4,a=2}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
SET ROLE regress_test_role;
SET ROLE regress_test_role_super;
ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5');
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+-------------------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | | {b=3,c=4,a=2,d=5}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+-------------------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | | {b=3,c=4,a=2,d=5}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role; -- ERROR
HINT: Must be superuser to alter a foreign-data wrapper.
RESET ROLE;
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------------+----------------+-------------------+-------------------
- dummy | foreign_data_user | dummy_fdw | |
- foo | regress_test_role_super | dummy_fdw | | {b=3,c=4,a=2,d=5}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------------+--------------------------+-------------------+-------------------
+ dummy | foreign_data_user | - | |
+ foo | regress_test_role_super | - | | {b=3,c=4,a=2,d=5}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
-- DROP FOREIGN DATA WRAPPER
DROP FOREIGN DATA WRAPPER IF EXISTS nonexistent;
NOTICE: foreign-data wrapper "nonexistent" does not exist, skipping
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------------+----------------+-------------------+-------------------
- dummy | foreign_data_user | dummy_fdw | |
- foo | regress_test_role_super | dummy_fdw | | {b=3,c=4,a=2,d=5}
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------------+--------------------------+-------------------+-------------------
+ dummy | foreign_data_user | - | |
+ foo | regress_test_role_super | - | | {b=3,c=4,a=2,d=5}
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
DROP ROLE regress_test_role_super; -- ERROR
DROP FOREIGN DATA WRAPPER foo;
DROP ROLE regress_test_role_super;
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+---------
- dummy | foreign_data_user | dummy_fdw | |
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+---------
+ dummy | foreign_data_user | - | |
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(2 rows)
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER foo;
CREATE SERVER s1 FOREIGN DATA WRAPPER foo;
CREATE USER MAPPING FOR current_user SERVER s1;
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+---------
- dummy | foreign_data_user | dummy_fdw | |
- foo | foreign_data_user | dummy_fdw | |
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+---------
+ dummy | foreign_data_user | - | |
+ foo | foreign_data_user | - | |
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(3 rows)
\des+
DETAIL: drop cascades to server s1
drop cascades to user mapping for foreign_data_user
\dew+
- List of foreign-data wrappers
- Name | Owner | Library | Access privileges | Options
-------------+-------------------+----------------+-------------------+---------
- dummy | foreign_data_user | dummy_fdw | |
- postgresql | foreign_data_user | postgresql_fdw | |
+ List of foreign-data wrappers
+ Name | Owner | Validator | Access privileges | Options
+------------+-------------------+--------------------------+-------------------+---------
+ dummy | foreign_data_user | - | |
+ postgresql | foreign_data_user | postgresql_fdw_validator | |
(2 rows)
\des+
-- exercise CREATE SERVER
CREATE SERVER s1 FOREIGN DATA WRAPPER foo; -- ERROR
ERROR: foreign-data wrapper "foo" does not exist
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (test_wrapper 'true');
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (test_wrapper 'true');
CREATE SERVER s1 FOREIGN DATA WRAPPER foo;
CREATE SERVER s1 FOREIGN DATA WRAPPER foo; -- ERROR
ERROR: server "s1" already exists
CREATE SERVER s6 VERSION '16.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b');
CREATE SERVER s7 TYPE 'oracle' VERSION '17.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b');
CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (foo '1'); -- ERROR
-ERROR: invalid option "foo" to server
-HINT: valid server options are: authtype, service, connect_timeout, dbname, host, hostaddr, port, tty, options, requiressl, sslmode, gsslib
+ERROR: invalid option "foo"
+HINT: Valid options in this context are: authtype, service, user, password, connect_timeout, dbname, host, hostaddr, port, tty, options, requiressl, sslmode, gsslib
CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (host 'localhost', dbname 's8db');
\des+
List of foreign servers
ERROR: permission denied for foreign-data wrapper foo
RESET ROLE;
ALTER SERVER s8 OPTIONS (foo '1'); -- ERROR option validation
-ERROR: invalid option "foo" to server
-HINT: valid server options are: authtype, service, connect_timeout, dbname, host, hostaddr, port, tty, options, requiressl, sslmode, gsslib
+ERROR: invalid option "foo"
+HINT: Valid options in this context are: authtype, service, user, password, connect_timeout, dbname, host, hostaddr, port, tty, options, requiressl, sslmode, gsslib
ALTER SERVER s8 OPTIONS (connect_timeout '30', SET dbname 'db1', DROP host);
SET ROLE regress_test_role;
ALTER SERVER s1 OWNER TO regress_test_indirect; -- ERROR
ERROR: user mapping "foreign_data_user" already exists for server s4
CREATE USER MAPPING FOR public SERVER s4 OPTIONS (mapping 'is public');
CREATE USER MAPPING FOR user SERVER s8 OPTIONS (username 'test', password 'secret'); -- ERROR
-ERROR: invalid option "username" to user mapping
-HINT: valid user mapping options are: user, password
+ERROR: invalid option "username"
+HINT: Valid options in this context are: authtype, service, user, password, connect_timeout, dbname, host, hostaddr, port, tty, options, requiressl, sslmode, gsslib
CREATE USER MAPPING FOR user SERVER s8 OPTIONS (user 'test', password 'secret');
ALTER SERVER s5 OWNER TO regress_test_role;
ALTER SERVER s6 OWNER TO regress_test_indirect;
ALTER USER MAPPING FOR public SERVER s5 OPTIONS (gotcha 'true'); -- ERROR
ERROR: user mapping "public" does not exist for the server
ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (username 'test'); -- ERROR
-ERROR: invalid option "username" to user mapping
-HINT: valid user mapping options are: user, password
+ERROR: invalid option "username"
+HINT: Valid options in this context are: authtype, service, user, password, connect_timeout, dbname, host, hostaddr, port, tty, options, requiressl, sslmode, gsslib
ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (DROP user, SET password 'public');
SET ROLE regress_test_role;
ALTER USER MAPPING FOR current_user SERVER s5 OPTIONS (ADD modified '1');
-- Information schema
SELECT * FROM information_schema.foreign_data_wrappers ORDER BY 1, 2;
- foreign_data_wrapper_catalog | foreign_data_wrapper_name | authorization_identifier | library_name | foreign_data_wrapper_language
-------------------------------+---------------------------+--------------------------+----------------+-------------------------------
- regression | dummy | foreign_data_user | dummy_fdw | c
- regression | foo | foreign_data_user | dummy_fdw | c
- regression | postgresql | foreign_data_user | postgresql_fdw | c
+ foreign_data_wrapper_catalog | foreign_data_wrapper_name | authorization_identifier | library_name | foreign_data_wrapper_language
+------------------------------+---------------------------+--------------------------+--------------+-------------------------------
+ regression | dummy | foreign_data_user | | c
+ regression | foo | foreign_data_user | | c
+ regression | postgresql | foreign_data_user | | c
(3 rows)
SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3;
DROP USER MAPPING FOR public SERVER s4;
ALTER SERVER s6 OPTIONS (DROP host, DROP dbname);
ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username);
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql';
-WARNING: changing the foreign-data wrapper library can cause the options for dependent objects to become invalid
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'default_fdw';
-ERROR: could not access file "default_fdw": No such file or directory
+ALTER FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator;
+WARNING: changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid
-- Privileges
SET ROLE unprivileged_role;
-CREATE FOREIGN DATA WRAPPER foobar LIBRARY 'dummy_fdw' LANGUAGE C; -- ERROR
+CREATE FOREIGN DATA WRAPPER foobar; -- ERROR
ERROR: permission denied to create foreign-data wrapper "foobar"
HINT: Must be superuser to create a foreign-data wrapper.
ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true'); -- ERROR
GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO unprivileged_role;
GRANT USAGE ON FOREIGN DATA WRAPPER foo TO unprivileged_role WITH GRANT OPTION;
SET ROLE unprivileged_role;
-CREATE FOREIGN DATA WRAPPER foobar LIBRARY 'dummy_fdw' LANGUAGE C; -- ERROR
+CREATE FOREIGN DATA WRAPPER foobar; -- ERROR
ERROR: permission denied to create foreign-data wrapper "foobar"
HINT: Must be superuser to create a foreign-data wrapper.
ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true'); -- ERROR
\c
DROP ROLE foreign_data_user;
-- At this point we should have no wrappers, no servers, and no mappings.
-SELECT fdwname, fdwlibrary, fdwoptions FROM pg_foreign_data_wrapper;
- fdwname | fdwlibrary | fdwoptions
----------+------------+------------
+SELECT fdwname, fdwvalidator, fdwoptions FROM pg_foreign_data_wrapper;
+ fdwname | fdwvalidator | fdwoptions
+---------+--------------+------------
(0 rows)
SELECT srvname, srvoptions FROM pg_foreign_server;
CREATE ROLE regress_test_indirect;
CREATE ROLE unprivileged_role;
-CREATE FOREIGN DATA WRAPPER dummy LIBRARY 'dummy_fdw' LANGUAGE C;
-CREATE FOREIGN DATA WRAPPER postgresql LIBRARY 'postgresql_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER dummy;
+CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
-- At this point we should have 2 built-in wrappers and no servers.
-SELECT fdwname, fdwlibrary, fdwoptions FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3;
+SELECT fdwname, fdwvalidator::regproc, fdwoptions FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3;
SELECT srvname, srvoptions FROM pg_foreign_server;
SELECT * FROM pg_user_mapping;
-- CREATE FOREIGN DATA WRAPPER
-CREATE FOREIGN DATA WRAPPER foo LIBRARY '' LANGUAGE C; -- ERROR
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql' LANGUAGE C;
-DROP FOREIGN DATA WRAPPER foo;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER foo VALIDATOR bar; -- ERROR
+CREATE FOREIGN DATA WRAPPER foo;
\dew
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C; -- duplicate
-CREATE FOREIGN DATA WRAPPER "Foo" LIBRARY 'dummy_fdw' LANGUAGE C;
-DROP FOREIGN DATA WRAPPER "Foo";
+CREATE FOREIGN DATA WRAPPER foo; -- duplicate
DROP FOREIGN DATA WRAPPER foo;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (testing '1');
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1');
\dew+
DROP FOREIGN DATA WRAPPER foo;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (testing '1', testing '2'); -- ERROR
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (testing '1', another '2');
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', testing '2'); -- ERROR
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', another '2');
\dew+
DROP FOREIGN DATA WRAPPER foo;
SET ROLE regress_test_role;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C; -- ERROR
+CREATE FOREIGN DATA WRAPPER foo; -- ERROR
RESET ROLE;
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'postgresql_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator;
\dew+
-- ALTER FOREIGN DATA WRAPPER
-ALTER FOREIGN DATA WRAPPER foo LIBRARY ''; -- ERROR
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql';
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw';
+ALTER FOREIGN DATA WRAPPER foo; -- ERROR
+ALTER FOREIGN DATA WRAPPER foo VALIDATOR bar; -- ERROR
+ALTER FOREIGN DATA WRAPPER foo NO VALIDATOR;
\dew+
ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2');
DROP ROLE regress_test_role_super;
\dew+
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C;
+CREATE FOREIGN DATA WRAPPER foo;
CREATE SERVER s1 FOREIGN DATA WRAPPER foo;
CREATE USER MAPPING FOR current_user SERVER s1;
\dew+
-- exercise CREATE SERVER
CREATE SERVER s1 FOREIGN DATA WRAPPER foo; -- ERROR
-CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C OPTIONS (test_wrapper 'true');
+CREATE FOREIGN DATA WRAPPER foo OPTIONS (test_wrapper 'true');
CREATE SERVER s1 FOREIGN DATA WRAPPER foo;
CREATE SERVER s1 FOREIGN DATA WRAPPER foo; -- ERROR
CREATE SERVER s2 FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b');
DROP USER MAPPING FOR public SERVER s4;
ALTER SERVER s6 OPTIONS (DROP host, DROP dbname);
ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username);
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql';
-ALTER FOREIGN DATA WRAPPER foo LIBRARY 'default_fdw';
+ALTER FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator;
-- Privileges
SET ROLE unprivileged_role;
-CREATE FOREIGN DATA WRAPPER foobar LIBRARY 'dummy_fdw' LANGUAGE C; -- ERROR
+CREATE FOREIGN DATA WRAPPER foobar; -- ERROR
ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true'); -- ERROR
ALTER FOREIGN DATA WRAPPER foo OWNER TO unprivileged_role; -- ERROR
DROP FOREIGN DATA WRAPPER foo; -- ERROR
GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO unprivileged_role;
GRANT USAGE ON FOREIGN DATA WRAPPER foo TO unprivileged_role WITH GRANT OPTION;
SET ROLE unprivileged_role;
-CREATE FOREIGN DATA WRAPPER foobar LIBRARY 'dummy_fdw' LANGUAGE C; -- ERROR
+CREATE FOREIGN DATA WRAPPER foobar; -- ERROR
ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true'); -- ERROR
DROP FOREIGN DATA WRAPPER foo; -- ERROR
GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_test_role; -- WARNING
DROP ROLE foreign_data_user;
-- At this point we should have no wrappers, no servers, and no mappings.
-SELECT fdwname, fdwlibrary, fdwoptions FROM pg_foreign_data_wrapper;
+SELECT fdwname, fdwvalidator, fdwoptions FROM pg_foreign_data_wrapper;
SELECT srvname, srvoptions FROM pg_foreign_server;
SELECT * FROM pg_user_mapping;