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

Commitc95c25f

Browse files
committed
Custom reloptions for table AM
Let table AM define custom reloptions for its tables. This allows tospecify AM-specific parameters by WITH clause when creating a table.The code may use some parts from prior work by Hao Wu.Discussion:https://postgr.es/m/CAPpHfdurb9ycV8udYqM%3Do0sPS66PJ4RCBM1g-bBpvzUfogY0EA%40mail.gmail.comDiscussion:https://postgr.es/m/AMUA1wBBBxfc3tKRLLdU64rb.1.1683276279979.Hmail.wuhao%40hashdata.cnReviewed-by: Reviewed-by: Pavel Borisov, Matthias van de Meent
1 parent27bc177 commitc95c25f

File tree

8 files changed

+126
-27
lines changed

8 files changed

+126
-27
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include"access/nbtree.h"
2525
#include"access/reloptions.h"
2626
#include"access/spgist_private.h"
27+
#include"access/tableam.h"
2728
#include"catalog/pg_type.h"
2829
#include"commands/defrem.h"
2930
#include"commands/tablespace.h"
@@ -1377,7 +1378,7 @@ untransformRelOptions(Datum options)
13771378
*/
13781379
bytea*
13791380
extractRelOptions(HeapTupletuple,TupleDesctupdesc,
1380-
amoptions_functionamoptions)
1381+
constTableAmRoutine*tableam,amoptions_functionamoptions)
13811382
{
13821383
bytea*options;
13831384
boolisnull;
@@ -1399,7 +1400,8 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
13991400
caseRELKIND_RELATION:
14001401
caseRELKIND_TOASTVALUE:
14011402
caseRELKIND_MATVIEW:
1402-
options=heap_reloptions(classForm->relkind,datum, false);
1403+
options=tableam_reloptions(tableam,classForm->relkind,
1404+
datum, false);
14031405
break;
14041406
caseRELKIND_PARTITIONED_TABLE:
14051407
options=partitioned_table_reloptions(datum, false);

‎src/backend/access/heap/heapam_handler.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include"access/heapam.h"
2424
#include"access/heaptoast.h"
2525
#include"access/multixact.h"
26+
#include"access/reloptions.h"
2627
#include"access/rewriteheap.h"
2728
#include"access/syncscan.h"
2829
#include"access/tableam.h"
@@ -2155,6 +2156,16 @@ heapam_relation_toast_am(Relation rel)
21552156
returnrel->rd_rel->relam;
21562157
}
21572158

2159+
staticbytea*
2160+
heapam_reloptions(charrelkind,Datumreloptions,boolvalidate)
2161+
{
2162+
Assert(relkind==RELKIND_RELATION||
2163+
relkind==RELKIND_TOASTVALUE||
2164+
relkind==RELKIND_MATVIEW);
2165+
2166+
returnheap_reloptions(relkind,reloptions,validate);
2167+
}
2168+
21582169

21592170
/* ------------------------------------------------------------------------
21602171
* Planner related callbacks for the heap AM
@@ -2660,6 +2671,7 @@ static const TableAmRoutine heapam_methods = {
26602671
.relation_needs_toast_table=heapam_relation_needs_toast_table,
26612672
.relation_toast_am=heapam_relation_toast_am,
26622673
.relation_fetch_toast_slice=heap_fetch_toast_slice,
2674+
.reloptions=heapam_reloptions,
26632675

26642676
.relation_estimate_size=heapam_estimate_rel_size,
26652677

‎src/backend/access/table/tableamapi.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
#include"access/tableam.h"
1515
#include"access/xact.h"
16+
#include"catalog/pg_am.h"
1617
#include"commands/defrem.h"
1718
#include"miscadmin.h"
1819
#include"utils/guc_hooks.h"
20+
#include"utils/syscache.h"
1921

2022

2123
/*
@@ -98,6 +100,29 @@ GetTableAmRoutine(Oid amhandler)
98100
returnroutine;
99101
}
100102

103+
/*
104+
* GetTableAmRoutineByAmOid
105+
*Given the table access method oid get its TableAmRoutine struct, which
106+
*will be palloc'd in the caller's memory context.
107+
*/
108+
constTableAmRoutine*
109+
GetTableAmRoutineByAmOid(Oidamoid)
110+
{
111+
HeapTupleht_am;
112+
Form_pg_amamrec;
113+
constTableAmRoutine*tableam=NULL;
114+
115+
ht_am=SearchSysCache1(AMOID,ObjectIdGetDatum(amoid));
116+
if (!HeapTupleIsValid(ht_am))
117+
elog(ERROR,"cache lookup failed for access method %u",
118+
amoid);
119+
amrec= (Form_pg_am)GETSTRUCT(ht_am);
120+
121+
tableam=GetTableAmRoutine(amrec->amhandler);
122+
ReleaseSysCache(ht_am);
123+
returntableam;
124+
}
125+
101126
/* check_hook: validate new default_table_access_method */
102127
bool
103128
check_default_table_access_method(char**newval,void**extra,GucSourcesource)

‎src/backend/commands/tablecmds.c

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
715715
ObjectAddress address;
716716
LOCKMODEparentLockmode;
717717
OidaccessMethodId = InvalidOid;
718+
const TableAmRoutine *tableam = NULL;
718719

719720
/*
720721
* Truncate relname to appropriate length (probably a waste of time, as
@@ -850,6 +851,28 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
850851
if (!OidIsValid(ownerId))
851852
ownerId = GetUserId();
852853

854+
/*
855+
* For relations with table AM and partitioned tables, select access
856+
* method to use: an explicitly indicated one, or (in the case of a
857+
* partitioned table) the parent's, if it has one.
858+
*/
859+
if (stmt->accessMethod != NULL)
860+
{
861+
Assert(RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE);
862+
accessMethodId = get_table_am_oid(stmt->accessMethod, false);
863+
}
864+
else if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE)
865+
{
866+
if (stmt->partbound)
867+
{
868+
Assert(list_length(inheritOids) == 1);
869+
accessMethodId = get_rel_relam(linitial_oid(inheritOids));
870+
}
871+
872+
if (RELKIND_HAS_TABLE_AM(relkind) && !OidIsValid(accessMethodId))
873+
accessMethodId = get_table_am_oid(default_table_access_method, false);
874+
}
875+
853876
/*
854877
* Parse and validate reloptions, if any.
855878
*/
@@ -858,6 +881,12 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
858881

859882
switch (relkind)
860883
{
884+
case RELKIND_RELATION:
885+
case RELKIND_TOASTVALUE:
886+
case RELKIND_MATVIEW:
887+
tableam = GetTableAmRoutineByAmOid(accessMethodId);
888+
(void) tableam_reloptions(tableam, relkind, reloptions, true);
889+
break;
861890
case RELKIND_VIEW:
862891
(void) view_reloptions(reloptions, true);
863892
break;
@@ -866,6 +895,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
866895
break;
867896
default:
868897
(void) heap_reloptions(relkind, reloptions, true);
898+
break;
869899
}
870900

871901
if (stmt->ofTypename)
@@ -957,28 +987,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
957987
}
958988
}
959989

960-
/*
961-
* For relations with table AM and partitioned tables, select access
962-
* method to use: an explicitly indicated one, or (in the case of a
963-
* partitioned table) the parent's, if it has one.
964-
*/
965-
if (stmt->accessMethod != NULL)
966-
{
967-
Assert(RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE);
968-
accessMethodId = get_table_am_oid(stmt->accessMethod, false);
969-
}
970-
else if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE)
971-
{
972-
if (stmt->partbound)
973-
{
974-
Assert(list_length(inheritOids) == 1);
975-
accessMethodId = get_rel_relam(linitial_oid(inheritOids));
976-
}
977-
978-
if (RELKIND_HAS_TABLE_AM(relkind) && !OidIsValid(accessMethodId))
979-
accessMethodId = get_table_am_oid(default_table_access_method, false);
980-
}
981-
982990
/*
983991
* Create the relation. Inherited defaults and constraints are passed in
984992
* for immediate handling --- since they don't need parsing, they can be
@@ -15524,7 +15532,8 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
1552415532
case RELKIND_RELATION:
1552515533
case RELKIND_TOASTVALUE:
1552615534
case RELKIND_MATVIEW:
15527-
(void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
15535+
(void) table_reloptions(rel, rel->rd_rel->relkind,
15536+
newOptions, true);
1552815537
break;
1552915538
case RELKIND_PARTITIONED_TABLE:
1553015539
(void) partitioned_table_reloptions(newOptions, true);

‎src/backend/postmaster/autovacuum.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2661,7 +2661,9 @@ extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
26612661
((Form_pg_class)GETSTRUCT(tup))->relkind==RELKIND_MATVIEW||
26622662
((Form_pg_class)GETSTRUCT(tup))->relkind==RELKIND_TOASTVALUE);
26632663

2664-
relopts=extractRelOptions(tup,pg_class_desc,NULL);
2664+
relopts=extractRelOptions(tup,pg_class_desc,
2665+
GetTableAmRoutineByAmOid(((Form_pg_class)GETSTRUCT(tup))->relam),
2666+
NULL);
26652667
if (relopts==NULL)
26662668
returnNULL;
26672669

‎src/backend/utils/cache/relcache.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include"access/htup_details.h"
3434
#include"access/multixact.h"
3535
#include"access/parallel.h"
36+
#include"access/relation.h"
3637
#include"access/reloptions.h"
3738
#include"access/sysattr.h"
3839
#include"access/table.h"
@@ -464,6 +465,7 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
464465
{
465466
bytea*options;
466467
amoptions_functionamoptsfn;
468+
constTableAmRoutine*tableam=NULL;
467469

468470
relation->rd_options=NULL;
469471

@@ -478,6 +480,7 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
478480
caseRELKIND_VIEW:
479481
caseRELKIND_MATVIEW:
480482
caseRELKIND_PARTITIONED_TABLE:
483+
tableam=relation->rd_tableam;
481484
amoptsfn=NULL;
482485
break;
483486
caseRELKIND_INDEX:
@@ -493,7 +496,8 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
493496
* we might not have any other for pg_class yet (consider executing this
494497
* code for pg_class itself)
495498
*/
496-
options=extractRelOptions(tuple,GetPgClassDescriptor(),amoptsfn);
499+
options=extractRelOptions(tuple,GetPgClassDescriptor(),
500+
tableam,amoptsfn);
497501

498502
/*
499503
* Copy parsed data into CacheMemoryContext. To guard against the

‎src/include/access/reloptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include"access/amapi.h"
2323
#include"access/htup.h"
24+
#include"access/tableam.h"
2425
#include"access/tupdesc.h"
2526
#include"nodes/pg_list.h"
2627
#include"storage/lock.h"
@@ -224,6 +225,7 @@ extern Datum transformRelOptions(Datum oldOptions, List *defList,
224225
boolacceptOidsOff,boolisReset);
225226
externList*untransformRelOptions(Datumoptions);
226227
externbytea*extractRelOptions(HeapTupletuple,TupleDesctupdesc,
228+
constTableAmRoutine*tableam,
227229
amoptions_functionamoptions);
228230
externvoid*build_reloptions(Datumreloptions,boolvalidate,
229231
relopt_kindkind,

‎src/include/access/tableam.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,28 @@ typedef struct TableAmRoutine
737737
int32slicelength,
738738
structvarlena*result);
739739

740+
/*
741+
* This callback parses and validates the reloptions array for a table.
742+
*
743+
* This is called only when a non-null reloptions array exists for the
744+
* table. 'reloptions' is a text array containing entries of the form
745+
* "name=value". The function should construct a bytea value, which will
746+
* be copied into the rd_options field of the table's relcache entry. The
747+
* data contents of the bytea value are open for the access method to
748+
* define.
749+
*
750+
* When 'validate' is true, the function should report a suitable error
751+
* message if any of the options are unrecognized or have invalid values;
752+
* when 'validate' is false, invalid entries should be silently ignored.
753+
* ('validate' is false when loading options already stored in pg_catalog;
754+
* an invalid entry could only be found if the access method has changed
755+
* its rules for options, and in that case ignoring obsolete entries is
756+
* appropriate.)
757+
*
758+
* It is OK to return NULL if default behavior is wanted.
759+
*/
760+
bytea*(*reloptions) (charrelkind,Datumreloptions,boolvalidate);
761+
740762

741763
/* ------------------------------------------------------------------------
742764
* Planner related functions.
@@ -1925,6 +1947,26 @@ table_relation_fetch_toast_slice(Relation toastrel, Oid valueid,
19251947
result);
19261948
}
19271949

1950+
/*
1951+
* Parse options for given table.
1952+
*/
1953+
staticinlinebytea*
1954+
table_reloptions(Relationrel,charrelkind,
1955+
Datumreloptions,boolvalidate)
1956+
{
1957+
returnrel->rd_tableam->reloptions(relkind,reloptions,validate);
1958+
}
1959+
1960+
/*
1961+
* Parse table options without knowledge of particular table.
1962+
*/
1963+
staticinlinebytea*
1964+
tableam_reloptions(constTableAmRoutine*tableam,charrelkind,
1965+
Datumreloptions,boolvalidate)
1966+
{
1967+
returntableam->reloptions(relkind,reloptions,validate);
1968+
}
1969+
19281970

19291971
/* ----------------------------------------------------------------------------
19301972
* Planner related functionality
@@ -2102,6 +2144,7 @@ extern void table_block_relation_estimate_size(Relation rel,
21022144
*/
21032145

21042146
externconstTableAmRoutine*GetTableAmRoutine(Oidamhandler);
2147+
externconstTableAmRoutine*GetTableAmRoutineByAmOid(Oidamoid);
21052148

21062149
/* ----------------------------------------------------------------------------
21072150
* Functions in heapam_handler.c

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp