Add exemptor functions for bit and varbit. These are probably the simplest
examples of the full range of optimizations. I would have used them as the test
case in the initial exemptor function patch if it were a more mainstream use
case.
*** a/src/backend/utils/adt/varbit.c
--- b/src/backend/utils/adt/varbit.c
***************
*** 18,23 ****
--- 18,24 ----
#include "access/htup.h"
#include "libpq/pqformat.h"
+ #include "nodes/primnodes.h"
#include "utils/array.h"
#include "utils/varbit.h"
***************
*** 337,342 **** bit_send(PG_FUNCTION_ARGS)
--- 338,359 ----
}
/*
+ * bit_exemptor()
+ * Identify superfluous calls to our length coercion function.
+ */
+ Datum
+ bit_exemptor(PG_FUNCTION_ARGS)
+ {
+ bool isExplicit = PG_GETARG_BOOL(2);
+
+ /*
+ * We could add COERCE_EXEMPT_NOERROR when the old and new lengths are
+ * identical, but that has zero practical value.
+ */
+ PG_RETURN_INT32(isExplicit ? 0 : COERCE_EXEMPT_NOCHANGE);
+ }
+
+ /*
* bit()
* Converts a bit() type to a specific internal length.
* len is the bitlength specified in the column definition.
***************
*** 645,650 **** varbit_send(PG_FUNCTION_ARGS)
--- 662,683 ----
}
/*
+ * varbit_exemptor()
+ * Identify superfluous calls to our length coercion function.
+ */
+ Datum
+ varbit_exemptor(PG_FUNCTION_ARGS)
+ {
+ int32 old_max = PG_GETARG_INT32(0);
+ int32 new_max = PG_GETARG_INT32(1);
+ bool isExplicit = PG_GETARG_BOOL(2);
+
+ if (new_max <= 0 || (old_max > 0 && new_max >= old_max))
+ PG_RETURN_INT32(COERCE_EXEMPT_NOCHANGE | COERCE_EXEMPT_NOERROR);
+ PG_RETURN_INT32(isExplicit ? 0 : COERCE_EXEMPT_NOCHANGE);
+ }
+
+ /*
* varbit()
* Converts a varbit() type to a specific internal length.
* len is the maximum bitlength specified in the column definition.
*** a/src/include/catalog/catversion.h
--- b/src/include/catalog/catversion.h
***************
*** 53,58 ****
*/
/* yyyymmddN */
! #define CATALOG_VERSION_NO 201101102
#endif
--- 53,58 ----
*/
/* yyyymmddN */
! #define CATALOG_VERSION_NO 201101103
#endif
*** a/src/include/catalog/pg_cast.h
--- b/src/include/catalog/pg_cast.h
***************
*** 355,362 **** DATA(insert ( 1114 1114 1961 3542 i f ));
DATA(insert ( 1184 1184 1967 3542 i f ));
DATA(insert ( 1186 1186 1200 3543 i f ));
DATA(insert ( 1266 1266 1969 3541 i f ));
! DATA(insert ( 1560 1560 1685 0 i f ));
! DATA(insert ( 1562 1562 1687 0 i f ));
DATA(insert ( 1700 1700 1703 0 i f ));
#endif /* PG_CAST_H */
--- 355,362 ----
DATA(insert ( 1184 1184 1967 3542 i f ));
DATA(insert ( 1186 1186 1200 3543 i f ));
DATA(insert ( 1266 1266 1969 3541 i f ));
! DATA(insert ( 1560 1560 1685 3817 i f ));
! DATA(insert ( 1562 1562 1687 3819 i f ));
DATA(insert ( 1700 1700 1703 0 i f ));
#endif /* PG_CAST_H */
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2433,2440 **** DESCR("int4 to bitstring");
--- 2433,2444 ----
DATA(insert OID = 1684 ( int4 PGNSP PGUID 12
1 0 0 f f f t f i 1 0 23 "1560" _null_ _null_ _null_ _null_ bittoint4 _null_
_null_ _null_ ));
DESCR("bitstring to int4");
+ DATA(insert OID = 3817 ( bit_exemptor PGNSP PGUID 12 1 0 0 f f f t
f i 3 0 23 "23 23 16" _null_ _null_ _null_ _null_ bit_exemptor _null_ _null_
_null_ ));
+ DESCR("bit cast exemptor");
DATA(insert OID = 1685 ( bit PGNSP PGUID 12 1 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 = 3819 ( varbit_exemptor PGNSP PGUID 12 1 0 0 f f f t f i 3
0 23 "23 23 16" _null_ _null_ _null_ _null_ varbit_exemptor _null_ _null_
_null_ ));
+ DESCR("varbit cast exemptor");
DATA(insert OID = 1687 ( varbit PGNSP PGUID 12 1 0 0 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");
*** a/src/include/utils/varbit.h
--- b/src/include/utils/varbit.h
***************
*** 71,77 **** extern Datum varbit_recv(PG_FUNCTION_ARGS);
--- 71,79 ----
extern Datum varbit_send(PG_FUNCTION_ARGS);
extern Datum varbittypmodin(PG_FUNCTION_ARGS);
extern Datum varbittypmodout(PG_FUNCTION_ARGS);
+ extern Datum bit_exemptor(PG_FUNCTION_ARGS);
extern Datum bit(PG_FUNCTION_ARGS);
+ extern Datum varbit_exemptor(PG_FUNCTION_ARGS);
extern Datum varbit(PG_FUNCTION_ARGS);
extern Datum biteq(PG_FUNCTION_ARGS);
extern Datum bitne(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/alter_table.out
--- b/src/test/regress/expected/alter_table.out
***************
*** 2454,2478 **** DEBUG: Rebuilding index "t_timegap_key"
ALTER TABLE t ALTER timegap TYPE interval(2);
-- noop
DEBUG: Rebuilding index "t_timegap_key"
ALTER TABLE t ALTER bits TYPE bit(6);
-- verify
- DEBUG: Rewriting table "t"
- DEBUG: Rebuilding index "t_network_key"
- DEBUG: Rebuilding index "t_strarr_idx"
- DEBUG: Rebuilding index "t_square_idx"
- DEBUG: Rebuilding index "t_touchy_f_idx"
- DEBUG: Rebuilding index "t_expr_idx"
- DEBUG: Rebuilding index "t_constraint4_key"
- DEBUG: Rebuilding index "t_integral_key"
- DEBUG: Rebuilding index "t_rational_key"
- DEBUG: Rebuilding index "t_string_idx1"
- DEBUG: Rebuilding index "t_string_idx"
- DEBUG: Rebuilding index "t_daytimetz_key"
- DEBUG: Rebuilding index "t_daytime_key"
- DEBUG: Rebuilding index "t_stamptz_key"
- DEBUG: Rebuilding index "t_stamp_key"
- DEBUG: Rebuilding index "t_timegap_key"
DEBUG: Rebuilding index "t_bits_key"
ALTER TABLE t ALTER bits TYPE bit(7);
-- verify-e
! DEBUG: Rewriting table "t"
ERROR: bit string length 6 does not match type bit(7)
ALTER TABLE t ALTER bits TYPE bit(7) USING bits::bit(7);
-- rewrite
DEBUG: Rewriting table "t"
--- 2454,2464 ----
ALTER TABLE t ALTER timegap TYPE interval(2);
-- noop
DEBUG: Rebuilding index "t_timegap_key"
ALTER TABLE t ALTER bits TYPE bit(6);
-- verify
DEBUG: Rebuilding index "t_bits_key"
+ DEBUG: Verifying table "t"
ALTER TABLE t ALTER bits TYPE bit(7);
-- verify-e
! DEBUG: Rebuilding index "t_bits_key"
! DEBUG: Verifying table "t"
ERROR: bit string length 6 does not match type bit(7)
ALTER TABLE t ALTER bits TYPE bit(7) USING bits::bit(7);
-- rewrite
DEBUG: Rewriting table "t"
***************
*** 2494,2536 **** DEBUG: Rebuilding index "t_timegap_key"
DEBUG: Rebuilding index "t_bits_key"
-- Next one could be a made a noop with an added cast.
ALTER TABLE t ALTER bits TYPE varbit(8);
-- verify
- DEBUG: Rewriting table "t"
- DEBUG: Rebuilding index "t_network_key"
- DEBUG: Rebuilding index "t_strarr_idx"
- DEBUG: Rebuilding index "t_square_idx"
- DEBUG: Rebuilding index "t_touchy_f_idx"
- DEBUG: Rebuilding index "t_expr_idx"
- DEBUG: Rebuilding index "t_constraint4_key"
- DEBUG: Rebuilding index "t_integral_key"
- DEBUG: Rebuilding index "t_rational_key"
- DEBUG: Rebuilding index "t_string_idx1"
- DEBUG: Rebuilding index "t_string_idx"
- DEBUG: Rebuilding index "t_daytimetz_key"
- DEBUG: Rebuilding index "t_daytime_key"
- DEBUG: Rebuilding index "t_stamptz_key"
- DEBUG: Rebuilding index "t_stamp_key"
- DEBUG: Rebuilding index "t_timegap_key"
DEBUG: Rebuilding index "t_bits_key"
ALTER TABLE t ALTER bits TYPE varbit(7);
-- verify
- DEBUG: Rewriting table "t"
- DEBUG: Rebuilding index "t_network_key"
- DEBUG: Rebuilding index "t_strarr_idx"
- DEBUG: Rebuilding index "t_square_idx"
- DEBUG: Rebuilding index "t_touchy_f_idx"
- DEBUG: Rebuilding index "t_expr_idx"
- DEBUG: Rebuilding index "t_constraint4_key"
- DEBUG: Rebuilding index "t_integral_key"
- DEBUG: Rebuilding index "t_rational_key"
- DEBUG: Rebuilding index "t_string_idx1"
- DEBUG: Rebuilding index "t_string_idx"
- DEBUG: Rebuilding index "t_daytimetz_key"
- DEBUG: Rebuilding index "t_daytime_key"
- DEBUG: Rebuilding index "t_stamptz_key"
- DEBUG: Rebuilding index "t_stamp_key"
- DEBUG: Rebuilding index "t_timegap_key"
DEBUG: Rebuilding index "t_bits_key"
ALTER TABLE t ALTER bits TYPE varbit(5);
-- verify-e
! DEBUG: Rewriting table "t"
ERROR: bit string too long for type bit varying(5)
ALTER TABLE t ALTER bits TYPE varbit(5) USING bits::varbit(5);
-- rewrite
DEBUG: Rewriting table "t"
--- 2480,2493 ----
DEBUG: Rebuilding index "t_bits_key"
-- Next one could be a made a noop with an added cast.
ALTER TABLE t ALTER bits TYPE varbit(8);
-- verify
DEBUG: Rebuilding index "t_bits_key"
+ DEBUG: Verifying table "t"
ALTER TABLE t ALTER bits TYPE varbit(7);
-- verify
DEBUG: Rebuilding index "t_bits_key"
+ DEBUG: Verifying table "t"
ALTER TABLE t ALTER bits TYPE varbit(5);
-- verify-e
! DEBUG: Rebuilding index "t_bits_key"
! DEBUG: Verifying table "t"
ERROR: bit string too long for type bit varying(5)
ALTER TABLE t ALTER bits TYPE varbit(5) USING bits::varbit(5);
-- rewrite
DEBUG: Rewriting table "t"
***************
*** 2551,2572 **** DEBUG: Rebuilding index "t_stamp_key"
DEBUG: Rebuilding index "t_timegap_key"
DEBUG: Rebuilding index "t_bits_key"
ALTER TABLE t ALTER bits TYPE varbit(8);
-- noop
- DEBUG: Rewriting table "t"
- DEBUG: Rebuilding index "t_network_key"
- DEBUG: Rebuilding index "t_strarr_idx"
- DEBUG: Rebuilding index "t_square_idx"
- DEBUG: Rebuilding index "t_touchy_f_idx"
- DEBUG: Rebuilding index "t_expr_idx"
- DEBUG: Rebuilding index "t_constraint4_key"
- DEBUG: Rebuilding index "t_integral_key"
- DEBUG: Rebuilding index "t_rational_key"
- DEBUG: Rebuilding index "t_string_idx1"
- DEBUG: Rebuilding index "t_string_idx"
- DEBUG: Rebuilding index "t_daytimetz_key"
- DEBUG: Rebuilding index "t_daytime_key"
- DEBUG: Rebuilding index "t_stamptz_key"
- DEBUG: Rebuilding index "t_stamp_key"
- DEBUG: Rebuilding index "t_timegap_key"
DEBUG: Rebuilding index "t_bits_key"
ALTER TABLE t ALTER network TYPE inet;
-- noop
DEBUG: Rebuilding index "t_network_key"
--- 2508,2513 ----
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers