Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make gp-style partition table compatible with greenplum #695

Merged
merged 1 commit into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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