/*

create function drive_tz_to_char(fmt text, count int) returns void
strict volatile language c as '/home/tgl/pgsql/drive_formatting.so';

create function drive_f8_to_char(fmt text, count int) returns void
strict volatile language c as '/home/tgl/pgsql/drive_formatting.so';

create function drive_to_number(fmt text, count int) returns void
strict volatile language c as '/home/tgl/pgsql/drive_formatting.so';

\timing

select drive_tz_to_char('YYYY-MM-DD HH24:MI:SS TZ', 10000000);

select drive_f8_to_char('99999999.999', 10000000);

select drive_to_number('99999.99999', 10000000);

 */

#include "postgres.h"

#include "access/xact.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/timestamp.h"

PG_MODULE_MAGIC;

/*
 * drive_tz_to_char(fmt text, count int) returns void
 */
PG_FUNCTION_INFO_V1(drive_tz_to_char);
Datum
drive_tz_to_char(PG_FUNCTION_ARGS)
{
	text	   *txt = PG_GETARG_TEXT_PP(0);
	int32		count = PG_GETARG_INT32(1);
	TimestampTz nowts = GetCurrentTransactionStartTimestamp();
	MemoryContext mycontext;

	mycontext = AllocSetContextCreate(CurrentMemoryContext,
									  "drive_tz_to_char work cxt",
									  ALLOCSET_DEFAULT_SIZES);

	while (count-- > 0)
	{
		MemoryContext oldcontext;

		oldcontext = MemoryContextSwitchTo(mycontext);

		(void) DirectFunctionCall2(timestamptz_to_char,
								   TimestampTzGetDatum(nowts),
								   PointerGetDatum(txt));

		MemoryContextSwitchTo(oldcontext);

		MemoryContextReset(mycontext);

		CHECK_FOR_INTERRUPTS();
	}

	PG_RETURN_VOID();
}

/*
 * drive_f8_to_char(fmt text, count int) returns void
 */
PG_FUNCTION_INFO_V1(drive_f8_to_char);
Datum
drive_f8_to_char(PG_FUNCTION_ARGS)
{
	text	   *txt = PG_GETARG_TEXT_PP(0);
	int32		count = PG_GETARG_INT32(1);
	Datum		val = Float8GetDatum(31415.9263);
	MemoryContext mycontext;

	mycontext = AllocSetContextCreate(CurrentMemoryContext,
									  "drive_f8_to_char work cxt",
									  ALLOCSET_DEFAULT_SIZES);

	while (count-- > 0)
	{
		MemoryContext oldcontext;

		oldcontext = MemoryContextSwitchTo(mycontext);

		(void) DirectFunctionCall2(float8_to_char,
								   val,
								   PointerGetDatum(txt));

		MemoryContextSwitchTo(oldcontext);

		MemoryContextReset(mycontext);

		CHECK_FOR_INTERRUPTS();
	}

	PG_RETURN_VOID();
}

/*
 * drive_to_number(fmt text, count int) returns void
 */
PG_FUNCTION_INFO_V1(drive_to_number);
Datum
drive_to_number(PG_FUNCTION_ARGS)
{
	text	   *txt = PG_GETARG_TEXT_PP(0);
	int32		count = PG_GETARG_INT32(1);
	Datum		val = PointerGetDatum(cstring_to_text("31415.9263"));
	MemoryContext mycontext;

	mycontext = AllocSetContextCreate(CurrentMemoryContext,
									  "drive_to_number work cxt",
									  ALLOCSET_DEFAULT_SIZES);

	while (count-- > 0)
	{
		MemoryContext oldcontext;

		oldcontext = MemoryContextSwitchTo(mycontext);

		(void) DirectFunctionCall2(numeric_to_number,
								   val,
								   PointerGetDatum(txt));

		MemoryContextSwitchTo(oldcontext);

		MemoryContextReset(mycontext);

		CHECK_FOR_INTERRUPTS();
	}

	PG_RETURN_VOID();
}
