Server IP : 103.119.228.120 / Your IP : 18.227.114.218 Web Server : Apache System : Linux v8.techscape8.com 3.10.0-1160.119.1.el7.tuxcare.els2.x86_64 #1 SMP Mon Jul 15 12:09:18 UTC 2024 x86_64 User : nobody ( 99) PHP Version : 5.6.40 Disable Function : shell_exec,symlink,system,exec,proc_get_status,proc_nice,proc_terminate,define_syslog_variables,syslog,openlog,closelog,escapeshellcmd,passthru,ocinum cols,ini_alter,leak,listen,chgrp,apache_note,apache_setenv,debugger_on,debugger_off,ftp_exec,dl,dll,myshellexec,proc_open,socket_bind,proc_close,escapeshellarg,parse_ini_filepopen,fpassthru,exec,passthru,escapeshellarg,escapeshellcmd,proc_close,proc_open,ini_alter,popen,show_source,proc_nice,proc_terminate,proc_get_status,proc_close,pfsockopen,leak,apache_child_terminate,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,dl,symlink,shell_exec,system,dl,passthru,escapeshellarg,escapeshellcmd,myshellexec,c99_buff_prepare,c99_sess_put,fpassthru,getdisfunc,fx29exec,fx29exec2,is_windows,disp_freespace,fx29sh_getupdate,fx29_buff_prepare,fx29_sess_put,fx29shexit,fx29fsearch,fx29ftpbrutecheck,fx29sh_tools,fx29sh_about,milw0rm,imagez,sh_name,myshellexec,checkproxyhost,dosyayicek,c99_buff_prepare,c99_sess_put,c99getsource,c99sh_getupdate,c99fsearch,c99shexit,view_perms,posix_getpwuid,posix_getgrgid,posix_kill,parse_perms,parsesort,view_perms_color,set_encoder_input,ls_setcheckboxall,ls_reverse_all,rsg_read,rsg_glob,selfURL,dispsecinfo,unix2DosTime,addFile,system,get_users,view_size,DirFiles,DirFilesWide,DirPrintHTMLHeaders,GetFilesTotal,GetTitles,GetTimeTotal,GetMatchesCount,GetFileMatchesCount,GetResultFiles,fs_copy_dir,fs_copy_obj,fs_move_dir,fs_move_obj,fs_rmdir,SearchText,getmicrotime MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/local/ssl/share/doc/postgresql-9.2.24/html/ |
Upload File : |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML ><HEAD ><TITLE >Function Volatility Categories</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK REV="MADE" HREF="mailto:pgsql-docs@postgresql.org"><LINK REL="HOME" TITLE="PostgreSQL 9.2.24 Documentation" HREF="index.html"><LINK REL="UP" TITLE="Extending SQL" HREF="extend.html"><LINK REL="PREVIOUS" TITLE="Function Overloading" HREF="xfunc-overload.html"><LINK REL="NEXT" TITLE="Procedural Language Functions" HREF="xfunc-pl.html"><LINK REL="STYLESHEET" TYPE="text/css" HREF="stylesheet.css"><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"><META NAME="creation" CONTENT="2017-11-06T22:43:11"></HEAD ><BODY CLASS="SECT1" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="5" ALIGN="center" VALIGN="bottom" ><A HREF="index.html" >PostgreSQL 9.2.24 Documentation</A ></TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="top" ><A TITLE="Function Overloading" HREF="xfunc-overload.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="10%" ALIGN="left" VALIGN="top" ><A HREF="extend.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="60%" ALIGN="center" VALIGN="bottom" >Chapter 35. Extending <ACRONYM CLASS="ACRONYM" >SQL</ACRONYM ></TD ><TD WIDTH="20%" ALIGN="right" VALIGN="top" ><A TITLE="Procedural Language Functions" HREF="xfunc-pl.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="XFUNC-VOLATILITY" >35.6. Function Volatility Categories</A ></H1 ><P > Every function has a <I CLASS="FIRSTTERM" >volatility</I > classification, with the possibilities being <TT CLASS="LITERAL" >VOLATILE</TT >, <TT CLASS="LITERAL" >STABLE</TT >, or <TT CLASS="LITERAL" >IMMUTABLE</TT >. <TT CLASS="LITERAL" >VOLATILE</TT > is the default if the <A HREF="sql-createfunction.html" >CREATE FUNCTION</A > command does not specify a category. The volatility category is a promise to the optimizer about the behavior of the function: <P ></P ></P><UL ><LI ><P > A <TT CLASS="LITERAL" >VOLATILE</TT > function can do anything, including modifying the database. It can return different results on successive calls with the same arguments. The optimizer makes no assumptions about the behavior of such functions. A query using a volatile function will re-evaluate the function at every row where its value is needed. </P ></LI ><LI ><P > A <TT CLASS="LITERAL" >STABLE</TT > function cannot modify the database and is guaranteed to return the same results given the same arguments for all rows within a single statement. This category allows the optimizer to optimize multiple calls of the function to a single call. In particular, it is safe to use an expression containing such a function in an index scan condition. (Since an index scan will evaluate the comparison value only once, not once at each row, it is not valid to use a <TT CLASS="LITERAL" >VOLATILE</TT > function in an index scan condition.) </P ></LI ><LI ><P > An <TT CLASS="LITERAL" >IMMUTABLE</TT > function cannot modify the database and is guaranteed to return the same results given the same arguments forever. This category allows the optimizer to pre-evaluate the function when a query calls it with constant arguments. For example, a query like <TT CLASS="LITERAL" >SELECT ... WHERE x = 2 + 2</TT > can be simplified on sight to <TT CLASS="LITERAL" >SELECT ... WHERE x = 4</TT >, because the function underlying the integer addition operator is marked <TT CLASS="LITERAL" >IMMUTABLE</TT >. </P ></LI ></UL ><P> </P ><P > For best optimization results, you should label your functions with the strictest volatility category that is valid for them. </P ><P > Any function with side-effects <SPAN CLASS="emphasis" ><I CLASS="EMPHASIS" >must</I ></SPAN > be labeled <TT CLASS="LITERAL" >VOLATILE</TT >, so that calls to it cannot be optimized away. Even a function with no side-effects needs to be labeled <TT CLASS="LITERAL" >VOLATILE</TT > if its value can change within a single query; some examples are <TT CLASS="LITERAL" >random()</TT >, <TT CLASS="LITERAL" >currval()</TT >, <TT CLASS="LITERAL" >timeofday()</TT >. </P ><P > Another important example is that the <CODE CLASS="FUNCTION" >current_timestamp</CODE > family of functions qualify as <TT CLASS="LITERAL" >STABLE</TT >, since their values do not change within a transaction. </P ><P > There is relatively little difference between <TT CLASS="LITERAL" >STABLE</TT > and <TT CLASS="LITERAL" >IMMUTABLE</TT > categories when considering simple interactive queries that are planned and immediately executed: it doesn't matter a lot whether a function is executed once during planning or once during query execution startup. But there is a big difference if the plan is saved and reused later. Labeling a function <TT CLASS="LITERAL" >IMMUTABLE</TT > when it really isn't might allow it to be prematurely folded to a constant during planning, resulting in a stale value being re-used during subsequent uses of the plan. This is a hazard when using prepared statements or when using function languages that cache plans (such as <SPAN CLASS="APPLICATION" >PL/pgSQL</SPAN >). </P ><P > For functions written in SQL or in any of the standard procedural languages, there is a second important property determined by the volatility category, namely the visibility of any data changes that have been made by the SQL command that is calling the function. A <TT CLASS="LITERAL" >VOLATILE</TT > function will see such changes, a <TT CLASS="LITERAL" >STABLE</TT > or <TT CLASS="LITERAL" >IMMUTABLE</TT > function will not. This behavior is implemented using the snapshotting behavior of MVCC (see <A HREF="mvcc.html" >Chapter 13</A >): <TT CLASS="LITERAL" >STABLE</TT > and <TT CLASS="LITERAL" >IMMUTABLE</TT > functions use a snapshot established as of the start of the calling query, whereas <TT CLASS="LITERAL" >VOLATILE</TT > functions obtain a fresh snapshot at the start of each query they execute. </P ><DIV CLASS="NOTE" ><BLOCKQUOTE CLASS="NOTE" ><P ><B >Note: </B > Functions written in C can manage snapshots however they want, but it's usually a good idea to make C functions work this way too. </P ></BLOCKQUOTE ></DIV ><P > Because of this snapshotting behavior, a function containing only <TT CLASS="COMMAND" >SELECT</TT > commands can safely be marked <TT CLASS="LITERAL" >STABLE</TT >, even if it selects from tables that might be undergoing modifications by concurrent queries. <SPAN CLASS="PRODUCTNAME" >PostgreSQL</SPAN > will execute all commands of a <TT CLASS="LITERAL" >STABLE</TT > function using the snapshot established for the calling query, and so it will see a fixed view of the database throughout that query. </P ><P > The same snapshotting behavior is used for <TT CLASS="COMMAND" >SELECT</TT > commands within <TT CLASS="LITERAL" >IMMUTABLE</TT > functions. It is generally unwise to select from database tables within an <TT CLASS="LITERAL" >IMMUTABLE</TT > function at all, since the immutability will be broken if the table contents ever change. However, <SPAN CLASS="PRODUCTNAME" >PostgreSQL</SPAN > does not enforce that you do not do that. </P ><P > A common error is to label a function <TT CLASS="LITERAL" >IMMUTABLE</TT > when its results depend on a configuration parameter. For example, a function that manipulates timestamps might well have results that depend on the <A HREF="runtime-config-client.html#GUC-TIMEZONE" >TimeZone</A > setting. For safety, such functions should be labeled <TT CLASS="LITERAL" >STABLE</TT > instead. </P ><DIV CLASS="NOTE" ><BLOCKQUOTE CLASS="NOTE" ><P ><B >Note: </B > Before <SPAN CLASS="PRODUCTNAME" >PostgreSQL</SPAN > release 8.0, the requirement that <TT CLASS="LITERAL" >STABLE</TT > and <TT CLASS="LITERAL" >IMMUTABLE</TT > functions cannot modify the database was not enforced by the system. Releases 8.0 and later enforce it by requiring SQL functions and procedural language functions of these categories to contain no SQL commands other than <TT CLASS="COMMAND" >SELECT</TT >. (This is not a completely bulletproof test, since such functions could still call <TT CLASS="LITERAL" >VOLATILE</TT > functions that modify the database. If you do that, you will find that the <TT CLASS="LITERAL" >STABLE</TT > or <TT CLASS="LITERAL" >IMMUTABLE</TT > function does not notice the database changes applied by the called function, since they are hidden from its snapshot.) </P ></BLOCKQUOTE ></DIV ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="xfunc-overload.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="xfunc-pl.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Function Overloading</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="extend.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Procedural Language Functions</TD ></TR ></TABLE ></DIV ></BODY ></HTML >