Datum pg_relation_size_name(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_P(0); RangeVar *relrv; Relation rel; int64 size; if (GP_ROLE_EXECUTE == Gp_role) { ereport(ERROR, (errcode(ERRCODE_GP_COMMAND_ERROR), errmsg("pg_relation_size: cannot be executed in segment"))); } relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); 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); relation_close(rel, AccessShareLock); PG_RETURN_INT64(size); }
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); }