|
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 |
|
@@ -520,6 +521,73 @@ get_rel_persistence(Oid relid) |
520 | 521 | #endif |
521 | 522 |
|
522 | 523 |
|
| 524 | +#if (PG_VERSION_NUM >=90500&&PG_VERSION_NUM <=90505)|| \ |
| 525 | +(PG_VERSION_NUM >=90600&&PG_VERSION_NUM <=90601) |
| 526 | +/* |
| 527 | + * Return a palloc'd bare attribute map for tuple conversion, matching input |
| 528 | + * and output columns by name. (Dropped columns are ignored in both input and |
| 529 | + * output.) This is normally a subroutine for convert_tuples_by_name, but can |
| 530 | + * be used standalone. |
| 531 | + */ |
| 532 | +AttrNumber* |
| 533 | +convert_tuples_by_name_map(TupleDescindesc, |
| 534 | +TupleDescoutdesc, |
| 535 | +constchar*msg) |
| 536 | +{ |
| 537 | +AttrNumber*attrMap; |
| 538 | +intn; |
| 539 | +inti; |
| 540 | + |
| 541 | +n=outdesc->natts; |
| 542 | +attrMap= (AttrNumber*)palloc0(n*sizeof(AttrNumber)); |
| 543 | +for (i=0;i<n;i++) |
| 544 | +{ |
| 545 | +Form_pg_attributeatt=outdesc->attrs[i]; |
| 546 | +char*attname; |
| 547 | +Oidatttypid; |
| 548 | +int32atttypmod; |
| 549 | +intj; |
| 550 | + |
| 551 | +if (att->attisdropped) |
| 552 | +continue;/* attrMap[i] is already 0 */ |
| 553 | +attname=NameStr(att->attname); |
| 554 | +atttypid=att->atttypid; |
| 555 | +atttypmod=att->atttypmod; |
| 556 | +for (j=0;j<indesc->natts;j++) |
| 557 | +{ |
| 558 | +att=indesc->attrs[j]; |
| 559 | +if (att->attisdropped) |
| 560 | +continue; |
| 561 | +if (strcmp(attname,NameStr(att->attname))==0) |
| 562 | +{ |
| 563 | +/* Found it, check type */ |
| 564 | +if (atttypid!=att->atttypid||atttypmod!=att->atttypmod) |
| 565 | +ereport(ERROR, |
| 566 | +(errcode(ERRCODE_DATATYPE_MISMATCH), |
| 567 | +errmsg_internal("%s",_(msg)), |
| 568 | +errdetail("Attribute \"%s\" of type %s does not match corresponding attribute of type %s.", |
| 569 | +attname, |
| 570 | +format_type_be(outdesc->tdtypeid), |
| 571 | +format_type_be(indesc->tdtypeid)))); |
| 572 | +attrMap[i]= (AttrNumber) (j+1); |
| 573 | +break; |
| 574 | +} |
| 575 | +} |
| 576 | +if (attrMap[i]==0) |
| 577 | +ereport(ERROR, |
| 578 | +(errcode(ERRCODE_DATATYPE_MISMATCH), |
| 579 | +errmsg_internal("%s",_(msg)), |
| 580 | +errdetail("Attribute \"%s\" of type %s does not exist in type %s.", |
| 581 | +attname, |
| 582 | +format_type_be(outdesc->tdtypeid), |
| 583 | +format_type_be(indesc->tdtypeid)))); |
| 584 | +} |
| 585 | + |
| 586 | +returnattrMap; |
| 587 | +} |
| 588 | +#endif |
| 589 | + |
| 590 | + |
523 | 591 |
|
524 | 592 | /* |
525 | 593 | * ------------- |
|