* Compare the tuples in the slots by checking if they have equal values. */
| 226 | * Compare the tuples in the slots by checking if they have equal values. |
| 227 | */ |
| 228 | static bool |
| 229 | tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2, |
| 230 | TypeCacheEntry **eq) |
| 231 | { |
| 232 | int attrnum; |
| 233 | |
| 234 | Assert(slot1->tts_tupleDescriptor->natts == |
| 235 | slot2->tts_tupleDescriptor->natts); |
| 236 | |
| 237 | slot_getallattrs(slot1); |
| 238 | slot_getallattrs(slot2); |
| 239 | |
| 240 | /* Check equality of the attributes. */ |
| 241 | for (attrnum = 0; attrnum < slot1->tts_tupleDescriptor->natts; attrnum++) |
| 242 | { |
| 243 | Form_pg_attribute att; |
| 244 | TypeCacheEntry *typentry; |
| 245 | |
| 246 | /* |
| 247 | * If one value is NULL and other is not, then they are certainly not |
| 248 | * equal |
| 249 | */ |
| 250 | if (slot1->tts_isnull[attrnum] != slot2->tts_isnull[attrnum]) |
| 251 | return false; |
| 252 | |
| 253 | /* |
| 254 | * If both are NULL, they can be considered equal. |
| 255 | */ |
| 256 | if (slot1->tts_isnull[attrnum] || slot2->tts_isnull[attrnum]) |
| 257 | continue; |
| 258 | |
| 259 | att = TupleDescAttr(slot1->tts_tupleDescriptor, attrnum); |
| 260 | |
| 261 | typentry = eq[attrnum]; |
| 262 | if (typentry == NULL) |
| 263 | { |
| 264 | typentry = lookup_type_cache(att->atttypid, |
| 265 | TYPECACHE_EQ_OPR_FINFO); |
| 266 | if (!OidIsValid(typentry->eq_opr_finfo.fn_oid)) |
| 267 | ereport(ERROR, |
| 268 | (errcode(ERRCODE_UNDEFINED_FUNCTION), |
| 269 | errmsg("could not identify an equality operator for type %s", |
| 270 | format_type_be(att->atttypid)))); |
| 271 | eq[attrnum] = typentry; |
| 272 | } |
| 273 | |
| 274 | if (!DatumGetBool(FunctionCall2Coll(&typentry->eq_opr_finfo, |
| 275 | att->attcollation, |
| 276 | slot1->tts_values[attrnum], |
| 277 | slot2->tts_values[attrnum]))) |
| 278 | return false; |
| 279 | } |
| 280 | |
| 281 | return true; |
| 282 | } |
| 283 | |
| 284 | /* |
| 285 | * Search the relation 'rel' for tuple using the sequential scan. |
no test coverage detected