mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +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:
33
src/backend/utils/cache/lsyscache.c
vendored
33
src/backend/utils/cache/lsyscache.c
vendored
@ -821,6 +821,39 @@ get_attnum(Oid relid, const char *attname)
|
||||
return InvalidAttrNumber;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_attgenerated
|
||||
*
|
||||
* Given the relation id and the attribute name,
|
||||
* return the "attgenerated" field from the attribute relation.
|
||||
*
|
||||
* Errors if not found.
|
||||
*
|
||||
* Since not generated is represented by '\0', this can also be used as a
|
||||
* Boolean test.
|
||||
*/
|
||||
char
|
||||
get_attgenerated(Oid relid, AttrNumber attnum)
|
||||
{
|
||||
HeapTuple tp;
|
||||
|
||||
tp = SearchSysCache2(ATTNUM,
|
||||
ObjectIdGetDatum(relid),
|
||||
Int16GetDatum(attnum));
|
||||
if (HeapTupleIsValid(tp))
|
||||
{
|
||||
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
|
||||
char result;
|
||||
|
||||
result = att_tup->attgenerated;
|
||||
ReleaseSysCache(tp);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
elog(ERROR, "cache lookup failed for attribute %d of relation %u",
|
||||
attnum, relid);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_atttype
|
||||
*
|
||||
|
1
src/backend/utils/cache/partcache.c
vendored
1
src/backend/utils/cache/partcache.c
vendored
@ -27,6 +27,7 @@
|
||||
#include "nodes/nodeFuncs.h"
|
||||
#include "optimizer/optimizer.h"
|
||||
#include "partitioning/partbounds.h"
|
||||
#include "rewrite/rewriteHandler.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/datum.h"
|
||||
#include "utils/lsyscache.h"
|
||||
|
4
src/backend/utils/cache/relcache.c
vendored
4
src/backend/utils/cache/relcache.c
vendored
@ -515,6 +515,7 @@ RelationBuildTupleDesc(Relation relation)
|
||||
constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext,
|
||||
sizeof(TupleConstr));
|
||||
constr->has_not_null = false;
|
||||
constr->has_generated_stored = false;
|
||||
|
||||
/*
|
||||
* Form a scan key that selects only user attributes (attnum > 0).
|
||||
@ -567,6 +568,8 @@ RelationBuildTupleDesc(Relation relation)
|
||||
/* Update constraint/default info */
|
||||
if (attp->attnotnull)
|
||||
constr->has_not_null = true;
|
||||
if (attp->attgenerated == ATTRIBUTE_GENERATED_STORED)
|
||||
constr->has_generated_stored = true;
|
||||
|
||||
/* If the column has a default, fill it into the attrdef array */
|
||||
if (attp->atthasdef)
|
||||
@ -3281,6 +3284,7 @@ RelationBuildLocalRelation(const char *relname,
|
||||
Form_pg_attribute datt = TupleDescAttr(rel->rd_att, i);
|
||||
|
||||
datt->attidentity = satt->attidentity;
|
||||
datt->attgenerated = satt->attgenerated;
|
||||
datt->attnotnull = satt->attnotnull;
|
||||
has_not_null |= satt->attnotnull;
|
||||
}
|
||||
|
Reference in New Issue
Block a user