Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc4096c7

Browse files
committed
Allow per-column foreign data wrapper options.
Shigeru Hanada, with fairly minor editing by me.
1 parent68cbb9f commitc4096c7

File tree

23 files changed

+407
-47
lines changed

23 files changed

+407
-47
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,15 @@
11571157
</entry>
11581158
</row>
11591159

1160+
<row>
1161+
<entry><structfield>attfdwoptions</structfield></entry>
1162+
<entry><type>text[]</type></entry>
1163+
<entry></entry>
1164+
<entry>
1165+
Attribute-level foreign data wrapper options, as <quote>keyword=value</> strings
1166+
</entry>
1167+
</row>
1168+
11601169
</tbody>
11611170
</tgroup>
11621171
</table>

‎doc/src/sgml/information_schema.sgml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,69 @@
10181018
</table>
10191019
</sect1>
10201020

1021+
<sect1 id="infoschema-column-options">
1022+
<title><literal>column_options</literal></title>
1023+
1024+
<para>
1025+
The view <literal>column_options</literal> contains all the
1026+
options defined for foreign table columns in the current database. Only
1027+
those foreign table columns are shown that the current user has access to
1028+
(by way of being the owner or having some privilege).
1029+
</para>
1030+
1031+
<table>
1032+
<title><literal>column_options</literal> Columns</title>
1033+
1034+
<tgroup cols="3">
1035+
<thead>
1036+
<row>
1037+
<entry>Name</entry>
1038+
<entry>Data Type</entry>
1039+
<entry>Description</entry>
1040+
</row>
1041+
</thead>
1042+
1043+
<tbody>
1044+
<row>
1045+
<entry><literal>table_catalog</literal></entry>
1046+
<entry><type>sql_identifier</type></entry>
1047+
<entry>Name of the database that contains the foreign table (always the current database)</entry>
1048+
</row>
1049+
1050+
<row>
1051+
<entry><literal>table_schema</literal></entry>
1052+
<entry><type>sql_identifier</type></entry>
1053+
<entry>Name of the schema that contains the foreign table</entry>
1054+
</row>
1055+
1056+
<row>
1057+
<entry><literal>table_name</literal></entry>
1058+
<entry><type>sql_identifier</type></entry>
1059+
<entry>Name of the foreign table</entry>
1060+
</row>
1061+
1062+
<row>
1063+
<entry><literal>column_name</literal></entry>
1064+
<entry><type>sql_identifier</type></entry>
1065+
<entry>Name of the column</entry>
1066+
</row>
1067+
1068+
<row>
1069+
<entry><literal>option_name</literal></entry>
1070+
<entry><type>sql_identifier</type></entry>
1071+
<entry>Name of an option</entry>
1072+
</row>
1073+
1074+
<row>
1075+
<entry><literal>option_value</literal></entry>
1076+
<entry><type>character_data</type></entry>
1077+
<entry>Value of the option</entry>
1078+
</row>
1079+
</tbody>
1080+
</tgroup>
1081+
</table>
1082+
</sect1>
1083+
10211084
<sect1 id="infoschema-column-privileges">
10221085
<title><literal>column_privileges</literal></title>
10231086

‎doc/src/sgml/ref/alter_foreign_table.sgml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ ALTER FOREIGN TABLE <replaceable class="PARAMETER">name</replaceable>
3636
DROP [ COLUMN ] [ IF EXISTS ] <replaceable class="PARAMETER">column</replaceable> [ RESTRICT | CASCADE ]
3737
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> [ SET DATA ] TYPE <replaceable class="PARAMETER">type</replaceable>
3838
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET | DROP } NOT NULL
39+
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ])
3940
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
4041
OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ])
4142
</synopsis>
@@ -125,12 +126,13 @@ ALTER FOREIGN TABLE <replaceable class="PARAMETER">name</replaceable>
125126
<term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] )</literal></term>
126127
<listitem>
127128
<para>
128-
Change options for the foreign table.
129+
Change options for the foreign table or one of its columns.
129130
<literal>ADD</>, <literal>SET</>, and <literal>DROP</>
130131
specify the action to be performed. <literal>ADD</> is assumed
131-
if no operation is explicitly specified. Option names must be
132-
unique; names and values are also validated using the foreign
133-
data wrapper library.
132+
if no operation is explicitly specified. Duplicate option names are not
133+
allowed (although it's OK for a table option and a column option to have
134+
the same name). Option names and values are also validated using the
135+
foreign data wrapper library.
134136
</para>
135137
</listitem>
136138
</varlistentry>

