#include <postgres.h>
#include <fmgr.h>
#include <miscadmin.h>
#include <utils/memutils.h>
#include <storage/shmem.h>
#include <unordered_map>
PG_MODULE_MAGIC;
typedef struct {
char *name;
int value;
} MyStruct;
static std::unordered_map<int, MyStruct*> *mystruct_map = nullptr;
static int mystruct_count = 0;
PG_FUNCTION_INFO_V1(create_foreign_table);
Datum create_foreign_table(PG_FUNCTION_ARGS)
{
char *tablename = text_to_cstring(PG_GETARG_TEXT_P(0));
MemoryContext oldcontext = CurrentMemoryContext;
/* Allocate shared memory for mystruct map */
char shmem_name[256];
snprintf(shmem_name, 256, "mystruct_map");
bool found;
Size mapsize = sizeof(std::unordered_map<int, MyStruct*>);
mystruct_map = (std::unordered_map<int, MyStruct*> *) ShmemInitStruct(shmem_name, mapsize, &found);
if (!found) {
new (mystruct_map) std::unordered_map<int, MyStruct*>;
}
/* Allocate shared memory for mystruct */
snprintf(shmem_name, 256, "mystruct_%d", mystruct_count);
Size structsize = sizeof(MyStruct);
MyStruct *mystruct = (MyStruct *) ShmemInitStruct(shmem_name, structsize, &found);
/* Initialize mystruct */
mystruct->name = tablename;
mystruct->value = mystruct_count;
/* Add mystruct to the map */
(*mystruct_map)[mystruct_count] = mystruct;
mystruct_count++;
PG_RETURN_VOID();
}
PG_FUNCTION_INFO_V1(get_mystruct_value);
Datum get_mystruct_value(PG_FUNCTION_ARGS)
{
int index = PG_GETARG_INT32(0);
if (mystruct_map == nullptr) {
ereport(ERROR, (errmsg("mystruct_map is null")));
}
auto it = mystruct_map->find(index);
if (it == mystruct_map->end()) {
ereport(ERROR, (errmsg("mystruct not found")));
}
MyStruct *mystruct = it->second;
PG_RETURN_INT32(mystruct->value);
}