I have applied the attached patch to HEAD in order to fix the problems
discussed in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-12/msg00187.php
regards, tom lane
Index: src/backend/executor/execQual.c
===
RCS file: /cvsroot/pgsql/src/backend/executor/execQual.c,v
retrieving revision 1.169
diff -c -r1.169 execQual.c
*** src/backend/executor/execQual.c 22 Sep 2004 17:41:50 - 1.169
--- src/backend/executor/execQual.c 11 Dec 2004 16:26:02 -
***
*** 87,92
--- 87,95
bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone);
+ static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
+
ExprContext *econtext,
+ bool
*isNull, ExprDoneCond *isDone);
static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
***
*** 428,434
*
*Returns a Datum whose value is the value of a range
*variable with respect to given expression context.
! * */
static Datum
ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone)
--- 431,438
*
*Returns a Datum whose value is the value of a range
*variable with respect to given expression context.
! *
! */
static Datum
ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone)
***
*** 1844,1849
--- 1848,1922
return BoolGetDatum(!AnyNull);
}
+ /*
+ *ExecEvalConvertRowtype
+ *
+ *Evaluate a rowtype coercion operation. This may require
+ *rearranging field positions.
+ *
+ */
+ static Datum
+ ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
+ ExprContext *econtext,
+ bool *isNull, ExprDoneCond *isDone)
+ {
+ HeapTuple result;
+ Datum tupDatum;
+ HeapTupleHeader tuple;
+ HeapTupleData tmptup;
+ AttrNumber *attrMap = cstate-attrMap;
+ Datum *invalues = cstate-invalues;
+ char *innulls = cstate-innulls;
+ Datum *outvalues = cstate-outvalues;
+ char *outnulls = cstate-outnulls;
+ int i;
+ int outnatts = cstate-outdesc-natts;
+
+ tupDatum = ExecEvalExpr(cstate-arg, econtext, isNull, isDone);
+
+ /* this test covers the isDone exception too: */
+ if (*isNull)
+ return tupDatum;
+
+ tuple = DatumGetHeapTupleHeader(tupDatum);
+
+ Assert(HeapTupleHeaderGetTypeId(tuple) == cstate-indesc-tdtypeid);
+ Assert(HeapTupleHeaderGetTypMod(tuple) == cstate-indesc-tdtypmod);
+
+ /*
+* heap_deformtuple needs a HeapTuple not a bare HeapTupleHeader.
+*/
+ tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
+ tmptup.t_data = tuple;
+
+ /*
+* Extract all the values of the old tuple, offsetting the arrays
+* so that invalues[0] is NULL and invalues[1] is the first
+* source attribute; this exactly matches the numbering convention
+* in attrMap.
+*/
+ heap_deformtuple(tmptup, cstate-indesc, invalues + 1, innulls + 1);
+ invalues[0] = (Datum) 0;
+ innulls[0] = 'n';
+
+ /*
+* Transpose into proper fields of the new tuple.
+*/
+ for (i = 0; i outnatts; i++)
+ {
+ int j = attrMap[i];
+
+ outvalues[i] = invalues[j];
+ outnulls[i] = innulls[j];
+ }
+
+ /*
+* Now form the new tuple.
+*/
+ result = heap_formtuple(cstate-outdesc, outvalues, outnulls);
+
+ return HeapTupleGetDatum(result);
+ }
/*
*ExecEvalCase
***
*** 2969,2974
--- 3042,3109
state = (ExprState *) gstate;
}
break;
+ case T_ConvertRowtypeExpr:
+ {
+ ConvertRowtypeExpr *convert =