Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit292176a

Browse files
committed
Improve ExecEvalVar's handling of whole-row variables in cases where the
rowtype contains dropped columns. Sometimes the input tuple will be formedfrom a select targetlist in which dropped columns are filled with a NULLof an arbitrary type (the planner typically uses INT4, since it can't tellwhat type the dropped column really was). So we need to relax the rowtypecompatibility check to not insist on physical compatibility if the actualcolumn value is NULL.In principle we might need to do this for functions returning compositetypes, too (see tupledesc_match()). In practice there doesn't seem to bea bug there, probably because the function will be using the same cachedrowtype descriptor as the caller. Fixing that code path would requiresignificant rearrangement, so I left it alone for now.Per complaint from Filip Rembialkowski.
1 parentccaad19 commit292176a

File tree

1 file changed

+48
-26
lines changed

1 file changed

+48
-26
lines changed

‎src/backend/executor/execQual.c

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.260 2010/01/09 20:46:19 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.261 2010/01/11 15:31:04 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -591,17 +591,23 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
591591
/*
592592
* We really only care about number of attributes and data type.
593593
* Also, we can ignore type mismatch on columns that are dropped
594-
* in the destination type, so long as the physical storage
595-
* matches. This is helpful in some cases involving out-of-date
596-
* cached plans. Also, we have to allow the case that the slot
597-
* has more columns than the Var's type, because we might be
598-
* looking at the output of a subplan that includes resjunk
599-
* columns. (XXX it would be nice to verify that the extra
600-
* columns are all marked resjunk, but we haven't got access to
601-
* the subplan targetlist here...)Resjunk columns should always
602-
* be at the end of a targetlist, so it's sufficient to ignore
603-
* them here; but we need to use ExecEvalWholeRowSlow to get rid
604-
* of them in the eventual output tuples.
594+
* in the destination type, so long as (1) the physical storage
595+
* matches or (2) the actual column value is NULL. Case (1) is
596+
* helpful in some cases involving out-of-date cached plans, while
597+
* case (2) is expected behavior in situations such as an INSERT
598+
* into a table with dropped columns (the planner typically
599+
* generates an INT4 NULL regardless of the dropped column type).
600+
* If we find a dropped column and cannot verify that case (1)
601+
* holds, we have to use ExecEvalWholeRowSlow to check (2) for
602+
* each row. Also, we have to allow the case that the slot has
603+
* more columns than the Var's type, because we might be looking
604+
* at the output of a subplan that includes resjunk columns.
605+
* (XXX it would be nice to verify that the extra columns are all
606+
* marked resjunk, but we haven't got access to the subplan
607+
* targetlist here...) Resjunk columns should always be at the end
608+
* of a targetlist, so it's sufficient to ignore them here; but we
609+
* need to use ExecEvalWholeRowSlow to get rid of them in the
610+
* eventual output tuples.
605611
*/
606612
var_tupdesc=lookup_rowtype_tupdesc(variable->vartype,-1);
607613

@@ -615,7 +621,7 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
615621
slot_tupdesc->natts,
616622
var_tupdesc->natts)));
617623
elseif (var_tupdesc->natts<slot_tupdesc->natts)
618-
needslow= true;
624+
needslow= true;/* need to trim trailing atts */
619625

620626
for (i=0;i<var_tupdesc->natts;i++)
621627
{
@@ -635,11 +641,7 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
635641

636642
if (vattr->attlen!=sattr->attlen||
637643
vattr->attalign!=sattr->attalign)
638-
ereport(ERROR,
639-
(errcode(ERRCODE_DATATYPE_MISMATCH),
640-
errmsg("table row type and query-specified row type do not match"),
641-
errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
642-
i+1)));
644+
needslow= true;/* need runtime check for null */
643645
}
644646

645647
ReleaseTupleDesc(var_tupdesc);
@@ -766,7 +768,7 @@ ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
766768
/* ----------------------------------------------------------------
767769
*ExecEvalWholeRowSlow
768770
*
769-
*Returns a Datum for a whole-row variable, in the "slow"case where
771+
*Returns a Datum for a whole-row variable, in the "slow"cases where
770772
*we can't just copy the subplan's output.
771773
* ----------------------------------------------------------------
772774
*/
@@ -779,6 +781,7 @@ ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
779781
HeapTupletuple;
780782
TupleDescvar_tupdesc;
781783
HeapTupleHeaderdtuple;
784+
inti;
782785

783786
if (isDone)
784787
*isDone=ExprSingleResult;
@@ -802,18 +805,38 @@ ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
802805
}
803806

804807
/*
805-
* Currently, the only case handled here is stripping of trailing resjunk
806-
* fields, which we do in a slightly chintzy way by just adjusting the
807-
* tuple's natts header field. Possibly there will someday be a need for
808-
* more-extensive rearrangements, in which case it'd be worth
809-
* disassembling and reassembling the tuple (perhaps use a JunkFilter for
810-
* that?)
808+
* Currently, the only data modification case handled here is stripping of
809+
* trailing resjunk fields, which we do in a slightly chintzy way by just
810+
* adjusting the tuple's natts header field. Possibly there will someday
811+
* be a need for more-extensive rearrangements, in which case we'd
812+
* probably use tupconvert.c.
811813
*/
812814
Assert(variable->vartype!=RECORDOID);
813815
var_tupdesc=lookup_rowtype_tupdesc(variable->vartype,-1);
814816

815817
tuple=ExecFetchSlotTuple(slot);
816818

819+
Assert(HeapTupleHeaderGetNatts(tuple->t_data) >=var_tupdesc->natts);
820+
821+
/* Check to see if any dropped attributes are non-null */
822+
for (i=0;i<var_tupdesc->natts;i++)
823+
{
824+
Form_pg_attributevattr=var_tupdesc->attrs[i];
825+
Form_pg_attributesattr=slot->tts_tupleDescriptor->attrs[i];
826+
827+
if (!vattr->attisdropped)
828+
continue;/* already checked non-dropped cols */
829+
if (heap_attisnull(tuple,i+1))
830+
continue;/* null is always okay */
831+
if (vattr->attlen!=sattr->attlen||
832+
vattr->attalign!=sattr->attalign)
833+
ereport(ERROR,
834+
(errcode(ERRCODE_DATATYPE_MISMATCH),
835+
errmsg("table row type and query-specified row type do not match"),
836+
errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
837+
i+1)));
838+
}
839+
817840
/*
818841
* We have to make a copy of the tuple so we can safely insert the Datum
819842
* overhead fields, which are not set in on-disk tuples; not to mention
@@ -826,7 +849,6 @@ ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
826849
HeapTupleHeaderSetTypeId(dtuple,variable->vartype);
827850
HeapTupleHeaderSetTypMod(dtuple,variable->vartypmod);
828851

829-
Assert(HeapTupleHeaderGetNatts(dtuple) >=var_tupdesc->natts);
830852
HeapTupleHeaderSetNatts(dtuple,var_tupdesc->natts);
831853

832854
ReleaseTupleDesc(var_tupdesc);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp