Commit f7d7dade authored by Robert Haas's avatar Robert Haas

Add a transform function for varbit typmod coercisions.

This enables ALTER TABLE to skip table and index rebuilds when the
new type is unconstraint varbit, or when the allowable number of bits
is not decreasing.

Noah Misch, with review and a fix for an OID collision by me.
parent 3cc08008
......@@ -18,6 +18,8 @@
#include "access/htup.h"
#include "libpq/pqformat.h"
#include "nodes/nodeFuncs.h"
#include "parser/parse_clause.h"
#include "utils/array.h"
#include "utils/varbit.h"
......@@ -645,6 +647,39 @@ varbit_send(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/*
* varbit_transform()
* Flatten calls to our length coercion function that leave the new maximum
* length >= the previous maximum length. We ignore the isExplicit argument,
* which only affects truncation.
*/
Datum
varbit_transform(PG_FUNCTION_ARGS)
{
FuncExpr *expr = (FuncExpr *) PG_GETARG_POINTER(0);
Node *typmod;
Node *ret = NULL;
if (!IsA(expr, FuncExpr))
PG_RETURN_POINTER(ret);
Assert(list_length(expr->args) == 3);
typmod = lsecond(expr->args);
if (IsA(typmod, Const))
{
Node *source = linitial(expr->args);
int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
int32 old_max = exprTypmod(source);
int32 new_max = new_typmod;
if (new_max <= 0 || (old_max >= 0 && old_max <= new_max))
ret = relabel_to_typmod(source, new_typmod);
}
PG_RETURN_POINTER(ret);
}
/*
* varbit()
* Converts a varbit() type to a specific internal length.
......
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201202071
#define CATALOG_VERSION_NO 201202072
#endif
......@@ -2009,7 +2009,9 @@ DESCR("convert bitstring to int4");
DATA(insert OID = 1685 ( bit PGNSP PGUID 12 1 0 0 0 f f f t f i 3 0 1560 "1560 23 16" _null_ _null_ _null_ _null_ bit _null_ _null_ _null_ ));
DESCR("adjust bit() to typmod length");
DATA(insert OID = 1687 ( varbit PGNSP PGUID 12 1 0 0 0 f f f t f i 3 0 1562 "1562 23 16" _null_ _null_ _null_ _null_ varbit _null_ _null_ _null_ ));
DATA(insert OID = 3158 ( varbit_transform PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ varbit_transform _null_ _null_ _null_ ));
DESCR("transform a varbit length coercion");
DATA(insert OID = 1687 ( varbit PGNSP PGUID 12 1 0 0 3158 f f f t f i 3 0 1562 "1562 23 16" _null_ _null_ _null_ _null_ varbit _null_ _null_ _null_ ));
DESCR("adjust varbit() to typmod length");
DATA(insert OID = 1698 ( position PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 23 "1560 1560" _null_ _null_ _null_ _null_ bitposition _null_ _null_ _null_ ));
......
......@@ -72,6 +72,7 @@ extern Datum varbit_send(PG_FUNCTION_ARGS);
extern Datum varbittypmodin(PG_FUNCTION_ARGS);
extern Datum varbittypmodout(PG_FUNCTION_ARGS);
extern Datum bit(PG_FUNCTION_ARGS);
extern Datum varbit_transform(PG_FUNCTION_ARGS);
extern Datum varbit(PG_FUNCTION_ARGS);
extern Datum biteq(PG_FUNCTION_ARGS);
extern Datum bitne(PG_FUNCTION_ARGS);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment