|
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(TupleDesc indesc, |
| 534 | + TupleDesc outdesc, |
| 535 | + const char *msg) |
| 536 | +{ |
| 537 | + AttrNumber *attrMap; |
| 538 | + int n; |
| 539 | + int i; |
| 540 | + |
| 541 | + n = outdesc->natts; |
| 542 | + attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber)); |
| 543 | + for (i = 0; i < n; i++) |
| 544 | + { |
| 545 | + Form_pg_attribute att = outdesc->attrs[i]; |
| 546 | + char *attname; |
| 547 | + Oid atttypid; |
| 548 | + int32 atttypmod; |
| 549 | + int j; |
| 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 | + return attrMap; |
| 587 | +} |
| 588 | +#endif |
| 589 | + |
| 590 | + |
523 | 591 |
|
524 | 592 | /*
|
525 | 593 | * -------------
|
|
0 commit comments