transaction_timestamp() (just like now()).
Also update statement_timeout() to mention it is statement arrival time
that is measured.
Catalog version updated.
-<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.55 2006/04/23 03:39:48 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.56 2006/04/25 00:25:15 momjian Exp $ -->
<chapter Id="runtime-config">
<title>Server Configuration</title>
<listitem>
<para>
Abort any statement that takes over the specified number of
- milliseconds. If <varname>log_min_error_statement</> is set to
+ milliseconds, starting from the time the command arrives at the server
+ from the client. If <varname>log_min_error_statement</> is set to
<literal>ERROR</> or lower, the statement that timed out will also be
logged. A value of zero (the default) turns off the
limitation.
-<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.314 2006/04/23 03:39:50 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.315 2006/04/25 00:25:15 momjian Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
<indexterm>
<primary>now</primary>
</indexterm>
+ <indexterm>
+ <primary>transaction_timestamp</primary>
+ </indexterm>
+ <indexterm>
+ <primary>statement_timestamp</primary>
+ </indexterm>
+ <indexterm>
+ <primary>clock_timestamp</primary>
+ </indexterm>
<indexterm>
<primary>timeofday</primary>
</indexterm>
<row>
<entry><literal><function>current_timestamp</function></literal></entry>
<entry><type>timestamp with time zone</type></entry>
- <entry>Date and time; see <xref linkend="functions-datetime-current">
+ <entry>Date and time of start of current transaction; see <xref linkend="functions-datetime-current">
</entry>
<entry></entry>
<entry></entry>
<row>
<entry><literal><function>now</function>()</literal></entry>
<entry><type>timestamp with time zone</type></entry>
- <entry>Current date and time (equivalent to
- <function>current_timestamp</function>); see <xref linkend="functions-datetime-current">
+ <entry>Date and time of start of current transaction (equivalent to
+ <function>CURRENT_TIMESTAMP</function>); see <xref linkend="functions-datetime-current">
+ </entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry><literal><function>transaction_timestamp</function>()</literal></entry>
+ <entry><type>timestamp with time zone</type></entry>
+ <entry>Date and time of start of current transaction (equivalent to
+ <function>CURRENT_TIMESTAMP</function>); see <xref linkend="functions-datetime-current">
+ </entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry><literal><function>statement_timestamp</function>()</literal></entry>
+ <entry><type>timestamp with time zone</type></entry>
+ <entry>Date and time of start of current statement; see <xref linkend="functions-datetime-current">
+ </entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry><literal><function>clock_timestamp</function>()</literal></entry>
+ <entry><type>timestamp with time zone</type></entry>
+ <entry>Current date and time (changes during statement execution); see <xref linkend="functions-datetime-current">
</entry>
<entry></entry>
<entry></entry>
<row>
<entry><literal><function>timeofday</function>()</literal></entry>
<entry><type>text</type></entry>
- <entry>Current date and time; see <xref linkend="functions-datetime-current">
+ <entry>Current date and time (like <function>clock_timestamp</>), but as a Unix-style <type>text</> value;
+ see <xref linkend="functions-datetime-current">
</entry>
<entry></entry>
<entry></entry>
</sect2>
<sect2 id="functions-datetime-current">
- <title>Current Date/Time</title>
+ <title>Date/Time of Transaction Start</title>
<indexterm>
<primary>date</primary>
</indexterm>
<para>
- The following functions are available to obtain the current date and/or
- time:
+ The following functions are available to obtain the date and/or
+ time of the start of the current transaction:
<synopsis>
CURRENT_DATE
CURRENT_TIME
</screen>
</para>
- <para>
- The function <function>now()</function> is the traditional
- <productname>PostgreSQL</productname> equivalent to
- <function>CURRENT_TIMESTAMP</function>.
- </para>
-
<para>
It is important to know that
<function>CURRENT_TIMESTAMP</function> and related functions return
the intent is to allow a single transaction to have a consistent
notion of the <quote>current</quote> time, so that multiple
modifications within the same transaction bear the same
- time stamp.
+ time stamp. Consider using <function>statement_timestamp</> or
+ <function>clock_timestamp</> if you need something that changes
+ more frequently.
</para>
- <note>
- <para>
- Other database systems may advance these values more
- frequently.
- </para>
- </note>
+ <para>
+ <function>CURRENT_TIMESTAMP</> might not be the
+ transaction start time on other database systems.
+ For this reason, and for completeness,
+ <function>transaction_timestamp</> is provided.
+ The function <function>now()</function> is the traditional
+ <productname>PostgreSQL</productname> equivalent to
+ the SQL-standard <function>CURRENT_TIMESTAMP</function>.
+ </para>
<para>
- There is also the function <function>timeofday()</function> which
- returns the wall-clock time and advances during transactions. For
- historical reasons <function>timeofday()</function> returns a
- <type>text</type> string rather than a <type>timestamp</type>
- value:
-<screen>
-SELECT timeofday();
-<lineannotation>Result: </lineannotation><computeroutput>Sat Feb 17 19:07:32.000126 2001 EST</computeroutput>
-</screen>
+ <function>STATEMENT_TIMESTAMP</> is the time the statement
+ arrived at the server from the client. It is not the time
+ the command started execution. If multiple commands were
+ sent as a single query string to the server, each command
+ has the same <function>STATEMENT_TIMESTAMP</> because they
+ all arrived at the same time. Also, commands executed
+ by server-side functions have a <function>STATEMENT_TIMESTAMP</>
+ based on the time the client sent the query that triggered
+ the function, not the time the function was executed.
</para>
<para>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.219 2006/03/29 21:17:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.220 2006/04/25 00:25:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
* keep it inside the TransactionState stack.
*/
static TimestampTz xactStartTimestamp;
+static TimestampTz stmtStartTimestamp;
/*
* GID to be used for preparing the current transaction. This is also
return xactStartTimestamp;
}
+/*
+ * GetCurrentStatementStartTimestamp
+ */
+TimestampTz
+GetCurrentStatementStartTimestamp(void)
+{
+ return stmtStartTimestamp;
+}
+
+/*
+ * SetCurrentStatementStartTimestamp
+ */
+void
+SetCurrentStatementStartTimestamp(void)
+{
+ stmtStartTimestamp = GetCurrentTimestamp();
+}
+
/*
* GetCurrentTransactionNestLevel
*
XactLockTableInsert(s->transactionId);
/*
- * set now()
+ * now() and statement_timestamp() should be the same time
*/
- xactStartTimestamp = GetCurrentTimestamp();
+ xactStartTimestamp = stmtStartTimestamp;
/*
* initialize current transaction state fields
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.485 2006/04/22 01:26:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.486 2006/04/25 00:25:18 momjian Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
*/
static bool xact_started = false;
+/*
+ * Flag to keep track of whether we have done statement initialization.
+ * For extended query protocol this has to be remembered across messages.
+ */
+static bool command_initialized = false;
+
/*
* Flag to indicate that we are doing the outer loop's read-from-client,
* as opposed to any random read from client that might happen within
static bool log_after_parse(List *raw_parsetree_list,
const char *query_string, char **prepare_string);
static List *pg_rewrite_queries(List *querytree_list);
+static void initialize_command(void);
+static void finalize_command(void);
static void start_xact_command(void);
static void finish_xact_command(void);
static bool IsTransactionExitStmt(Node *parsetree);
* one of those, else bad things will happen in xact.c. (Note that this
* will normally change current memory context.)
*/
- start_xact_command();
+ initialize_command();
/*
* Zap any pre-existing unnamed statement. (While not strictly necessary,
/*
* Close down transaction statement, if one is open.
*/
- finish_xact_command();
+ finalize_command();
/*
* If there were no parsetrees, return EmptyQueryResponse message.
* that this will normally change current memory context.) Nothing happens
* if we are already in one.
*/
- start_xact_command();
+ initialize_command();
/*
* Switch to appropriate context for constructing parsetrees.
* this will normally change current memory context.) Nothing happens if
* we are already in one.
*/
- start_xact_command();
+ initialize_command();
/* Switch back to message context */
MemoryContextSwitchTo(MessageContext);
* Ensure we are in a transaction command (this should normally be the
* case already due to prior BIND).
*/
- start_xact_command();
+ initialize_command();
/*
* If we are in aborted transaction state, the only portals we can
* Start up a transaction command. (Note that this will normally change
* current memory context.) Nothing happens if we are already in one.
*/
- start_xact_command();
+ initialize_command();
/* Switch back to message context */
MemoryContextSwitchTo(MessageContext);
* Start up a transaction command. (Note that this will normally change
* current memory context.) Nothing happens if we are already in one.
*/
- start_xact_command();
+ initialize_command();
/* Switch back to message context */
MemoryContextSwitchTo(MessageContext);
/*
- * Convenience routines for starting/committing a single command.
+ * Start xact if necessary, and set statement_timestamp() and optionally
+ * statement_timeout.
*/
static void
-start_xact_command(void)
+initialize_command(void)
{
- if (!xact_started)
+ if (!command_initialized)
{
- ereport(DEBUG3,
- (errmsg_internal("StartTransactionCommand")));
- StartTransactionCommand();
+ SetCurrentStatementStartTimestamp();
/* Set statement timeout running, if any */
if (StatementTimeout > 0)
else
cancel_from_timeout = false;
- xact_started = true;
+ command_initialized = true;
}
+ start_xact_command();
}
static void
-finish_xact_command(void)
+finalize_command(void)
{
- if (xact_started)
+ if (command_initialized)
{
/* Cancel any active statement timeout before committing */
disable_sig_alarm(true);
- /* Now commit the command */
+ command_initialized = false;
+ }
+ finish_xact_command();
+}
+
+
+/*
+ * Check if the newly-arrived query string needs to have an implicit
+ * transaction started.
+ */
+static void
+start_xact_command(void)
+{
+ if (!xact_started)
+ {
+ ereport(DEBUG3,
+ (errmsg_internal("StartTransactionCommand")));
+
+ StartTransactionCommand();
+
+ xact_started = true;
+ }
+}
+
+static void
+finish_xact_command(void)
+{
+ if (xact_started)
+ {
ereport(DEBUG3,
(errmsg_internal("CommitTransactionCommand")));
/* We don't have a transaction command open anymore */
xact_started = false;
-
+ command_initialized = false;
+
/* Now we can allow interrupts again */
RESUME_INTERRUPTS();
}
pgstat_report_activity("<FASTPATH> function call");
/* start an xact for this function invocation */
- start_xact_command();
+ initialize_command();
/* switch back to message context */
MemoryContextSwitchTo(MessageContext);
}
/* commit the function-invocation transaction */
- finish_xact_command();
+ finalize_command();
send_ready_for_query = true;
break;
case 'S': /* sync */
pq_getmsgend(&input_message);
- finish_xact_command();
+ finalize_command();
send_ready_for_query = true;
break;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.162 2006/03/06 22:49:16 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.163 2006/04/25 00:25:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
PG_RETURN_TIMESTAMPTZ(GetCurrentTransactionStartTimestamp());
}
+Datum
+statement_timestamp(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_TIMESTAMPTZ(GetCurrentStatementStartTimestamp());
+}
+
+Datum
+clock_timestamp(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_TIMESTAMPTZ(GetCurrentTimestamp());
+}
+
Datum
pgsql_postmaster_start_time(PG_FUNCTION_ARGS)
{
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.81 2006/03/24 04:32:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.82 2006/04/25 00:25:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
extern SubTransactionId GetCurrentSubTransactionId(void);
extern CommandId GetCurrentCommandId(void);
extern TimestampTz GetCurrentTransactionStartTimestamp(void);
+extern TimestampTz GetCurrentStatementStartTimestamp(void);
+extern void SetCurrentStatementStartTimestamp(void);
extern int GetCurrentTransactionNestLevel(void);
extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
extern void CommandCounterIncrement(void);
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.323 2006/04/22 01:26:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.324 2006/04/25 00:25:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200604211
+#define CATALOG_VERSION_NO 200604241
#endif
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.405 2006/04/05 22:11:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.406 2006/04/25 00:25:20 momjian Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
DESCR("convert time with time zone and date to timestamp with time zone");
DATA(insert OID = 1299 ( now PGNSP PGUID 12 f f t f s 0 1184 "" _null_ _null_ _null_ now - _null_ ));
DESCR("current transaction time");
+DATA(insert OID = 2647 ( transaction_timestamp PGNSP PGUID 12 f f t f s 0 1184 "" _null_ _null_ _null_ now - _null_ ));
+DESCR("current transaction time");
+DATA(insert OID = 2648 ( statement_timestamp PGNSP PGUID 12 f f t f s 0 1184 "" _null_ _null_ _null_ statement_timestamp - _null_ ));
+DESCR("current statement time");
+DATA(insert OID = 2649 ( clock_timestamp PGNSP PGUID 12 f f t f v 0 1184 "" _null_ _null_ _null_ clock_timestamp - _null_ ));
+DESCR("current clock time");
/* OIDS 1300 - 1399 */
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.59 2006/03/06 22:49:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.60 2006/04/25 00:25:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
extern Datum timestamptz_part(PG_FUNCTION_ARGS);
extern Datum now(PG_FUNCTION_ARGS);
+extern Datum statement_timestamp(PG_FUNCTION_ARGS);
+extern Datum clock_timestamp(PG_FUNCTION_ARGS);
extern Datum pgsql_postmaster_start_time(PG_FUNCTION_ARGS);