summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/information_schema.sql5
-rw-r--r--src/backend/commands/foreigncmds.c103
-rw-r--r--src/backend/foreign/Makefile10
-rw-r--r--src/backend/foreign/dummy/Makefile27
-rw-r--r--src/backend/foreign/dummy/dummy_fdw.c24
-rw-r--r--src/backend/foreign/foreign.c165
-rw-r--r--src/backend/foreign/postgresql/Makefile27
-rw-r--r--src/backend/foreign/postgresql/postgresql_fdw.c123
-rw-r--r--src/backend/nodes/copyfuncs.c7
-rw-r--r--src/backend/nodes/equalfuncs.c7
-rw-r--r--src/backend/parser/gram.y40
-rw-r--r--src/backend/parser/keywords.c3
12 files changed, 200 insertions, 341 deletions
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index 4206e9eaf52..80132e27ea4 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -4,7 +4,7 @@
*
* 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
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
@@ -2458,7 +2457,7 @@ CREATE VIEW foreign_data_wrappers AS
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;
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 0967001aa3f..24052556a4b 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -7,7 +7,7 @@
*
*
* 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 @@
#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"
@@ -90,10 +92,11 @@ transformGenericOptions(Datum oldOptions,
List *optionDefList,
GenericOptionFlags flags,
ForeignDataWrapper *fdw,
- OptionListValidatorFunc validateOptionList)
+ Oid fdwvalidator)
{
List *resultOptions = untransformRelOptions(oldOptions);
ListCell *optcell;
+ Datum result;
foreach(optcell, optionDefList)
{
@@ -157,10 +160,12 @@ transformGenericOptions(Datum oldOptions,
}
}
- if (validateOptionList)
- validateOptionList(fdw, flags, resultOptions);
+ result = optionListToArray(resultOptions);
- return optionListToArray(resultOptions);
+ if (fdwvalidator)
+ OidFunctionCall2(fdwvalidator, result, 0);
+
+ return result;
}
@@ -310,6 +315,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
*/
void
@@ -320,9 +340,9 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
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())
@@ -355,18 +375,19 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
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;
@@ -380,6 +401,21 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
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);
@@ -400,7 +436,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
Oid fdwId;
bool isnull;
Datum datum;
- ForeignDataWrapperLibrary *fdwlib;
+ Oid fdwvalidator;
/* Must be super user */
if (!superuser())
@@ -425,36 +461,33 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
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);
}
/*
@@ -472,7 +505,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
/* 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;
@@ -640,7 +673,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
/* 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;
@@ -738,7 +771,7 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
/* 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;
@@ -910,7 +943,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
/* 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;
@@ -1005,7 +1038,7 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
/* 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;
diff --git a/src/backend/foreign/Makefile b/src/backend/foreign/Makefile
index b3cc209c161..dff0c775403 100644
--- a/src/backend/foreign/Makefile
+++ b/src/backend/foreign/Makefile
@@ -4,7 +4,7 @@
# 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 $
#
#-------------------------------------------------------------------------
@@ -15,11 +15,3 @@ include $(top_builddir)/src/Makefile.global
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
diff --git a/src/backend/foreign/dummy/Makefile b/src/backend/foreign/dummy/Makefile
deleted file mode 100644
index 8a05ada0197..00000000000
--- a/src/backend/foreign/dummy/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-#-------------------------------------------------------------------------
-#
-# 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)
diff --git a/src/backend/foreign/dummy/dummy_fdw.c b/src/backend/foreign/dummy/dummy_fdw.c
deleted file mode 100644
index a89d68e0ae2..00000000000
--- a/src/backend/foreign/dummy/dummy_fdw.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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.
- */
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index b5b502cc032..3ec42506777 100644
--- a/src/backend/foreign/foreign.c
+++ b/src/backend/foreign/foreign.c
@@ -6,7 +6,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -31,66 +31,12 @@
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)
@@ -114,15 +60,7 @@ 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,
@@ -387,3 +325,100 @@ pg_options_to_table(PG_FUNCTION_ARGS)
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);
+}
diff --git a/src/backend/foreign/postgresql/Makefile b/src/backend/foreign/postgresql/Makefile
deleted file mode 100644
index 40ed90f8d70..00000000000
--- a/src/backend/foreign/postgresql/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-#-------------------------------------------------------------------------
-#
-# 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)
diff --git a/src/backend/foreign/postgresql/postgresql_fdw.c b/src/backend/foreign/postgresql/postgresql_fdw.c
deleted file mode 100644
index 3fb4d2f8631..00000000000
--- a/src/backend/foreign/postgresql/postgresql_fdw.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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)));
- }
- }
-}
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index bc4232bdc8b..2175e0c0fc0 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -2994,7 +2994,7 @@ _copyCreateFdwStmt(CreateFdwStmt *from)
CreateFdwStmt *newnode = makeNode(CreateFdwStmt);
COPY_STRING_FIELD(fdwname);
- COPY_STRING_FIELD(library);
+ COPY_NODE_FIELD(validator);
COPY_NODE_FIELD(options);
return newnode;
@@ -3006,7 +3006,8 @@ _copyAlterFdwStmt(AlterFdwStmt *from)
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;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 2b8b542e749..4d905dc945e 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -22,7 +22,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -1548,7 +1548,7 @@ static bool
_equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b)
{
COMPARE_STRING_FIELD(fdwname);
- COMPARE_STRING_FIELD(library);
+ COMPARE_NODE_FIELD(validator);
COMPARE_NODE_FIELD(options);
return true;
@@ -1558,7 +1558,8 @@ static bool
_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;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 6688324e05a..3dadbcffdeb 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* 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
@@ -254,7 +254,7 @@ static TypeName *TableFuncTypeName(List *columns);
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
@@ -469,7 +469,7 @@ static TypeName *TableFuncTypeName(List *columns);
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
@@ -2724,8 +2724,13 @@ handler_name:
| name attrs { $$ = lcons(makeString($1), $2); }
;
-opt_validator:
+validator_clause:
VALIDATOR handler_name { $$ = $2; }
+ | NO VALIDATOR { $$ = NIL; }
+ ;
+
+opt_validator:
+ validator_clause { $$ = $1; }
| /*EMPTY*/ { $$ = NIL; }
;
@@ -2808,23 +2813,17 @@ DropTableSpaceStmt: DROP TABLESPACE name
/*****************************************************************************
*
* 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)));
}
;
@@ -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);
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
@@ -10231,7 +10232,6 @@ unreserved_keyword:
| INVOKER
| ISOLATION
| KEY
- | LIBRARY
| LANCOMPILER
| LANGUAGE
| LARGE_P
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 3f3388e7fef..48218df9c4b 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -11,7 +11,7 @@
*
*
* 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[] = {
{"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},