mirror of
https://github.com/postgres/postgres.git
synced 2025-10-22 14:32:25 +03:00
Fast ALTER TABLE ADD COLUMN with a non-NULL default
Currently adding a column to a table with a non-NULL default results in a rewrite of the table. For large tables this can be both expensive and disruptive. This patch removes the need for the rewrite as long as the default value is not volatile. The default expression is evaluated at the time of the ALTER TABLE and the result stored in a new column (attmissingval) in pg_attribute, and a new column (atthasmissing) is set to true. Any existing row when fetched will be supplied with the attmissingval. New rows will have the supplied value or the default and so will never need the attmissingval. Any time the table is rewritten all the atthasmissing and attmissingval settings for the attributes are cleared, as they are no longer needed. The most visible code change from this is in heap_attisnull, which acquires a third TupleDesc argument, allowing it to detect a missing value if there is one. In many cases where it is known that there will not be any (e.g. catalog relations) NULL can be passed for this argument. Andrew Dunstan, heavily modified from an original patch from Serge Rielau. Reviewed by Tom Lane, Andres Freund, Tomas Vondra and David Rowley. Discussion: https://postgr.es/m/31e2e921-7002-4c27-59f5-51f08404c858@2ndQuadrant.com
This commit is contained in:
@@ -799,7 +799,7 @@ extern void heap_fill_tuple(TupleDesc tupleDesc,
|
||||
Datum *values, bool *isnull,
|
||||
char *data, Size data_size,
|
||||
uint16 *infomask, bits8 *bit);
|
||||
extern bool heap_attisnull(HeapTuple tup, int attnum);
|
||||
extern bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc);
|
||||
extern Datum nocachegetattr(HeapTuple tup, int attnum,
|
||||
TupleDesc att);
|
||||
extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
|
||||
@@ -830,5 +830,7 @@ extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
|
||||
extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
|
||||
extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
|
||||
extern size_t varsize_any(void *p);
|
||||
extern HeapTuple heap_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc);
|
||||
extern MinimalTuple minimal_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc);
|
||||
|
||||
#endif /* HTUP_DETAILS_H */
|
||||
|
@@ -25,6 +25,8 @@ typedef struct attrDefault
|
||||
char *adbin; /* nodeToString representation of expr */
|
||||
} AttrDefault;
|
||||
|
||||
typedef struct attrMissing *MissingPtr;
|
||||
|
||||
typedef struct constrCheck
|
||||
{
|
||||
char *ccname;
|
||||
@@ -38,6 +40,7 @@ typedef struct tupleConstr
|
||||
{
|
||||
AttrDefault *defval; /* array */
|
||||
ConstrCheck *check; /* array */
|
||||
MissingPtr missing; /* missing attributes values, NULL if none */
|
||||
uint16 num_defval;
|
||||
uint16 num_check;
|
||||
bool has_not_null;
|
||||
|
29
src/include/access/tupdesc_details.h
Normal file
29
src/include/access/tupdesc_details.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* tupdesc_details.h
|
||||
* POSTGRES tuple descriptor definitions we can't include everywhere
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/access/tupdesc_details.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TUPDESC_DETAILS_H
|
||||
#define TUPDESC_DETAILS_H
|
||||
|
||||
/*
|
||||
* Structure used to represent value to be used when the attribute is not
|
||||
* present at all in a tuple, i.e. when the column was created after the tuple
|
||||
*/
|
||||
|
||||
typedef struct attrMissing
|
||||
{
|
||||
bool ammissingPresent; /* true if non-NULL missing value exists */
|
||||
Datum ammissing; /* value when attribute is missing */
|
||||
} AttrMissing;
|
||||
|
||||
#endif /* TUPDESC_DETAILS_H */
|
Reference in New Issue
Block a user