From: Shigeru Hanada Date: Thu, 18 Nov 2010 08:18:27 +0000 (+0900) Subject: Simplify the interface of MakeFileState() to make it easier to reuse X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=0a998e548b8d3cf98b7b4a33c06a63cdd26b642e;p=users%2Fhanada%2Fpostgres.git Simplify the interface of MakeFileState() to make it easier to reuse file_parser module in COPY FROM. --- diff --git a/src/backend/foreign/file_fdw.c b/src/backend/foreign/file_fdw.c index 8cdb090652..33984d467d 100644 --- a/src/backend/foreign/file_fdw.c +++ b/src/backend/foreign/file_fdw.c @@ -39,6 +39,9 @@ struct FileFdwOption /* * Valid options for file_fdw. * These options are based on the options for COPY FROM command. + * + * Note: If you are adding new option for user mapping, you need to modify + * fileBeginScan(). See comments of the function for detail. */ static struct FileFdwOption valid_options[] = { /* File options */ @@ -262,17 +265,35 @@ file_fdw_handler(PG_FUNCTION_ARGS) /* * BeginScan() - * - initiate access to the file, but we have nothing to do + * - initiate access to the file with creating FileState + * + * Parameters for parsing file such as filename and format are passed via + * generic options of FDW-related objects; foreign-data wrapper, server and + * foreign table. User mapping is not used to get options because there is no + * valid option in context of user mapping. */ static void fileBeginScan(ForeignScanState *scanstate) { + ForeignTable *table; + ForeignServer *server; + ForeignDataWrapper *wrapper; + List *options; FileState fstate; elog(DEBUG2, "%s called", __FUNCTION__); - /* create FileFdwReply and set default settings */ - fstate = MakeFileState(scanstate); + /* Extract options from FDW objects */ + table = GetForeignTable(scanstate->ss.ss_currentRelation->rd_id); + server = GetForeignServer(table->serverid); + wrapper = GetForeignDataWrapper(server->fdwid); + options = NIL; + options = list_concat(options, wrapper->options); + options = list_concat(options, server->options); + options = list_concat(options, table->options); + + /* create FileState and set default settings */ + fstate = MakeFileState(scanstate->ss.ss_currentRelation, options); /* pack file information into reply and pass it to subsequent functions */ scanstate->reply = (FdwReply *) fstate; diff --git a/src/backend/foreign/file_parser.c b/src/backend/foreign/file_parser.c index 924ca0597d..4cabc08c8d 100644 --- a/src/backend/foreign/file_parser.c +++ b/src/backend/foreign/file_parser.c @@ -286,17 +286,12 @@ FileLoadRawBuf(FileState fstate) /* * MakeFileState() makes a FileState for a foreign scan on the relation rel. - * - * Parameters for parsing file such as filename and format are passed via - * generic options of FDW-related objects; foreign-data wrapper, server, - * user mapping and foreign table. */ FileState -MakeFileState(ForeignScanState *scanstate) +MakeFileState(Relation rel, List *options) { FileState fstate; bool format_specified = false; - List *options; ListCell *option; TupleDesc tupDesc; int num_phys_attrs; @@ -308,13 +303,7 @@ MakeFileState(ForeignScanState *scanstate) /* Allocate workspace and zero all fields */ fstate = (FileStateData *) palloc0(sizeof(FileStateData)); - options = NIL; - options = list_concat(options, scanstate->wrapper->options); - options = list_concat(options, scanstate->server->options); - options = list_concat(options, scanstate->user->options); - options = list_concat(options, scanstate->table->options); - - /* Extract options from the statement node tree */ + /* Extract information about the file and its format from options */ foreach(option, options) { DefElem *defel = (DefElem *) lfirst(option); @@ -486,7 +475,7 @@ MakeFileState(ForeignScanState *scanstate) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to read from a file"))); - fstate->rel = scanstate->ss.ss_currentRelation; + fstate->rel = rel; tupDesc = RelationGetDescr(fstate->rel); /* Don't allow read OIDs from a table without them */ @@ -522,7 +511,7 @@ MakeFileState(ForeignScanState *scanstate) if (attrs[i]->attisdropped) continue; - tuple = SearchSysCache2(ATTNUM, scanstate->table->relid, i + 1); + tuple = SearchSysCache2(ATTNUM, rel->rd_id, i + 1); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), diff --git a/src/backend/foreign/file_parser.h b/src/backend/foreign/file_parser.h index fef3052a56..a12f24a930 100644 --- a/src/backend/foreign/file_parser.h +++ b/src/backend/foreign/file_parser.h @@ -18,7 +18,7 @@ typedef struct FileStateData *FileState; /* * */ -FileState MakeFileState(ForeignScanState *scanstate); +FileState MakeFileState(Relation rel, List *options); HeapTuple GetNextTuple(FileState cstate, MemoryContext tupleContext); void ResetFileState(FileState cstate); void FreeFileState(FileState cstate);