|
24 | 24 | #include"optimizer/prep.h"
|
25 | 25 | #include"parser/parse_utilcmd.h"
|
26 | 26 | #include"port.h"
|
| 27 | +#include"utils/builtins.h" |
27 | 28 | #include"utils/lsyscache.h"
|
28 | 29 | #include"utils/syscache.h"
|
29 | 30 |
|
@@ -575,3 +576,69 @@ set_append_rel_size_compat(PlannerInfo *root, RelOptInfo *rel, Index rti)
|
575 | 576 |
|
576 | 577 | rel->tuples=parent_rows;
|
577 | 578 | }
|
| 579 | + |
| 580 | +#if (PG_VERSION_NUM >=90500&&PG_VERSION_NUM <=90505) \ |
| 581 | +|| (PG_VERSION_NUM >=90600&&PG_VERSION_NUM <=90601) |
| 582 | +/* |
| 583 | + * Return a palloc'd bare attribute map for tuple conversion, matching input |
| 584 | + * and output columns by name. (Dropped columns are ignored in both input and |
| 585 | + * output.) This is normally a subroutine for convert_tuples_by_name, but can |
| 586 | + * be used standalone. |
| 587 | + */ |
| 588 | +AttrNumber* |
| 589 | +convert_tuples_by_name_map(TupleDescindesc, |
| 590 | +TupleDescoutdesc, |
| 591 | +constchar*msg) |
| 592 | +{ |
| 593 | +AttrNumber*attrMap; |
| 594 | +intn; |
| 595 | +inti; |
| 596 | + |
| 597 | +n=outdesc->natts; |
| 598 | +attrMap= (AttrNumber*)palloc0(n*sizeof(AttrNumber)); |
| 599 | +for (i=0;i<n;i++) |
| 600 | +{ |
| 601 | +Form_pg_attributeatt=outdesc->attrs[i]; |
| 602 | +char*attname; |
| 603 | +Oidatttypid; |
| 604 | +int32atttypmod; |
| 605 | +intj; |
| 606 | + |
| 607 | +if (att->attisdropped) |
| 608 | +continue;/* attrMap[i] is already 0 */ |
| 609 | +attname=NameStr(att->attname); |
| 610 | +atttypid=att->atttypid; |
| 611 | +atttypmod=att->atttypmod; |
| 612 | +for (j=0;j<indesc->natts;j++) |
| 613 | +{ |
| 614 | +att=indesc->attrs[j]; |
| 615 | +if (att->attisdropped) |
| 616 | +continue; |
| 617 | +if (strcmp(attname,NameStr(att->attname))==0) |
| 618 | +{ |
| 619 | +/* Found it, check type */ |
| 620 | +if (atttypid!=att->atttypid||atttypmod!=att->atttypmod) |
| 621 | +ereport(ERROR, |
| 622 | +(errcode(ERRCODE_DATATYPE_MISMATCH), |
| 623 | +errmsg_internal("%s",_(msg)), |
| 624 | +errdetail("Attribute \"%s\" of type %s does not match corresponding attribute of type %s.", |
| 625 | +attname, |
| 626 | +format_type_be(outdesc->tdtypeid), |
| 627 | +format_type_be(indesc->tdtypeid)))); |
| 628 | +attrMap[i]= (AttrNumber) (j+1); |
| 629 | +break; |
| 630 | +} |
| 631 | +} |
| 632 | +if (attrMap[i]==0) |
| 633 | +ereport(ERROR, |
| 634 | +(errcode(ERRCODE_DATATYPE_MISMATCH), |
| 635 | +errmsg_internal("%s",_(msg)), |
| 636 | +errdetail("Attribute \"%s\" of type %s does not exist in type %s.", |
| 637 | +attname, |
| 638 | +format_type_be(outdesc->tdtypeid), |
| 639 | +format_type_be(indesc->tdtypeid)))); |
| 640 | +} |
| 641 | + |
| 642 | +returnattrMap; |
| 643 | +} |
| 644 | +#endif |