* op_mergejoinable * * Returns true if the operator is potentially mergejoinable. (The planner * will fail to find any mergejoin plans unless there are suitable btree * opfamily entries for this operator and associated sortops. The pg_operator * flag is just a hint to tell the planner whether to bother looking.) * * In some cases (currently only array_eq and record_eq), mergejoinability
| 1527 | * is needed to check this --- by convention, pass the left input's data type. |
| 1528 | */ |
| 1529 | bool |
| 1530 | op_mergejoinable(Oid opno, Oid inputtype) |
| 1531 | { |
| 1532 | bool result = false; |
| 1533 | HeapTuple tp; |
| 1534 | TypeCacheEntry *typentry; |
| 1535 | |
| 1536 | /* |
| 1537 | * For array_eq or record_eq, we can sort if the element or field types |
| 1538 | * are all sortable. We could implement all the checks for that here, but |
| 1539 | * the typcache already does that and caches the results too, so let's |
| 1540 | * rely on the typcache. |
| 1541 | */ |
| 1542 | if (opno == ARRAY_EQ_OP) |
| 1543 | { |
| 1544 | typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC); |
| 1545 | if (typentry->cmp_proc == F_BTARRAYCMP) |
| 1546 | result = true; |
| 1547 | } |
| 1548 | else if (opno == RECORD_EQ_OP) |
| 1549 | { |
| 1550 | typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC); |
| 1551 | if (typentry->cmp_proc == F_BTRECORDCMP) |
| 1552 | result = true; |
| 1553 | } |
| 1554 | else |
| 1555 | { |
| 1556 | /* For all other operators, rely on pg_operator.oprcanmerge */ |
| 1557 | tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno)); |
| 1558 | if (HeapTupleIsValid(tp)) |
| 1559 | { |
| 1560 | Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); |
| 1561 | |
| 1562 | result = optup->oprcanmerge; |
| 1563 | ReleaseSysCache(tp); |
| 1564 | } |
| 1565 | } |
| 1566 | return result; |
| 1567 | } |
| 1568 | |
| 1569 | /* |
| 1570 | * op_hashjoinable |
no test coverage detected