mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
Generated columns
This is an SQL-standard feature that allows creating columns that are computed from expressions rather than assigned, similar to a view or materialized view but on a column basis. This implements one kind of generated column: stored (computed on write). Another kind, virtual (computed on read), is planned for the future, and some room is left for it. Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/b151f851-4019-bdb1-699e-ebab07d2f40a@2ndquadrant.com
This commit is contained in:
@ -818,6 +818,13 @@ rewriteTargetListIU(List *targetList,
|
||||
|
||||
if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT && override == OVERRIDING_USER_VALUE)
|
||||
apply_default = true;
|
||||
|
||||
if (att_tup->attgenerated && !apply_default)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("cannot insert into column \"%s\"", NameStr(att_tup->attname)),
|
||||
errdetail("Column \"%s\" is a generated column.",
|
||||
NameStr(att_tup->attname))));
|
||||
}
|
||||
|
||||
if (commandType == CMD_UPDATE)
|
||||
@ -828,9 +835,23 @@ rewriteTargetListIU(List *targetList,
|
||||
errmsg("column \"%s\" can only be updated to DEFAULT", NameStr(att_tup->attname)),
|
||||
errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
|
||||
NameStr(att_tup->attname))));
|
||||
|
||||
if (att_tup->attgenerated && new_tle && !apply_default)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("column \"%s\" can only be updated to DEFAULT", NameStr(att_tup->attname)),
|
||||
errdetail("Column \"%s\" is a generated column.",
|
||||
NameStr(att_tup->attname))));
|
||||
}
|
||||
|
||||
if (apply_default)
|
||||
if (att_tup->attgenerated)
|
||||
{
|
||||
/*
|
||||
* stored generated column will be fixed in executor
|
||||
*/
|
||||
new_tle = NULL;
|
||||
}
|
||||
else if (apply_default)
|
||||
{
|
||||
Node *new_expr;
|
||||
|
||||
@ -1137,13 +1158,12 @@ build_column_default(Relation rel, int attrno)
|
||||
}
|
||||
}
|
||||
|
||||
if (expr == NULL)
|
||||
{
|
||||
/*
|
||||
* No per-column default, so look for a default for the type itself.
|
||||
*/
|
||||
/*
|
||||
* No per-column default, so look for a default for the type itself. But
|
||||
* not for generated columns.
|
||||
*/
|
||||
if (expr == NULL && !att_tup->attgenerated)
|
||||
expr = get_typdefault(atttype);
|
||||
}
|
||||
|
||||
if (expr == NULL)
|
||||
return NULL; /* No default anywhere */
|
||||
@ -1720,12 +1740,14 @@ ApplyRetrieveRule(Query *parsetree,
|
||||
subrte->selectedCols = rte->selectedCols;
|
||||
subrte->insertedCols = rte->insertedCols;
|
||||
subrte->updatedCols = rte->updatedCols;
|
||||
subrte->extraUpdatedCols = rte->extraUpdatedCols;
|
||||
|
||||
rte->requiredPerms = 0; /* no permission check on subquery itself */
|
||||
rte->checkAsUser = InvalidOid;
|
||||
rte->selectedCols = NULL;
|
||||
rte->insertedCols = NULL;
|
||||
rte->updatedCols = NULL;
|
||||
rte->extraUpdatedCols = NULL;
|
||||
|
||||
return parsetree;
|
||||
}
|
||||
|
Reference in New Issue
Block a user