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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to