diff options
-rw-r--r-- | doc/src/sgml/config.sgml | 5 | ||||
-rw-r--r-- | doc/src/sgml/func.sgml | 97 | ||||
-rw-r--r-- | src/backend/access/transam/xact.c | 25 | ||||
-rw-r--r-- | src/backend/tcop/postgres.c | 81 | ||||
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 14 | ||||
-rw-r--r-- | src/include/access/xact.h | 4 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 4 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 8 | ||||
-rw-r--r-- | src/include/utils/timestamp.h | 4 |
9 files changed, 179 insertions, 63 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 2ec9c3026cb..384a71a74b2 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,4 +1,4 @@ -<!-- $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> @@ -3279,7 +3279,8 @@ SELECT * FROM parent WHERE key = 2400; <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. diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 0b5fb01e4da..b53bdca6fc3 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,4 +1,4 @@ -<!-- $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> @@ -5303,6 +5303,15 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); <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> @@ -5358,7 +5367,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); <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> @@ -5474,8 +5483,36 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); <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> @@ -5484,7 +5521,8 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); <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> @@ -6072,7 +6110,7 @@ SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST'; </sect2> <sect2 id="functions-datetime-current"> - <title>Current Date/Time</title> + <title>Date/Time of Transaction Start</title> <indexterm> <primary>date</primary> @@ -6085,8 +6123,8 @@ SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST'; </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 @@ -6139,12 +6177,6 @@ SELECT LOCALTIMESTAMP; </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 start time of the current transaction; their values do not @@ -6152,26 +6184,31 @@ SELECT LOCALTIMESTAMP; 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> diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 0bbe2c0d495..b59cea044b9 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -10,7 +10,7 @@ * * * 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 $ * *------------------------------------------------------------------------- */ @@ -172,6 +172,7 @@ static CommandId currentCommandId; * keep it inside the TransactionState stack. */ static TimestampTz xactStartTimestamp; +static TimestampTz stmtStartTimestamp; /* * GID to be used for preparing the current transaction. This is also @@ -428,6 +429,24 @@ GetCurrentTransactionStartTimestamp(void) } /* + * GetCurrentStatementStartTimestamp + */ +TimestampTz +GetCurrentStatementStartTimestamp(void) +{ + return stmtStartTimestamp; +} + +/* + * SetCurrentStatementStartTimestamp + */ +void +SetCurrentStatementStartTimestamp(void) +{ + stmtStartTimestamp = GetCurrentTimestamp(); +} + +/* * GetCurrentTransactionNestLevel * * Note: this will return zero when not inside any transaction, one when @@ -1367,9 +1386,9 @@ StartTransaction(void) XactLockTableInsert(s->transactionId); /* - * set now() + * now() and statement_timestamp() should be the same time */ - xactStartTimestamp = GetCurrentTimestamp(); + xactStartTimestamp = stmtStartTimestamp; /* * initialize current transaction state fields diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 04e432594e3..2135c92fd80 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * 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 @@ -119,6 +119,12 @@ static volatile sig_atomic_t got_SIGHUP = false; 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 * commands like COPY FROM STDIN. @@ -164,6 +170,8 @@ static int ReadCommand(StringInfo inBuf); 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); @@ -858,7 +866,7 @@ exec_simple_query(const char *query_string) * 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, @@ -1067,7 +1075,7 @@ exec_simple_query(const char *query_string) /* * Close down transaction statement, if one is open. */ - finish_xact_command(); + finalize_command(); /* * If there were no parsetrees, return EmptyQueryResponse message. @@ -1170,7 +1178,7 @@ exec_parse_message(const char *query_string, /* string to execute */ * 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. @@ -1393,7 +1401,7 @@ exec_bind_message(StringInfo input_message) * 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); @@ -1759,7 +1767,7 @@ exec_execute_message(const char *portal_name, long max_rows) * 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 @@ -1883,7 +1891,7 @@ exec_describe_statement_message(const char *stmt_name) * 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); @@ -1961,7 +1969,7 @@ exec_describe_portal_message(const char *portal_name) * 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); @@ -2000,16 +2008,15 @@ exec_describe_portal_message(const char *portal_name) /* - * 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) @@ -2017,19 +2024,48 @@ start_xact_command(void) 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"))); @@ -3137,7 +3173,8 @@ PostgresMain(int argc, char *argv[], const char *username) /* We don't have a transaction command open anymore */ xact_started = false; - + command_initialized = false; + /* Now we can allow interrupts again */ RESUME_INTERRUPTS(); } @@ -3305,7 +3342,7 @@ PostgresMain(int argc, char *argv[], const char *username) 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); @@ -3328,7 +3365,7 @@ PostgresMain(int argc, char *argv[], const char *username) } /* commit the function-invocation transaction */ - finish_xact_command(); + finalize_command(); send_ready_for_query = true; break; @@ -3416,7 +3453,7 @@ PostgresMain(int argc, char *argv[], const char *username) case 'S': /* sync */ pq_getmsgend(&input_message); - finish_xact_command(); + finalize_command(); send_ready_for_query = true; break; diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 0524bf12394..fd40c1ebfdd 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * 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 $ * *------------------------------------------------------------------------- */ @@ -920,6 +920,18 @@ now(PG_FUNCTION_ARGS) } 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) { PG_RETURN_TIMESTAMPTZ(PgStartTime); diff --git a/src/include/access/xact.h b/src/include/access/xact.h index da2455f68fd..6591ba0456b 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -7,7 +7,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -141,6 +141,8 @@ extern TransactionId GetCurrentTransactionIdIfAny(void); 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); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index a88d3cfd597..11b02f691ad 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200604211 +#define CATALOG_VERSION_NO 200604241 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 9542d632f25..61339eadadc 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * 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 @@ -1614,6 +1614,12 @@ DATA(insert OID = 1298 ( timetzdate_pl PGNSP PGUID 14 f f t f i 2 1184 "1266 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 */ diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index 9747b300b6c..4e9e0c3f6f7 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -6,7 +6,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -284,6 +284,8 @@ extern Datum timestamptz_trunc(PG_FUNCTION_ARGS); 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); |