‎doc/src/sgml/ref/create_foreign_table.sgml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<refsynopsisdiv>
2020
<synopsis>
2121
CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> ( [
22-
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ NULL | NOT NULL ] }
22+
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ] [NULL | NOT NULL ] }
2323
[, ... ]
2424
] )
2525
SERVER <replaceable class="parameter">server_name</replaceable>
@@ -138,10 +138,12 @@ CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name
138138
<term><literal>OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ...] )</literal></term>
139139
<listitem>
140140
<para>
141-
Options to be associated with the new foreign table.
141+
Options to be associated with the new foreign table or one of its
142+
columns.
142143
The allowed option names and values are specific to each foreign
143144
data wrapper and are validated using the foreign-data wrapper's
144-
validator function. Option names must be unique.
145+
validator function. Duplicate option names are not allowed (although
146+
it's OK for a table option and a column option to have the same name).
145147
</para>
146148
</listitem>
147149
</varlistentry>

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,12 @@ testdb=&gt;
891891
below.)
892892
</para>
893893

894+
<para>
895+
For some types of relation, <literal>\d</> shows additional information
896+
for each column: column values for sequences, indexed expression for
897+
indexes and per-column foreign data wrapper options for foreign tables.
898+
</para>
899+
894900
<para>
895901
The command form <literal>\d+</literal> is identical, except that
896902
more information is displayed: any comments associated with the

‎src/backend/access/common/tupdesc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
363363
return false;
364364
if (attr1->attcollation!=attr2->attcollation)
365365
return false;
366-
/* attaclandattoptions are not even present... */
366+
/* attacl, attoptionsandattfdwoptions are not even present... */
367367
}
368368

369369
if (tupdesc1->constr!=NULL)
@@ -483,7 +483,7 @@ TupleDescInitEntry(TupleDesc desc,
483483
att->attisdropped= false;
484484
att->attislocal= true;
485485
att->attinhcount=0;
486-
/* attaclandattoptions are not present in tupledescs */
486+
/* attacl, attoptionsandattfdwoptions are not present in tupledescs */
487487

488488
tuple=SearchSysCache1(TYPEOID,ObjectIdGetDatum(oidtypeid));
489489
if (!HeapTupleIsValid(tuple))

‎src/backend/catalog/genbki.pl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ sub emit_pgattr_row
369369
attislocal=>'t',
370370
attinhcount=>'0',
371371
attacl=>'_null_',
372-
attoptions=>'_null_'
372+
attoptions=>'_null_',
373+
attfdwoptions=>'_null_'
373374
);
374375
return {%PGATTR_DEFAULTS,%row};
375376
}
@@ -400,6 +401,7 @@ sub emit_schemapg_row
400401
# Only the fixed-size portions of the descriptors are ever used.
401402
delete$row->{attacl};
402403
delete$row->{attoptions};
404+
delete$row->{attfdwoptions};
403405

404406
# Expand booleans from 'f'/'t' to 'false'/'true'.
405407
# Some values might be other macros (eg FLOAT4PASSBYVAL), don't change.

‎src/backend/catalog/heap.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ static List *insert_ordered_unique_oid(List *list, Oid datum);
126126
*/
127127

128128
/*
129-
* The initializers below do not includethe attoptions or attacl fields,
129+
* The initializers below do not includetrailing variable length fields,
130130
* but that's OK - we're never going to reference anything beyond the
131131
* fixed-size portion of the structure anyway.
132132
*/
@@ -620,6 +620,7 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
620620
/* start out with empty permissions and empty options */
621621
nulls[Anum_pg_attribute_attacl-1]= true;
622622
nulls[Anum_pg_attribute_attoptions-1]= true;
623+
nulls[Anum_pg_attribute_attfdwoptions-1]= true;
623624

624625
tup=heap_form_tuple(RelationGetDescr(pg_attribute_rel),values,nulls);
625626

‎src/backend/catalog/information_schema.sql

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,6 +2534,39 @@ GRANT SELECT ON element_types TO PUBLIC;
25342534

25352535
-- SQL/MED views; these use section numbers from part 9 of the standard.
25362536

