#include "postgres.h"
#include "fmgr.h"
#include "access/clog.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "utils/builtins.h"
#include "commands/tablecmds.h"

static Oid set_next_oid(Oid newoid);
Datum toasttbl_recreate(PG_FUNCTION_ARGS);

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

static Oid
set_next_oid(Oid newoid)
{
	Oid		prevoid = InvalidOid;
	
	LWLockAcquire(OidGenLock, LW_EXCLUSIVE);

	prevoid = ShmemVariableCache->nextOid;
	ShmemVariableCache->nextOid = newoid;
	
	LWLockRelease(OidGenLock);
	
	PG_RETURN_OID(prevoid);
}

PG_FUNCTION_INFO_V1(toasttbl_recreate);

/*
 * recreates a toast table with the specified oid of the given
 * parent table oid. Strictly written for pg_migrator. Assumes that the caller has 
 * already removed the old pg_toast and pg_toast_index relations and also the pg_type
 * entry for parent table.
 */
Datum
toasttbl_recreate(PG_FUNCTION_ARGS)
{
	Oid		parentid = InvalidOid;
	Oid		relid = InvalidOid;
	Oid		oldnxtid = InvalidOid;
	
	if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid format parameters")));
	
	parentid = PG_GETARG_OID(0);
	relid = PG_GETARG_OID(1);
	
	oldnxtid = set_next_oid(relid);
	AlterTableCreateToastTable(parentid, true);
	set_next_oid(oldnxtid);
	
	PG_RETURN_VOID();
}
