@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / executor / execQual . c , v 1.250 .2 .2 2009 / 12 / 29 17 : 41 : 09 heikki Exp $
* $ PostgreSQL : pgsql / src / backend / executor / execQual . c , v 1.250 .2 .3 2010 / 01 / 11 15 : 31 : 12 tgl Exp $
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
@ -599,17 +599,23 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
/*
/*
* We really only care about number of attributes and data type .
* We really only care about number of attributes and data type .
* Also , we can ignore type mismatch on columns that are dropped
* Also , we can ignore type mismatch on columns that are dropped
* in the destination type , so long as the physical storage
* in the destination type , so long as ( 1 ) the physical storage
* matches . This is helpful in some cases involving out - of - date
* matches or ( 2 ) the actual column value is NULL . Case ( 1 ) is
* cached plans . Also , we have to allow the case that the slot
* helpful in some cases involving out - of - date cached plans , while
* has more columns than the Var ' s type , because we might be
* case ( 2 ) is expected behavior in situations such as an INSERT
* looking at the output of a subplan that includes resjunk
* into a table with dropped columns ( the planner typically
* columns . ( XXX it would be nice to verify that the extra
* generates an INT4 NULL regardless of the dropped column type ) .
* columns are all marked resjunk , but we haven ' t got access to
* If we find a dropped column and cannot verify that case ( 1 )
* the subplan targetlist here . . . ) Resjunk columns should always
* holds , we have to use ExecEvalWholeRowSlow to check ( 2 ) for
* be at the end of a targetlist , so it ' s sufficient to ignore
* each row . Also , we have to allow the case that the slot has
* them here ; but we need to use ExecEvalWholeRowSlow to get rid
* more columns than the Var ' s type , because we might be looking
* of them in the eventual output tuples .
* at the output of a subplan that includes resjunk columns .
* ( XXX it would be nice to verify that the extra columns are all
* marked resjunk , but we haven ' t got access to the subplan
* targetlist here . . . ) Resjunk columns should always be at the end
* of a targetlist , so it ' s sufficient to ignore them here ; but we
* need to use ExecEvalWholeRowSlow to get rid of them in the
* eventual output tuples .
*/
*/
var_tupdesc = lookup_rowtype_tupdesc ( variable - > vartype , - 1 ) ;
var_tupdesc = lookup_rowtype_tupdesc ( variable - > vartype , - 1 ) ;
@ -623,7 +629,7 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
slot_tupdesc - > natts ,
slot_tupdesc - > natts ,
var_tupdesc - > natts ) ) ) ;
var_tupdesc - > natts ) ) ) ;
else if ( var_tupdesc - > natts < slot_tupdesc - > natts )
else if ( var_tupdesc - > natts < slot_tupdesc - > natts )
needslow = true ;
needslow = true ; /* need to trim trailing atts */
for ( i = 0 ; i < var_tupdesc - > natts ; i + + )
for ( i = 0 ; i < var_tupdesc - > natts ; i + + )
{
{
@ -643,11 +649,7 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
if ( vattr - > attlen ! = sattr - > attlen | |
if ( vattr - > attlen ! = sattr - > attlen | |
vattr - > attalign ! = sattr - > attalign )
vattr - > attalign ! = sattr - > attalign )
ereport ( ERROR ,
needslow = true ; /* need runtime check for null */
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " table row type and query-specified row type do not match " ) ,
errdetail ( " Physical storage mismatch on dropped attribute at ordinal position %d. " ,
i + 1 ) ) ) ;
}
}
ReleaseTupleDesc ( var_tupdesc ) ;
ReleaseTupleDesc ( var_tupdesc ) ;
@ -757,7 +759,7 @@ ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
/* ----------------------------------------------------------------
/* ----------------------------------------------------------------
* ExecEvalWholeRowSlow
* ExecEvalWholeRowSlow
*
*
* Returns a Datum for a whole - row variable , in the " slow " case where
* Returns a Datum for a whole - row variable , in the " slow " cases where
* we can ' t just copy the subplan ' s output .
* we can ' t just copy the subplan ' s output .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
@ -770,24 +772,45 @@ ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
HeapTuple tuple ;
HeapTuple tuple ;
TupleDesc var_tupdesc ;
TupleDesc var_tupdesc ;
HeapTupleHeader dtuple ;
HeapTupleHeader dtuple ;
int i ;
if ( isDone )
if ( isDone )
* isDone = ExprSingleResult ;
* isDone = ExprSingleResult ;
* isNull = false ;
* isNull = false ;
/*
/*
* Currently , the only case handled here is stripping of trailing resjunk
* Currently , the only data modification case handled here is stripping of
* fields , which we do in a slightly chintzy way by just adjusting the
* trailing resjunk fields , which we do in a slightly chintzy way by just
* tuple ' s natts header field . Possibly there will someday be a need for
* adjusting the tuple ' s natts header field . Possibly there will someday
* more - extensive rearrangements , in which case it ' d be worth
* be a need for more - extensive rearrangements , in which case we ' d
* disassembling and reassembling the tuple ( perhaps use a JunkFilter for
* probably use tupconvert . c .
* that ? )
*/
*/
Assert ( variable - > vartype ! = RECORDOID ) ;
Assert ( variable - > vartype ! = RECORDOID ) ;
var_tupdesc = lookup_rowtype_tupdesc ( variable - > vartype , - 1 ) ;
var_tupdesc = lookup_rowtype_tupdesc ( variable - > vartype , - 1 ) ;
tuple = ExecFetchSlotTuple ( slot ) ;
tuple = ExecFetchSlotTuple ( slot ) ;
Assert ( HeapTupleHeaderGetNatts ( tuple - > t_data ) > = var_tupdesc - > natts ) ;
/* Check to see if any dropped attributes are non-null */
for ( i = 0 ; i < var_tupdesc - > natts ; i + + )
{
Form_pg_attribute vattr = var_tupdesc - > attrs [ i ] ;
Form_pg_attribute sattr = slot - > tts_tupleDescriptor - > attrs [ i ] ;
if ( ! vattr - > attisdropped )
continue ; /* already checked non-dropped cols */
if ( heap_attisnull ( tuple , i + 1 ) )
continue ; /* null is always okay */
if ( vattr - > attlen ! = sattr - > attlen | |
vattr - > attalign ! = sattr - > attalign )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " table row type and query-specified row type do not match " ) ,
errdetail ( " Physical storage mismatch on dropped attribute at ordinal position %d. " ,
i + 1 ) ) ) ;
}
/*
/*
* We have to make a copy of the tuple so we can safely insert the Datum
* We have to make a copy of the tuple so we can safely insert the Datum
* overhead fields , which are not set in on - disk tuples ; not to mention
* overhead fields , which are not set in on - disk tuples ; not to mention
@ -800,7 +823,6 @@ ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
HeapTupleHeaderSetTypeId ( dtuple , variable - > vartype ) ;
HeapTupleHeaderSetTypeId ( dtuple , variable - > vartype ) ;
HeapTupleHeaderSetTypMod ( dtuple , variable - > vartypmod ) ;
HeapTupleHeaderSetTypMod ( dtuple , variable - > vartypmod ) ;
Assert ( HeapTupleHeaderGetNatts ( dtuple ) > = var_tupdesc - > natts ) ;
HeapTupleHeaderSetNatts ( dtuple , var_tupdesc - > natts ) ;
HeapTupleHeaderSetNatts ( dtuple , var_tupdesc - > natts ) ;
ReleaseTupleDesc ( var_tupdesc ) ;
ReleaseTupleDesc ( var_tupdesc ) ;