2537+
/* Base view for foreign table columns*/
2538+
CREATEVIEW_pg_foreign_table_columnsAS
2539+
SELECTn.nspname,
2540+
c.relname,
2541+
a.attname,
2542+
a.attfdwoptions
2543+
FROM pg_foreign_table t, pg_authid u, pg_namespace n, pg_class c,
2544+
pg_attribute a
2545+
WHEREu.oid=c.relowner
2546+
AND (pg_has_role(c.relowner,'USAGE')
2547+
OR has_column_privilege(c.oid,a.attnum,'SELECT, INSERT, UPDATE, REFERENCES'))
2548+
ANDn.oid=c.relnamespace
2549+
ANDc.oid=t.ftrelid
2550+
ANDc.relkind='f'
2551+
ANDa.attrelid=c.oid
2552+
ANDa.attnum>0;
2553+
2554+
/*
2555+
* 24.2
2556+
* COLUMN_OPTIONS view
2557+
*/
2558+
CREATEVIEWcolumn_optionsAS
2559+
SELECT CAST(current_database()AS sql_identifier)AS table_catalog,
2560+
c.nspnameAS table_schema,
2561+
c.relnameAS table_name,
2562+
c.attnameAS column_name,
2563+
CAST((pg_options_to_table(c.attfdwoptions)).option_nameAS sql_identifier)AS option_name,
2564+
CAST((pg_options_to_table(c.attfdwoptions)).option_valueAS character_data)AS option_value
2565+
FROM _pg_foreign_table_columns c;
2566+
2567+
GRANTSELECTON column_options TO PUBLIC;
2568+
2569+
25372570
/* Base view for foreign-data wrappers*/
25382571
CREATEVIEW_pg_foreign_data_wrappersAS
25392572
SELECTw.oid,

