/* ---------------------------------------------------------------- * caql_getattname() * * The equivalent of SearchSysCacheCopyAttName - * caql_getfirst(pCtx, * "SELECT * FROM pg_attribute * WHERE attrelid = :relid * AND attname = :attname * AND attisdropped is false" * ); * * That is, find the existing ("undropped") attribute and return * a copy. * NOTE: need to be careful if this pCtx is used for update... * ---------------------------------------------------------------- */ HeapTuple caql_getattname(cqContext *pCtx, Oid relid, const char *attname) { HeapTuple tup; disable_attribute_check(relid); tup = SearchSysCacheCopyAttName(relid, attname); if (pCtx) { /* treat as ATTNAME cache lookup */ pCtx->cq_usesyscache = true; pCtx->cq_cacheId = ATTNAME; pCtx->cq_NumKeys = 2; /* NOTE: no valid relation for subsequent INSERT/UPDATE/DELETE *unless* an external relation is supplied */ if (!pCtx->cq_externrel) { pCtx->cq_externrel = true; /* pretend we have external relation */ pCtx->cq_heap_rel = InvalidRelation; } if (!pCtx->cq_setidxOK) pCtx->cq_useidxOK = true; pCtx->cq_lasttup = tup; } return (tup); }
/* ---------------------------------------------------------------- * caql_getattname_scan() * * The equivalent of SearchSysCacheAttName - * caql_beginscan(pCtx, * "SELECT * FROM pg_attribute * WHERE attrelid = :relid * AND attname = :attname * AND attisdropped is false" * ); * * That is, find the existing ("undropped") attribute and return * a context where the tuple is already fetched. Retrieve the tuple * using caql_get_current() * NOTE: this is hideous. My abject apologies. * NOTE: need to be careful if this pCtx is used for update... * ---------------------------------------------------------------- */ cqContext * caql_getattname_scan(cqContext *pCtx0, Oid relid, const char *attname) { cqContext *pCtx; HeapTuple tup; disable_attribute_check(relid); /* use the provided context, or *allocate* a clean one */ if (pCtx0) pCtx = pCtx0; else { pCtx = (cqContext *) palloc0(sizeof(cqContext)); pCtx->cq_free = true; /* free this context in caql_endscan */ } tup = SearchSysCacheAttName(relid, attname); if (pCtx) { /* treat as ATTNAME cache lookup */ pCtx->cq_usesyscache = true; pCtx->cq_cacheId = ATTNAME; pCtx->cq_NumKeys = 2; /* NOTE: no valid relation for subsequent INSERT/UPDATE/DELETE *unless* an external relation is supplied */ if (!pCtx->cq_externrel) { pCtx->cq_externrel = true; /* pretend we have external relation */ pCtx->cq_heap_rel = InvalidRelation; } if (!pCtx->cq_setidxOK) pCtx->cq_useidxOK = true; pCtx->cq_freeScan = true; pCtx->cq_EOF = true; /* for caql_update_current(), etc */ if (pCtx->cq_setpklock) caql_iud_switch(pCtx, 0, tup, NULL, false /* Wait */); pCtx->cq_lasttup = tup; } return pCtx; }
/* * from lsyscach.c/get_attnum(): * * Given the relation id and the attribute name, * return the "attnum" field from the attribute relation. * * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped). */ AttrNumber caql_getattnumber(Oid relid, const char *attname) { HeapTuple tp; disable_attribute_check(relid); tp = SearchSysCacheAttName(relid, attname); if (HeapTupleIsValid(tp)) { Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); AttrNumber result; result = att_tup->attnum; ReleaseSysCache(tp); return result; } else return InvalidAttrNumber; }