/* * ResQueueIdForName -- Return the Oid for a resource queue name * * Notes: * Used by the various admin commands to convert a user supplied queue name * to Oid. */ Oid GetResQueueIdForName(char *name) { Oid queueid = InvalidOid; queueid = caql_getoid( NULL, cql("SELECT oid FROM pg_resqueue " " WHERE rsqname = :1 ", CStringGetDatum(name))); return queueid; }
/* * IsErrorTable * * Returns true if relid is used as an error table, which has dependent object * that is an external table. Though it's not great we didn't have a clear * definition of Error Table, it satisfies the current requirements. */ bool IsErrorTable(Relation rel) { cqContext *pcqCtx, *pcqCtxExt, ctxExt; HeapTuple tup; Relation extrel; bool result = false; /* fast path to quick check */ if (!RelationIsHeap(rel)) return false; /* * Otherwise, go deeper and play with pg_depend... */ pcqCtx = caql_beginscan(NULL, cql("SELECT * FROM pg_depend " " WHERE refclassid = :1 " " AND refobjid = :2 " " AND refobjsubid = :3 ", ObjectIdGetDatum(RelationRelationId), ObjectIdGetDatum(RelationGetRelid(rel)), Int32GetDatum(0))); extrel = relation_open(ExtTableRelationId, AccessShareLock); pcqCtxExt = caql_addrel(cqclr(&ctxExt), extrel); while (HeapTupleIsValid(tup = caql_getnext(pcqCtx))) { Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(tup); Oid fmterrtbl; fmterrtbl = caql_getoid(pcqCtxExt, cql("SELECT fmterrtbl FROM pg_exttable " " WHERE reloid = :1", ObjectIdGetDatum(dep->objid))); if (RelationGetRelid(rel) == fmterrtbl) { result = true; break; } } relation_close(extrel, AccessShareLock); caql_endscan(pcqCtx); return result; }
Datum pg_relation_size_name(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_P(0); RangeVar *relrv; Relation rel; int64 size; /** * This function is peculiar in that it does its own dispatching. * It does not work on entry db since we do not support dispatching * from entry-db currently. */ if (Gp_role == GP_ROLE_EXECUTE && Gp_segment == -1) { elog(ERROR, "This query is not currently supported by GPDB."); } relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); if (Gp_role == GP_ROLE_EXECUTE && relrv->schemaname != NULL) { Oid namespaceId; Oid relOid; /* * Do this the hard way, because the optimizer wants to be * able to use this function on relations the user might not * have direct access to. */ AcceptInvalidationMessages(); namespaceId = caql_getoid( NULL, cql("SELECT oid FROM pg_namespace " " WHERE nspname = :1 ", CStringGetDatum(relrv->schemaname))); relOid = get_relname_relid(relrv->relname, namespaceId); if (!OidIsValid(relOid)) { size = 0; PG_RETURN_INT64(size); } /* Let relation_open do the rest */ rel = try_relation_open(relOid, AccessShareLock, false); } else rel = try_relation_openrv(relrv, AccessShareLock, false); /* * While we scan pg_class with an MVCC snapshot, * someone else might drop the table. It's better to return NULL for * already-dropped tables than throw an error and abort the whole query. */ if (!RelationIsValid(rel)) PG_RETURN_NULL(); if (rel->rd_node.relNode == 0) size = 0; else size = calculate_relation_size(rel); if (Gp_role == GP_ROLE_DISPATCH) { char * rawname; StringInfoData buffer; initStringInfo(&buffer); rawname = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(relname))); initStringInfo(&buffer); appendStringInfo(&buffer, "select sum(pg_relation_size('%s'))::int8 from gp_dist_random('gp_id');", rawname); size += get_size_from_segDBs(buffer.data); } relation_close(rel, AccessShareLock); PG_RETURN_INT64(size); }