⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi.sgml

📁 关系型数据库 Postgresql 6.5.2
💻 SGML
📖 第 1 页 / 共 5 页
字号:
<TITLE>Structures</TITLE><PARA>None</PARA></REFSECT1>--></REFENTRY><!-- *********************************************** --><!-- *********************************************** --><!-- *********************************************** --><REFENTRY ID="SPI-SPIPALLOC"><REFMETA><REFENTRYTITLE>SPI_palloc</REFENTRYTITLE><REFMISCINFO>SPI - Memory Management</REFMISCINFO></REFMETA><REFNAMEDIV><REFNAME>SPI_palloc</REFNAME><REFPURPOSE>Allocates memory in upper Executor context</REFPURPOSE><INDEXTERM ID="IX-SPI-SPIPALLOC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM><INDEXTERM ID="IX-SPI-SPIPALLOC-2"><PRIMARY>SPI_palloc</PRIMARY></INDEXTERM></REFNAMEDIV><REFSYNOPSISDIV><REFSYNOPSISDIVINFO><DATE>1997-12-24</DATE></REFSYNOPSISDIVINFO><SYNOPSIS>SPI_palloc(<REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)</SYNOPSIS><REFSECT2 ID="R2-SPI-SPIPALLOC-1"><REFSECT2INFO><DATE>1997-12-24</DATE></REFSECT2INFO><TITLE>Inputs</TITLE><VARIABLELIST><VARLISTENTRY><TERM>Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE></TERM><LISTITEM><PARA>Octet size of storage to allocate</PARA></LISTITEM></VARLISTENTRY></VARIABLELIST></REFSECT2><REFSECT2 ID="R2-SPI-SPIPALLOC-2"><REFSECT2INFO><DATE>1997-12-24</DATE></REFSECT2INFO><TITLE>Outputs</TITLE><VARIABLELIST><VARLISTENTRY><TERM>void *</TERM><LISTITEM><PARA>New storage space of specified size</PARA></LISTITEM></VARLISTENTRY></VARIABLELIST></REFSECT2></REFSYNOPSISDIV><REFSECT1 ID="R1-SPI-SPIPALLOC-1"><REFSECT1INFO><DATE>1997-12-24</DATE></REFSECT1INFO><TITLE>Description</TITLE><PARA><FUNCTION>SPI_palloc</FUNCTION>    allocates memory in upper Executor context. See section on memory management.</PARA></REFSECT1><REFSECT1 ID="R1-SPI-SPIPALLOC-2"><TITLE>Usage</TITLE><Para>TBD</PARA></REFSECT1><!--<REFSECT1 ID="R1-SPI-SPIPALLOC-3"><TITLE>Algorithm</TITLE><PARA>TBD</PARA></REFSECT1>--><!--<REFSECT1 ID="R1-SPI-SPIPALLOC-4"><TITLE>Structures</TITLE><PARA>None</PARA></REFSECT1>--></REFENTRY><!-- *********************************************** --><!-- *********************************************** --><!-- *********************************************** --><REFENTRY ID="SPI-SPIREPALLOC"><REFMETA><REFENTRYTITLE>SPI_repalloc</REFENTRYTITLE><REFMISCINFO>SPI - Memory Management</REFMISCINFO></REFMETA><REFNAMEDIV><REFNAME>SPI_repalloc</REFNAME><REFPURPOSE>Re-allocates memory in upper Executor context</REFPURPOSE><INDEXTERM ID="IX-SPI-SPIREPALLOC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM><INDEXTERM ID="IX-SPI-SPIREPALLOC-2"><PRIMARY>SPI_repalloc</PRIMARY></INDEXTERM></REFNAMEDIV><REFSYNOPSISDIV><REFSYNOPSISDIVINFO><DATE>1997-12-24</DATE></REFSYNOPSISDIVINFO><SYNOPSIS>SPI_repalloc(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)</SYNOPSIS><REFSECT2 ID="R2-SPI-SPIREPALLOC-1"><REFSECT2INFO><DATE>1997-12-24</DATE></REFSECT2INFO><TITLE>Inputs</TITLE><VARIABLELIST><VARLISTENTRY><TERM>void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE></TERM><LISTITEM><PARA>Pointer to existing storage</PARA></LISTITEM></VARLISTENTRY><VARLISTENTRY><TERM>Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE></TERM><LISTITEM><PARA>Octet size of storage to allocate</PARA></LISTITEM></VARLISTENTRY></VARIABLELIST></REFSECT2><REFSECT2 ID="R2-SPI-SPIREPALLOC-2"><REFSECT2INFO><DATE>1997-12-24</DATE></REFSECT2INFO><TITLE>Outputs</TITLE><VARIABLELIST><VARLISTENTRY><TERM>void *</TERM><LISTITEM><PARA>New storage space of specified size with contents copied from existing area</PARA></LISTITEM></VARLISTENTRY></VARIABLELIST></REFSECT2></REFSYNOPSISDIV><REFSECT1 ID="R1-SPI-SPIREPALLOC-1"><REFSECT1INFO><DATE>1997-12-24</DATE></REFSECT1INFO><TITLE>Description</TITLE><PARA><FUNCTION>SPI_repalloc</FUNCTION>    re-allocates memory in upper Executor context. See section on memory management.</PARA></REFSECT1><REFSECT1 ID="R1-SPI-SPIREPALLOC-2"><TITLE>Usage</TITLE><Para>TBD</PARA></REFSECT1><!--<REFSECT1 ID="R1-SPI-SPIREPALLOC-3"><TITLE>Algorithm</TITLE><PARA>TBD</PARA></REFSECT1>--><!--<REFSECT1 ID="R1-SPI-SPIREPALLOC-4"><TITLE>Structures</TITLE><PARA>None</PARA></REFSECT1>--></REFENTRY><!-- *********************************************** --><!-- *********************************************** --><!-- *********************************************** --><REFENTRY ID="SPI-SPIPFREE"><REFMETA><REFENTRYTITLE>SPI_pfree</REFENTRYTITLE><REFMISCINFO>SPI - Memory Management</REFMISCINFO></REFMETA><REFNAMEDIV><REFNAME>SPI_pfree</REFNAME><REFPURPOSE>Frees memory from upper Executor context</REFPURPOSE><INDEXTERM ID="IX-SPI-SPIPFREE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM><INDEXTERM ID="IX-SPI-SPIPFREE-2"><PRIMARY>SPI_pfree</PRIMARY></INDEXTERM></REFNAMEDIV><REFSYNOPSISDIV><REFSYNOPSISDIVINFO><DATE>1997-12-24</DATE></REFSYNOPSISDIVINFO><SYNOPSIS>SPI_pfree(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>)</SYNOPSIS><REFSECT2 ID="R2-SPI-SPIPFREE-1"><REFSECT2INFO><DATE>1997-12-24</DATE></REFSECT2INFO><TITLE>Inputs</TITLE><VARIABLELIST><VARLISTENTRY><TERM>void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE></TERM><LISTITEM><PARA>Pointer to existing storage</PARA></LISTITEM></VARLISTENTRY></VARIABLELIST></REFSECT2><REFSECT2 ID="R2-SPI-SPIPFREE-2"><REFSECT2INFO><DATE>1997-12-24</DATE></REFSECT2INFO><TITLE>Outputs</TITLE><VARIABLELIST><VARLISTENTRY><TERM>None</TERM><LISTITEM><PARA></PARA></LISTITEM></VARLISTENTRY></VARIABLELIST></REFSECT2></REFSYNOPSISDIV><REFSECT1 ID="R1-SPI-SPIPFREE-1"><REFSECT1INFO><DATE>1997-12-24</DATE></REFSECT1INFO><TITLE>Description</TITLE><PARA><FUNCTION>SPI_pfree</FUNCTION>    frees memory in upper Executor context. See section on memory management.</PARA></REFSECT1><REFSECT1 ID="R1-SPI-SPIPFREE-2"><TITLE>Usage</TITLE><Para>TBD</PARA></REFSECT1><!--<REFSECT1 ID="R1-SPI-SPIPFREE-3"><TITLE>Algorithm</TITLE><PARA>TBD</PARA></REFSECT1>--><!--<REFSECT1 ID="R1-SPI-SPIPFREE-4"><TITLE>Structures</TITLE><PARA>None</PARA></REFSECT1>--></REFENTRY></Sect1><Sect1><Title>Memory Management</Title><Para>   Server allocates memory in memory contexts in such way that allocationsmade in one context may be freed by context destruction without affectingallocations made in other contexts. All allocations (via <Function>palloc</Function>, etc) aremade in the context which are chosen as current one. You'll getunpredictable results if you'll try to free (or reallocate) memory allocatednot in current context.</Para><Para>   Creation and switching between memory contexts are subject of SPI managermemory management.</Para><Para>   SPI procedures deal with two memory contexts: upper Executor memorycontext and procedure memory context (if connected). </Para><Para>   Before a procedure is connected to the SPI manager, current memory contextis upper Executor context so all allocation made by the procedure itself via<Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility functions before connecting to SPI aremade in this context.</Para><Para>   After <Function>SPI_connect</Function> is called current context is the procedure's one.  Allallocations made via <Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility functions (exceptfor <Function>SPI_copytuple</Function>, <Function>SPI_modifytuple</Function>, <Function>SPI_palloc</Function> and <Function>SPI_repalloc</Function>) aremade in this context.</Para><Para>   When a procedure disconnects from the SPI manager (via <Function>SPI_finish</Function>) thecurrent context is restored to the upper Executor context and all allocationsmade in the procedure memory context are freed and can't be used any more!</Para><Para>   If you want to return something to the upper Executor then you have toallocate memory for this in the upper context!</Para><Para>   SPI has no ability to automatically free allocations in the upper Executorcontext!</Para><Para>   SPI automatically frees memory allocated during execution of a query whenthis query is done!</Para></Sect1><Sect1><Title>Visibility of Data Changes</Title><Para><ProductName>Postgres</ProductName> data changes visibility rule: during a query execution, datachanges made by the query itself (via SQL-function, SPI-function, triggers)are invisible to the query scan.  For example, in query   INSERT INTO a SELECT * FROM a   tuples inserted are invisible for SELECT' scan.  In effect, thisduplicates the database table within itself (subject to unique indexrules, of course) without recursing.</Para><Para>   Changes made by query Q are visible by queries which are started afterquery Q, no matter whether they are started inside Q (during the executionof Q) or after Q is done.</Para></Sect1><Sect1><Title>Examples</Title><Para>   This example of SPI usage demonstrates the visibility rule.   There are more complex examples in in src/test/regress/regress.c andin contrib/spi.</Para><Para>   This is a very simple example of SPI usage. The procedure execq acceptsan SQL-query in its first argument and tcount in its second, executes thequery using SPI_exec and returns the number of tuples for which the queryexecuted:<ProgramListing>#include "executor/spi.h"	/* this is what you need to work with SPI */int execq(text *sql, int cnt);intexecq(text *sql, int cnt){	int ret;	int proc = 0;		SPI_connect();		ret = SPI_exec(textout(sql), cnt);		proc = SPI_processed;	/*	 * If this is SELECT and some tuple(s) fetched -	 * returns tuples to the caller via elog (NOTICE).	 */	if ( ret == SPI_OK_SELECT && SPI_processed > 0 )	{		TupleDesc tupdesc = SPI_tuptable->tupdesc;		SPITupleTable *tuptable = SPI_tuptable;		char buf[8192];		int i;				for (ret = 0; ret < proc; ret++)		{			HeapTuple tuple = tuptable->vals[ret];						for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)				sprintf(buf + strlen (buf), " %s%s",					SPI_getvalue(tuple, tupdesc, i),					(i == tupdesc->natts) ? " " : " |");			elog (NOTICE, "EXECQ: %s", buf);		}	}	SPI_finish();	return (proc);}</ProgramListing></Para><Para>   Now, compile and create the function:<ProgramListing>create function execq (text, int4) returns int4 as '...path_to_so' language 'c';</ProgramListing><ProgramListing>vac=> select execq('create table a (x int4)', 0);execq-----    0(1 row)vac=> insert into a values (execq('insert into a values (0)',0));INSERT 167631 1vac=> select execq('select * from a',0);NOTICE:EXECQ:  0 <<< inserted by execqNOTICE:EXECQ:  1 <<< value returned by execq and inserted by upper INSERTexecq-----    2(1 row)vac=> select execq('insert into a select x + 2 from a',1);execq-----    1(1 row)vac=> select execq('select * from a', 10);NOTICE:EXECQ:  0 NOTICE:EXECQ:  1 NOTICE:EXECQ:  2 <<< 0 + 2, only one tuple inserted - as specifiedexecq-----    3            <<< 10 is max value only, 3 is real # of tuples(1 row)vac=> delete from a;DELETE 3vac=> insert into a values (execq('select * from a', 0) + 1);INSERT 167712 1vac=> select * from a;x-1                <<< no tuples in a (0) + 1(1 row)vac=> insert into a values (execq('select * from a', 0) + 1);NOTICE:EXECQ:  0 INSERT 167713 1vac=> select * from a;x-12                <<< there was single tuple in a + 1(2 rows)--   This demonstrates data changes visibility rule:vac=> insert into a select execq('select * from a', 0) * x from a;NOTICE:EXECQ:  1 NOTICE:EXECQ:  2 NOTICE:EXECQ:  1 NOTICE:EXECQ:  2 NOTICE:EXECQ:  2 INSERT 0 2vac=> select * from a;x-122                <<< 2 tuples * 1 (x in first tuple)6                <<< 3 tuples (2 + 1 just inserted) * 2 (x in second tuple)(4 rows)             ^^^^^^^^                      tuples visible to execq() in different invocations</ProgramListing></Para></Sect1></Chapter>

⌨️ 快捷键说明

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