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

Commit9bd99f4

Browse files
committed
Custom reloptions for table AM
Let table AM define custom reloptions for its tables. This allows specifyingAM-specific parameters by the WITH clause when creating a table.The reloptions, which could be used outside of table AM, are now extractedinto the CommonRdOptions data structure. These options could be by decisionof table AM directly specified by a user or calculated in some way.The new test module test_tam_options evaluates the ability to set up customreloptions and calculate fields of CommonRdOptions on their base.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, Jess Davis
1 parent6f3d8d5 commit9bd99f4

29 files changed

+639
-161
lines changed

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

Lines changed: 86 additions & 35 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"
@@ -44,7 +45,7 @@
4445
* value, upper and lower bounds (if applicable); for strings, consider a
4546
* validation routine.
4647
* (ii) add a record below (or use add_<type>_reloption).
47-
* (iii) add it to the appropriate options struct (perhapsStdRdOptions)
48+
* (iii) add it to the appropriate options struct (perhapsHeapRdOptions)
4849
* (iv) add it to the appropriate handling routine (perhaps
4950
* default_reloptions)
5051
* (v) make sure the lock level is set correctly for that operation
@@ -1374,10 +1375,16 @@ untransformRelOptions(Datum options)
13741375
* tupdesc is pg_class' tuple descriptor. amoptions is a pointer to the index
13751376
* AM's options parser function in the case of a tuple corresponding to an
13761377
* index, or NULL otherwise.
1378+
*
1379+
* If common pointer is provided, then the corresponding struct will be
1380+
* filled with options that table AM exposes for external usage. That must
1381+
* be filled with defaults before passing here.
13771382
*/
1383+
13781384
bytea*
13791385
extractRelOptions(HeapTupletuple,TupleDesctupdesc,
1380-
amoptions_functionamoptions)
1386+
constTableAmRoutine*tableam,amoptions_functionamoptions,
1387+
CommonRdOptions*common)
13811388
{
13821389
bytea*options;
13831390
boolisnull;
@@ -1399,7 +1406,8 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
13991406
caseRELKIND_RELATION:
14001407
caseRELKIND_TOASTVALUE:
14011408
caseRELKIND_MATVIEW:
1402-
options=heap_reloptions(classForm->relkind,datum, false);
1409+
options=tableam_reloptions(tableam,classForm->relkind,
1410+
datum,common, false);
14031411
break;
14041412
caseRELKIND_PARTITIONED_TABLE:
14051413
options=partitioned_table_reloptions(datum, false);
@@ -1695,7 +1703,7 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
16951703
* Given the result from parseRelOptions, allocate a struct that's of the
16961704
* specified base size plus any extra space that's needed for string variables.
16971705
*
1698-
* "base" should be sizeof(struct) of the reloptions struct (StdRdOptions or
1706+
* "base" should be sizeof(struct) of the reloptions struct (HeapRdOptions or
16991707
* equivalent).
17001708
*/
17011709
staticvoid*
@@ -1832,59 +1840,95 @@ fillRelOptions(void *rdopts, Size basesize,
18321840

18331841

18341842
/*
1835-
* Option parser for anything that usesStdRdOptions.
1843+
* Option parser for anything that usesHeapRdOptions.
18361844
*/
1837-
bytea*
1845+
staticbytea*
18381846
default_reloptions(Datumreloptions,boolvalidate,relopt_kindkind)
18391847
{
18401848
staticconstrelopt_parse_elttab[]= {
1841-
{"fillfactor",RELOPT_TYPE_INT, offsetof(StdRdOptions,fillfactor)},
1849+
{"fillfactor",RELOPT_TYPE_INT, offsetof(HeapRdOptions,fillfactor)},
18421850
{"autovacuum_enabled",RELOPT_TYPE_BOOL,
1843-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,enabled)},
1851+
offsetof(HeapRdOptions,common)+
1852+
offsetof(CommonRdOptions,autovacuum)+
1853+
offsetof(AutoVacOpts,enabled)},
18441854
{"autovacuum_vacuum_threshold",RELOPT_TYPE_INT,
1845-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,vacuum_threshold)},
1855+
offsetof(HeapRdOptions,common)+
1856+
offsetof(CommonRdOptions,autovacuum)+
1857+
offsetof(AutoVacOpts,vacuum_threshold)},
18461858
{"autovacuum_vacuum_insert_threshold",RELOPT_TYPE_INT,
1847-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,vacuum_ins_threshold)},
1859+
offsetof(HeapRdOptions,common)+
1860+
offsetof(CommonRdOptions,autovacuum)+
1861+
offsetof(AutoVacOpts,vacuum_ins_threshold)},
18481862
{"autovacuum_analyze_threshold",RELOPT_TYPE_INT,
1849-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,analyze_threshold)},
1863+
offsetof(HeapRdOptions,common)+
1864+
offsetof(CommonRdOptions,autovacuum)+
1865+
offsetof(AutoVacOpts,analyze_threshold)},
18501866
{"autovacuum_vacuum_cost_limit",RELOPT_TYPE_INT,
1851-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,vacuum_cost_limit)},
1867+
offsetof(HeapRdOptions,common)+
1868+
offsetof(CommonRdOptions,autovacuum)+
1869+
offsetof(AutoVacOpts,vacuum_cost_limit)},
18521870
{"autovacuum_freeze_min_age",RELOPT_TYPE_INT,
1853-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,freeze_min_age)},
1871+
offsetof(HeapRdOptions,common)+
1872+
offsetof(CommonRdOptions,autovacuum)+
1873+
offsetof(AutoVacOpts,freeze_min_age)},
18541874
{"autovacuum_freeze_max_age",RELOPT_TYPE_INT,
1855-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,freeze_max_age)},
1875+
offsetof(HeapRdOptions,common)+
1876+
offsetof(CommonRdOptions,autovacuum)+
1877+
offsetof(AutoVacOpts,freeze_max_age)},
18561878
{"autovacuum_freeze_table_age",RELOPT_TYPE_INT,
1857-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,freeze_table_age)},
1879+
offsetof(HeapRdOptions,common)+
1880+
offsetof(CommonRdOptions,autovacuum)+
1881+
offsetof(AutoVacOpts,freeze_table_age)},
18581882
{"autovacuum_multixact_freeze_min_age",RELOPT_TYPE_INT,
1859-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,multixact_freeze_min_age)},
1883+
offsetof(HeapRdOptions,common)+
1884+
offsetof(CommonRdOptions,autovacuum)+
1885+
offsetof(AutoVacOpts,multixact_freeze_min_age)},
18601886
{"autovacuum_multixact_freeze_max_age",RELOPT_TYPE_INT,
1861-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,multixact_freeze_max_age)},
1887+
offsetof(HeapRdOptions,common)+
1888+
offsetof(CommonRdOptions,autovacuum)+
1889+
offsetof(AutoVacOpts,multixact_freeze_max_age)},
18621890
{"autovacuum_multixact_freeze_table_age",RELOPT_TYPE_INT,
1863-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,multixact_freeze_table_age)},
1891+
offsetof(HeapRdOptions,common)+
1892+
offsetof(CommonRdOptions,autovacuum)+
1893+
offsetof(AutoVacOpts,multixact_freeze_table_age)},
18641894
{"log_autovacuum_min_duration",RELOPT_TYPE_INT,
1865-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,log_min_duration)},
1895+
offsetof(HeapRdOptions,common)+
1896+
offsetof(CommonRdOptions,autovacuum)+
1897+
offsetof(AutoVacOpts,log_min_duration)},
18661898
{"toast_tuple_target",RELOPT_TYPE_INT,
1867-
offsetof(StdRdOptions,toast_tuple_target)},
1899+
offsetof(HeapRdOptions,toast_tuple_target)},
18681900
{"autovacuum_vacuum_cost_delay",RELOPT_TYPE_REAL,
1869-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,vacuum_cost_delay)},
1901+
offsetof(HeapRdOptions,common)+
1902+
offsetof(CommonRdOptions,autovacuum)+
1903+
offsetof(AutoVacOpts,vacuum_cost_delay)},
18701904
{"autovacuum_vacuum_scale_factor",RELOPT_TYPE_REAL,
1871-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,vacuum_scale_factor)},
1905+
offsetof(HeapRdOptions,common)+
1906+
offsetof(CommonRdOptions,autovacuum)+
1907+
offsetof(AutoVacOpts,vacuum_scale_factor)},
18721908
{"autovacuum_vacuum_insert_scale_factor",RELOPT_TYPE_REAL,
1873-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,vacuum_ins_scale_factor)},
1909+
offsetof(HeapRdOptions,common)+
1910+
offsetof(CommonRdOptions,autovacuum)+
1911+
offsetof(AutoVacOpts,vacuum_ins_scale_factor)},
18741912
{"autovacuum_analyze_scale_factor",RELOPT_TYPE_REAL,
1875-
offsetof(StdRdOptions,autovacuum)+ offsetof(AutoVacOpts,analyze_scale_factor)},
1913+
offsetof(HeapRdOptions,common)+
1914+
offsetof(CommonRdOptions,autovacuum)+
1915+
offsetof(AutoVacOpts,analyze_scale_factor)},
18761916
{"user_catalog_table",RELOPT_TYPE_BOOL,
1877-
offsetof(StdRdOptions,user_catalog_table)},
1917+
offsetof(HeapRdOptions,common)+
1918+
offsetof(CommonRdOptions,user_catalog_table)},
18781919
{"parallel_workers",RELOPT_TYPE_INT,
1879-
offsetof(StdRdOptions,parallel_workers)},
1920+
offsetof(HeapRdOptions,common)+
1921+
offsetof(CommonRdOptions,parallel_workers)},
18801922
{"vacuum_index_cleanup",RELOPT_TYPE_ENUM,
1881-
offsetof(StdRdOptions,vacuum_index_cleanup)},
1923+
offsetof(HeapRdOptions,common)+
1924+
offsetof(CommonRdOptions,vacuum_index_cleanup)},
18821925
{"vacuum_truncate",RELOPT_TYPE_BOOL,
1883-
offsetof(StdRdOptions,vacuum_truncate)}
1926+
offsetof(HeapRdOptions,common)+
1927+
offsetof(CommonRdOptions,vacuum_truncate)}
18841928
};
18851929

