Polymorfní variadická funkce format

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

Funkci, která zjednoduší formátování (sestavení) chybového hlášení v PostgreSQL nemáme. S podporou variadických a polymorfních parametrů si ji můžeme dopsat sami:

#include "postgres.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(pg_format);

Datum		pg_format(PG_FUNCTION_ARGS);

Datum
pg_format(PG_FUNCTION_ARGS)
{
	char	   *fmt = PG_GETARG_CSTRING(0);
	StringInfo	str;
	char		*cp;
	int			i = 1;

	if (PG_ARGISNULL(0))
		PG_RETURN_NULL();
	
	str = makeStringInfo();
	
	for (cp = fmt; *cp; cp++)
	{
		if (cp[0] == '%')
		{
			Oid	valtype;
			Datum	value;
			Oid                     typoutput;
			bool            typIsVarlena;
			        
		
			if (cp[1] == '%')
			{
				appendStringInfoChar(str, cp[1]);
				cp++;
				continue;
			}
			
			if (i > PG_NARGS())
				elog(ERROR, "too few parameters specified by format string");
			
			if (PG_ARGISNULL(i))
			{
				appendStringInfoString(str, "NULL");
			}
			else
			{
				/* append n-th value */
				value = PG_GETARG_DATUM(i);
				valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
				
				getTypeOutputInfo(valtype, &typoutput, &typIsVarlena);
				appendStringInfoString(str, OidOutputFunctionCall(typoutput, value));
			}
			i++;
		}
		else
			appendStringInfoChar(str, cp[0]);
	}
	
	if (i != PG_NARGS())
		elog(ERROR, "too much parameters");
	
	PG_RETURN_TEXT_P(CStringGetTextDatum(str->data));
}

/*
 * Varianta pouze s formátovacím řetězcem, pouze obálka.
 */
Datum
pg_format1(PG_FUNCTION_ARGS)
{
        return pg_format(fcinfo);
}

registrační skript:

SET search_path = public;

CREATE OR REPLACE FUNCTION format(cstring, variadic "any")
RETURNS text
AS 'MODULE_PATHNAME', 'pg_format'
LANGUAGE C IMMUTABLE;

CREATE OR REPLACE FUNCTION format(cstring)
RETURNS text
AS 'MODULE_PATHNAME', 'pg_format1'
LANGUAGE C IMMUTABLE;