‎src/backend/commands/tablecmds.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ static void ATPrepAlterColumnType(List **wqueue,
346346
staticboolATColumnChangeRequiresRewrite(Node*expr,AttrNumbervarattno);
347347
staticvoidATExecAlterColumnType(AlteredTableInfo*tab,Relationrel,
348348
AlterTableCmd*cmd,LOCKMODElockmode);
349+
staticvoidATExecAlterColumnGenericOptions(Relationrel,constchar*colName,
350+
List*options,LOCKMODElockmode);
349351
staticvoidATPostAlterTypeCleanup(List**wqueue,AlteredTableInfo*tab,LOCKMODElockmode);
350352
staticvoidATPostAlterTypeParse(OidoldId,char*cmd,
351353
List**wqueue,LOCKMODElockmode,boolrewrite);
@@ -2648,6 +2650,7 @@ AlterTableGetLockLevel(List *cmds)
26482650
caseAT_DropNotNull:/* may change some SQL plans */
26492651
caseAT_SetNotNull:
26502652
caseAT_GenericOptions:
2653+
caseAT_AlterColumnGenericOptions:
26512654
cmd_lockmode=AccessExclusiveLock;
26522655
break;
26532656

@@ -2925,6 +2928,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
29252928
ATPrepAlterColumnType(wqueue,tab,rel,recurse,recursing,cmd,lockmode);
29262929
pass=AT_PASS_ALTER_TYPE;
29272930
break;
2931+
caseAT_AlterColumnGenericOptions:
2932+
ATSimplePermissions(rel,ATT_FOREIGN_TABLE);
2933+
/* This command never recurses */
2934+
/* No command-specific prep needed */
2935+
pass=AT_PASS_MISC;
2936+
break;
29282937
caseAT_ChangeOwner:/* ALTER OWNER */
29292938
/* This command never recurses */
29302939
/* No command-specific prep needed */
@@ -3169,6 +3178,9 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
31693178
caseAT_AlterColumnType:/* ALTER COLUMN TYPE */
31703179
ATExecAlterColumnType(tab,rel,cmd,lockmode);
31713180
break;
3181+
caseAT_AlterColumnGenericOptions:/* ALTER COLUMN OPTIONS */
3182+
ATExecAlterColumnGenericOptions(rel,cmd->name, (List*)cmd->def,lockmode);
3183+
break;
31723184
caseAT_ChangeOwner:/* ALTER OWNER */
31733185
ATExecChangeOwner(RelationGetRelid(rel),
31743186
get_role_oid(cmd->name, false),
@@ -7397,6 +7409,100 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
73977409
heap_freetuple(heapTup);
73987410
}
73997411

7412+
staticvoid
7413+
ATExecAlterColumnGenericOptions(Relationrel,
7414+
constchar*colName,
7415+
List*options,
7416+
LOCKMODElockmode)
7417+
{
7418+
Relationftrel;
7419+
Relationattrel;
7420+
ForeignServer*server;
7421+
ForeignDataWrapper*fdw;
7422+
HeapTupletuple;
7423+
HeapTuplenewtuple;
7424+
boolisnull;
7425+
Datumrepl_val[Natts_pg_attribute];
7426+
boolrepl_null[Natts_pg_attribute];
7427+
boolrepl_repl[Natts_pg_attribute];
7428+
Datumdatum;
7429+
Form_pg_foreign_tablefttableform;
7430+
Form_pg_attributeatttableform;
7431+
7432+
if (options==NIL)
7433+
return;
7434+
7435+
/* First, determine FDW validator associated to the foreign table. */
7436+
ftrel=heap_open(ForeignTableRelationId,AccessShareLock);
7437+
tuple=SearchSysCache1(FOREIGNTABLEREL,rel->rd_id);
7438+
if (!HeapTupleIsValid(tuple))
7439+
ereport(ERROR,
7440+
(errcode(ERRCODE_UNDEFINED_OBJECT),
7441+
errmsg("foreign table \"%s\" does not exist",
7442+
RelationGetRelationName(rel))));
7443+
fttableform= (Form_pg_foreign_table)GETSTRUCT(tuple);
7444+
server=GetForeignServer(fttableform->ftserver);
7445+
fdw=GetForeignDataWrapper(server->fdwid);
7446+
7447+
heap_close(ftrel,AccessShareLock);
7448+
ReleaseSysCache(tuple);
7449+
7450+
attrel=heap_open(AttributeRelationId,RowExclusiveLock);
7451+
tuple=SearchSysCacheAttName(RelationGetRelid(rel),colName);
7452+
if (!HeapTupleIsValid(tuple))
7453+
ereport(ERROR,
7454+
(errcode(ERRCODE_UNDEFINED_COLUMN),
7455+
errmsg("column \"%s\" of relation \"%s\" does not exist",
7456+
colName,RelationGetRelationName(rel))));
7457+
7458+
/* Prevent them from altering a system attribute */
7459+
atttableform= (Form_pg_attribute)GETSTRUCT(tuple);
7460+
if (atttableform->attnum <=0)
7461+
ereport(ERROR,
7462+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7463+
errmsg("cannot alter system column \"%s\"",colName)));
7464+
7465+
7466+
/* Initialize buffers for new tuple values */
7467+
memset(repl_val,0,sizeof(repl_val));
7468+
memset(repl_null, false,sizeof(repl_null));
7469+
memset(repl_repl, false,sizeof(repl_repl));
7470+
7471+
/* Extract the current options */
7472+
datum=SysCacheGetAttr(ATTNAME,
7473+
tuple,
7474+
Anum_pg_attribute_attfdwoptions,
7475+
&isnull);
7476+
if (isnull)
7477+
datum=PointerGetDatum(NULL);
7478+
7479+
/* Transform the options */
7480+
datum=transformGenericOptions(AttributeRelationId,
7481+
datum,
7482+
options,
7483+
fdw->fdwvalidator);
7484+
7485+
if (PointerIsValid(DatumGetPointer(datum)))
7486+
repl_val[Anum_pg_attribute_attfdwoptions-1]=datum;
7487+
else
7488+
repl_null[Anum_pg_attribute_attfdwoptions-1]= true;
7489+
7490+
repl_repl[Anum_pg_attribute_attfdwoptions-1]= true;
7491+
7492+
/* Everything looks good - update the tuple */
7493+
7494+
newtuple=heap_modify_tuple(tuple,RelationGetDescr(attrel),
7495+
repl_val,repl_null,repl_repl);
7496+
ReleaseSysCache(tuple);
7497+
7498+
simple_heap_update(attrel,&newtuple->t_self,newtuple);
7499+
CatalogUpdateIndexes(attrel,newtuple);
7500+
7501+
heap_close(attrel,RowExclusiveLock);
7502+
7503+
heap_freetuple(newtuple);
7504+
}
7505+
74007506
/*
74017507
* Cleanup after we've finished all the ALTER TYPE operations for a
74027508
* particular relation. We have to drop and recreate all the indexes

‎src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,7 @@ _copyColumnDef(ColumnDef *from)
23122312
COPY_NODE_FIELD(collClause);
23132313
COPY_SCALAR_FIELD(collOid);
23142314
COPY_NODE_FIELD(constraints);
2315+
COPY_NODE_FIELD(fdwoptions);
23152316

23162317
returnnewnode;
23172318
}

‎src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,7 @@ _outColumnDef(StringInfo str, ColumnDef *node)
21022102
WRITE_NODE_FIELD(collClause);
21032103
WRITE_OID_FIELD(collOid);
21042104
WRITE_NODE_FIELD(constraints);
2105+
WRITE_NODE_FIELD(fdwoptions);
21052106
}
21062107

21072108
staticvoid

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp