8000 Add a transform function for varbit typmod coercisions. · postgrespro/postgres@f7d7dad · GitHub
[go: up one dir, main page]

Skip to content
  • Commit f7d7dad

    Browse files
    committed
    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.
    1 parent 3cc0800 commit f7d7dad

    File tree

    4 files changed

    +40
    -2
    lines changed

    4 files changed

    +40
    -2
    lines changed

    src/backend/utils/adt/varbit.c

    Lines changed: 35 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -18,6 +18,8 @@
    1818

    1919
    #include "access/htup.h"
    2020
    #include "libpq/pqformat.h"
    21+
    #include "nodes/nodeFuncs.h"
    22+
    #include "parser/parse_clause.h"
    2123
    #include "utils/array.h"
    2224
    #include "utils/varbit.h"
    2325

    @@ -645,6 +647,39 @@ varbit_send(PG_FUNCTION_ARGS)
    645647
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
    646648
    }
    647649

    650+
    /*
    651+
    * varbit_transform()
    652+
    * Flatten calls to our length coercion function that leave the new maximum
    653+
    * length >= the previous maximum length. We ignore the isExplicit argument,
    654+
    * which only affects truncation.
    655+
    */
    656+
    Datum
    657+
    varbit_transform(PG_FUNCTION_ARGS)
    658+
    {
    659+
    FuncExpr *expr = (FuncExpr *) PG_GETARG_POINTER(0);
    660+
    Node *typmod;
    661+
    Node *ret = NULL;
    662+
    663+
    if (!IsA(expr, FuncExpr))
    664+
    PG_RETURN_POINTER(ret);
    665+
    666+
    Assert(list_length(expr->args) == 3);
    667+
    typmod = lsecond(expr->args);
    668+
    669+
    if (IsA(typmod, Const))
    670+
    {
    671+
    Node *source = linitial(expr->args);
    672+
    int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
    673+
    int32 old_max = exprTypmod(source);
    674+
    int32 new_max = new_typmod;
    675+
    676+
    if (new_max <= 0 || (old_max >= 0 && old_max <= new_max))
    677+
    ret = relabel_to_typmod(source, new_typmod);
    678+
    }
    679+
    680+
    PG_RETURN_POINTER(ret);
    681+
    }
    682+
    648683
    /*
    649684
    * varbit()
    650685
    * Converts a varbit() type to a specific internal length.

    src/include/catalog/catversion.h

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -53,6 +53,6 @@
    5353
    */
    5454

    5555
    /* yyyymmddN */
    56-
    #define CATALOG_VERSION_NO 201202071
    56+
    #define CATALOG_VERSION_NO 201202072
    5757

    5858
    #endif

    src/include/catalog/pg_proc.h

    Lines changed: 3 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -2009,7 +2009,9 @@ DESCR("convert bitstring to int4");
    20092009

    20102010
    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_ ));
    20112011
    DESCR("adjust bit() to typmod length");
    2012-
    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_ ));
    2012+
    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_ ));
    2013+
    DESCR("transform a varbit length coercion");
    2014+
    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_ ));
    20132015
    DESCR("adjust varbit() to typmod length");
    20142016

    20152017
    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_ ));

    src/include/utils/varbit.h

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -72,6 +72,7 @@ extern Datum varbit_send(PG_FUNCTION_ARGS);
    7272
    extern Datum varbittypmodin(PG_FUNCTION_ARGS);
    7373
    extern Datum varbittypmodout(PG_FUNCTION_ARGS);
    7474
    extern Datum bit(PG_FUNCTION_ARGS);
    75+
    extern Datum varbit_transform(PG_FUNCTION_ARGS);
    7576
    extern Datum varbit(PG_FUNCTION_ARGS);
    7677
    extern Datum biteq(PG_FUNCTION_ARGS);
    7778
    extern Datum bitne(PG_FUNCTION_ARGS);

    0 commit comments

    Comments
     (0)
    0