/* * pg_get_extensiondef_string finds the foreign data wrapper that corresponds to * the given foreign tableId, and checks if an extension owns this foreign data * wrapper. If it does, the function returns the extension's definition. If not, * the function returns null. */ char * pg_get_extensiondef_string(Oid tableRelationId) { ForeignTable *foreignTable = GetForeignTable(tableRelationId); ForeignServer *server = GetForeignServer(foreignTable->serverid); ForeignDataWrapper *foreignDataWrapper = GetForeignDataWrapper(server->fdwid); StringInfoData buffer = { NULL, 0, 0, 0 }; Oid classId = ForeignDataWrapperRelationId; Oid objectId = server->fdwid; Oid extensionId = getExtensionOfObject(classId, objectId); if (OidIsValid(extensionId)) { char *extensionName = get_extension_name(extensionId); Oid extensionSchemaId = get_extension_schema(extensionId); char *extensionSchema = get_namespace_name(extensionSchemaId); initStringInfo(&buffer); appendStringInfo(&buffer, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s", quote_identifier(extensionName), quote_identifier(extensionSchema)); } else { ereport(NOTICE, (errmsg("foreign-data wrapper \"%s\" does not have an " "extension defined", foreignDataWrapper->fdwname))); } return (buffer.data); }
/* * Create partitions and return an OID of the partition that contain value */ Oid create_partitions(Oid relid, Datum value, Oid value_type, bool *crashed) { int ret; RangeEntry *ranges; Datum vals[2]; Oid oids[] = {OIDOID, value_type}; bool nulls[] = {false, false}; char *sql; bool found; int pos; PartRelationInfo *prel; RangeRelation *rangerel; FmgrInfo cmp_func; char *schema; *crashed = false; schema = get_extension_schema(); prel = get_pathman_relation_info(relid, NULL); rangerel = get_pathman_range_relation(relid, NULL); ranges = dsm_array_get_pointer(&rangerel->ranges); /* Comparison function */ cmp_func = *get_cmp_func(value_type, prel->atttype); vals[0] = ObjectIdGetDatum(relid); vals[1] = value; /* Perform PL procedure */ sql = psprintf("SELECT %s.append_partitions_on_demand_internal($1, $2)", schema); PG_TRY(); { ret = SPI_execute_with_args(sql, 2, oids, vals, nulls, false, 0); if (ret > 0) { /* Update relation info */ free_dsm_array(&rangerel->ranges); free_dsm_array(&prel->children); load_check_constraints(relid, GetCatalogSnapshot(relid)); } } PG_CATCH(); { elog(WARNING, "Attempt to create new partitions failed"); if (crashed != NULL) *crashed = true; return 0; } PG_END_TRY(); /* Repeat binary search */ ranges = dsm_array_get_pointer(&rangerel->ranges); pos = range_binary_search(rangerel, &cmp_func, value, &found); if (found) return ranges[pos].child_oid; return 0; }
/* LocalTableSize returns the size on disk of the given table. */ static uint64 LocalTableSize(Oid relationId) { uint64 tableSize = 0; char relationType = 0; Datum relationIdDatum = ObjectIdGetDatum(relationId); relationType = get_rel_relkind(relationId); if (relationType == RELKIND_RELATION) { Datum tableSizeDatum = DirectFunctionCall1(pg_table_size, relationIdDatum); tableSize = DatumGetInt64(tableSizeDatum); } else if (relationType == RELKIND_FOREIGN_TABLE) { bool cstoreTable = CStoreTable(relationId); if (cstoreTable) { /* extract schema name of cstore */ Oid cstoreId = get_extension_oid(CSTORE_FDW_NAME, false); Oid cstoreSchemaOid = get_extension_schema(cstoreId); const char *cstoreSchemaName = get_namespace_name(cstoreSchemaOid); const int tableSizeArgumentCount = 1; Oid tableSizeFunctionOid = FunctionOid(cstoreSchemaName, CSTORE_TABLE_SIZE_FUNCTION_NAME, tableSizeArgumentCount); Datum tableSizeDatum = OidFunctionCall1(tableSizeFunctionOid, relationIdDatum); tableSize = DatumGetInt64(tableSizeDatum); } else { char *relationName = get_rel_name(relationId); struct stat fileStat; int statOK = 0; StringInfo localFilePath = makeStringInfo(); appendStringInfo(localFilePath, FOREIGN_CACHED_FILE_PATH, relationName); /* extract the file size using stat, analogous to pg_stat_file */ statOK = stat(localFilePath->data, &fileStat); if (statOK < 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", localFilePath->data))); } tableSize = (uint64) fileStat.st_size; } } else { char *relationName = get_rel_name(relationId); ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot get size for table \"%s\"", relationName), errdetail("Only regular and foreign tables are supported."))); } return tableSize; }