Skip to content

Commit

Permalink
Save the acces method in pg_class for gp style partition table
Browse files Browse the repository at this point in the history
TODO: XXX

Inherit parent reloptions for child partitions of gp-style partition table

MESSAGE: XXX
  • Loading branch information
gfphoenix78 committed Nov 21, 2024
1 parent f92faf0 commit bdc7f6c
Show file tree
Hide file tree
Showing 25 changed files with 1,030 additions and 302 deletions.
18 changes: 13 additions & 5 deletions src/backend/access/common/reloptions_gp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1569,15 +1569,17 @@ find_crsd(const char *column, List *stenc)
* This needs access to possible inherited columns, so it can only be done after
* expanding them.
*/
List* transformColumnEncoding(const TableAmRoutine *tam, Relation rel, List *colDefs, List *stenc, List *withOptions, bool createDefaultOne)
List *
transformColumnEncoding(const TableAmRoutine *tam, Relation rel, List *colDefs,
List *stenc, List *withOptions, List *parentenc,
bool explicitOnly, bool createDefaultOne)
{
ColumnReferenceStorageDirective *deflt = NULL;
ListCell *lc;
List *result = NIL;
bool errorOnEncodingClause;

Assert(tam);
AssertImply(rel, rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE);
errorOnEncodingClause = !AMHandlerSupportEncodingClause(tam);

if (stenc) {
Expand Down Expand Up @@ -1664,7 +1666,8 @@ List* transformColumnEncoding(const TableAmRoutine *tam, Relation rel, List *col
* 1. An explicit encoding clause in the ColumnDef
* 2. A column reference storage directive for this column
* 3. A default column encoding in the statement
* 4. A default for the type.
* 4. Parent partition's column encoding values
* 5. A default for the type.
*/
if (d->encoding)
{
Expand All @@ -1684,9 +1687,14 @@ List* transformColumnEncoding(const TableAmRoutine *tam, Relation rel, List *col
} else {
if (deflt)
encoding = copyObject(deflt->encoding);
else
else if (!explicitOnly)
{
if (d->typeName) {
if (parentenc)
{
ColumnReferenceStorageDirective *parent_col_encoding = find_crsd(d->colname, parentenc);
encoding = transformStorageEncodingClause(parent_col_encoding->encoding, true);
}
else if (d->typeName) {
/* get encoding by type, still need do transform and validate */
encoding = get_type_encoding(d->typeName);
if (tam->transform_column_encoding_clauses)
Expand Down
102 changes: 94 additions & 8 deletions src/backend/commands/tablecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
List *old_constraints;
List *rawDefaults;
List *cookedDefaults;
List *parentenc = NIL;
Datum reloptions;
Datum oldoptions = (Datum) 0;
ListCell *listptr;
AttrNumber attnum;
bool partitioned;
Expand Down Expand Up @@ -834,14 +836,38 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
{
accessMethod = stmt->accessMethod;

if (partitioned)
/* Only to allow access method when the partition is gp style partition */
if (partitioned && Gp_role == GP_ROLE_DISPATCH && !stmt->partspec->gpPartDef)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("specifying a table access method is not supported on a partitioned table")));

}
else if (relkind == RELKIND_DIRECTORY_TABLE)
accessMethod = DEFAULT_TABLE_ACCESS_METHOD;
else if (stmt->partbound && (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE))
{
HeapTuple tup;
Oid relid;

/*
* For partitioned tables, when no access method is specified, we
* default to the parent table's AM.
*/
Assert(list_length(inheritOids) == 1);
relid = linitial_oid(inheritOids);
tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for relation %u", relid);

accessMethodId = ((Form_pg_class) GETSTRUCT(tup))->relam;
accessMethod = get_am_name(accessMethodId);

ReleaseSysCache(tup);

if (!OidIsValid(accessMethodId))
accessMethodId = get_table_am_oid(default_table_access_method, false);
}
else if (relkind == RELKIND_RELATION ||
relkind == RELKIND_TOASTVALUE ||
relkind == RELKIND_MATVIEW)
Expand All @@ -854,10 +880,38 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
amHandlerOid = get_table_am_handler_oid(accessMethod, false);
}

/*
* GPDB: for partitioned tables, inherit reloptions from the parent.
* Note this is applicable only if the parent has the same AM as the child.
*/
if (stmt->partbound && (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE))
{
Oid parentrelid;
Relation parentrel;

/*
* For partitioned children, when no reloptions is specified, we
* default to the parent table's reloptions. If partitioned
* children has different access method with parent. Do not do it.
*/
Assert(list_length(inheritOids) == 1);
parentrelid = linitial_oid(inheritOids);
parentrel = table_open(parentrelid, AccessShareLock);

if (parentrel->rd_rel->relam == accessMethodId)
{
oldoptions = get_rel_opts(parentrel);
if (accessMethodId == AO_COLUMN_TABLE_AM_OID)
parentenc = rel_get_column_encodings(parentrel);
}

table_close(parentrel, AccessShareLock);
}

/*
* Parse and validate reloptions, if any.
*/
reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
reloptions = transformRelOptions((Datum) oldoptions, stmt->options, NULL, validnsps,
true, false);

/*
Expand All @@ -867,7 +921,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
*/
if (AMHandlerIsAO(amHandlerOid))
{
Assert(relkind == RELKIND_MATVIEW || relkind == RELKIND_RELATION || relkind == RELKIND_DIRECTORY_TABLE);
Assert(relkind == RELKIND_MATVIEW || relkind == RELKIND_RELATION ||
relkind == RELKIND_PARTITIONED_TABLE || relkind == RELKIND_DIRECTORY_TABLE);

/*
* Extract and process any WITH options supplied, otherwise use defaults
Expand Down Expand Up @@ -897,7 +952,10 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
(void) view_reloptions(reloptions, true);
break;
case RELKIND_PARTITIONED_TABLE:
(void) partitioned_table_reloptions(reloptions, true);
if (OidIsValid(accessMethodId))
(void) table_reloptions_am(accessMethodId, reloptions, 'r', true);
else
(void) partitioned_table_reloptions(reloptions, true);
break;
case RELKIND_RELATION:
case RELKIND_MATVIEW:
Expand Down Expand Up @@ -1050,7 +1108,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
* This is done in dispatcher (and in utility mode). In QE, we receive
* the already-processed options from the QD.
*/
if ((relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW || relkind == RELKIND_DIRECTORY_TABLE) &&
if ((relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW ||
relkind == RELKIND_DIRECTORY_TABLE ||
(relkind == RELKIND_PARTITIONED_TABLE && OidIsValid(accessMethodId))) &&
Gp_role != GP_ROLE_EXECUTE)
{
const TableAmRoutine *tam = GetTableAmRoutineByAmId(accessMethodId);
Expand All @@ -1069,6 +1129,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
schema,
stmt->attr_encodings,
stmt->options,
parentenc,
relkind == RELKIND_PARTITIONED_TABLE,
AMHandlerIsAoCols(amHandlerOid) /* createDefaultOne*/);
if (!AMHandlerSupportEncodingClause(tam) && relkind != RELKIND_PARTITIONED_TABLE)
stmt->attr_encodings = NIL;
Expand All @@ -1084,6 +1146,11 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
* Also in this time, we can't get the access method from root partition.
* But for other access method which support encoding clause, still can't
* pass the encoding clause from root partition.
*
* The relam of partition table is 0 for pg partition tables in current(14.4)
* version. In higher postgres kernel, the partition table is allowed to set
* table access method. The partition table will have the same behaviors on
* relam, reloptions, attribute encodings in the future.
*/
stmt->attr_encodings = transfromColumnEncodingAocoRootPartition(schema,
stmt->attr_encodings,
Expand Down Expand Up @@ -1238,7 +1305,24 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
cooked_constraints = list_concat(cooked_constraints, newCookedDefaults);
}

if (stmt->attr_encodings && (relkind != RELKIND_PARTITIONED_TABLE))
if (relkind == RELKIND_PARTITIONED_TABLE && rel->rd_rel->relam == AO_COLUMN_TABLE_AM_OID)
{
const TableAmRoutine *tam = GetTableAmRoutineByAmId(rel->rd_rel->relam);
List *part_attr_encodings =
transformColumnEncoding(tam,
NULL /* Relation */,
schema,
stmt->attr_encodings,
stmt->options,
parentenc,
false,
accessMethodId != AO_COLUMN_TABLE_AM_OID
&& !stmt->partbound && !stmt->partspec
/* errorOnEncodingClause */);

AddRelationAttributeEncodings(rel, part_attr_encodings);
}
else if (stmt->attr_encodings && (relkind != RELKIND_PARTITIONED_TABLE))
AddRelationAttributeEncodings(rel, stmt->attr_encodings);

/*
Expand Down Expand Up @@ -8462,7 +8546,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
add_column_datatype_dependency(myrelid, newattnum, attribute.atttypid);
add_column_collation_dependency(myrelid, newattnum, attribute.attcollation);

if (OidIsValid(rel->rd_rel->relam))
if (OidIsValid(rel->rd_rel->relam) && rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
{
List *enc;
const TableAmRoutine *tam = GetTableAmRoutineByAmId(rel->rd_rel->relam);
Expand All @@ -8480,6 +8564,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
enc = transformColumnEncoding(tam /* TableAmRoutine */, rel, list_make1(colDef),
NULL /* COLUMN ENCODING clauses is only for CREATE TABLE */,
NULL /* withOptions */,
NULL /* parentenc */,
false /* explicitOnly */,
RelationIsAoCols(rel) /* createDefaultOne */);
/*
* Store the encoding clause for AO/CO tables.
Expand Down Expand Up @@ -17704,7 +17790,7 @@ build_ctas_with_dist(Relation rel, DistributedBy *dist_clause,
/*
* GPDB: Convenience function to get reloptions for a given relation.
*/
static Datum
Datum
get_rel_opts(Relation rel)
{
Datum newOptions = PointerGetDatum(NULL);
Expand Down
11 changes: 11 additions & 0 deletions src/backend/gpopt/gpdbwrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,17 @@ gpdb::GetRelationPartConstraints(Relation rel)
return nullptr;
}

PartitionKey
gpdb::GetRelationPartitionKey(Relation rel)
{
GP_WRAP_START;
{
return RelationGetPartitionKey(rel);
}
GP_WRAP_END;
return nullptr;
}

#if 0
bool
gpdb::HasExternalPartition
Expand Down
2 changes: 1 addition & 1 deletion src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2516,7 +2516,7 @@ CTranslatorRelcacheToDXL::RetrievePartKeysAndTypes(CMemoryPool *mp,
*part_keys = GPOS_NEW(mp) ULongPtrArray(mp);
*part_types = GPOS_NEW(mp) CharPtrArray(mp);

PartitionKeyData *partkey = rel->rd_partkey;
PartitionKeyData *partkey = gpdb::GetRelationPartitionKey(rel);

if (1 < partkey->partnatts)
{
Expand Down
9 changes: 4 additions & 5 deletions src/backend/tcop/utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -1468,8 +1468,6 @@ ProcessUtilitySlow(ParseState *pstate,
char relKind = RELKIND_RELATION;
Datum toast_options;
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
List *options = NIL;
char *accessmethod = NULL;

/*
* If this T_CreateStmt was dispatched and we're a QE
Expand All @@ -1484,6 +1482,7 @@ ProcessUtilitySlow(ParseState *pstate,
else
cstmt->relKind = relKind;

#if 0
/*
* Upstream postgres does not support user specified
* RelOptions and TableAM for a parent partitioned
Expand All @@ -1500,9 +1499,9 @@ ProcessUtilitySlow(ParseState *pstate,
{
options = cstmt->options;
cstmt->options = NIL;
accessmethod = cstmt->accessMethod;
cstmt->accessMethod = NULL;
}
#endif

/*
* GPDB: Don't dispatch it yet, as we haven't
Expand All @@ -1523,8 +1522,8 @@ ProcessUtilitySlow(ParseState *pstate,
parts = generatePartitions(address.objectId,
cstmt->partspec->gpPartDef,
cstmt->partspec->subPartSpec,
queryString, options,
accessmethod,
queryString, cstmt->options,
cstmt->accessMethod,
cstmt->attr_encodings, false);
stmts = list_concat(stmts, parts);
}
Expand Down
4 changes: 3 additions & 1 deletion src/backend/utils/cache/relcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1250,9 +1250,11 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
case RELKIND_VIEW:
case RELKIND_COMPOSITE_TYPE:
case RELKIND_FOREIGN_TABLE:
case RELKIND_PARTITIONED_TABLE:
Assert(relation->rd_rel->relam == InvalidOid);
break;
case RELKIND_PARTITIONED_TABLE:
/* gp partition tables may set access method for its children */
break;
case RELKIND_AOSEGMENTS:
case RELKIND_AOVISIMAP:
case RELKIND_AOBLOCKDIR:
Expand Down
30 changes: 20 additions & 10 deletions src/bin/psql/describe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2287,8 +2287,10 @@ describeOneTableDetails(const char *schemaname,
goto error_return; /* not an error, just return early */
}

if (greenplum_is_ao_column(tableinfo.relstorage, tableinfo.relam)
|| greenplum_is_ao_row(tableinfo.relstorage, tableinfo.relam))
/* if AO reloptions are specified for table, replace the default reloptions */
if (tableinfo.relkind != RELKIND_PARTITIONED_TABLE &&
(greenplum_is_ao_column(tableinfo.relstorage, tableinfo.relam) ||
greenplum_is_ao_row(tableinfo.relstorage, tableinfo.relam)))
{
PGresult *result = NULL;
/* Get Append Only information
Expand Down Expand Up @@ -2948,15 +2950,23 @@ describeOneTableDetails(const char *schemaname,
{
if (greenplum_is_ao_row(tableinfo.relstorage, tableinfo.relam))
{
printfPQExpBuffer(&buf, _("Compression Type: %s"), tableinfo.compressionType);
printTableAddFooter(&cont, buf.data);
printfPQExpBuffer(&buf, _("Compression Level: %s"), tableinfo.compressionLevel);
printTableAddFooter(&cont, buf.data);
printfPQExpBuffer(&buf, _("Block Size: %s"), tableinfo.blockSize);
printTableAddFooter(&cont, buf.data);
if (tableinfo.compressionType) {
printfPQExpBuffer(&buf, _("Compression Type: %s"), tableinfo.compressionType);
printTableAddFooter(&cont, buf.data);
}
if (tableinfo.compressionLevel) {
printfPQExpBuffer(&buf, _("Compression Level: %s"), tableinfo.compressionLevel);
printTableAddFooter(&cont, buf.data);
}
if (tableinfo.blockSize) {
printfPQExpBuffer(&buf, _("Block Size: %s"), tableinfo.blockSize);
printTableAddFooter(&cont, buf.data);
}
}
if (tableinfo.checksum) {
printfPQExpBuffer(&buf, _("Checksum: %s"), tableinfo.checksum);
printTableAddFooter(&cont, buf.data);
}
printfPQExpBuffer(&buf, _("Checksum: %s"), tableinfo.checksum);
printTableAddFooter(&cont, buf.data);
}

/* print indexes */
Expand Down
3 changes: 2 additions & 1 deletion src/include/access/reloptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ extern void validate_and_adjust_options(StdRdOptions *result, relopt_value *opti
/* attribute enconding specific functions */
extern void validateAOCOColumnEncodingClauses(List *aocoColumnEncoding);
extern List *transformColumnEncoding(const TableAmRoutine *tam, Relation rel, List *colDefs,
List *stenc, List *withOptions, bool createDefaultOne);
List *stenc, List *withOptions, List *parentenc,
bool explicitOnly, bool createDefaultOne);

List* transfromColumnEncodingAocoRootPartition(List *colDefs, List *stenc, List *withOptions, bool errorOnEncodingClause);

Expand Down
1 change: 1 addition & 0 deletions src/include/commands/tablecmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,5 @@ extern void GpRenameChildPartitions(Relation targetrelation,
const char *newparentrelname);
extern void set_random_distribution_if_drop_distkey(Relation rel, AttrNumber attnum);

extern Datum get_rel_opts(Relation rel);
#endif /* TABLECMDS_H */
Loading

0 comments on commit bdc7f6c

Please sign in to comment.