Skip to content

Commit

Permalink
[Feature] Support Invisible Columns
Browse files Browse the repository at this point in the history
  • Loading branch information
YinZheng-Sun committed Jul 18, 2023
1 parent 5c5e5ae commit d561664
Show file tree
Hide file tree
Showing 22 changed files with 393 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/backend/access/common/tupdesc.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
return false;
if (attr1->attisdropped != attr2->attisdropped)
return false;
if (attr1->attisinvisible != attr2->attisinvisible)
return false;
if (attr1->attislocal != attr2->attislocal)
return false;
if (attr1->attinhcount != attr2->attinhcount)
Expand Down Expand Up @@ -644,6 +646,7 @@ TupleDescInitEntry(TupleDesc desc,
att->atthasmissing = false;
att->attidentity = '\0';
att->attisdropped = false;
att->attisinvisible = false;
att->attislocal = true;
att->attinhcount = 0;
/* attacl, attoptions and attfdwoptions are not present in tupledescs */
Expand Down Expand Up @@ -703,6 +706,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
att->atthasmissing = false;
att->attidentity = '\0';
att->attisdropped = false;
att->attisinvisible = false;
att->attislocal = true;
att->attinhcount = 0;
/* attacl, attoptions and attfdwoptions are not present in tupledescs */
Expand Down
19 changes: 10 additions & 9 deletions src/backend/catalog/heap.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -152,37 +152,37 @@ static List *insert_ordered_unique_oid(List *list, Oid datum);
static FormData_pg_attribute a1 = {
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
SelfItemPointerAttributeNumber, 0, -1, -1,
false, 'p', 's', true, false, false, '\0', false, true, 0
false, 'p', 's', true, false, false, '\0', false, false, true, 0
};

static FormData_pg_attribute a2 = {
0, {"oid"}, OIDOID, 0, sizeof(Oid),
ObjectIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, '\0', false, true, 0
true, 'p', 'i', true, false, false, '\0', false, false, true, 0
};

static FormData_pg_attribute a3 = {
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
MinTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, '\0', false, true, 0
true, 'p', 'i', true, false, false, '\0', false, false, true, 0
};

static FormData_pg_attribute a4 = {
0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
MinCommandIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, '\0', false, true, 0
true, 'p', 'i', true, false, false, '\0', false, false, true, 0
};

static FormData_pg_attribute a5 = {
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
MaxTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, '\0', false, true, 0
true, 'p', 'i', true, false, false, '\0', false, false, true, 0
};

static FormData_pg_attribute a6 = {
0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
MaxCommandIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, '\0', false, true, 0
true, 'p', 'i', true, false, false, '\0', false, false, true, 0
};

/*
Expand All @@ -194,20 +194,20 @@ static FormData_pg_attribute a6 = {
static FormData_pg_attribute a7 = {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
TableOidAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, '\0', false, true, 0
true, 'p', 'i', true, false, false, '\0', false, false, true, 0
};

/* POLAR px */
static FormData_pg_attribute a8 = {
0, {"_px_worker_id"}, INT4OID, 0, sizeof(PxWorkerId),
PxWorkerIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, '\0', false, true, 0
true, 'p', 'i', true, false, false, '\0', false, false, true, 0
};

static FormData_pg_attribute a9 = {
0, {"_root_ctid"}, TIDOID, 0, sizeof(ItemPointerData),
RootSelfItemPointerAttributeNumber, 0, -1, -1,
false, 'p', 's', true, false, false, '\0', false, true, 0
false, 'p', 's', true, false, false, '\0', false, false, true, 0
};
/* POLAR end */

Expand Down Expand Up @@ -691,6 +691,7 @@ HeapTuple heaptuple_from_pg_attribute(Relation pg_attribute_rel,
values[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(new_attribute->atthasmissing);
values[Anum_pg_attribute_attidentity - 1] = CharGetDatum(new_attribute->attidentity);
values[Anum_pg_attribute_attisdropped - 1] = BoolGetDatum(new_attribute->attisdropped);
values[Anum_pg_attribute_attisinvisible - 1] = BoolGetDatum(new_attribute->attisinvisible);
values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(new_attribute->attislocal);
values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);
values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(new_attribute->attcollation);
Expand Down
1 change: 1 addition & 0 deletions src/backend/commands/sequence.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
ColumnDef *coldef = makeNode(ColumnDef);

coldef->inhcount = 0;
coldef->is_invisible = false;
coldef->is_local = true;
coldef->is_not_null = true;
coldef->is_from_type = false;
Expand Down
144 changes: 144 additions & 0 deletions src/backend/commands/tablecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMO
static void ATPrepSetNotNull(Relation rel, bool recurse, bool recursing);
static ObjectAddress ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
const char *colName, LOCKMODE lockmode);
static ObjectAddress ATExecSetVisible(AlteredTableInfo *tab, Relation rel,
const char *colName, LOCKMODE lockmode);
static ObjectAddress ATExecSetInvisible(AlteredTableInfo *tab, Relation rel,
const char *colName, LOCKMODE lockmode);
static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName,
Node *newDefault, LOCKMODE lockmode);
static ObjectAddress ATExecAddIdentity(Relation rel, const char *colName,
Expand Down Expand Up @@ -772,6 +776,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,

if (colDef->identity)
attr->attidentity = colDef->identity;

if (colDef->is_invisible)
attr->attisinvisible = colDef->is_invisible;
}

