Commit 7babccb9 authored by Peter Eisentraut's avatar Peter Eisentraut

Add the possibility to specify an explicit validator function for foreign-data

wrappers (similar to procedural languages).  This way we don't need to retain
the nearly empty libraries, and we are more free in how to implement the
wrapper API in the future.
parent f73bed30
<!-- $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 Documentation of the system catalogs, directed toward PostgreSQL developers
--> -->
...@@ -2466,10 +2466,16 @@ ...@@ -2466,10 +2466,16 @@
</row> </row>
<row> <row>
<entry><structfield>fdwlibrary</structfield></entry> <entry><structfield>fdwvalidator</structfield></entry>
<entry><type>text</type></entry> <entry><type>oid</type></entry>
<entry></entry> <entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>File name of the library implementing this foreign-data wrapper</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>
<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"> <appendix id="sql-keywords-appendix">
<title><acronym>SQL</acronym> Key Words</title> <title><acronym>SQL</acronym> Key Words</title>
...@@ -2687,14 +2687,6 @@ ...@@ -2687,14 +2687,6 @@
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
</row> </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> <row>
<entry><token>LIKE</token></entry> <entry><token>LIKE</token></entry>
<entry>reserved (can be function or type)</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 PostgreSQL documentation
--> -->
...@@ -21,7 +21,7 @@ PostgreSQL documentation ...@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> 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>'] [, ... ]) ] [ 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> ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
</synopsis> </synopsis>
...@@ -58,14 +58,14 @@ ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWN ...@@ -58,14 +58,14 @@ ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWN
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">libraryname</replaceable></term> <term><literal>VALIDATOR <replaceable class="parameter">valfunction</replaceable></literal></term>
<listitem> <listitem>
<para> <para>
New name of the foreign-data wrapper library. Specifies a new foreign-data wrapper validator function.
</para> </para>
<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 options to the foreign-data wrapper, servers, and user mappings
have become invalid. It is up to the user to make sure that have become invalid. It is up to the user to make sure that
these options are correct before using the foreign-data these options are correct before using the foreign-data
...@@ -74,6 +74,16 @@ ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWN ...@@ -74,6 +74,16 @@ ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWN
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] )</literal></term> <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] )</literal></term>
<listitem> <listitem>
...@@ -102,10 +112,10 @@ ALTER FOREIGN DATA WRAPPER dbi OPTIONS (ADD foo '1', DROP 'bar'); ...@@ -102,10 +112,10 @@ ALTER FOREIGN DATA WRAPPER dbi OPTIONS (ADD foo '1', DROP 'bar');
</para> </para>
<para> <para>
Change the foreign-data wrapper <literal>dbi</> library Change the foreign-data wrapper <literal>dbi</> validator
to <literal>/home/bob/mylibrary.so</>: to <literal>bob.myvalidator</>:
<programlisting> <programlisting>
ALTER FOREIGN DATA WRAPPER dbi LIBRARY '/home/bob/mylibrary.so'; ALTER FOREIGN DATA WRAPPER dbi VALIDATOR bob.myvalidator;
</programlisting> </programlisting>
</para> </para>
</refsect1> </refsect1>
...@@ -115,8 +125,9 @@ ALTER FOREIGN DATA WRAPPER dbi LIBRARY '/home/bob/mylibrary.so'; ...@@ -115,8 +125,9 @@ ALTER FOREIGN DATA WRAPPER dbi LIBRARY '/home/bob/mylibrary.so';
<para> <para>
<command>ALTER FOREIGN DATA WRAPPER</command> conforms to ISO/IEC <command>ALTER FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
9075-9 (SQL/MED). The standard does not specify the <literal>OWNER 9075-9 (SQL/MED). The standard does not specify the <literal>
TO</> variant of the command. VALIDATOR</literal> and <literal>OWNER TO</> variants of the
command.
</para> </para>
</refsect1> </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 PostgreSQL documentation
--> -->
...@@ -21,8 +21,7 @@ PostgreSQL documentation ...@@ -21,8 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
LIBRARY '<replaceable class="parameter">libraryname</replaceable>' [ VALIDATOR <replaceable class="parameter">valfunction</replaceable> | NO VALIDATOR ]
LANGUAGE C
[ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ] [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -59,25 +58,25 @@ CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> ...@@ -59,25 +58,25 @@ CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">libraryname</replaceable></term> <term><literal>VALIDATOR <replaceable class="parameter">valfunction</replaceable></literal></term>
<listitem> <listitem>
<para> <para>
The name of the shared library implementing the foreign-data <replaceable class="parameter">valfunction</replaceable> is the
wrapper. The file name is specified in the same way as for name of a previously registered function that will be called to
shared library names in <xref linkend="sql-createfunction" check the generic options given to the foreign-data wrapper, as
endterm="sql-createfunction-title">; in particular, one can rely well as to foreign servers and user mappings using the
on a search path and automatic addition of the system's standard foreign-data wrapper. If no validator function or <literal>NO
shared library file name extension. VALIDATOR</literal> is specified, then options will not be
</para> checked at creation time. (Foreign-data wrappers will possibly
</listitem> ignore or reject invalid option specifications at run time,
</varlistentry> depending on the implementation.) The validator function must
take two arguments: one of type <type>text[]</type>, which will
<varlistentry> contain the array of options as stored in the system catalogs,
<term><literal>LANGUAGE C</literal></term> and one of type <type>oid</type>, which will be the OID of the
<listitem> system catalog containing the options, or zero if the context is
<para> not known. The return type is ignored; the function should
Currently, only the C programming language is supported for indicate invalid options using
implementing foreign-data wrappers. the <function>ereport()</function> function.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -109,18 +108,11 @@ CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> ...@@ -109,18 +108,11 @@ CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
</para> </para>
<para> <para>
The C language API for foreign-data wrappers is currently not There is currently one foreign-data wrapper validator function
documented, stable, or complete. Would-be authors of functionality provided:
interfacing with the SQL/MED functionality are advised to contact <filename>postgresql_fdw_validator</filename>, which accepts
the PostgreSQL developers. options corresponding to <application>libpq</> connection
</para> parameters.
<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.
</para> </para>
</refsect1> </refsect1>
...@@ -128,28 +120,25 @@ CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> ...@@ -128,28 +120,25 @@ CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
<title>Examples</title> <title>Examples</title>
<para> <para>
Create a foreign-data wrapper <literal>dummy</> with Create a foreign-data wrapper <literal>dummy</>:
library <literal>dummy_fdw</>:
<programlisting> <programlisting>
CREATE FOREIGN DATA WRAPPER dummy LIBRARY 'dummy_fdw' LANGUAGE C; CREATE FOREIGN DATA WRAPPER dummy;
</programlisting> </programlisting>
</para> </para>
<para> <para>
Create a foreign-data wrapper <literal>postgresql</> with Create a foreign-data wrapper <literal>postgresql</> with
library <literal>postgresql_fdw</>: validator function <literal>postgresql_fdw_validator</>:
<programlisting> <programlisting>
CREATE FOREIGN DATA WRAPPER postgresql LIBRARY 'postgresql_fdw' LANGUAGE C; CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
</programlisting> </programlisting>
</para> </para>
<para> <para>
Create a foreign-data wrapper <literal>mywrapper</> with library Create a foreign-data wrapper <literal>mywrapper</> with some
<literal>/home/bob/mywrapper.so</> and some options: options:
<programlisting> <programlisting>
CREATE FOREIGN DATA WRAPPER mywrapper CREATE FOREIGN DATA WRAPPER mywrapper
LIBRARY '/home/bob/mywrapper.so'
LANGUAGE C
OPTIONS (debug 'true'); OPTIONS (debug 'true');
</programlisting> </programlisting>
</para> </para>
...@@ -161,8 +150,9 @@ CREATE FOREIGN DATA WRAPPER mywrapper ...@@ -161,8 +150,9 @@ CREATE FOREIGN DATA WRAPPER mywrapper
<para> <para>
<command>CREATE FOREIGN DATA WRAPPER</command> conforms to ISO/IEC <command>CREATE FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
9075-9 (SQL/MED), with the exception that 9075-9 (SQL/MED), with the exception that
the <literal>LIBRARY</literal> clause is not optional in the <literal>VALIDATOR</literal> clause is an extension and the
PostgreSQL. clauses <literal>LIBRARY</literal> and <literal>LANGUAGE</literal>
are not yet implemented in PostgreSQL.
</para> </para>
<para> <para>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
# Copyright (c) 1994, Regents of the University of California # 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 $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -19,7 +19,6 @@ all install installdirs uninstall distprep: ...@@ -19,7 +19,6 @@ all install installdirs uninstall distprep:
$(MAKE) -C backend $@ $(MAKE) -C backend $@
$(MAKE) -C backend/utils/mb/conversion_procs $@ $(MAKE) -C backend/utils/mb/conversion_procs $@
$(MAKE) -C backend/snowball $@ $(MAKE) -C backend/snowball $@
$(MAKE) -C backend/foreign $@-fdw
$(MAKE) -C include $@ $(MAKE) -C include $@
$(MAKE) -C interfaces $@ $(MAKE) -C interfaces $@
$(MAKE) -C bin $@ $(MAKE) -C bin $@
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (c) 2003-2009, PostgreSQL Global Development Group * 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 $
*/ */
/* /*
...@@ -2428,7 +2428,6 @@ CREATE VIEW _pg_foreign_data_wrappers AS ...@@ -2428,7 +2428,6 @@ CREATE VIEW _pg_foreign_data_wrappers AS
CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog, CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
CAST(fdwname AS sql_identifier) AS foreign_data_wrapper_name, CAST(fdwname AS sql_identifier) AS foreign_data_wrapper_name,
CAST(u.rolname AS sql_identifier) AS authorization_identifier, 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 CAST('c' AS character_data) AS foreign_data_wrapper_language
FROM pg_foreign_data_wrapper w, pg_authid u FROM pg_foreign_data_wrapper w, pg_authid u
WHERE u.oid = w.fdwowner WHERE u.oid = w.fdwowner
...@@ -2458,7 +2457,7 @@ CREATE VIEW foreign_data_wrappers AS ...@@ -2458,7 +2457,7 @@ CREATE VIEW foreign_data_wrappers AS
SELECT foreign_data_wrapper_catalog, SELECT foreign_data_wrapper_catalog,
foreign_data_wrapper_name, foreign_data_wrapper_name,
authorization_identifier, authorization_identifier,
library_name, CAST(NULL AS character_data) AS library_name,
foreign_data_wrapper_language foreign_data_wrapper_language
FROM _pg_foreign_data_wrappers w; FROM _pg_foreign_data_wrappers w;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -20,11 +20,13 @@ ...@@ -20,11 +20,13 @@
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_foreign_data_wrapper.h" #include "catalog/pg_foreign_data_wrapper.h"
#include "catalog/pg_foreign_server.h" #include "catalog/pg_foreign_server.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "catalog/pg_user_mapping.h" #include "catalog/pg_user_mapping.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "foreign/foreign.h" #include "foreign/foreign.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/parse_func.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
...@@ -90,10 +92,11 @@ transformGenericOptions(Datum oldOptions, ...@@ -90,10 +92,11 @@ transformGenericOptions(Datum oldOptions,
List *optionDefList, List *optionDefList,
GenericOptionFlags flags, GenericOptionFlags flags,
ForeignDataWrapper *fdw, ForeignDataWrapper *fdw,
OptionListValidatorFunc validateOptionList) Oid fdwvalidator)
{ {
List *resultOptions = untransformRelOptions(oldOptions); List *resultOptions = untransformRelOptions(oldOptions);
ListCell *optcell; ListCell *optcell;
Datum result;
foreach(optcell, optionDefList) foreach(optcell, optionDefList)
{ {
...@@ -157,10 +160,12 @@ transformGenericOptions(Datum oldOptions, ...@@ -157,10 +160,12 @@ transformGenericOptions(Datum oldOptions,
} }
} }
if (validateOptionList) result = optionListToArray(resultOptions);
validateOptionList(fdw, flags, resultOptions);
return optionListToArray(resultOptions); if (fdwvalidator)
OidFunctionCall2(fdwvalidator, result, 0);
return result;
} }
...@@ -309,6 +314,21 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId) ...@@ -309,6 +314,21 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
} }
/*
* 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 * Create a foreign-data wrapper
*/ */
...@@ -320,9 +340,9 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) ...@@ -320,9 +340,9 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
bool nulls[Natts_pg_foreign_data_wrapper]; bool nulls[Natts_pg_foreign_data_wrapper];
HeapTuple tuple; HeapTuple tuple;
Oid fdwId; Oid fdwId;
Oid fdwvalidator;
Datum fdwoptions; Datum fdwoptions;
Oid ownerId; Oid ownerId;
ForeignDataWrapperLibrary *fdwlib;
/* Must be super user */ /* Must be super user */
if (!superuser()) if (!superuser())
...@@ -355,18 +375,19 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) ...@@ -355,18 +375,19 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
values[Anum_pg_foreign_data_wrapper_fdwname - 1] = values[Anum_pg_foreign_data_wrapper_fdwname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->fdwname)); DirectFunctionCall1(namein, CStringGetDatum(stmt->fdwname));
values[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(ownerId); 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;
/* if (stmt->validator)
* See if the FDW library loads at all. We also might want to use it fdwvalidator = lookup_fdw_validator_func(stmt->validator);
* later for validating the options. else
*/ fdwvalidator = InvalidOid;
fdwlib = GetForeignDataWrapperLibrary(stmt->library);
values[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = fdwvalidator;
nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
fdwoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options, fdwoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
FdwOpt, NULL, FdwOpt, NULL,
fdwlib->validateOptionList); fdwvalidator);
if (PointerIsValid(DatumGetPointer(fdwoptions))) if (PointerIsValid(DatumGetPointer(fdwoptions)))
values[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = fdwoptions; values[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = fdwoptions;
...@@ -380,6 +401,21 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) ...@@ -380,6 +401,21 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
heap_freetuple(tuple); 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); recordDependencyOnOwner(ForeignDataWrapperRelationId, fdwId, ownerId);
heap_close(rel, NoLock); heap_close(rel, NoLock);
...@@ -400,7 +436,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) ...@@ -400,7 +436,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
Oid fdwId; Oid fdwId;
bool isnull; bool isnull;
Datum datum; Datum datum;
ForeignDataWrapperLibrary *fdwlib; Oid fdwvalidator;
/* Must be super user */ /* Must be super user */
if (!superuser()) if (!superuser())
...@@ -425,36 +461,33 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) ...@@ -425,36 +461,33 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
memset(repl_null, false, sizeof(repl_null)); memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl)); memset(repl_repl, false, sizeof(repl_repl));
if (stmt->library) if (stmt->change_validator)
{ {
/* fdwvalidator = stmt->validator ? lookup_fdw_validator_func(stmt->validator) : InvalidOid;
* New library specified -- load to see if valid. repl_val[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = ObjectIdGetDatum(fdwvalidator);
*/ repl_repl[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = true;
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;
/* /*
* It could be that the options for the FDW, SERVER and USER MAPPING * 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, if (stmt->validator)
(errmsg("changing the foreign-data wrapper library can cause " ereport(WARNING,
"the options for dependent objects to become invalid"))); (errmsg("changing the foreign-data wrapper validator can cause "
"the options for dependent objects to become invalid")));
} }
else else
{ {
/* /*
* No LIBRARY clause specified, but we need to load it for validating * Validator is not changed, but we need it for validating
* options. * options.
*/ */
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
tp, tp,
Anum_pg_foreign_data_wrapper_fdwlibrary, Anum_pg_foreign_data_wrapper_fdwvalidator,
&isnull); &isnull);
Assert(!isnull); Assert(!isnull);
fdwlib = GetForeignDataWrapperLibrary(TextDatumGetCString(datum)); fdwvalidator = DatumGetObjectId(datum);
} }
/* /*
...@@ -472,7 +505,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) ...@@ -472,7 +505,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
/* Transform the options */ /* Transform the options */
datum = transformGenericOptions(datum, stmt->options, FdwOpt, datum = transformGenericOptions(datum, stmt->options, FdwOpt,
NULL, fdwlib->validateOptionList); NULL, fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum))) if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = datum; repl_val[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = datum;
...@@ -640,7 +673,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt) ...@@ -640,7 +673,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
/* Add server options */ /* Add server options */
srvoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options, srvoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
ServerOpt, fdw, ServerOpt, fdw,
fdw->lib->validateOptionList); fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(srvoptions))) if (PointerIsValid(DatumGetPointer(srvoptions)))
values[Anum_pg_foreign_server_srvoptions - 1] = srvoptions; values[Anum_pg_foreign_server_srvoptions - 1] = srvoptions;
...@@ -738,7 +771,7 @@ AlterForeignServer(AlterForeignServerStmt *stmt) ...@@ -738,7 +771,7 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
/* Prepare the options array */ /* Prepare the options array */
datum = transformGenericOptions(datum, stmt->options, ServerOpt, datum = transformGenericOptions(datum, stmt->options, ServerOpt,
fdw, fdw->lib->validateOptionList); fdw, fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum))) if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_server_srvoptions - 1] = datum; repl_val[Anum_pg_foreign_server_srvoptions - 1] = datum;
...@@ -910,7 +943,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt) ...@@ -910,7 +943,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
/* Add user options */ /* Add user options */
useoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options, useoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
UserMappingOpt, UserMappingOpt,
fdw, fdw->lib->validateOptionList); fdw, fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(useoptions))) if (PointerIsValid(DatumGetPointer(useoptions)))
values[Anum_pg_user_mapping_umoptions - 1] = useoptions; values[Anum_pg_user_mapping_umoptions - 1] = useoptions;
...@@ -1005,7 +1038,7 @@ AlterUserMapping(AlterUserMappingStmt *stmt) ...@@ -1005,7 +1038,7 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
/* Prepare the options array */ /* Prepare the options array */
datum = transformGenericOptions(datum, stmt->options, UserMappingOpt, datum = transformGenericOptions(datum, stmt->options, UserMappingOpt,
fdw, fdw->lib->validateOptionList); fdw, fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum))) if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_user_mapping_umoptions - 1] = datum; repl_val[Anum_pg_user_mapping_umoptions - 1] = datum;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for foreign # Makefile for foreign
# #
# IDENTIFICATION # 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 $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -15,11 +15,3 @@ include $(top_builddir)/src/Makefile.global ...@@ -15,11 +15,3 @@ include $(top_builddir)/src/Makefile.global
OBJS= foreign.o OBJS= foreign.o
include $(top_srcdir)/src/backend/common.mk 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
#-------------------------------------------------------------------------
#
# 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)
/*-------------------------------------------------------------------------
*
* 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.
*/
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -31,66 +31,12 @@ ...@@ -31,66 +31,12 @@
extern Datum pg_options_to_table(PG_FUNCTION_ARGS); 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. * 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 * ForeignDataWrapper *
GetForeignDataWrapper(Oid fdwid) GetForeignDataWrapper(Oid fdwid)
...@@ -114,15 +60,7 @@ GetForeignDataWrapper(Oid fdwid) ...@@ -114,15 +60,7 @@ GetForeignDataWrapper(Oid fdwid)
fdw->fdwid = fdwid; fdw->fdwid = fdwid;
fdw->owner = fdwform->fdwowner; fdw->owner = fdwform->fdwowner;
fdw->fdwname = pstrdup(NameStr(fdwform->fdwname)); fdw->fdwname = pstrdup(NameStr(fdwform->fdwname));
fdw->fdwvalidator = fdwform->fdwvalidator;
/* Extract library name */
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
tp,
Anum_pg_foreign_data_wrapper_fdwlibrary,
&isnull);
fdw->fdwlibrary = pstrdup(TextDatumGetCString(datum));
fdw->lib = GetForeignDataWrapperLibrary(fdw->fdwlibrary);
/* Extract the options */ /* Extract the options */
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
...@@ -387,3 +325,100 @@ pg_options_to_table(PG_FUNCTION_ARGS) ...@@ -387,3 +325,100 @@ pg_options_to_table(PG_FUNCTION_ARGS)
return (Datum) 0; 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);
}
#-------------------------------------------------------------------------
#
# 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)
/*-------------------------------------------------------------------------
*
* 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)));
}
}
}
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2994,7 +2994,7 @@ _copyCreateFdwStmt(CreateFdwStmt *from) ...@@ -2994,7 +2994,7 @@ _copyCreateFdwStmt(CreateFdwStmt *from)
CreateFdwStmt *newnode = makeNode(CreateFdwStmt); CreateFdwStmt *newnode = makeNode(CreateFdwStmt);
COPY_STRING_FIELD(fdwname); COPY_STRING_FIELD(fdwname);
COPY_STRING_FIELD(library); COPY_NODE_FIELD(validator);
COPY_NODE_FIELD(options); COPY_NODE_FIELD(options);
return newnode; return newnode;
...@@ -3006,7 +3006,8 @@ _copyAlterFdwStmt(AlterFdwStmt *from) ...@@ -3006,7 +3006,8 @@ _copyAlterFdwStmt(AlterFdwStmt *from)
AlterFdwStmt *newnode = makeNode(AlterFdwStmt); AlterFdwStmt *newnode = makeNode(AlterFdwStmt);
COPY_STRING_FIELD(fdwname); COPY_STRING_FIELD(fdwname);
COPY_STRING_FIELD(library); COPY_NODE_FIELD(validator);
COPY_SCALAR_FIELD(change_validator);
COPY_NODE_FIELD(options); COPY_NODE_FIELD(options);
return newnode; return newnode;
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1548,7 +1548,7 @@ static bool ...@@ -1548,7 +1548,7 @@ static bool
_equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b) _equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b)
{ {
COMPARE_STRING_FIELD(fdwname); COMPARE_STRING_FIELD(fdwname);
COMPARE_STRING_FIELD(library); COMPARE_NODE_FIELD(validator);
COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(options);
return true; return true;
...@@ -1558,7 +1558,8 @@ static bool ...@@ -1558,7 +1558,8 @@ static bool
_equalAlterFdwStmt(AlterFdwStmt *a, AlterFdwStmt *b) _equalAlterFdwStmt(AlterFdwStmt *a, AlterFdwStmt *b)
{ {
COMPARE_STRING_FIELD(fdwname); COMPARE_STRING_FIELD(fdwname);
COMPARE_STRING_FIELD(library); COMPARE_NODE_FIELD(validator);
COMPARE_SCALAR_FIELD(change_validator);
COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(options);
return true; return true;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -254,7 +254,7 @@ static TypeName *TableFuncTypeName(List *columns); ...@@ -254,7 +254,7 @@ static TypeName *TableFuncTypeName(List *columns);
index_name name file_name cluster_index_specification index_name name file_name cluster_index_specification
%type <list> func_name handler_name qual_Op qual_all_Op subquery_Op %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 %type <range> qualified_name OptConstrFromTable
...@@ -469,7 +469,7 @@ static TypeName *TableFuncTypeName(List *columns); ...@@ -469,7 +469,7 @@ static TypeName *TableFuncTypeName(List *columns);
KEY KEY
LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL 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 LOCK_P LOGIN_P
MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
...@@ -2724,8 +2724,13 @@ handler_name: ...@@ -2724,8 +2724,13 @@ handler_name:
| name attrs { $$ = lcons(makeString($1), $2); } | name attrs { $$ = lcons(makeString($1), $2); }
; ;
opt_validator: validator_clause:
VALIDATOR handler_name { $$ = $2; } VALIDATOR handler_name { $$ = $2; }
| NO VALIDATOR { $$ = NIL; }
;
opt_validator:
validator_clause { $$ = $1; }
| /*EMPTY*/ { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; }
; ;
...@@ -2808,23 +2813,17 @@ DropTableSpaceStmt: DROP TABLESPACE name ...@@ -2808,23 +2813,17 @@ DropTableSpaceStmt: DROP TABLESPACE name
/***************************************************************************** /*****************************************************************************
* *
* QUERY: * 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); CreateFdwStmt *n = makeNode(CreateFdwStmt);
n->fdwname = $5; n->fdwname = $5;
n->library = $7; n->validator = $6;
n->options = $10; n->options = $7;
$$ = (Node *) n; $$ = (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)));
} }
; ;
...@@ -2860,19 +2859,21 @@ DropFdwStmt: DROP FOREIGN DATA_P WRAPPER name opt_drop_behavior ...@@ -2860,19 +2859,21 @@ DropFdwStmt: DROP FOREIGN DATA_P WRAPPER name opt_drop_behavior
* *
****************************************************************************/ ****************************************************************************/
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); AlterFdwStmt *n = makeNode(AlterFdwStmt);
n->fdwname = $5; n->fdwname = $5;
n->library = $7; n->validator = $6;
n->options = $8; n->change_validator = true;
n->options = $7;
$$ = (Node *) n; $$ = (Node *) n;
} }
| ALTER FOREIGN DATA_P WRAPPER name LIBRARY Sconst | ALTER FOREIGN DATA_P WRAPPER name validator_clause
{ {
AlterFdwStmt *n = makeNode(AlterFdwStmt); AlterFdwStmt *n = makeNode(AlterFdwStmt);
n->fdwname = $5; n->fdwname = $5;
n->library = $7; n->validator = $6;
n->change_validator = true;
$$ = (Node *) n; $$ = (Node *) n;
} }
| ALTER FOREIGN DATA_P WRAPPER name alter_generic_options | ALTER FOREIGN DATA_P WRAPPER name alter_generic_options
...@@ -10231,7 +10232,6 @@ unreserved_keyword: ...@@ -10231,7 +10232,6 @@ unreserved_keyword:
| INVOKER | INVOKER
| ISOLATION | ISOLATION
| KEY | KEY
| LIBRARY
| LANCOMPILER | LANCOMPILER
| LANGUAGE | LANGUAGE
| LARGE_P | LARGE_P
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -230,7 +230,6 @@ const ScanKeyword ScanKeywords[] = { ...@@ -230,7 +230,6 @@ const ScanKeyword ScanKeywords[] = {
{"least", LEAST, COL_NAME_KEYWORD}, {"least", LEAST, COL_NAME_KEYWORD},
{"left", LEFT, TYPE_FUNC_NAME_KEYWORD}, {"left", LEFT, TYPE_FUNC_NAME_KEYWORD},
{"level", LEVEL, UNRESERVED_KEYWORD}, {"level", LEVEL, UNRESERVED_KEYWORD},
{"library", LIBRARY, UNRESERVED_KEYWORD},
{"like", LIKE, TYPE_FUNC_NAME_KEYWORD}, {"like", LIKE, TYPE_FUNC_NAME_KEYWORD},
{"limit", LIMIT, RESERVED_KEYWORD}, {"limit", LIMIT, RESERVED_KEYWORD},
{"listen", LISTEN, UNRESERVED_KEYWORD}, {"listen", LISTEN, UNRESERVED_KEYWORD},
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -5394,7 +5394,7 @@ getForeignDataWrappers(int *numForeignDataWrappers) ...@@ -5394,7 +5394,7 @@ getForeignDataWrappers(int *numForeignDataWrappers)
int i_oid; int i_oid;
int i_fdwname; int i_fdwname;
int i_rolname; int i_rolname;
int i_fdwlibrary; int i_fdwvalidator;
int i_fdwacl; int i_fdwacl;
int i_fdwoptions; int i_fdwoptions;
...@@ -5409,7 +5409,7 @@ getForeignDataWrappers(int *numForeignDataWrappers) ...@@ -5409,7 +5409,7 @@ getForeignDataWrappers(int *numForeignDataWrappers)
selectSourceSchema("pg_catalog"); selectSourceSchema("pg_catalog");
appendPQExpBuffer(query, "SELECT oid, fdwname, " appendPQExpBuffer(query, "SELECT oid, fdwname, "
"(%s fdwowner) AS rolname, fdwlibrary, fdwacl," "(%s fdwowner) AS rolname, fdwvalidator::pg_catalog.regproc, fdwacl,"
"array_to_string(ARRAY(" "array_to_string(ARRAY("
" SELECT option_name || ' ' || quote_literal(option_value) " " SELECT option_name || ' ' || quote_literal(option_value) "
" FROM pg_options_to_table(fdwoptions)), ', ') AS fdwoptions " " FROM pg_options_to_table(fdwoptions)), ', ') AS fdwoptions "
...@@ -5427,7 +5427,7 @@ getForeignDataWrappers(int *numForeignDataWrappers) ...@@ -5427,7 +5427,7 @@ getForeignDataWrappers(int *numForeignDataWrappers)
i_oid = PQfnumber(res, "oid"); i_oid = PQfnumber(res, "oid");
i_fdwname = PQfnumber(res, "fdwname"); i_fdwname = PQfnumber(res, "fdwname");
i_rolname = PQfnumber(res, "rolname"); i_rolname = PQfnumber(res, "rolname");
i_fdwlibrary = PQfnumber(res, "fdwlibrary"); i_fdwvalidator = PQfnumber(res, "fdwvalidator");
i_fdwacl = PQfnumber(res, "fdwacl"); i_fdwacl = PQfnumber(res, "fdwacl");
i_fdwoptions = PQfnumber(res, "fdwoptions"); i_fdwoptions = PQfnumber(res, "fdwoptions");
...@@ -5439,7 +5439,7 @@ getForeignDataWrappers(int *numForeignDataWrappers) ...@@ -5439,7 +5439,7 @@ getForeignDataWrappers(int *numForeignDataWrappers)
fdwinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_fdwname)); fdwinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_fdwname));
fdwinfo[i].dobj.namespace = NULL; fdwinfo[i].dobj.namespace = NULL;
fdwinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname)); 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].fdwoptions = strdup(PQgetvalue(res, i, i_fdwoptions));
fdwinfo[i].fdwacl = strdup(PQgetvalue(res, i, i_fdwacl)); fdwinfo[i].fdwacl = strdup(PQgetvalue(res, i, i_fdwacl));
...@@ -9308,8 +9308,13 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo) ...@@ -9308,8 +9308,13 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
q = createPQExpBuffer(); q = createPQExpBuffer();
delq = createPQExpBuffer(); delq = createPQExpBuffer();
appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s LIBRARY '%s' LANGUAGE C", appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
fmtId(fdwinfo->dobj.name), fdwinfo->fdwlibrary); fmtId(fdwinfo->dobj.name));
if (fdwinfo->fdwvalidator && strcmp(fdwinfo->fdwvalidator, "-") != 0)
appendPQExpBuffer(q, " VALIDATOR %s",
fdwinfo->fdwvalidator);
if (fdwinfo->fdwoptions && strlen(fdwinfo->fdwoptions) > 0) if (fdwinfo->fdwoptions && strlen(fdwinfo->fdwoptions) > 0)
appendPQExpBuffer(q, " OPTIONS (%s)", fdwinfo->fdwoptions); appendPQExpBuffer(q, " OPTIONS (%s)", fdwinfo->fdwoptions);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -409,7 +409,7 @@ typedef struct _fdwInfo ...@@ -409,7 +409,7 @@ typedef struct _fdwInfo
{ {
DumpableObject dobj; DumpableObject dobj;
char *rolname; char *rolname;
char *fdwlibrary; char *fdwvalidator;
char *fdwoptions; char *fdwoptions;
char *fdwacl; char *fdwacl;
} FdwInfo; } FdwInfo;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* Copyright (c) 2000-2009, PostgreSQL Global Development Group * 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" #include "postgres_fe.h"
...@@ -2894,10 +2894,10 @@ listForeignDataWrappers(const char *pattern, bool verbose) ...@@ -2894,10 +2894,10 @@ listForeignDataWrappers(const char *pattern, bool verbose)
printfPQExpBuffer(&buf, printfPQExpBuffer(&buf,
"SELECT fdwname AS \"%s\",\n" "SELECT fdwname AS \"%s\",\n"
" pg_catalog.pg_get_userbyid(fdwowner) 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("Name"),
gettext_noop("Owner"), gettext_noop("Owner"),
gettext_noop("Library")); gettext_noop("Validator"));
if (verbose) if (verbose)
{ {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2009, PostgreSQL Global Development Group * 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 $
*/ */
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
...@@ -749,7 +749,7 @@ psql_completion(char *text, int start, int end) ...@@ -749,7 +749,7 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev2_wd, "WRAPPER") == 0) pg_strcasecmp(prev2_wd, "WRAPPER") == 0)
{ {
static const char *const list_ALTER_FDW[] = static const char *const list_ALTER_FDW[] =
{"LIBRARY", "OPTIONS", "OWNER TO", NULL}; {"VALIDATOR", "OPTIONS", "OWNER TO", NULL};
COMPLETE_WITH_LIST(list_ALTER_FDW); COMPLETE_WITH_LIST(list_ALTER_FDW);
} }
...@@ -1258,12 +1258,7 @@ psql_completion(char *text, int start, int end) ...@@ -1258,12 +1258,7 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev4_wd, "FOREIGN") == 0 && pg_strcasecmp(prev4_wd, "FOREIGN") == 0 &&
pg_strcasecmp(prev3_wd, "DATA") == 0 && pg_strcasecmp(prev3_wd, "DATA") == 0 &&
pg_strcasecmp(prev2_wd, "WRAPPER") == 0) pg_strcasecmp(prev2_wd, "WRAPPER") == 0)
COMPLETE_WITH_CONST("LIBRARY"); COMPLETE_WITH_CONST("VALIDATOR");
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");
/* CREATE INDEX */ /* CREATE INDEX */
/* First off we complete CREATE UNIQUE with "INDEX" */ /* First off we complete CREATE UNIQUE with "INDEX" */
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200902092 #define CATALOG_VERSION_NO 200902242
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -32,10 +32,10 @@ CATALOG(pg_foreign_data_wrapper,2328) ...@@ -32,10 +32,10 @@ CATALOG(pg_foreign_data_wrapper,2328)
{ {
NameData fdwname; /* foreign-data wrapper name */ NameData fdwname; /* foreign-data wrapper name */
Oid fdwowner; /* FDW owner */ Oid fdwowner; /* FDW owner */
Oid fdwvalidator; /* optional validation function */
/* VARIABLE LENGTH FIELDS start here. */ /* VARIABLE LENGTH FIELDS start here. */
text fdwlibrary; /* FDW shared library location */
aclitem fdwacl[1]; /* access permissions */ aclitem fdwacl[1]; /* access permissions */
text fdwoptions[1]; /* FDW options */ text fdwoptions[1]; /* FDW options */
} FormData_pg_foreign_data_wrapper; } FormData_pg_foreign_data_wrapper;
...@@ -55,7 +55,7 @@ typedef FormData_pg_foreign_data_wrapper *Form_pg_foreign_data_wrapper; ...@@ -55,7 +55,7 @@ typedef FormData_pg_foreign_data_wrapper *Form_pg_foreign_data_wrapper;
#define Natts_pg_foreign_data_wrapper 5 #define Natts_pg_foreign_data_wrapper 5
#define Anum_pg_foreign_data_wrapper_fdwname 1 #define Anum_pg_foreign_data_wrapper_fdwname 1
#define Anum_pg_foreign_data_wrapper_fdwowner 2 #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_fdwacl 4
#define Anum_pg_foreign_data_wrapper_fdwoptions 5 #define Anum_pg_foreign_data_wrapper_fdwoptions 5
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
...@@ -3682,6 +3682,8 @@ DESCR("total disk space usage for the specified table and associated indexes and ...@@ -3682,6 +3682,8 @@ DESCR("total disk space usage for the specified table and associated indexes and
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_ )); 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"); 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_ )); 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"); 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_ )); 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_ ));
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,17 +33,13 @@ typedef enum { ...@@ -33,17 +33,13 @@ typedef enum {
FdwOpt = 4, /* options for FOREIGN DATA WRAPPER */ FdwOpt = 4, /* options for FOREIGN DATA WRAPPER */
} GenericOptionFlags; } GenericOptionFlags;
typedef struct ForeignDataWrapperLibrary ForeignDataWrapperLibrary;
typedef struct ForeignDataWrapper typedef struct ForeignDataWrapper
{ {
Oid fdwid; /* FDW Oid */ Oid fdwid; /* FDW Oid */
Oid owner; /* FDW owner user Oid */ Oid owner; /* FDW owner user Oid */
char *fdwname; /* Name of the FDW */ char *fdwname; /* Name of the FDW */
char *fdwlibrary; /* Library name */ Oid fdwvalidator;
List *options; /* fdwoptions as DefElem list */ List *options; /* fdwoptions as DefElem list */
ForeignDataWrapperLibrary *lib; /* interface to the FDW functions */
} ForeignDataWrapper; } ForeignDataWrapper;
typedef struct ForeignServer typedef struct ForeignServer
...@@ -65,25 +61,6 @@ typedef struct UserMapping ...@@ -65,25 +61,6 @@ typedef struct UserMapping
} UserMapping; } 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 *GetForeignServer(Oid serverid);
extern ForeignServer *GetForeignServerByName(const char *name, bool missing_ok); extern ForeignServer *GetForeignServerByName(const char *name, bool missing_ok);
extern Oid GetForeignServerOidByName(const char *name, bool missing_ok); extern Oid GetForeignServerOidByName(const char *name, bool missing_ok);
...@@ -92,7 +69,6 @@ extern ForeignDataWrapper *GetForeignDataWrapper(Oid fdwid); ...@@ -92,7 +69,6 @@ extern ForeignDataWrapper *GetForeignDataWrapper(Oid fdwid);
extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name, extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name,
bool missing_ok); bool missing_ok);
extern Oid GetForeignDataWrapperOidByName(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 */ /* Foreign data wrapper interface functions */
extern void _pg_validateOptionList(ForeignDataWrapper *fdw, extern void _pg_validateOptionList(ForeignDataWrapper *fdw,
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1468,7 +1468,7 @@ typedef struct CreateFdwStmt ...@@ -1468,7 +1468,7 @@ typedef struct CreateFdwStmt
{ {
NodeTag type; NodeTag type;
char *fdwname; /* foreign-data wrapper name */ char *fdwname; /* foreign-data wrapper name */
char *library; /* libray name */ List *validator; /* optional validator function (qual. name) */
List *options; /* generic options to FDW */ List *options; /* generic options to FDW */
} CreateFdwStmt; } CreateFdwStmt;
...@@ -1476,7 +1476,8 @@ typedef struct AlterFdwStmt ...@@ -1476,7 +1476,8 @@ typedef struct AlterFdwStmt
{ {
NodeTag type; NodeTag type;
char *fdwname; /* foreign-data wrapper name */ 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 */ List *options; /* generic options to FDW */
} AlterFdwStmt; } AlterFdwStmt;
......
This diff is collapsed.
...@@ -20,44 +20,40 @@ CREATE ROLE regress_test_role_super SUPERUSER; ...@@ -20,44 +20,40 @@ CREATE ROLE regress_test_role_super SUPERUSER;
CREATE ROLE regress_test_indirect; CREATE ROLE regress_test_indirect;
CREATE ROLE unprivileged_role; CREATE ROLE unprivileged_role;
CREATE FOREIGN DATA WRAPPER dummy LIBRARY 'dummy_fdw' LANGUAGE C; CREATE FOREIGN DATA WRAPPER dummy;
CREATE FOREIGN DATA WRAPPER postgresql LIBRARY 'postgresql_fdw' LANGUAGE C; CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
-- At this point we should have 2 built-in wrappers and no servers. -- 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 srvname, srvoptions FROM pg_foreign_server;
SELECT * FROM pg_user_mapping; SELECT * FROM pg_user_mapping;
-- CREATE FOREIGN DATA WRAPPER -- CREATE FOREIGN DATA WRAPPER
CREATE FOREIGN DATA WRAPPER foo LIBRARY '' LANGUAGE C; -- ERROR CREATE FOREIGN DATA WRAPPER foo VALIDATOR bar; -- ERROR
CREATE FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql' LANGUAGE C; CREATE FOREIGN DATA WRAPPER foo;
DROP FOREIGN DATA WRAPPER foo;
CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C;
\dew \dew
CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C; -- duplicate CREATE FOREIGN DATA WRAPPER foo; -- duplicate
CREATE FOREIGN DATA WRAPPER "Foo" LIBRARY 'dummy_fdw' LANGUAGE C;
DROP FOREIGN DATA WRAPPER "Foo";
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+ \dew+
DROP FOREIGN DATA WRAPPER foo; 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
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+ \dew+
DROP FOREIGN DATA WRAPPER foo; DROP FOREIGN DATA WRAPPER foo;
SET ROLE regress_test_role; SET ROLE regress_test_role;
CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C; -- ERROR CREATE FOREIGN DATA WRAPPER foo; -- ERROR
RESET ROLE; RESET ROLE;
CREATE FOREIGN DATA WRAPPER foo LIBRARY 'postgresql_fdw' LANGUAGE C; CREATE FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator;
\dew+ \dew+
-- ALTER FOREIGN DATA WRAPPER -- ALTER FOREIGN DATA WRAPPER
ALTER FOREIGN DATA WRAPPER foo LIBRARY ''; -- ERROR ALTER FOREIGN DATA WRAPPER foo; -- ERROR
ALTER FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql'; ALTER FOREIGN DATA WRAPPER foo VALIDATOR bar; -- ERROR
ALTER FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw'; ALTER FOREIGN DATA WRAPPER foo NO VALIDATOR;
\dew+ \dew+
ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2'); ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2');
...@@ -101,7 +97,7 @@ DROP FOREIGN DATA WRAPPER foo; ...@@ -101,7 +97,7 @@ DROP FOREIGN DATA WRAPPER foo;
DROP ROLE regress_test_role_super; DROP ROLE regress_test_role_super;
\dew+ \dew+
CREATE FOREIGN DATA WRAPPER foo LIBRARY 'dummy_fdw' LANGUAGE C; CREATE FOREIGN DATA WRAPPER foo;
CREATE SERVER s1 FOREIGN DATA WRAPPER foo; CREATE SERVER s1 FOREIGN DATA WRAPPER foo;
CREATE USER MAPPING FOR current_user SERVER s1; CREATE USER MAPPING FOR current_user SERVER s1;
\dew+ \dew+
...@@ -118,7 +114,7 @@ DROP FOREIGN DATA WRAPPER foo CASCADE; ...@@ -118,7 +114,7 @@ DROP FOREIGN DATA WRAPPER foo CASCADE;
-- exercise CREATE SERVER -- exercise CREATE SERVER
CREATE SERVER s1 FOREIGN DATA WRAPPER foo; -- ERROR 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;
CREATE SERVER s1 FOREIGN DATA WRAPPER foo; -- ERROR CREATE SERVER s1 FOREIGN DATA WRAPPER foo; -- ERROR
CREATE SERVER s2 FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b'); CREATE SERVER s2 FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b');
...@@ -313,12 +309,11 @@ GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role; ...@@ -313,12 +309,11 @@ GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role;
DROP USER MAPPING FOR public SERVER s4; DROP USER MAPPING FOR public SERVER s4;
ALTER SERVER s6 OPTIONS (DROP host, DROP dbname); ALTER SERVER s6 OPTIONS (DROP host, DROP dbname);
ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username); ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username);
ALTER FOREIGN DATA WRAPPER foo LIBRARY 'plpgsql'; ALTER FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator;
ALTER FOREIGN DATA WRAPPER foo LIBRARY 'default_fdw';
-- Privileges -- Privileges
SET ROLE unprivileged_role; 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 OPTIONS (gotcha 'true'); -- ERROR
ALTER FOREIGN DATA WRAPPER foo OWNER TO unprivileged_role; -- ERROR ALTER FOREIGN DATA WRAPPER foo OWNER TO unprivileged_role; -- ERROR
DROP FOREIGN DATA WRAPPER foo; -- ERROR DROP FOREIGN DATA WRAPPER foo; -- ERROR
...@@ -336,7 +331,7 @@ RESET ROLE; ...@@ -336,7 +331,7 @@ RESET ROLE;
GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO unprivileged_role; GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO unprivileged_role;
GRANT USAGE ON FOREIGN DATA WRAPPER foo TO unprivileged_role WITH GRANT OPTION; GRANT USAGE ON FOREIGN DATA WRAPPER foo TO unprivileged_role WITH GRANT OPTION;
SET ROLE unprivileged_role; 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 OPTIONS (gotcha 'true'); -- ERROR
DROP FOREIGN DATA WRAPPER foo; -- ERROR DROP FOREIGN DATA WRAPPER foo; -- ERROR
GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_test_role; -- WARNING GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_test_role; -- WARNING
...@@ -391,6 +386,6 @@ DROP FOREIGN DATA WRAPPER dummy CASCADE; ...@@ -391,6 +386,6 @@ DROP FOREIGN DATA WRAPPER dummy CASCADE;
DROP ROLE foreign_data_user; DROP ROLE foreign_data_user;
-- At this point we should have no wrappers, no servers, and no mappings. -- 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 srvname, srvoptions FROM pg_foreign_server;
SELECT * FROM pg_user_mapping; SELECT * FROM pg_user_mapping;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment