On Sat, Jun 11, 2011 at 03:03:18PM -0400, Tom Lane wrote:
> Noah Misch <n...@leadboat.com> writes:
> > Good points.  I'm thinking, then, add an Expr argument to 
> > simplify_function()
> > and have the CoerceViaIO branch of eval_const_expressions_mutator() pass 
> > NULL
> > for both its simplify_function() calls.  If simplify_function() gets a NULL 
> > Expr
> > for a function that has a protransform, synthesize a FuncExpr based on its 
> > other
> > arguments before calling the transform function.  Seem reasonable?  Granted,
> > that would be dead code until someone applies a transform function to a 
> > type I/O
> > function, which could easily never happen.  Perhaps just ignore the 
> > transform
> > function when we started with a CoerceViaIO node?
> 
> Until we actually have a use-case for simplifying I/O functions like this,
> I can't see going out of our way for it ...

Sounds good.  Updated patch attached, incorporating your ideas.  Before applying
it, run this command to update the uninvolved pg_proc.h DATA entries:
  perl -pi -e 's/PGUID(\s+\d+){4}/$& 0/' src/include/catalog/pg_proc.h

Thanks,
nm
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 8504555..5d1a447 100644
*** a/doc/src/sgml/catalogs.sgml
--- b/doc/src/sgml/catalogs.sgml
***************
*** 4337,4342 ****
--- 4337,4349 ----
       </row>
  
       <row>
+       <entry><structfield>protransform</structfield></entry>
+       <entry><type>regproc</type></entry>
+       <entry><literal><link 
linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
+       <entry>Calls to function can be simplified by this other 
function</entry>
+      </row>
+ 
+      <row>
        <entry><structfield>proisagg</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
diff --git a/src/backend/catalog/index 6250b07..92be0a7 100644
*** a/src/backend/catalog/pg_proc.c
--- b/src/backend/catalog/pg_proc.c
***************
*** 304,309 **** ProcedureCreate(const char *procedureName,
--- 304,310 ----
        values[Anum_pg_proc_procost - 1] = Float4GetDatum(procost);
        values[Anum_pg_proc_prorows - 1] = Float4GetDatum(prorows);
        values[Anum_pg_proc_provariadic - 1] = ObjectIdGetDatum(variadicType);
+       values[Anum_pg_proc_protransform - 1] = ObjectIdGetDatum(InvalidOid);
        values[Anum_pg_proc_proisagg - 1] = BoolGetDatum(isAgg);
        values[Anum_pg_proc_proiswindow - 1] = BoolGetDatum(isWindowFunc);
        values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer);
diff --git a/src/backend/commands/taindex 2c9f855..563a1b2 100644
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 56,61 ****
--- 56,62 ----
  #include "nodes/nodeFuncs.h"
  #include "nodes/parsenodes.h"
  #include "optimizer/clauses.h"
+ #include "optimizer/planner.h"
  #include "parser/parse_clause.h"
  #include "parser/parse_coerce.h"
  #include "parser/parse_collate.h"
***************
*** 3495,3501 **** ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, 
LOCKMODE lockmode)
        {
                NewColumnValue *ex = lfirst(l);
  
!               ex->exprstate = ExecPrepareExpr((Expr *) ex->expr, estate);
        }
  
        notnull_attrs = NIL;
--- 3496,3503 ----
        {
                NewColumnValue *ex = lfirst(l);
  
!               /* expr already planned */
!               ex->exprstate = ExecInitExpr((Expr *) ex->expr, NULL);
        }
  
        notnull_attrs = NIL;
***************
*** 4398,4404 **** ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, 
Relation rel,
  
                        newval = (NewColumnValue *) 
palloc0(sizeof(NewColumnValue));
                        newval->attnum = attribute.attnum;
!                       newval->expr = defval;
  
                        tab->newvals = lappend(tab->newvals, newval);
                        tab->rewrite = true;
--- 4400,4406 ----
  
                        newval = (NewColumnValue *) 