/*
Expand Down Expand Up @@ -3527,6 +3534,14 @@ AlterTableGetLockLevel(List *cmds)
cmd_lockmode = AccessExclusiveLock;
break;

/*
* changing visibilty can affect concurrent SELECTs
*/
case AT_SetInvisible:
case AT_SetVisible:
cmd_lockmode = AccessExclusiveLock;
break;

/*
* These subcommands affect write operations only.
*/
Expand Down Expand Up @@ -3816,6 +3831,16 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
/* No command-specific prep needed */
pass = AT_PASS_ADD_CONSTR;
break;
case AT_SetVisible: /* ALTER COLUMN SET VISIBLE */
ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
/* No command-specific prep needed */
pass = AT_PASS_ADD_CONSTR;
case AT_SetInvisible: /* ALTER COLUMN SET INVISIBLE */
ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
/* No command-specific prep needed */
pass = AT_PASS_ADD_CONSTR;
case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
/* Performs own permission checks */
Expand Down Expand Up @@ -4149,6 +4174,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
address = ATExecSetNotNull(tab, rel, cmd->name, lockmode);
break;
case AT_SetVisible: /* ALTER COLUMN SET VISIBLE */
address = ATExecSetVisible(tab, rel, cmd->name, lockmode);
break;
case AT_SetInvisible: /* ALTER COLUMN SET INVISIBLE */
address = ATExecSetInvisible(tab, rel, cmd->name, lockmode);
break;
case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
address = ATExecSetStatistics(rel, cmd->name, cmd->num, cmd->def, lockmode);
break;
Expand Down Expand Up @@ -5646,6 +5677,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
attribute.atthasmissing = false;
attribute.attidentity = colDef->identity;
attribute.attisdropped = false;
attribute.attisinvisible = colDef->is_invisible;
attribute.attislocal = colDef->is_local;
attribute.attinhcount = colDef->inhcount;
attribute.attcollation = collOid;
Expand Down Expand Up @@ -6228,6 +6260,118 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
return address;
}

/*
* Return the address of the modified column. If the column was already Invisible,
* InvalidObjectAddress is returned.
*/
static ObjectAddress
ATExecSetVisible(AlteredTableInfo *tab, Relation rel,
const char *colName, LOCKMODE lockmode)
{
HeapTuple tuple;
AttrNumber attnum;
Relation attr_rel;
ObjectAddress address;

/*
* lookup the attribute
*/
attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);

tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);

if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
colName, RelationGetRelationName(rel))));

attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;

/* Prevent them from altering a system attribute */
if (attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot alter system column \"%s\"",
colName)));

if (((Form_pg_attribute) GETSTRUCT(tuple))->attisinvisible)
{
((Form_pg_attribute) GETSTRUCT(tuple))->attisinvisible = false;

CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);

ObjectAddressSubSet(address, RelationRelationId,
RelationGetRelid(rel), attnum);
}
else
address = InvalidObjectAddress;

InvokeObjectPostAlterHook(RelationRelationId,
RelationGetRelid(rel), attnum);

heap_close(attr_rel, RowExclusiveLock);
heap_freetuple(tuple);

return address;
}

/*
* Return the address of the modified column. If the column was already Invisible,
* InvalidObjectAddress is returned.
*/
static ObjectAddress
ATExecSetInvisible(AlteredTableInfo *tab, Relation rel,
const char *colName, LOCKMODE lockmode)
{
HeapTuple tuple;
AttrNumber attnum;
Relation attr_rel;
ObjectAddress address;

/*
* lookup the attribute
*/
attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);

tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);

if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
colName, RelationGetRelationName(rel))));

attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;

/* Prevent them from altering a system attribute */
if (attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot alter system column \"%s\"",
colName)));

if (!((Form_pg_attribute) GETSTRUCT(tuple))->attisinvisible)
{
((Form_pg_attribute) GETSTRUCT(tuple))->attisinvisible = true;

CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);

ObjectAddressSubSet(address, RelationRelationId,
RelationGetRelid(rel), attnum);
}
else
address = InvalidObjectAddress;

InvokeObjectPostAlterHook(RelationRelationId,
RelationGetRelid(rel), attnum);

heap_close(attr_rel, RowExclusiveLock);
heap_freetuple(tuple);

return address;
}

/*
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
*
Expand Down
1 change: 1 addition & 0 deletions src/backend/nodes/makefuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
n->colname = pstrdup(colname);
n->typeName = makeTypeNameFromOid(typeOid, typmod);
n->inhcount = 0;
n->is_invisible = false;
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
Expand Down
4 changes: 4 additions & 0 deletions src/backend/nodes/outfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3733,6 +3733,10 @@ _outConstraint(StringInfo str, const Constraint *node)
WRITE_CHAR_FIELD(generated_when);
break;

case CONSTR_INVISIBLE:
appendStringInfoString(str, "INVISIBLE");
break;

case CONSTR_CHECK:
appendStringInfoString(str, "CHECK");
WRITE_BOOL_FIELD(is_no_inherit);
Expand Down
Loading

0 comments on commit d561664

Please sign in to comment.