diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-03-23 17:29:57 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-03-23 17:29:57 -0400 |
commit | 0339047bc93147c1c6f78f867ae6b0c215406235 (patch) | |
tree | 116a4cd10a9eb1b0b6beb4cf871bc126c504572a /src/backend/utils/adt/varbit.c | |
parent | e08b4101e1daa2f4e6644330918177a10cac0aab (diff) | |
download | postgresql-0339047bc93147c1c6f78f867ae6b0c215406235.tar.gz postgresql-0339047bc93147c1c6f78f867ae6b0c215406235.zip |
Code review for protransform patches.
Fix loss of previous expression-simplification work when a transform
function fires: we must not simply revert to untransformed input tree.
Instead build a dummy FuncExpr node to pass to the transform function.
This has the additional advantage of providing a simpler, more uniform
API for transform functions.
Move documentation to a somewhat less buried spot, relocate some
poorly-placed code, be more wary of null constants and invalid typmod
values, add an opr_sanity check on protransform function signatures,
and some other minor cosmetic adjustments.
Note: although this patch touches pg_proc.h, no need for catversion
bump, because the changes are cosmetic and don't actually change the
intended catalog contents.
Diffstat (limited to 'src/backend/utils/adt/varbit.c')
-rw-r--r-- | src/backend/utils/adt/varbit.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index 1227e5a5082..e74e062338d 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -19,7 +19,6 @@ #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" @@ -649,31 +648,31 @@ 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. + * Flatten calls to varbit's length coercion function that set the new maximum + * length >= the previous maximum length. We can ignore the isExplicit + * argument, since that only affects truncation cases. */ Datum varbit_transform(PG_FUNCTION_ARGS) { FuncExpr *expr = (FuncExpr *) PG_GETARG_POINTER(0); - Node *typmod; Node *ret = NULL; + Node *typmod; - if (!IsA(expr, FuncExpr)) - PG_RETURN_POINTER(ret); + Assert(IsA(expr, FuncExpr)); + Assert(list_length(expr->args) >= 2); - Assert(list_length(expr->args) == 3); - typmod = lsecond(expr->args); + typmod = (Node *) lsecond(expr->args); - if (IsA(typmod, Const)) + if (IsA(typmod, Const) && !((Const *) typmod)->constisnull) { - Node *source = linitial(expr->args); + Node *source = (Node *) 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)) + /* Note: varbit() treats typmod 0 as invalid, so we do too */ + if (new_max <= 0 || (old_max > 0 && old_max <= new_max)) ret = relabel_to_typmod(source, new_typmod); } |