* Check if two tupdescs match in type of attributes */
| 1551 | * Check if two tupdescs match in type of attributes |
| 1552 | */ |
| 1553 | static bool |
| 1554 | compatCrosstabTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc) |
| 1555 | { |
| 1556 | int i; |
| 1557 | Form_pg_attribute ret_attr; |
| 1558 | Oid ret_atttypid; |
| 1559 | Form_pg_attribute sql_attr; |
| 1560 | Oid sql_atttypid; |
| 1561 | |
| 1562 | if (ret_tupdesc->natts < 2 || |
| 1563 | sql_tupdesc->natts < 3) |
| 1564 | return false; |
| 1565 | |
| 1566 | /* check the rowid types match */ |
| 1567 | ret_atttypid = TupleDescAttr(ret_tupdesc, 0)->atttypid; |
| 1568 | sql_atttypid = TupleDescAttr(sql_tupdesc, 0)->atttypid; |
| 1569 | if (ret_atttypid != sql_atttypid) |
| 1570 | ereport(ERROR, |
| 1571 | (errcode(ERRCODE_DATATYPE_MISMATCH), |
| 1572 | errmsg("invalid return type"), |
| 1573 | errdetail("SQL rowid datatype does not match " \ |
| 1574 | "return rowid datatype."))); |
| 1575 | |
| 1576 | /* |
| 1577 | * - attribute [1] of the sql tuple is the category; no need to check it - |
| 1578 | * attribute [2] of the sql tuple should match attributes [1] to [natts] |
| 1579 | * of the return tuple |
| 1580 | */ |
| 1581 | sql_attr = TupleDescAttr(sql_tupdesc, 2); |
| 1582 | for (i = 1; i < ret_tupdesc->natts; i++) |
| 1583 | { |
| 1584 | ret_attr = TupleDescAttr(ret_tupdesc, i); |
| 1585 | |
| 1586 | if (ret_attr->atttypid != sql_attr->atttypid) |
| 1587 | return false; |
| 1588 | } |
| 1589 | |
| 1590 | /* OK, the two tupdescs are compatible for our purposes */ |
| 1591 | return true; |
| 1592 | } |