|
6 | 6 | * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group |
7 | 7 | * Portions Copyright (c) 1994, Regents of the University of California |
8 | 8 | * |
9 | | - *$Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.257 2002/12/13 19:45:56 tgl Exp $ |
| 9 | + *$Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.258 2002/12/17 01:18:29 tgl Exp $ |
10 | 10 | * |
11 | 11 | *------------------------------------------------------------------------- |
12 | 12 | */ |
@@ -521,41 +521,48 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt, |
521 | 521 | * Prepare columns for assignment to target table. |
522 | 522 | */ |
523 | 523 | attnos=attrnos; |
524 | | -foreach(tl,qry->targetList) |
| 524 | +/* cannot use foreach here because of possible lremove */ |
| 525 | +tl=qry->targetList; |
| 526 | +while (tl) |
525 | 527 | { |
526 | 528 | TargetEntry*tle= (TargetEntry*)lfirst(tl); |
527 | 529 | ResTarget*col; |
528 | 530 |
|
| 531 | +/* must advance tl before lremove possibly pfree's it */ |
| 532 | +tl=lnext(tl); |
| 533 | + |
529 | 534 | if (icolumns==NIL||attnos==NIL) |
530 | 535 | elog(ERROR,"INSERT has more expressions than target columns"); |
| 536 | + |
531 | 537 | col= (ResTarget*)lfirst(icolumns); |
| 538 | +Assert(IsA(col,ResTarget)); |
532 | 539 |
|
533 | 540 | /* |
534 | 541 | * When the value is to be set to the column default we can simply |
535 | | - * dropit now and handle it later on using methods for missing |
| 542 | + * dropthe TLE now and handle it later on using methods for missing |
536 | 543 | * columns. |
537 | 544 | */ |
538 | | -if (!IsA(tle,InsertDefault)) |
| 545 | +if (IsA(tle,InsertDefault)) |
539 | 546 | { |
540 | | -Assert(IsA(col,ResTarget)); |
541 | | -Assert(!tle->resdom->resjunk); |
542 | | -updateTargetListEntry(pstate,tle,col->name,lfirsti(attnos), |
543 | | -col->indirection); |
| 547 | +qry->targetList=lremove(tle,qry->targetList); |
| 548 | +/* Note: the stmt->cols list is not adjusted to match */ |
544 | 549 | } |
545 | 550 | else |
546 | 551 | { |
547 | | -icolumns=lremove(icolumns,icolumns); |
548 | | -attnos=lremove(attnos,attnos); |
549 | | -qry->targetList=lremove(tle,qry->targetList); |
| 552 | +/* Normal case */ |
| 553 | +Assert(!tle->resdom->resjunk); |
| 554 | +updateTargetListEntry(pstate,tle,col->name,lfirsti(attnos), |
| 555 | +col->indirection); |
550 | 556 | } |
551 | 557 |
|
552 | 558 | icolumns=lnext(icolumns); |
553 | 559 | attnos=lnext(attnos); |
554 | 560 | } |
555 | 561 |
|
556 | 562 | /* |
557 | | - * Ensure that the targetlist has the same number of entries that |
558 | | - * were present in the columns list. Don't do the check for select |
| 563 | + * Ensure that the targetlist has the same number of entries that |
| 564 | + * were present in the columns list. Don't do the check unless |
| 565 | + * an explicit columns list was given, though. |
559 | 566 | * statements. |
560 | 567 | */ |
561 | 568 | if (stmt->cols!=NIL&& (icolumns!=NIL||attnos!=NIL)) |
|