* Search the actual catalogs, rather than the cache. * * This is kept separate from SearchCatCacheInternal() to keep the fast-path * as small as possible. To avoid that effort being undone by a helpful * compiler, try to explicitly forbid inlining. */
| 1363 | * compiler, try to explicitly forbid inlining. |
| 1364 | */ |
| 1365 | static pg_noinline HeapTuple |
| 1366 | SearchCatCacheMiss(CatCache *cache, |
| 1367 | int nkeys, |
| 1368 | uint32 hashValue, |
| 1369 | Index hashIndex, |
| 1370 | Datum v1, |
| 1371 | Datum v2, |
| 1372 | Datum v3, |
| 1373 | Datum v4) |
| 1374 | { |
| 1375 | ScanKeyData cur_skey[CATCACHE_MAXKEYS]; |
| 1376 | Relation relation; |
| 1377 | SysScanDesc scandesc; |
| 1378 | HeapTuple ntp; |
| 1379 | CatCTup *ct; |
| 1380 | Datum arguments[CATCACHE_MAXKEYS]; |
| 1381 | |
| 1382 | /* Initialize local parameter array */ |
| 1383 | arguments[0] = v1; |
| 1384 | arguments[1] = v2; |
| 1385 | arguments[2] = v3; |
| 1386 | arguments[3] = v4; |
| 1387 | |
| 1388 | /* |
| 1389 | * Ok, need to make a lookup in the relation, copy the scankey and fill |
| 1390 | * out any per-call fields. |
| 1391 | */ |
| 1392 | memcpy(cur_skey, cache->cc_skey, sizeof(ScanKeyData) * nkeys); |
| 1393 | cur_skey[0].sk_argument = v1; |
| 1394 | cur_skey[1].sk_argument = v2; |
| 1395 | cur_skey[2].sk_argument = v3; |
| 1396 | cur_skey[3].sk_argument = v4; |
| 1397 | |
| 1398 | /* |
| 1399 | * Tuple was not found in cache, so we have to try to retrieve it directly |
| 1400 | * from the relation. If found, we will add it to the cache; if not |
| 1401 | * found, we will add a negative cache entry instead. |
| 1402 | * |
| 1403 | * NOTE: it is possible for recursive cache lookups to occur while reading |
| 1404 | * the relation --- for example, due to shared-cache-inval messages being |
| 1405 | * processed during table_open(). This is OK. It's even possible for one |
| 1406 | * of those lookups to find and enter the very same tuple we are trying to |
| 1407 | * fetch here. If that happens, we will enter a second copy of the tuple |
| 1408 | * into the cache. The first copy will never be referenced again, and |
| 1409 | * will eventually age out of the cache, so there's no functional problem. |
| 1410 | * This case is rare enough that it's not worth expending extra cycles to |
| 1411 | * detect. |
| 1412 | */ |
| 1413 | relation = table_open(cache->cc_reloid, AccessShareLock); |
| 1414 | |
| 1415 | scandesc = systable_beginscan(relation, |
| 1416 | cache->cc_indexoid, |
| 1417 | IndexScanOK(cache, cur_skey), |
| 1418 | NULL, |
| 1419 | nkeys, |
| 1420 | cur_skey); |
| 1421 | |
| 1422 | ct = NULL; |
no test coverage detected