funcapi.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 156 行

C
156
字号
/*------------------------------------------------------------------------- * * funcapi.c *	  Utility and convenience functions for fmgr functions that return *	  sets and/or composite types. * * Copyright (c) 2002-2003, PostgreSQL Global Development Group * * IDENTIFICATION *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/funcapi.c,v 1.11.2.1 2003/12/19 00:00:27 joe Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "funcapi.h"#include "catalog/pg_type.h"#include "utils/syscache.h"static void shutdown_MultiFuncCall(Datum arg);/* * init_MultiFuncCall * Create an empty FuncCallContext data structure * and do some other basic Multi-function call setup * and error checking */FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS){	FuncCallContext *retval;	/*	 * Bail if we're called in the wrong context	 */	if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo))		ereport(ERROR,				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),				 errmsg("set-valued function called in context that cannot accept a set")));	if (fcinfo->flinfo->fn_extra == NULL)	{		/*		 * First call		 */		ReturnSetInfo	   *rsi = (ReturnSetInfo *) fcinfo->resultinfo;		/*		 * Allocate suitably long-lived space and zero it		 */		retval = (FuncCallContext *)			MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,							   sizeof(FuncCallContext));		MemSet(retval, 0, sizeof(FuncCallContext));		/*		 * initialize the elements		 */		retval->call_cntr = 0;		retval->max_calls = 0;		retval->slot = NULL;		retval->user_fctx = NULL;		retval->attinmeta = NULL;		retval->multi_call_memory_ctx = fcinfo->flinfo->fn_mcxt;		/*		 * save the pointer for cross-call use		 */		fcinfo->flinfo->fn_extra = retval;		/*		 * Ensure we will get shut down cleanly if the exprcontext is not		 * run to completion.		 */		RegisterExprContextCallback(rsi->econtext,									shutdown_MultiFuncCall,									PointerGetDatum(fcinfo->flinfo));	}	else	{		/* second and subsequent calls */		elog(ERROR, "init_MultiFuncCall may not be called more than once");		/* never reached, but keep compiler happy */		retval = NULL;	}	return retval;}/* * per_MultiFuncCall * * Do Multi-function per-call setup */FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS){	FuncCallContext *retval = (FuncCallContext *) fcinfo->flinfo->fn_extra;	/*	 * Clear the TupleTableSlot, if present.  This is for safety's sake:	 * the Slot will be in a long-lived context (it better be, if the	 * FuncCallContext is pointing to it), but in most usage patterns the	 * tuples stored in it will be in the function's per-tuple context. So	 * at the beginning of each call, the Slot will hold a dangling	 * pointer to an already-recycled tuple.  We clear it out here.  (See	 * also the definition of TupleGetDatum() in funcapi.h!)	 */	if (retval->slot != NULL)		ExecClearTuple(retval->slot);	return retval;}/* * end_MultiFuncCall * Clean up after init_MultiFuncCall */voidend_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx){	ReturnSetInfo	   *rsi = (ReturnSetInfo *) fcinfo->resultinfo;	/* Deregister the shutdown callback */	UnregisterExprContextCallback(rsi->econtext,								  shutdown_MultiFuncCall,								  PointerGetDatum(fcinfo->flinfo));	/* But use it to do the real work */	shutdown_MultiFuncCall(PointerGetDatum(fcinfo->flinfo));}/* * shutdown_MultiFuncCall * Shutdown function to clean up after init_MultiFuncCall */static voidshutdown_MultiFuncCall(Datum arg){	FmgrInfo *flinfo = (FmgrInfo *) DatumGetPointer(arg);	FuncCallContext *funcctx = (FuncCallContext *) flinfo->fn_extra;	/* unbind from flinfo */	flinfo->fn_extra = NULL;	/*	 * Caller is responsible to free up memory for individual struct	 * elements other than att_in_funcinfo and elements.	 */	if (funcctx->attinmeta != NULL)		pfree(funcctx->attinmeta);	pfree(funcctx);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?