|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.182 2005/10/1918:18:33 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.183 2005/10/1922:30:30 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -64,6 +64,8 @@ static Datum ExecEvalAggref(AggrefExprState *aggref,
|
64 | 64 | bool*isNull,ExprDoneCond*isDone);
|
65 | 65 | staticDatumExecEvalVar(ExprState*exprstate,ExprContext*econtext,
|
66 | 66 | bool*isNull,ExprDoneCond*isDone);
|
| 67 | +staticDatumExecEvalWholeRowVar(ExprState*exprstate,ExprContext*econtext, |
| 68 | +bool*isNull,ExprDoneCond*isDone); |
67 | 69 | staticDatumExecEvalConst(ExprState*exprstate,ExprContext*econtext,
|
68 | 70 | bool*isNull,ExprDoneCond*isDone);
|
69 | 71 | staticDatumExecEvalParam(ExprState*exprstate,ExprContext*econtext,
|
@@ -448,9 +450,9 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
|
448 | 450 | /*
|
449 | 451 | * Get the slot and attribute number we want
|
450 | 452 | *
|
451 |
| - * The asserts check that references to system attributes only appear at the |
452 |
| - * level of a relation scan; at higher levels, system attributes must be |
453 |
| - * treated as ordinary variables (since we no longer have access to the |
| 453 | + * The asserts check that references to system attributes only appear at |
| 454 | + *thelevel of a relation scan; at higher levels, system attributes must |
| 455 | + *betreated as ordinary variables (since we no longer have access to the |
454 | 456 | * original tuple).
|
455 | 457 | */
|
456 | 458 | attnum=variable->varattno;
|
@@ -505,6 +507,77 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
|
505 | 507 | returnslot_getattr(slot,attnum,isNull);
|
506 | 508 | }
|
507 | 509 |
|
| 510 | +/* ---------------------------------------------------------------- |
| 511 | + *ExecEvalWholeRowVar |
| 512 | + * |
| 513 | + *Returns a Datum for a whole-row variable. |
| 514 | + * |
| 515 | + *This could be folded into ExecEvalVar, but we make it a separate |
| 516 | + *routine so as not to slow down ExecEvalVar with tests for this |
| 517 | + *uncommon case. |
| 518 | + * ---------------------------------------------------------------- |
| 519 | + */ |
| 520 | +staticDatum |
| 521 | +ExecEvalWholeRowVar(ExprState*exprstate,ExprContext*econtext, |
| 522 | +bool*isNull,ExprDoneCond*isDone) |
| 523 | +{ |
| 524 | +Var*variable= (Var*)exprstate->expr; |
| 525 | +TupleTableSlot*slot; |
| 526 | +HeapTupletuple; |
| 527 | +TupleDesctupleDesc; |
| 528 | +HeapTupleHeaderdtuple; |
| 529 | + |
| 530 | +if (isDone) |
| 531 | +*isDone=ExprSingleResult; |
| 532 | +*isNull= false; |
| 533 | + |
| 534 | +Assert(variable->varattno==InvalidAttrNumber); |
| 535 | + |
| 536 | +/* |
| 537 | + * Whole-row Vars can only appear at the level of a relation scan, |
| 538 | + * never in a join. |
| 539 | + */ |
| 540 | +Assert(variable->varno!=INNER); |
| 541 | +Assert(variable->varno!=OUTER); |
| 542 | +slot=econtext->ecxt_scantuple; |
| 543 | + |
| 544 | +tuple=slot->tts_tuple; |
| 545 | +tupleDesc=slot->tts_tupleDescriptor; |
| 546 | + |
| 547 | +/* |
| 548 | + * We have to make a copy of the tuple so we can safely insert the |
| 549 | + * Datum overhead fields, which are not set in on-disk tuples. |
| 550 | + */ |
| 551 | +dtuple= (HeapTupleHeader)palloc(tuple->t_len); |
| 552 | +memcpy((char*)dtuple, (char*)tuple->t_data,tuple->t_len); |
| 553 | + |
| 554 | +HeapTupleHeaderSetDatumLength(dtuple,tuple->t_len); |
| 555 | + |
| 556 | +/* |
| 557 | + * If the Var identifies a named composite type, label the tuple |
| 558 | + * with that type; otherwise use what is in the tupleDesc. |
| 559 | + * |
| 560 | + * It's likely that the slot's tupleDesc is a record type; if so, |
| 561 | + * make sure it's been "blessed", so that the Datum can be interpreted |
| 562 | + * later. |
| 563 | + */ |
| 564 | +if (variable->vartype!=RECORDOID) |
| 565 | +{ |
| 566 | +HeapTupleHeaderSetTypeId(dtuple,variable->vartype); |
| 567 | +HeapTupleHeaderSetTypMod(dtuple,variable->vartypmod); |
| 568 | +} |
| 569 | +else |
| 570 | +{ |
| 571 | +if (tupleDesc->tdtypeid==RECORDOID&& |
| 572 | +tupleDesc->tdtypmod<0) |
| 573 | +assign_record_type_typmod(tupleDesc); |
| 574 | +HeapTupleHeaderSetTypeId(dtuple,tupleDesc->tdtypeid); |
| 575 | +HeapTupleHeaderSetTypMod(dtuple,tupleDesc->tdtypmod); |
| 576 | +} |
| 577 | + |
| 578 | +returnPointerGetDatum(dtuple); |
| 579 | +} |
| 580 | + |
508 | 581 | /* ----------------------------------------------------------------
|
509 | 582 | *ExecEvalConst
|
510 | 583 | *
|
@@ -2841,8 +2914,15 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
2841 | 2914 | switch (nodeTag(node))
|
2842 | 2915 | {
|
2843 | 2916 | caseT_Var:
|
2844 |
| -state= (ExprState*)makeNode(ExprState); |
2845 |
| -state->evalfunc=ExecEvalVar; |
| 2917 | +{ |
| 2918 | +Var*var= (Var*)node; |
| 2919 | + |
| 2920 | +state= (ExprState*)makeNode(ExprState); |
| 2921 | +if (var->varattno!=InvalidAttrNumber) |
| 2922 | +state->evalfunc=ExecEvalVar; |
| 2923 | +else |
| 2924 | +state->evalfunc=ExecEvalWholeRowVar; |
| 2925 | +} |
2846 | 2926 | break;
|
2847 | 2927 | caseT_Const:
|
2848 | 2928 | state= (ExprState*)makeNode(ExprState);
|
|