From 5213ea4cc1fdf2884ba2fc83a2ad5596f4b35884 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Fri, 5 May 2023 09:13:22 +0800 Subject: [PATCH 1/4] Add reloption support for table --- src/backend/access/aocs/aocsam_handler.c | 5 +- .../access/appendonly/appendonlyam_handler.c | 5 +- src/backend/access/bitmap/bitmap.c | 2 +- src/backend/access/brin/brin.c | 2 +- src/backend/access/common/reloptions.c | 64 ++++++++++--------- src/backend/access/common/reloptions_gp.c | 27 ++++++++ src/backend/access/gin/ginutil.c | 2 +- src/backend/access/gist/gistutil.c | 2 +- src/backend/access/hash/hashutil.c | 2 +- src/backend/access/heap/heapam_handler.c | 36 ++++++++++- src/backend/access/nbtree/nbtutils.c | 2 +- src/backend/access/spgist/spgutils.c | 2 +- src/backend/access/table/tableamapi.c | 33 ++++++++++ src/backend/catalog/toasting.c | 6 ++ src/backend/commands/createas.c | 2 - src/backend/commands/indexcmds.c | 2 +- src/backend/commands/tablecmds.c | 17 ++--- src/backend/postmaster/autovacuum.c | 14 +++- src/backend/tcop/utility.c | 3 - src/backend/utils/cache/relcache.c | 11 ++-- src/include/access/amapi.h | 1 + src/include/access/bitmap_private.h | 2 +- src/include/access/brin_internal.h | 2 +- src/include/access/gin_private.h | 2 +- src/include/access/gist_private.h | 2 +- src/include/access/hash.h | 2 +- src/include/access/nbtree.h | 2 +- src/include/access/reloptions.h | 10 ++- src/include/access/spgist.h | 2 +- src/include/access/tableam.h | 6 ++ 30 files changed, 200 insertions(+), 70 deletions(-) diff --git a/src/backend/access/aocs/aocsam_handler.c b/src/backend/access/aocs/aocsam_handler.c index 50a77a03704..7fe9c7f287c 100644 --- a/src/backend/access/aocs/aocsam_handler.c +++ b/src/backend/access/aocs/aocsam_handler.c @@ -19,6 +19,7 @@ #include "access/appendonlywriter.h" #include "access/heapam.h" #include "access/multixact.h" +#include "access/reloptions.h" #include "access/tableam.h" #include "access/tsmapi.h" #include "access/xact.h" @@ -2254,7 +2255,9 @@ static TableAmRoutine ao_column_methods = { .scan_bitmap_next_block = aoco_scan_bitmap_next_block, .scan_bitmap_next_tuple = aoco_scan_bitmap_next_tuple, .scan_sample_next_block = aoco_scan_sample_next_block, - .scan_sample_next_tuple = aoco_scan_sample_next_tuple + .scan_sample_next_tuple = aoco_scan_sample_next_tuple, + + .amoptions = ao_amoptions, }; Datum diff --git a/src/backend/access/appendonly/appendonlyam_handler.c b/src/backend/access/appendonly/appendonlyam_handler.c index 1916c452283..78cbf6cc436 100644 --- a/src/backend/access/appendonly/appendonlyam_handler.c +++ b/src/backend/access/appendonly/appendonlyam_handler.c @@ -22,6 +22,7 @@ #include "access/heapam.h" #include "access/heaptoast.h" #include "access/multixact.h" +#include "access/reloptions.h" #include "access/tableam.h" #include "access/tsmapi.h" #include "access/xact.h" @@ -2381,7 +2382,9 @@ static const TableAmRoutine ao_row_methods = { .scan_bitmap_next_block = appendonly_scan_bitmap_next_block, .scan_bitmap_next_tuple = appendonly_scan_bitmap_next_tuple, .scan_sample_next_block = appendonly_scan_sample_next_block, - .scan_sample_next_tuple = appendonly_scan_sample_next_tuple + .scan_sample_next_tuple = appendonly_scan_sample_next_tuple, + + .amoptions = ao_amoptions, }; Datum diff --git a/src/backend/access/bitmap/bitmap.c b/src/backend/access/bitmap/bitmap.c index 30d0dd49fa7..970193b2d6e 100644 --- a/src/backend/access/bitmap/bitmap.c +++ b/src/backend/access/bitmap/bitmap.c @@ -1097,7 +1097,7 @@ GetBitmapIndexAuxOids(Relation index, Oid *heapId, Oid *indexId) } bytea * -bmoptions(Datum reloptions, bool validate) +bmoptions(Datum reloptions, char relkind, bool validate) { return default_reloptions(reloptions, validate, RELOPT_KIND_BITMAP); } diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index df5ceacc90f..ca0909871ac 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -1099,7 +1099,7 @@ brinvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) * reloptions processor for BRIN indexes */ bytea * -brinoptions(Datum reloptions, bool validate) +brinoptions(Datum reloptions, char relkind, bool validate) { static const relopt_parse_elt tab[] = { {"pages_per_range", RELOPT_TYPE_INT, offsetof(BrinOptions, pagesPerRange)}, diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index f928fb6e058..79d987b5f25 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -1403,7 +1403,7 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, case RELKIND_RELATION: case RELKIND_TOASTVALUE: case RELKIND_MATVIEW: - options = heap_reloptions(classForm->relkind, datum, false); + options = table_reloptions(amoptions, datum, classForm->relkind, false); break; case RELKIND_PARTITIONED_TABLE: options = partitioned_table_reloptions(datum, false); @@ -1413,7 +1413,7 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, break; case RELKIND_INDEX: case RELKIND_PARTITIONED_INDEX: - options = index_reloptions(amoptions, datum, false); + options = index_reloptions(amoptions, datum, classForm->relkind, false); break; case RELKIND_FOREIGN_TABLE: options = NULL; @@ -2024,39 +2024,41 @@ view_reloptions(Datum reloptions, bool validate) tab, lengthof(tab)); } -/* - * Parse options for heaps, views and toast tables. - */ bytea * -heap_reloptions(char relkind, Datum reloptions, bool validate) +table_reloptions(amoptions_function amoptions, Datum reloptions, char relkind, bool validate) +{ + Assert(relkind == RELKIND_RELATION || + relkind == RELKIND_TOASTVALUE || + relkind == RELKIND_MATVIEW); + if (amoptions == NULL) + { + if (PointerIsValid(DatumGetPointer(reloptions))) + elog(ERROR, "table access method doesn't supported reloptions"); + return NULL; + } + return amoptions(reloptions, relkind, validate); +} + +bytea * +table_reloptions_am(Oid accessMethodId, Datum reloptions, char relkind, bool validate) { - StdRdOptions *rdopts; + const TableAmRoutine *tam; + + Assert(relkind == RELKIND_RELATION || + relkind == RELKIND_TOASTVALUE || + relkind == RELKIND_MATVIEW); - switch (relkind) + switch(accessMethodId) { - case RELKIND_TOASTVALUE: - rdopts = (StdRdOptions *) - default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); - if (rdopts != NULL) - { - /* adjust default-only parameters for TOAST relations */ - rdopts->fillfactor = 100; - rdopts->autovacuum.analyze_threshold = -1; - rdopts->autovacuum.analyze_scale_factor = -1; - } - return (bytea *) rdopts; - case RELKIND_RELATION: - case RELKIND_MATVIEW: - /* - * GPDB_12_AFTER_MERGE_FIXME: should we accept AO-related options for - * partitioned tables? A partitioned table has no data, but the options - * might be inherited by partitions. - */ - return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); + /* built-in table access method put here to fetch TAM fast */ + case HEAP_TABLE_AM_OID: + tam = GetHeapamTableAmRoutine(); + break; default: - /* other relkinds are not supported */ - return NULL; + tam = GetTableAmRoutineByAmId(accessMethodId); + break; } + return table_reloptions(tam->amoptions, reloptions, relkind, validate); } /* @@ -2067,7 +2069,7 @@ heap_reloptions(char relkind, Datum reloptions, bool validate) * validate error flag */ bytea * -index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate) +index_reloptions(amoptions_function amoptions, Datum reloptions, char relkind, bool validate) { Assert(amoptions != NULL); @@ -2075,7 +2077,7 @@ index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate) if (!PointerIsValid(DatumGetPointer(reloptions))) return NULL; - return amoptions(reloptions, validate); + return amoptions(reloptions, relkind, validate); } /* diff --git a/src/backend/access/common/reloptions_gp.c b/src/backend/access/common/reloptions_gp.c index d505b0986a3..6a6fad59226 100644 --- a/src/backend/access/common/reloptions_gp.c +++ b/src/backend/access/common/reloptions_gp.c @@ -1697,3 +1697,30 @@ List* transformColumnEncoding(Relation rel, List *colDefs, List *stenc, List *wi return result; } + +bytea * +ao_amoptions(Datum reloptions, char relkind, bool validate) +{ + StdRdOptions *rdopts; + + switch (relkind) + { + case RELKIND_TOASTVALUE: + rdopts = (StdRdOptions *) + default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); + if (rdopts != NULL) + { + /* adjust default-only parameters for TOAST relations */ + rdopts->fillfactor = 100; + rdopts->autovacuum.analyze_threshold = -1; + rdopts->autovacuum.analyze_scale_factor = -1; + } + return (bytea *) rdopts; + case RELKIND_RELATION: + case RELKIND_MATVIEW: + return default_reloptions(reloptions, validate, RELOPT_KIND_APPENDOPTIMIZED); + default: + Assert(false); + return NULL; + } +} diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index cdd626ff0a4..d8101429ad4 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -605,7 +605,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum, } bytea * -ginoptions(Datum reloptions, bool validate) +ginoptions(Datum reloptions, char relkind, bool validate) { static const relopt_parse_elt tab[] = { {"fastupdate", RELOPT_TYPE_BOOL, offsetof(GinOptions, useFastUpdate)}, diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index 43ba03b6eb9..4f245c18107 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -917,7 +917,7 @@ gistPageRecyclable(Page page) } bytea * -gistoptions(Datum reloptions, bool validate) +gistoptions(Datum reloptions, char relkind, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(GiSTOptions, fillfactor)}, diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c index 519872850e0..f34222c1e47 100644 --- a/src/backend/access/hash/hashutil.c +++ b/src/backend/access/hash/hashutil.c @@ -273,7 +273,7 @@ _hash_checkpage(Relation rel, Buffer buf, int flags) } bytea * -hashoptions(Datum reloptions, bool validate) +hashoptions(Datum reloptions, char relkind, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(HashOptions, fillfactor)}, diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 48c19366a5f..064e7dc03db 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -23,6 +23,7 @@ #include "access/heapam.h" #include "access/heaptoast.h" #include "access/multixact.h" +#include "access/reloptions.h" #include "access/rewriteheap.h" #include "access/syncscan.h" #include "access/tableam.h" @@ -2548,6 +2549,36 @@ SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer, } } +/* + * Parse options for heaps, views and toast tables. + */ +static bytea * +heapam_amoptions(Datum reloptions, char relkind, bool validate) +{ + StdRdOptions *rdopts; + + switch (relkind) + { + case RELKIND_TOASTVALUE: + rdopts = (StdRdOptions *) + default_reloptions(reloptions, validate, RELOPT_KIND_TOAST); + if (rdopts != NULL) + { + /* adjust default-only parameters for TOAST relations */ + rdopts->fillfactor = 100; + rdopts->autovacuum.analyze_threshold = -1; + rdopts->autovacuum.analyze_scale_factor = -1; + } + return (bytea *) rdopts; + case RELKIND_RELATION: + case RELKIND_MATVIEW: + return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); + default: + Assert(false); + return NULL; + } +} + /* ------------------------------------------------------------------------ * Definition of the heap table access method. @@ -2610,7 +2641,10 @@ static const TableAmRoutine heapam_methods = { .scan_bitmap_next_block = heapam_scan_bitmap_next_block, .scan_bitmap_next_tuple = heapam_scan_bitmap_next_tuple, .scan_sample_next_block = heapam_scan_sample_next_block, - .scan_sample_next_tuple = heapam_scan_sample_next_tuple + .scan_sample_next_tuple = heapam_scan_sample_next_tuple, + + .amoptions = heapam_amoptions, + }; diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 733a97a76df..b057f98a6c3 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2101,7 +2101,7 @@ BTreeShmemInit(void) } bytea * -btoptions(Datum reloptions, bool validate) +btoptions(Datum reloptions, char relkind, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(BTOptions, fillfactor)}, diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index e3e663a006e..cc448980f3a 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -735,7 +735,7 @@ SpGistInitMetapage(Page page) * reloptions processing for SPGiST */ bytea * -spgoptions(Datum reloptions, bool validate) +spgoptions(Datum reloptions, char relkind, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(SpGistOptions, fillfactor)}, diff --git a/src/backend/access/table/tableamapi.c b/src/backend/access/table/tableamapi.c index 325ecdc1229..7a87987fd07 100644 --- a/src/backend/access/table/tableamapi.c +++ b/src/backend/access/table/tableamapi.c @@ -106,6 +106,39 @@ GetTableAmRoutine(Oid amhandler) return routine; } +/* + * GetTableAmRoutineByAmId - look up the handler of the table access method + * with the given OID, and get its TableAmRoutine struct. + * + * If the given OID isn't a valid index access method, throws error. + */ +const TableAmRoutine * +GetTableAmRoutineByAmId(Oid amoid) +{ + HeapTuple tuple; + Form_pg_am amform; + regproc amhandler; + + if (amoid == HEAP_TABLE_AM_OID) + return GetHeapamTableAmRoutine(); + + tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(amoid)); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, (errmsg("cache lookup failed for access method %u", amoid))); + + amform = (Form_pg_am) GETSTRUCT(tuple); + if (amform->amtype != AMTYPE_TABLE) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("access method \"%s\" is not of type TABLE", + NameStr(amform->amname)))); + + amhandler = amform->amhandler; + ReleaseSysCache(tuple); + + return GetTableAmRoutine(amhandler); +} + /* check_hook: validate new default_table_access_method */ bool check_default_table_access_method(char **newval, void **extra, GucSource source) diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index dc96d606869..b3ce905db7b 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -15,6 +15,7 @@ #include "postgres.h" #include "access/heapam.h" +#include "access/reloptions.h" #include "access/toast_compression.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" @@ -152,6 +153,11 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, ObjectAddress baseobject, toastobject; + Assert(rel->rd_tableam || rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); + if (rel->rd_tableam && table_relation_needs_toast_table(rel)) + (void) table_reloptions_am(table_relation_toast_am(rel), reloptions, + RELKIND_TOASTVALUE, true); + /* * Is it already toasted? */ diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index aa4c7f53155..a91e85e8dbf 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -216,8 +216,6 @@ create_ctas_internal(List *attrList, IntoClause *into, QueryDesc *queryDesc, boo validnsps, true, false); - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); /* Create the "view" part of a materialized view. */ diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index a6db5e14fd9..325066eeb32 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1131,7 +1131,7 @@ DefineIndex(Oid relationId, reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, false, false); - (void) index_reloptions(amoptions, reloptions, true); + (void) index_reloptions(amoptions, reloptions, RELKIND_INDEX, true); /* * Prepare arguments for index_create, primarily an IndexInfo structure. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 29d3304c575..fa2616d4713 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -825,7 +825,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, amHandlerOid = get_table_am_handler_oid(accessMethod, false); } - /* * Parse and validate reloptions, if any. */ @@ -871,8 +870,13 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, case RELKIND_PARTITIONED_TABLE: (void) partitioned_table_reloptions(reloptions, true); break; + case RELKIND_RELATION: + case RELKIND_MATVIEW: + case RELKIND_TOASTVALUE: + (void) table_reloptions_am(accessMethodId, reloptions, relkind, true); + break; default: - (void) heap_reloptions(relkind, reloptions, true); + break; } if (stmt->ofTypename) @@ -15683,10 +15687,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, case RELKIND_AOSEGMENTS: case RELKIND_AOBLOCKDIR: case RELKIND_AOVISIMAP: - if (RelationIsAppendOptimized(rel)) - (void) default_reloptions(newOptions, true, RELOPT_KIND_APPENDOPTIMIZED); - else - (void) heap_reloptions(rel->rd_rel->relkind, newOptions, true); + (void) table_reloptions(rel->rd_tableam->amoptions, newOptions, rel->rd_rel->relkind, true); break; case RELKIND_PARTITIONED_TABLE: (void) partitioned_table_reloptions(newOptions, true); @@ -15696,7 +15697,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, break; case RELKIND_INDEX: case RELKIND_PARTITIONED_INDEX: - (void) index_reloptions(rel->rd_indam->amoptions, newOptions, true); + (void) index_reloptions(rel->rd_indam->amoptions, newOptions, rel->rd_rel->relkind, true); break; default: ereport(ERROR, @@ -15798,7 +15799,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, defList, "toast", validnsps, false, operation == AT_ResetRelOptions); - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); + (void) table_reloptions(toastrel->rd_tableam->amoptions, newOptions, RELKIND_TOASTVALUE, true); memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index d33b5e2e6a5..e788b4e9c5a 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2853,16 +2853,26 @@ extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc) { bytea *relopts; AutoVacOpts *av; + Oid relam; + const TableAmRoutine *tam; Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION || ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW || ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE || ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOSEGMENTS || ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOBLOCKDIR || - ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOVISIMAP); + ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOVISIMAP); + relam = ((Form_pg_class) GETSTRUCT(tup))->relam; + tam = GetTableAmRoutineByAmId(relam); - relopts = extractRelOptions(tup, pg_class_desc, NULL); + /* FIXME: external TAM may have reloption other than StdRdOptions. */ + if (relam != HEAP_TABLE_AM_OID && + relam != AO_ROW_TABLE_AM_OID && + relam != AO_COLUMN_TABLE_AM_OID) + return NULL; + + relopts = extractRelOptions(tup, pg_class_desc, tam->amoptions); if (relopts == NULL) return NULL; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index f8b5b15dc31..49d0dbce11b 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1489,9 +1489,6 @@ ProcessUtilitySlow(ParseState *pstate, validnsps, true, false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); NewRelationCreateToastTable(address.objectId, toast_options); diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 1faad8729cb..c79cb2571a4 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -492,11 +492,10 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple) { case RELKIND_RELATION: case RELKIND_TOASTVALUE: - case RELKIND_AOSEGMENTS: - case RELKIND_AOBLOCKDIR: - case RELKIND_AOVISIMAP: - case RELKIND_VIEW: case RELKIND_MATVIEW: + amoptsfn = relation->rd_tableam->amoptions; + break; + case RELKIND_VIEW: case RELKIND_PARTITIONED_TABLE: amoptsfn = NULL; break; @@ -504,6 +503,10 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple) case RELKIND_PARTITIONED_INDEX: amoptsfn = relation->rd_indam->amoptions; break; + /* Can AO aux tables have reloptions? */ + case RELKIND_AOSEGMENTS: + case RELKIND_AOBLOCKDIR: + case RELKIND_AOVISIMAP: default: return; } diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index a30f4bb6a63..5d95ce6ea22 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -140,6 +140,7 @@ typedef void (*amcostestimate_function) (struct PlannerInfo *root, /* parse index reloptions */ typedef bytea *(*amoptions_function) (Datum reloptions, + char relkind, bool validate); /* report AM, index, or index column property */ diff --git a/src/include/access/bitmap_private.h b/src/include/access/bitmap_private.h index cb7c1178d0b..9390112777f 100644 --- a/src/include/access/bitmap_private.h +++ b/src/include/access/bitmap_private.h @@ -269,7 +269,7 @@ extern IndexBulkDeleteResult *bmbulkdelete(IndexVacuumInfo *info, extern IndexBulkDeleteResult *bmvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); extern bool bmcanreturn(Relation index, int attno); -extern bytea *bmoptions(Datum reloptions, bool validate); +extern bytea *bmoptions(Datum reloptions, char relkind, bool validate); extern bool bmvalidate(Oid opclassoid); extern void GetBitmapIndexAuxOids(Relation index, Oid *heapId, Oid *indexId); diff --git a/src/include/access/brin_internal.h b/src/include/access/brin_internal.h index 03274589873..796f1f367c0 100644 --- a/src/include/access/brin_internal.h +++ b/src/include/access/brin_internal.h @@ -107,7 +107,7 @@ extern IndexBulkDeleteResult *brinbulkdelete(IndexVacuumInfo *info, void *callback_state); extern IndexBulkDeleteResult *brinvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); -extern bytea *brinoptions(Datum reloptions, bool validate); +extern bytea *brinoptions(Datum reloptions, char relkind, bool validate); /* brin_validate.c */ extern bool brinvalidate(Oid opclassoid); diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 74c9b70dc32..9d423762a6d 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -89,7 +89,7 @@ typedef struct GinState /* ginutil.c */ -extern bytea *ginoptions(Datum reloptions, bool validate); +extern bytea *ginoptions(Datum reloptions, char relkind, bool validate); extern void initGinState(GinState *state, Relation index); extern Buffer GinNewBuffer(Relation index); extern void GinInitBuffer(Buffer b, uint32 f); diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 4b441b2adf1..afba817ee61 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -484,7 +484,7 @@ extern void gistadjustmembers(Oid opfamilyoid, #define GIST_MIN_FILLFACTOR 10 #define GIST_DEFAULT_FILLFACTOR 90 -extern bytea *gistoptions(Datum reloptions, bool validate); +extern bytea *gistoptions(Datum reloptions, char relkind, bool validate); extern bool gistproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull); diff --git a/src/include/access/hash.h b/src/include/access/hash.h index f29cd3db35e..0ee0cbe814b 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -378,7 +378,7 @@ extern IndexBulkDeleteResult *hashbulkdelete(IndexVacuumInfo *info, void *callback_state); extern IndexBulkDeleteResult *hashvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); -extern bytea *hashoptions(Datum reloptions, bool validate); +extern bytea *hashoptions(Datum reloptions, char relkind, bool validate); extern bool hashvalidate(Oid opclassoid); extern void hashadjustmembers(Oid opfamilyoid, Oid opclassoid, diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 816a0fe761d..231ff593767 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1252,7 +1252,7 @@ extern void _bt_end_vacuum(Relation rel); extern void _bt_end_vacuum_callback(int code, Datum arg); extern Size BTreeShmemSize(void); extern void BTreeShmemInit(void); -extern bytea *btoptions(Datum reloptions, bool validate); +extern bytea *btoptions(Datum reloptions, char relkind, bool validate); extern bool btproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull); diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index 7e202a27117..fd24fb6945d 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -259,17 +259,23 @@ extern void *build_local_reloptions(local_relopts *relopts, Datum options, extern bytea *default_reloptions(Datum reloptions, bool validate, relopt_kind kind); -extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate); + +extern bytea *table_reloptions(amoptions_function amoptions, Datum reloptions, + char relkind, bool validate); +extern bytea *table_reloptions_am(Oid accessMethodId, Datum reloptions, + char relkind, bool validate); extern bytea *view_reloptions(Datum reloptions, bool validate); extern bytea *partitioned_table_reloptions(Datum reloptions, bool validate); extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions, - bool validate); + char relkind, bool validate); extern bytea *attribute_reloptions(Datum reloptions, bool validate); extern bytea *tablespace_reloptions(Datum reloptions, bool validate); extern LOCKMODE AlterTableGetRelOptionsLockLevel(List *defList); /* in reloptions_gp.c */ +extern bytea *ao_amoptions(Datum reloptions, char relkind, + bool validate); extern Datum transformAOStdRdOptions(StdRdOptions *opts, Datum withOpts); extern void validateAppendOnlyRelOptions(int blocksize, int writesize, diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h index 8e7c3cf0d5c..82794d7de05 100644 --- a/src/include/access/spgist.h +++ b/src/include/access/spgist.h @@ -190,7 +190,7 @@ typedef struct spgLeafConsistentOut /* spgutils.c */ -extern bytea *spgoptions(Datum reloptions, bool validate); +extern bytea *spgoptions(Datum reloptions, char relkind, bool validate); /* spginsert.c */ extern IndexBuildResult *spgbuild(Relation heap, Relation index, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index aabec3dc474..02edd0a17c8 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -883,6 +883,11 @@ typedef struct TableAmRoutine struct SampleScanState *scanstate, TupleTableSlot *slot); + /* + * This callback is used to parse reloptions for relation/matview/toast. + */ + bytea *(*amoptions)(Datum reloptions, char relkind, bool validate); + } TableAmRoutine; @@ -2189,6 +2194,7 @@ extern void table_block_relation_estimate_size(Relation rel, */ extern const TableAmRoutine *GetTableAmRoutine(Oid amhandler); +extern const TableAmRoutine *GetTableAmRoutineByAmId(Oid amoid); extern const TableAmRoutine *GetHeapamTableAmRoutine(void); extern bool check_default_table_access_method(char **newval, void **extra, GucSource source); From 9bc3c35fa2082503439796ef584aef16a3fcfc68 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Fri, 15 Dec 2023 17:39:20 +0800 Subject: [PATCH 2/4] restore index reloption --- src/backend/access/bitmap/bitmap.c | 2 +- src/backend/access/brin/brin.c | 2 +- src/backend/access/common/reloptions.c | 23 +++++++---------------- src/backend/access/gin/ginutil.c | 2 +- src/backend/access/gist/gistutil.c | 2 +- src/backend/access/hash/hashutil.c | 2 +- src/backend/access/nbtree/nbtutils.c | 2 +- src/backend/access/spgist/spgutils.c | 2 +- src/backend/commands/indexcmds.c | 2 +- src/backend/commands/tablecmds.c | 2 +- src/backend/postmaster/autovacuum.c | 1 + src/backend/utils/cache/relcache.c | 9 ++++----- src/include/access/amapi.h | 1 - src/include/access/bitmap_private.h | 2 +- src/include/access/brin_internal.h | 2 +- src/include/access/gin_private.h | 2 +- src/include/access/gist_private.h | 2 +- src/include/access/hash.h | 2 +- src/include/access/nbtree.h | 2 +- src/include/access/reloptions.h | 11 +++++++---- src/include/access/spgist.h | 2 +- src/include/access/tableam.h | 4 ++++ 22 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/backend/access/bitmap/bitmap.c b/src/backend/access/bitmap/bitmap.c index 970193b2d6e..30d0dd49fa7 100644 --- a/src/backend/access/bitmap/bitmap.c +++ b/src/backend/access/bitmap/bitmap.c @@ -1097,7 +1097,7 @@ GetBitmapIndexAuxOids(Relation index, Oid *heapId, Oid *indexId) } bytea * -bmoptions(Datum reloptions, char relkind, bool validate) +bmoptions(Datum reloptions, bool validate) { return default_reloptions(reloptions, validate, RELOPT_KIND_BITMAP); } diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index ca0909871ac..df5ceacc90f 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -1099,7 +1099,7 @@ brinvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) * reloptions processor for BRIN indexes */ bytea * -brinoptions(Datum reloptions, char relkind, bool validate) +brinoptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"pages_per_range", RELOPT_TYPE_INT, offsetof(BrinOptions, pagesPerRange)}, diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 79d987b5f25..0f3a1ed6bf4 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -1381,7 +1381,7 @@ untransformRelOptions(Datum options) */ bytea * extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, - amoptions_function amoptions) + reloption_function amoptions) { bytea *options; bool isnull; @@ -1403,7 +1403,7 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, case RELKIND_RELATION: case RELKIND_TOASTVALUE: case RELKIND_MATVIEW: - options = table_reloptions(amoptions, datum, classForm->relkind, false); + options = table_reloptions((tamoptions_function)amoptions, datum, classForm->relkind, false); break; case RELKIND_PARTITIONED_TABLE: options = partitioned_table_reloptions(datum, false); @@ -1413,7 +1413,7 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, break; case RELKIND_INDEX: case RELKIND_PARTITIONED_INDEX: - options = index_reloptions(amoptions, datum, classForm->relkind, false); + options = index_reloptions((amoptions_function)amoptions, datum, false); break; case RELKIND_FOREIGN_TABLE: options = NULL; @@ -2025,7 +2025,7 @@ view_reloptions(Datum reloptions, bool validate) } bytea * -table_reloptions(amoptions_function amoptions, Datum reloptions, char relkind, bool validate) +table_reloptions(tamoptions_function amoptions, Datum reloptions, char relkind, bool validate) { Assert(relkind == RELKIND_RELATION || relkind == RELKIND_TOASTVALUE || @@ -2048,16 +2048,7 @@ table_reloptions_am(Oid accessMethodId, Datum reloptions, char relkind, bool val relkind == RELKIND_TOASTVALUE || relkind == RELKIND_MATVIEW); - switch(accessMethodId) - { - /* built-in table access method put here to fetch TAM fast */ - case HEAP_TABLE_AM_OID: - tam = GetHeapamTableAmRoutine(); - break; - default: - tam = GetTableAmRoutineByAmId(accessMethodId); - break; - } + tam = GetTableAmRoutineByAmId(accessMethodId); return table_reloptions(tam->amoptions, reloptions, relkind, validate); } @@ -2069,7 +2060,7 @@ table_reloptions_am(Oid accessMethodId, Datum reloptions, char relkind, bool val * validate error flag */ bytea * -index_reloptions(amoptions_function amoptions, Datum reloptions, char relkind, bool validate) +index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate) { Assert(amoptions != NULL); @@ -2077,7 +2068,7 @@ index_reloptions(amoptions_function amoptions, Datum reloptions, char relkind, b if (!PointerIsValid(DatumGetPointer(reloptions))) return NULL; - return amoptions(reloptions, relkind, validate); + return amoptions(reloptions, validate); } /* diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index d8101429ad4..cdd626ff0a4 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -605,7 +605,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum, } bytea * -ginoptions(Datum reloptions, char relkind, bool validate) +ginoptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"fastupdate", RELOPT_TYPE_BOOL, offsetof(GinOptions, useFastUpdate)}, diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index 4f245c18107..43ba03b6eb9 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -917,7 +917,7 @@ gistPageRecyclable(Page page) } bytea * -gistoptions(Datum reloptions, char relkind, bool validate) +gistoptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(GiSTOptions, fillfactor)}, diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c index f34222c1e47..519872850e0 100644 --- a/src/backend/access/hash/hashutil.c +++ b/src/backend/access/hash/hashutil.c @@ -273,7 +273,7 @@ _hash_checkpage(Relation rel, Buffer buf, int flags) } bytea * -hashoptions(Datum reloptions, char relkind, bool validate) +hashoptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(HashOptions, fillfactor)}, diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index b057f98a6c3..733a97a76df 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2101,7 +2101,7 @@ BTreeShmemInit(void) } bytea * -btoptions(Datum reloptions, char relkind, bool validate) +btoptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(BTOptions, fillfactor)}, diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index cc448980f3a..e3e663a006e 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -735,7 +735,7 @@ SpGistInitMetapage(Page page) * reloptions processing for SPGiST */ bytea * -spgoptions(Datum reloptions, char relkind, bool validate) +spgoptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(SpGistOptions, fillfactor)}, diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 325066eeb32..a6db5e14fd9 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1131,7 +1131,7 @@ DefineIndex(Oid relationId, reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, NULL, false, false); - (void) index_reloptions(amoptions, reloptions, RELKIND_INDEX, true); + (void) index_reloptions(amoptions, reloptions, true); /* * Prepare arguments for index_create, primarily an IndexInfo structure. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index fa2616d4713..b7d8e666c62 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15697,7 +15697,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, break; case RELKIND_INDEX: case RELKIND_PARTITIONED_INDEX: - (void) index_reloptions(rel->rd_indam->amoptions, newOptions, rel->rd_rel->relkind, true); + (void) index_reloptions(rel->rd_indam->amoptions, newOptions, true); break; default: ereport(ERROR, diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index e788b4e9c5a..7a10cc913a5 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -122,6 +122,7 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/namespace.h" +#include "catalog/pg_am.h" #include "catalog/pg_database.h" #include "commands/dbcommands.h" #include "commands/vacuum.h" diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index c79cb2571a4..7ac042ab4fd 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -480,7 +480,7 @@ static void RelationParseRelOptions(Relation relation, HeapTuple tuple) { bytea *options; - amoptions_function amoptsfn; + reloption_function amoptsfn; relation->rd_options = NULL; @@ -493,6 +493,9 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple) case RELKIND_RELATION: case RELKIND_TOASTVALUE: case RELKIND_MATVIEW: + case RELKIND_AOSEGMENTS: + case RELKIND_AOBLOCKDIR: + case RELKIND_AOVISIMAP: amoptsfn = relation->rd_tableam->amoptions; break; case RELKIND_VIEW: @@ -503,10 +506,6 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple) case RELKIND_PARTITIONED_INDEX: amoptsfn = relation->rd_indam->amoptions; break; - /* Can AO aux tables have reloptions? */ - case RELKIND_AOSEGMENTS: - case RELKIND_AOBLOCKDIR: - case RELKIND_AOVISIMAP: default: return; } diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index 5d95ce6ea22..a30f4bb6a63 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -140,7 +140,6 @@ typedef void (*amcostestimate_function) (struct PlannerInfo *root, /* parse index reloptions */ typedef bytea *(*amoptions_function) (Datum reloptions, - char relkind, bool validate); /* report AM, index, or index column property */ diff --git a/src/include/access/bitmap_private.h b/src/include/access/bitmap_private.h index 9390112777f..cb7c1178d0b 100644 --- a/src/include/access/bitmap_private.h +++ b/src/include/access/bitmap_private.h @@ -269,7 +269,7 @@ extern IndexBulkDeleteResult *bmbulkdelete(IndexVacuumInfo *info, extern IndexBulkDeleteResult *bmvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); extern bool bmcanreturn(Relation index, int attno); -extern bytea *bmoptions(Datum reloptions, char relkind, bool validate); +extern bytea *bmoptions(Datum reloptions, bool validate); extern bool bmvalidate(Oid opclassoid); extern void GetBitmapIndexAuxOids(Relation index, Oid *heapId, Oid *indexId); diff --git a/src/include/access/brin_internal.h b/src/include/access/brin_internal.h index 796f1f367c0..03274589873 100644 --- a/src/include/access/brin_internal.h +++ b/src/include/access/brin_internal.h @@ -107,7 +107,7 @@ extern IndexBulkDeleteResult *brinbulkdelete(IndexVacuumInfo *info, void *callback_state); extern IndexBulkDeleteResult *brinvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); -extern bytea *brinoptions(Datum reloptions, char relkind, bool validate); +extern bytea *brinoptions(Datum reloptions, bool validate); /* brin_validate.c */ extern bool brinvalidate(Oid opclassoid); diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 9d423762a6d..74c9b70dc32 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -89,7 +89,7 @@ typedef struct GinState /* ginutil.c */ -extern bytea *ginoptions(Datum reloptions, char relkind, bool validate); +extern bytea *ginoptions(Datum reloptions, bool validate); extern void initGinState(GinState *state, Relation index); extern Buffer GinNewBuffer(Relation index); extern void GinInitBuffer(Buffer b, uint32 f); diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index afba817ee61..4b441b2adf1 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -484,7 +484,7 @@ extern void gistadjustmembers(Oid opfamilyoid, #define GIST_MIN_FILLFACTOR 10 #define GIST_DEFAULT_FILLFACTOR 90 -extern bytea *gistoptions(Datum reloptions, char relkind, bool validate); +extern bytea *gistoptions(Datum reloptions, bool validate); extern bool gistproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull); diff --git a/src/include/access/hash.h b/src/include/access/hash.h index 0ee0cbe814b..f29cd3db35e 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -378,7 +378,7 @@ extern IndexBulkDeleteResult *hashbulkdelete(IndexVacuumInfo *info, void *callback_state); extern IndexBulkDeleteResult *hashvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); -extern bytea *hashoptions(Datum reloptions, char relkind, bool validate); +extern bytea *hashoptions(Datum reloptions, bool validate); extern bool hashvalidate(Oid opclassoid); extern void hashadjustmembers(Oid opfamilyoid, Oid opclassoid, diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 231ff593767..816a0fe761d 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1252,7 +1252,7 @@ extern void _bt_end_vacuum(Relation rel); extern void _bt_end_vacuum_callback(int code, Datum arg); extern Size BTreeShmemSize(void); extern void BTreeShmemInit(void); -extern bytea *btoptions(Datum reloptions, char relkind, bool validate); +extern bytea *btoptions(Datum reloptions, bool validate); extern bool btproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull); diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index fd24fb6945d..cfdfba9e434 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -247,8 +247,11 @@ extern Datum transformRelOptions(Datum oldOptions, List *defList, const char *namspace, char *validnsps[], bool acceptOidsOff, bool isReset); extern List *untransformRelOptions(Datum options); + +/* reloption_function is either amoptions_function or tamoptions_function */ +typedef void *reloption_function; extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, - amoptions_function amoptions); + reloption_function amoptions); extern void *build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, @@ -260,14 +263,14 @@ extern void *build_local_reloptions(local_relopts *relopts, Datum options, extern bytea *default_reloptions(Datum reloptions, bool validate, relopt_kind kind); -extern bytea *table_reloptions(amoptions_function amoptions, Datum reloptions, - char relkind, bool validate); +extern bytea *table_reloptions(tamoptions_function amoptions, Datum reloptions, + char relkind, bool validate); extern bytea *table_reloptions_am(Oid accessMethodId, Datum reloptions, char relkind, bool validate); extern bytea *view_reloptions(Datum reloptions, bool validate); extern bytea *partitioned_table_reloptions(Datum reloptions, bool validate); extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions, - char relkind, bool validate); + bool validate); extern bytea *attribute_reloptions(Datum reloptions, bool validate); extern bytea *tablespace_reloptions(Datum reloptions, bool validate); extern LOCKMODE AlterTableGetRelOptionsLockLevel(List *defList); diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h index 82794d7de05..8e7c3cf0d5c 100644 --- a/src/include/access/spgist.h +++ b/src/include/access/spgist.h @@ -190,7 +190,7 @@ typedef struct spgLeafConsistentOut /* spgutils.c */ -extern bytea *spgoptions(Datum reloptions, char relkind, bool validate); +extern bytea *spgoptions(Datum reloptions, bool validate); /* spginsert.c */ extern IndexBuildResult *spgbuild(Relation heap, Relation index, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 02edd0a17c8..d4c8d6beb9c 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -261,6 +261,10 @@ typedef void (*IndexBuildCallback) (Relation index, */ struct PlanState; +typedef bytea *(*tamoptions_function)(Datum reloptions, + char relkind, + bool validate); + /* * API struct for a table AM. Note this must be allocated in a * server-lifetime manner, typically as a static const struct, which then gets From a420facd034ae2594d6aba83b2ad72a57bea5122 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Fri, 15 Dec 2023 20:55:25 +0800 Subject: [PATCH 3/4] fix answer --- src/test/regress/expected/reloptions.out | 5 ++++- src/test/regress/sql/reloptions.sql | 4 ++++ src/test/singlenode_regress/expected/reloptions.out | 5 ++++- src/test/singlenode_regress/sql/reloptions.sql | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index ceb569e280b..4776b0a4c14 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -168,9 +168,12 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid; (1 row) +-- CBDB: The following CREATE clause will success, which is different from upstream. +-- The toast reloption is ignored, because the table has no toast +-- table and the options are validated by the AM-spec routine. + -- Fail on non-existent options in toast namespace CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" -- Mix TOAST & heap DROP TABLE reloptions_test; CREATE TABLE reloptions_test (s VARCHAR) WITH diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 4252b0202f4..1766afebc99 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -91,6 +91,10 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid; ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); SELECT reloptions FROM pg_class WHERE oid = :toast_oid; +-- CBDB: The following CREATE clause will success, which is different from upstream. +-- The toast reloption is ignored, because the table has no toast +-- table and the options are validated by the AM-spec routine. + -- Fail on non-existent options in toast namespace CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); diff --git a/src/test/singlenode_regress/expected/reloptions.out b/src/test/singlenode_regress/expected/reloptions.out index ceb569e280b..4776b0a4c14 100644 --- a/src/test/singlenode_regress/expected/reloptions.out +++ b/src/test/singlenode_regress/expected/reloptions.out @@ -168,9 +168,12 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid; (1 row) +-- CBDB: The following CREATE clause will success, which is different from upstream. +-- The toast reloption is ignored, because the table has no toast +-- table and the options are validated by the AM-spec routine. + -- Fail on non-existent options in toast namespace CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -ERROR: unrecognized parameter "not_existing_option" -- Mix TOAST & heap DROP TABLE reloptions_test; CREATE TABLE reloptions_test (s VARCHAR) WITH diff --git a/src/test/singlenode_regress/sql/reloptions.sql b/src/test/singlenode_regress/sql/reloptions.sql index 4252b0202f4..1766afebc99 100644 --- a/src/test/singlenode_regress/sql/reloptions.sql +++ b/src/test/singlenode_regress/sql/reloptions.sql @@ -91,6 +91,10 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid; ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); SELECT reloptions FROM pg_class WHERE oid = :toast_oid; +-- CBDB: The following CREATE clause will success, which is different from upstream. +-- The toast reloption is ignored, because the table has no toast +-- table and the options are validated by the AM-spec routine. + -- Fail on non-existent options in toast namespace CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); From c62ed789eb39020eaee66b8f5a52f100f824a698 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Fri, 15 Dec 2023 21:38:52 +0800 Subject: [PATCH 4/4] fix anser --- src/test/regress/expected/reloptions.out | 1 - src/test/singlenode_regress/expected/reloptions.out | 1 - 2 files changed, 2 deletions(-) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 4776b0a4c14..10f2c5b90a0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -171,7 +171,6 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid; -- CBDB: The following CREATE clause will success, which is different from upstream. -- The toast reloption is ignored, because the table has no toast -- table and the options are validated by the AM-spec routine. - -- Fail on non-existent options in toast namespace CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -- Mix TOAST & heap diff --git a/src/test/singlenode_regress/expected/reloptions.out b/src/test/singlenode_regress/expected/reloptions.out index 4776b0a4c14..10f2c5b90a0 100644 --- a/src/test/singlenode_regress/expected/reloptions.out +++ b/src/test/singlenode_regress/expected/reloptions.out @@ -171,7 +171,6 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid; -- CBDB: The following CREATE clause will success, which is different from upstream. -- The toast reloption is ignored, because the table has no toast -- table and the options are validated by the AM-spec routine. - -- Fail on non-existent options in toast namespace CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); -- Mix TOAST & heap