diff options
| author | Robert Haas <rhaas@postgresql.org> | 2012-02-07 12:41:42 -0500 |
|---|---|---|
| committer | Robert Haas <rhaas@postgresql.org> | 2012-02-07 12:42:50 -0500 |
| commit | f7d7dade8afe19847510efe44be191c35e1ce26c (patch) | |
| tree | 7fcf4ebc6f73c83acc6875ffc6634581c1c6814b /src/backend/utils/adt/varbit.c | |
| parent | 3cc0800829a6dda5347497337b0cf43848da4acf (diff) | |
| download | postgresql-f7d7dade8afe19847510efe44be191c35e1ce26c.tar.gz | |
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.
Diffstat (limited to 'src/backend/utils/adt/varbit.c')
| -rw-r--r-- | src/backend/utils/adt/varbit.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index adb08369ed..1227e5a508 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -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" @@ -646,6 +648,39 @@ varbit_send(PG_FUNCTION_ARGS) } /* + * 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. * len is the maximum bitlength specified in the column definition. |