palloc0(sizeof(NewColumnValue));
                        newval->attnum = attribute.attnum;
!                       newval->expr = expression_planner(defval);
  
                        tab->newvals = lappend(tab->newvals, newval);
                        tab->rewrite = true;
***************
*** 6706,6711 **** ATPrepAlterColumnType(List **wqueue,
--- 6708,6716 ----
                /* Fix collations after all else */
                assign_expr_collations(pstate, transform);
  
+               /* Plan the expr now so we can accurately assess the need to 
rewrite. */
+               transform = (Node *) expression_planner((Expr *) transform);
+ 
                /*
                 * Add a work queue item to make ATRewriteTable update the 
column
                 * contents.
diff --git a/src/backend/optimizer/utilindex 2914c39..e9fb750 100644
*** a/src/backend/optimizer/util/clauses.c
--- b/src/backend/optimizer/util/clauses.c
***************
*** 106,114 **** static List *simplify_and_arguments(List *args,
                                           eval_const_expressions_context 
*context,
                                           bool *haveNull, bool *forceFalse);
  static Node *simplify_boolean_equality(Oid opno, List *args);
! static Expr *simplify_function(Oid funcid,
!                                 Oid result_type, int32 result_typmod,
!                                 Oid result_collid, Oid input_collid, List 
**args,
                                  bool has_named_args,
                                  bool allow_inline,
                                  eval_const_expressions_context *context);
--- 106,114 ----
                                           eval_const_expressions_context 
*context,
                                           bool *haveNull, bool *forceFalse);
  static Node *simplify_boolean_equality(Oid opno, List *args);
! static Expr *simplify_function(Expr *oldexpr, Oid funcid,
!                                 Oid result_type, int32 result_typmod, Oid 
result_collid,
!                                 Oid input_collid, List **args,
                                  bool has_named_args,
                                  bool allow_inline,
                                  eval_const_expressions_context *context);
***************
*** 2223,2229 **** eval_const_expressions_mutator(Node *node,
                 * FuncExpr, but not when the node is recognizably a length 
coercion;
                 * we want to preserve the typmod in the eventual Const if so.
                 */
!               simple = simplify_function(expr->funcid,
                                                                   
expr->funcresulttype, exprTypmod(node),
                                                                   
expr->funccollid,
                                                                   
expr->inputcollid,
--- 2223,2230 ----
                 * FuncExpr, but not when the node is recognizably a length 
coercion;
                 * we want to preserve the typmod in the eventual Const if so.
                 */
!               simple = simplify_function((Expr *) expr,
!                                                                  expr->funcid,
                                                                   
expr->funcresulttype, exprTypmod(node),
                                                                   
expr->funccollid,
                                                                   
expr->inputcollid,
***************
*** 2275,2281 **** eval_const_expressions_mutator(Node *node,
                 * Code for op/func reduction is pretty bulky, so split it out 
as a
                 * separate function.
                 */
!               simple = simplify_function(expr->opfuncid,
                                                                   
expr->opresulttype, -1,
                                                                   
expr->opcollid,
                                                                   
expr->inputcollid,
--- 2276,2283 ----
                 * Code for op/func reduction is pretty bulky, so split it out 
as a
                 * separate function.
                 */
!               simple = simplify_function((Expr *) expr,
!                                                                  
expr->opfuncid,
                                                                   
expr->opresulttype, -1,
                                                                   
expr->opcollid,
                                                                   
expr->inputcollid,
***************
*** 2372,2378 **** eval_const_expressions_mutator(Node *node,
                         * Code for op/func reduction is pretty bulky, so split 
it out as
                         * a separate function.
                         */
!                       simple = simplify_function(expr->opfuncid,
                                                                           
expr->opresulttype, -1,
                                                                           
expr->opcollid,
                                                                           
expr->inputcollid,
--- 2374,2381 ----
                         * Code for op/func reduction is pretty bulky, so split 
it out as
                         * a separate function.
                         */
!                       simple = simplify_function((Expr *) expr,
!                                                                          
expr->opfuncid,
                                                                           
expr->opresulttype, -1,
                                                                           
expr->opcollid,
                                                                           
expr->inputcollid,
***************
*** 2561,2567 **** eval_const_expressions_mutator(Node *node,
                getTypeOutputInfo(exprType((Node *) arg), &outfunc, 
&outtypisvarlena);
                getTypeInputInfo(expr->resulttype, &infunc, &intypioparam);
  
!               simple = simplify_function(outfunc,
                                                                   CSTRINGOID, 
-1,
                                                                   InvalidOid,
                                                                   InvalidOid,
--- 2564,2571 ----
                getTypeOutputInfo(exprType((Node *) arg), &outfunc, 
&outtypisvarlena);
                getTypeInputInfo(expr->resulttype, &infunc, &intypioparam);
  
!               simple = simplify_function(NULL,
!                                                                  outfunc,
                                                                   CSTRINGOID, 
-1,
                                                                   InvalidOid,
                                                                   InvalidOid,
***************
*** 2581,2587 **** eval_const_expressions_mutator(Node *node,
                                                                          
Int32GetDatum(-1),
                                                                          
false, true));
  
!                       simple = simplify_function(infunc,
                                                                           
expr->resulttype, -1,
                                                                           
expr->resultcollid,
                                                                           
InvalidOid,
--- 2585,2592 ----
                                                                          
Int32GetDatum(-1),
                                                                          
false, true));
  
!                       simple = simplify_function(NULL,
!                                                                          
infunc,
                                                                           
expr->resulttype, -1,
                                                                           
expr->resultcollid,
                                                                           
InvalidOid,
***************
*** 3417,3427 **** simplify_boolean_equality(Oid opno, List *args)
   * Subroutine for eval_const_expressions: try to simplify a function call
   * (which might originally have been an operator; we don't care)
   *
!  * Inputs are the function OID, actual result type OID (which is needed for
!  * polymorphic functions), result typmod, result collation,
!  * the input collation to use for the function,
!  * the pre-simplified argument list, and some flags;
!  * also the context data for eval_const_expressions.
   *
   * Returns a simplified expression if successful, or NULL if cannot
   * simplify the function call.
--- 3422,3436 ----
   * Subroutine for eval_const_expressions: try to simplify a function call
   * (which might originally have been an operator; we don't care)
   *
!  * Inputs are the original expression (can be NULL), function OID, actual
!  * result type OID (which is needed for polymorphic functions), result typmod,
!  * result collation, the input collation to use for the function, the
!  * pre-simplified argument list, and some flags; also the context data for
!  * eval_const_expressions.  In common cases, several of the arguments could be
!  * derived from the original expression.  Sending them separately avoids
!  * duplicating NodeTag-specific knowledge, and it's necessary for CoerceViaIO.
!  * A NULL original expression disables use of transform functions while
!  * retaining all other behaviors.
   *
   * Returns a simplified expression if successful, or NULL if cannot
   * simplify the function call.
***************
*** 3433,3446 **** simplify_boolean_equality(Oid opno, List *args)
   * pass-by-reference, and it may get modified even if simplification fails.
   */
  static Expr *
! simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
!                                 Oid result_collid, Oid input_collid, List 
**args,
                                  bool has_named_args,
                                  bool allow_inline,
                                  eval_const_expressions_context *context)
  {
        HeapTuple       func_tuple;
        Expr       *newexpr;
  
        /*
         * We have two strategies for simplification: either execute the 
function
--- 3442,3457 ----
   * pass-by-reference, and it may get modified even if simplification fails.
   */
  static Expr *
! simplify_function(Expr *oldexpr, Oid funcid,
!                                 Oid result_type, int32 result_typmod, Oid 
result_collid,
!                                 Oid input_collid, List **args,
                                  bool has_named_args,
                                  bool allow_inline,
                                  eval_const_expressions_context *context)
  {
        HeapTuple       func_tuple;
        Expr       *newexpr;
+       Oid                     transform;
  
        /*
         * We have two strategies for simplification: either execute the 
function
***************
*** 3468,3473 **** simplify_function(Oid funcid, Oid result_type, int32 
result_typmod,
--- 3479,3489 ----
                                                                result_collid, 
input_collid, *args,
                                                                func_tuple, 
context);
  
+       transform = ((Form_pg_proc) GETSTRUCT(func_tuple))->protransform;
+       if (!newexpr && OidIsValid(transform) && oldexpr)
+               newexpr = (Expr *) DatumGetPointer(OidFunctionCall1(transform,
+                                                                               
                                        PointerGetDatum(oldexpr)));
+ 
        if (!newexpr && allow_inline)
                newexpr = inline_function(funcid, result_type, result_collid,
                                                                  input_collid, 
*args,
diff --git a/src/backend/parser/parse_clausindex c5fe6b6..a8549e0 100644
*** a/src/backend/parser/parse_clause.c
--- b/src/backend/parser/parse_clause.c
***************
*** 2278,2280 **** transformFrameOffset(ParseState *pstate, int frameOptions, 
Node *clause)
--- 2278,2302 ----
  
        return node;
  }
+ 
+ /*
+  * relabel_to_typmod
+  *            Add a RelabelType node that changes just the typmod, and remove 
all
+  *            now-superfluous RelabelType nodes beneath it.
+  */
+ Node *
+ relabel_to_typmod(Node *expr, int32 typmod)
+ {
+       Oid                     type = exprType(expr);
+       Oid                     coll = exprCollation(expr);
+ 
+       /*
+        * Strip any existing RelabelType, then add one. This is to preserve the
+        * invariant of no redundant RelabelTypes.
+        */
+       while (IsA(expr, RelabelType))
+               expr = (Node *) ((RelabelType *) expr)->arg;
+ 
+       return (Node *) makeRelabelType((Expr *) expr, type, typmod, coll,
+                                                                       
COERCE_DONTCARE);
+ }
diff --git a/src/backend/utils/adt/varchindex 1c0ef92..efa483d 100644
*** a/src/backend/utils/adt/varchar.c
--- b/src/backend/utils/adt/varchar.c
***************
*** 18,23 ****
--- 18,25 ----
  #include "access/hash.h"
  #include "access/tuptoaster.h"
  #include "libpq/pqformat.h"
+ #include "nodes/nodeFuncs.h"
+ #include "parser/parse_clause.h"
  #include "utils/array.h"
  #include "utils/builtins.h"
  #include "mb/pg_wchar.h"
***************
*** 549,554 **** varcharsend(PG_FUNCTION_ARGS)
--- 551,588 ----
  
  
  /*
+  * 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
+ varchar_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) - VARHDRSZ;
+               int32           new_max = new_typmod - VARHDRSZ;
+ 
+               if (new_max < 0 || (old_max >= 0 && old_max <= new_max))
+                       ret = relabel_to_typmod(source, new_typmod);
+       }
+ 
+       PG_RETURN_POINTER(ret);
+ }
+ 
+ /*
   * Converts a VARCHAR type to the specified size.
   *
   * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
diff --git a/src/include/catalog/pg_clindex ffcce3c..002ae6b 100644
*** a/src/include/catalog/pg_class.h
--- b/src/include/catalog/pg_class.h
***************
*** 134,140 **** DATA(insert OID = 1247 (  pg_type              PGNSP 71 0 
PGUID 0 0 0 0 0 0 0 f f p r 29 0 t
  DESCR("");
  DATA(insert OID = 1249 (  pg_attribute        PGNSP 75 0 PGUID 0 0 0 0 0 0 0 
f f p r 20 0 f f f f f 3 _null_ _null_ ));
  DESCR("");
! DATA(insert OID = 1255 (  pg_proc             PGNSP 81 0 PGUID 0 0 0 0 0 0 0 
f f p r 25 0 t f f f f 3 _null_ _null_ ));
  DESCR("");
  DATA(insert OID = 1259 (  pg_class            PGNSP 83 0 PGUID 0 0 0 0 0 0 0 
f f p r 26 0 t f f f f 3 _null_ _null_ ));
  DESCR("");
--- 134,140 ----
  DESCR("");
  DATA(insert OID = 1249 (  pg_attribute        PGNSP 75 0 PGUID 0 0 0 0 0 0 0 
f f p r 20 0 f f f f f 3 _null_ _null_ ));
  DESCR("");
! DATA(insert OID = 1255 (  pg_proc             PGNSP 81 0 PGUID 0 0 0 0 0 0 0 
f f p r 26 0 t f f f f 3 _null_ _null_ ));
  DESCR("");
  DATA(insert OID = 1259 (  pg_class            PGNSP 83 0 PGUID 0 0 0 0 0 0 0 
f f p r 26 0 t f f f f 3 _null_ _null_ ));
  DESCR("");
diff --git a/src/include/catalog/pg_pindex a66ecf1..6980d3e 100644
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 42,47 **** CATALOG(pg_proc,1255) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81) 
BKI_SCHEMA_MACRO
--- 42,48 ----
        float4          procost;                /* estimated execution cost */
        float4          prorows;                /* estimated # of rows out (if 
proretset) */
        Oid                     provariadic;    /* element type of variadic 
array, or 0 */
+       regproc         protransform;   /* transforms calls to it during 
planning */
        bool            proisagg;               /* is it an aggregate? */
        bool            proiswindow;    /* is it a window function? */
        bool            prosecdef;              /* security definer */
***************
*** 76,82 **** typedef FormData_pg_proc *Form_pg_proc;
   *            compiler constants for pg_proc
   * ----------------
   */
! #define Natts_pg_proc                                 25
  #define Anum_pg_proc_proname                  1
  #define Anum_pg_proc_pronamespace             2
  #define Anum_pg_proc_proowner                 3
--- 77,83 ----
   *            compiler constants for pg_proc
   * ----------------
   */
! #define Natts_pg_proc                                 26
  #define Anum_pg_proc_proname                  1
  #define Anum_pg_proc_pronamespace             2
  #define Anum_pg_proc_proowner                 3
***************
*** 84,107 **** typedef FormData_pg_proc *Form_pg_proc;
  #define Anum_pg_proc_procost                  5
  #define Anum_pg_proc_prorows                  6
  #define Anum_pg_proc_provariadic              7
! #define Anum_pg_proc_proisagg                 8
! #define Anum_pg_proc_proiswindow              9
! #define Anum_pg_proc_prosecdef                        10
! #define Anum_pg_proc_proisstrict              11
! #define Anum_pg_proc_proretset                        12
! #define Anum_pg_proc_provolatile              13
! #define Anum_pg_proc_pronargs                 14
! #define Anum_pg_proc_pronargdefaults  15
! #define Anum_pg_proc_prorettype                       16
! #define Anum_pg_proc_proargtypes              17
! #define Anum_pg_proc_proallargtypes           18
! #define Anum_pg_proc_proargmodes              19
! #define Anum_pg_proc_proargnames              20
! #define Anum_pg_proc_proargdefaults           21
! #define Anum_pg_proc_prosrc                           22
! #define Anum_pg_proc_probin                           23
! #define Anum_pg_proc_proconfig                        24
! #define Anum_pg_proc_proacl                           25
  
  /* ----------------
   *            initial contents of pg_proc
--- 85,109 ----
  #define Anum_pg_proc_procost                  5
  #define Anum_pg_proc_prorows                  6
  #define Anum_pg_proc_provariadic              7
! #define Anum_pg_proc_protransform             8
! #define Anum_pg_proc_proisagg                 9
! #define Anum_pg_proc_proiswindow              10
! #define Anum_pg_proc_prosecdef                        11
! #define Anum_pg_proc_proisstrict              12
! #define Anum_pg_proc_proretset                        13
! #define Anum_pg_proc_provolatile              14
! #define Anum_pg_proc_pronargs                 15
! #define Anum_pg_proc_pronargdefaults  16
! #define Anum_pg_proc_prorettype                       17
! #define Anum_pg_proc_proargtypes              18
! #define Anum_pg_proc_proallargtypes           19
! #define Anum_pg_proc_proargmodes              20
! #define Anum_pg_proc_proargnames              21
! #define Anum_pg_proc_proargdefaults           22
! #define Anum_pg_proc_prosrc                           23
! #define Anum_pg_proc_probin                           24
! #define Anum_pg_proc_proconfig                        25
! #define Anum_pg_proc_proacl                           26
  
  /* ----------------
   *            initial contents of pg_proc
***************
*** 743,749 **** DATA(insert OID = 659 (  namene                           
PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "
  
  DATA(insert OID = 668 (  bpchar                          PGNSP PGUID 12 1 0 0 
0 f f f t f i 3 0 1042 "1042 23 16" _null_ _null_ _null_ _null_ bpchar _null_ 
_null_ _null_ ));
  DESCR("adjust char() to typmod length");
! DATA(insert OID = 669 (  varchar                 PGNSP PGUID 12 1 0 0 0 f f f 
t f i 3 0 1043 "1043 23 16" _null_ _null_ _null_ _null_ varchar _null_ _null_ 
_null_ ));
  DESCR("adjust varchar() to typmod length");
  
  DATA(insert OID = 676 (  mktinterval     PGNSP PGUID 12 1 0 0 0 f f f t f i 2 
0 704 "702 702" _null_ _null_ _null_ _null_ mktinterval _null_ _null_ _null_ ));
--- 745,753 ----
  
  DATA(insert OID = 668 (  bpchar                          PGNSP PGUID 12 1 0 0 
0 f f f t f i 3 0 1042 "1042 23 16" _null_ _null_ _null_ _null_ bpchar _null_ 
_null_ _null_ ));
  DESCR("adjust char() to typmod length");
! DATA(insert OID = 3097 ( varchar_transform PGNSP PGUID 12 1 0 0 0 f f f t f i 
1 0 2281 "2281" _null_ _null_ _null_ _null_ varchar_transform _null_ _null_ 
_null_ ));
! DESCR("transform a varchar length coercion");
! DATA(insert OID = 669 (  varchar                 PGNSP PGUID 12 1 0 0 3097 f 
f f t f i 3 0 1043 "1043 23 16" _null_ _null_ _null_ _null_ varchar _null_ 
_null_ _null_ ));
  DESCR("adjust varchar() to typmod length");
  
  DATA(insert OID = 676 (  mktinterval     PGNSP PGUID 12 1 0 0 0 f f f t f i 2 
0 704 "702 702" _null_ _null_ _null_ _null_ mktinterval _null_ _null_ _null_ ));
diff --git a/src/include/parser/parsindex 09ef450..f5ce2ff 100644
*** a/src/include/parser/parse_clause.h
--- b/src/include/parser/parse_clause.h
***************
*** 44,47 **** extern List *transformDistinctOnClause(ParseState *pstate, List 
*distinctlist,
--- 44,49 ----
  extern Index assignSortGroupRef(TargetEntry *tle, List *tlist);
  extern bool targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList);
  
+ extern Node *relabel_to_typmod(Node *expr, int32 typmod);
+ 
  #endif   /* PARSE_CLAUSE_H */
diff --git a/src/include/utils/builtins.index 14215db..8a1c82e 100644
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 684,689 **** extern Datum varcharrecv(PG_FUNCTION_ARGS);
--- 684,690 ----
  extern Datum varcharsend(PG_FUNCTION_ARGS);
  extern Datum varchartypmodin(PG_FUNCTION_ARGS);
  extern Datum varchartypmodout(PG_FUNCTION_ARGS);
+ extern Datum varchar_transform(PG_FUNCTION_ARGS);
  extern Datum varchar(PG_FUNCTION_ARGS);
  
  /* varlena.c */
diff --git a/src/test/regress/expecindex 3326f93..1b5a878 100644
-- 
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