diff options
Diffstat (limited to 'src/backend/commands')
| -rw-r--r-- | src/backend/commands/foreigncmds.c | 103 | 
1 files changed, 68 insertions, 35 deletions
| 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; | 
