|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.182 2005/10/19 18:18:33 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.183 2005/10/19 22: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 | static Datum ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
|
66 | 66 | bool *isNull, ExprDoneCond *isDone);
|
| 67 | +static Datum ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext, |
| 68 | + bool *isNull, ExprDoneCond *isDone); |
67 | 69 | static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
|
68 | 70 | bool *isNull, ExprDoneCond *isDone);
|
69 | 71 | static Datum ExecEvalParam(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 | + * the level of a relation scan; at higher levels, system attributes must |
| 455 | + * be treated 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 | return slot_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 | +static Datum |
| 521 | +ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext, |
| 522 | + bool *isNull, ExprDoneCond *isDone) |
| 523 | +{ |
| 524 | + Var *variable = (Var *) exprstate->expr; |
| 525 | + TupleTableSlot *slot; |
| 526 | + HeapTuple tuple; |
| 527 | + TupleDesc tupleDesc; |
| 528 | + HeapTupleHeader dtuple; |
| 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 | + return PointerGetDatum(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 | case T_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 | case T_Const:
|
2848 | 2928 | state = (ExprState *) makeNode(ExprState);
|
|
0 commit comments