18861930
return (bytea*)build_reloptions(reloptions,validate,kind,
1887-
sizeof(StdRdOptions),
1931+
sizeof(HeapRdOptions),
18881932
tab,lengthof(tab));
18891933
}
18901934

@@ -2016,26 +2060,33 @@ view_reloptions(Datum reloptions, bool validate)
20162060
* Parse options for heaps, views and toast tables.
20172061
*/
20182062
bytea*
2019-
heap_reloptions(charrelkind,Datumreloptions,boolvalidate)
2063+
heap_reloptions(charrelkind,Datumreloptions,
2064+
CommonRdOptions*common,boolvalidate)
20202065
{
2021-
StdRdOptions*rdopts;
2066+
HeapRdOptions*rdopts;
20222067

20232068
switch (relkind)
20242069
{
20252070
caseRELKIND_TOASTVALUE:
2026-
rdopts= (StdRdOptions*)
2071+
rdopts= (HeapRdOptions*)
20272072
default_reloptions(reloptions,validate,RELOPT_KIND_TOAST);
20282073
if (rdopts!=NULL)
20292074
{
20302075
/* adjust default-only parameters for TOAST relations */
20312076
rdopts->fillfactor=100;
2032-
rdopts->autovacuum.analyze_threshold=-1;
2033-
rdopts->autovacuum.analyze_scale_factor=-1;
2077+
rdopts->common.autovacuum.analyze_threshold=-1;
2078+
rdopts->common.autovacuum.analyze_scale_factor=-1;
20342079
}
2080+
if (rdopts!=NULL&&common!=NULL)
2081+
*common=rdopts->common;
20352082
return (bytea*)rdopts;
20362083
caseRELKIND_RELATION:
20372084
caseRELKIND_MATVIEW:
2038-
returndefault_reloptions(reloptions,validate,RELOPT_KIND_HEAP);
2085+
rdopts= (HeapRdOptions*)
2086+
default_reloptions(reloptions,validate,RELOPT_KIND_HEAP);
2087+
if (rdopts!=NULL&&common!=NULL)
2088+
*common=rdopts->common;
2089+
return (bytea*)rdopts;
20392090
default:
20402091
/* other relkinds are not supported */
20412092
returnNULL;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,8 +2279,8 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
22792279
Assert(!(options&HEAP_INSERT_NO_LOGICAL));
22802280

22812281
needwal=RelationNeedsWAL(relation);
2282-
saveFreeSpace=RelationGetTargetPageFreeSpace(relation,
2283-
HEAP_DEFAULT_FILLFACTOR);
2282+
saveFreeSpace=HeapGetTargetPageFreeSpace(relation,
2283+
HEAP_DEFAULT_FILLFACTOR);
22842284

22852285
/* Toast and set header data in all the slots */
22862286
heaptuples=palloc(ntuples*sizeof(HeapTuple));

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

Lines changed: 13 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"
@@ -2161,6 +2162,17 @@ heapam_relation_toast_am(Relation rel)
21612162
returnrel->rd_rel->relam;
21622163
}
21632164

2165+
staticbytea*
2166+
heapam_reloptions(charrelkind,Datumreloptions,
2167+
CommonRdOptions*common,boolvalidate)
2168+
{
2169+
Assert(relkind==RELKIND_RELATION||
2170+
relkind==RELKIND_TOASTVALUE||
2171+
relkind==RELKIND_MATVIEW);
2172+
2173+
returnheap_reloptions(relkind,reloptions,common,validate);
2174+
}
2175+
21642176

21652177
/* ------------------------------------------------------------------------
21662178
* Planner related callbacks for the heap AM
@@ -2710,6 +2722,7 @@ static const TableAmRoutine heapam_methods = {
27102722
.relation_needs_toast_table=heapam_relation_needs_toast_table,
27112723
.relation_toast_am=heapam_relation_toast_am,
27122724
.relation_fetch_toast_slice=heap_fetch_toast_slice,
2725+
.reloptions=heapam_reloptions,
27132726

27142727
.relation_estimate_size=heapam_estimate_rel_size,
27152728

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
#include"access/toast_internals.h"
3333
#include"utils/fmgroids.h"
3434

35+
/*
36+
* HeapGetToastTupleTarget
37+
* Returns the heap relation's toast_tuple_target. Note multiple eval of argument!
38+
*/
39+
#defineHeapGetToastTupleTarget(relation,defaulttarg) \
40+
((HeapRdOptions *) (relation)->rd_options ? \
41+
((HeapRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
3542

3643
/* ----------
3744
* heap_toast_delete -
@@ -174,7 +181,7 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
174181
hoff+=BITMAPLEN(numAttrs);
175182
hoff=MAXALIGN(hoff);
176183
/* now convert to a limit on the tuple data size */
177-
maxDataLen=RelationGetToastTupleTarget(rel,TOAST_TUPLE_TARGET)-hoff;
184+
maxDataLen=HeapGetToastTupleTarget(rel,TOAST_TUPLE_TARGET)-hoff;
178185

179186
/*
180187
* Look for attributes with attstorage EXTENDED to compress. Also find

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,8 +536,8 @@ RelationGetBufferForTuple(Relation relation, Size len,
536536
len,MaxHeapTupleSize)));
537537

538538
/* Compute desired extra freespace due to fillfactor option */
539-
saveFreeSpace=RelationGetTargetPageFreeSpace(relation,
540-
HEAP_DEFAULT_FILLFACTOR);
539+
saveFreeSpace=HeapGetTargetPageFreeSpace(relation,
540+
HEAP_DEFAULT_FILLFACTOR);
541541

542542
/*
543543
* Since pages without tuples can still have line pointers, we consider

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
235235
* important than sometimes getting a wrong answer in what is after all
236236
* just a heuristic estimate.
237237
*/
238-
minfree=RelationGetTargetPageFreeSpace(relation,
239-
HEAP_DEFAULT_FILLFACTOR);
238+
minfree=HeapGetTargetPageFreeSpace(relation,
239+
HEAP_DEFAULT_FILLFACTOR);
240240
minfree=Max(minfree,BLCKSZ /10);
241241

242242
if (PageIsFull(page)||PageGetHeapFreeSpace(page)<minfree)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,8 +641,8 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
641641
len,MaxHeapTupleSize)));
642642

643643
/* Compute desired extra freespace due to fillfactor option */
644-
saveFreeSpace=RelationGetTargetPageFreeSpace(state->rs_new_rel,
645-
HEAP_DEFAULT_FILLFACTOR);
644+
saveFreeSpace=HeapGetTargetPageFreeSpace(state->rs_new_rel,
645+
HEAP_DEFAULT_FILLFACTOR);
646646

647647
/* Now we can check to see if there's enough free space already. */
648648
page= (Page)state->rs_buffer;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ table_block_relation_estimate_size(Relation rel, int32 *attr_widths,
750750
* The other branch considers it implicitly by calculating density
751751
* from actual relpages/reltuples statistics.
752752
*/
753-
fillfactor=RelationGetFillFactor(rel,HEAP_DEFAULT_FILLFACTOR);
753+
fillfactor=HeapGetFillFactor(rel,HEAP_DEFAULT_FILLFACTOR);
754754

755755
tuple_width=get_rel_data_width(rel,attr_widths);
756756
tuple_width+=overhead_bytes_per_tuple;

‎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/createas.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ create_ctas_internal(List *attrList, IntoClause *into)
8585
Datumtoast_options;
8686
staticchar*validnsps[]=HEAP_RELOPT_NAMESPACES;
8787
ObjectAddressintoRelationAddr;
88+
constTableAmRoutine*tableam=NULL;
89+
OidaccessMethodId=InvalidOid;
90+
Relationrel;
8891

8992
/* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */
9093
is_matview= (into->viewQuery!=NULL);
@@ -125,7 +128,15 @@ create_ctas_internal(List *attrList, IntoClause *into)
125128
validnsps,
126129
true, false);
127130

128-
(void)heap_reloptions(RELKIND_TOASTVALUE,toast_options, true);
131+
rel=relation_open(intoRelationAddr.objectId,AccessShareLock);
132+
accessMethodId=table_relation_toast_am(rel);
133+
relation_close(rel,AccessShareLock);
134+
135+
if (OidIsValid(accessMethodId))
136+
{
137+
tableam=GetTableAmRoutineByAmOid(accessMethodId);
138+
(void)tableam_reloptions(tableam,RELKIND_TOASTVALUE,toast_options,NULL, true);
139+
}
129140

130141
NewRelationCreateToastTable(intoRelationAddr.objectId,toast_options);
131142

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp