]> granicus.if.org Git - postgresql/commitdiff
Create a standard function pg_sleep() to sleep for a specified amount of time.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 11 Jan 2006 20:12:43 +0000 (20:12 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 11 Jan 2006 20:12:43 +0000 (20:12 +0000)
Replace the former ad-hoc implementation used in the regression tests.
Joachim Wieland

doc/src/sgml/func.sgml
src/backend/utils/adt/misc.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/utils/builtins.h
src/test/regress/expected/stats.out
src/test/regress/input/create_function_1.source
src/test/regress/output/create_function_1.source
src/test/regress/regress.c
src/test/regress/sql/stats.sql

index d90bc15d411d33b1fab88256e0f3db622c75e549..a3eadb4bc400398137f02006a97e672765db4bc4 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.301 2005/12/28 01:29:58 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.302 2006/01/11 20:12:38 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -6170,6 +6170,56 @@ SELECT TIMESTAMP 'now';  -- incorrect for use with DEFAULT
      </para>
     </tip>
   </sect2>
+
+  <sect2 id="functions-datetime-delay">
+   <title>Delaying Execution</title>
+
+   <indexterm>
+    <primary>pg_sleep</primary>
+   </indexterm>
+   <indexterm>
+    <primary>sleep</primary>
+   </indexterm>
+   <indexterm>
+    <primary>delay</primary>
+   </indexterm>
+
+   <para>
+    The following function is available to delay execution of the server
+    process:
+<synopsis>
+pg_sleep(<replaceable>seconds</replaceable>)
+</synopsis>
+
+    <function>pg_sleep</function> makes the current session's process
+    sleep until <replaceable>seconds</replaceable> seconds have
+    elapsed.  <replaceable>seconds</replaceable> is a value of type
+    <type>double precision</>, so fractional-second delays can be specified.
+    For example:
+
+<programlisting>
+SELECT pg_sleep(1.5);
+</programlisting>
+   </para>
+
+   <note>
+     <para>
+      The effective resolution of the sleep interval is platform-specific;
+      0.01 seconds is a common value.  The sleep delay will be at least as long
+      as specified. It may be longer depending on factors such as server load.
+     </para>
+   </note>
+
+   <warning>
+     <para>
+      Make sure that your session does not hold more locks than necessary
+      when calling <function>pg_sleep</function>.  Otherwise other sessions
+      might have to wait for your sleeping process, slowing down the entire
+      system.
+     </para>
+   </warning>
+  </sect2>
+
  </sect1>
 
   
index 14bb593c2c27d6dbae2a3e5899f92b095ff0b345..2ceea8969a56d1f66501e617e6799be2b82c33cd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.49 2005/10/15 02:49:29 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.50 2006/01/11 20:12:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,6 +17,7 @@
 #include <sys/file.h>
 #include <signal.h>
 #include <dirent.h>
+#include <math.h>
 
 #include "catalog/pg_tablespace.h"
 #include "catalog/pg_type.h"
@@ -259,3 +260,51 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
        FreeDir(fctx->dirdesc);
        SRF_RETURN_DONE(funcctx);
 }
+
+
+/*
+ * pg_sleep - delay for N seconds
+ */
+Datum
+pg_sleep(PG_FUNCTION_ARGS)
+{
+       float8          secs = PG_GETARG_FLOAT8(0);
+       float8          endtime;
+
+       /*
+        * We break the requested sleep into segments of no more than 1 second,
+        * to put an upper bound on how long it will take us to respond to a
+        * cancel or die interrupt.  (Note that pg_usleep is interruptible by
+        * signals on some platforms but not others.)  Also, this method avoids
+        * exposing pg_usleep's upper bound on allowed delays.
+        *
+        * By computing the intended stop time initially, we avoid accumulation
+        * of extra delay across multiple sleeps.  This also ensures we won't
+        * delay less than the specified time if pg_usleep is interrupted
+        * by other signals such as SIGHUP.
+        */
+
+#ifdef HAVE_INT64_TIMESTAMP
+#define GetNowFloat()  ((float8) GetCurrentTimestamp() / 1000000.0)
+#else
+#define GetNowFloat()  GetCurrentTimestamp()
+#endif
+
+       endtime = GetNowFloat() + secs;
+
+       for (;;)
+       {
+               float8          delay;
+
+               CHECK_FOR_INTERRUPTS();
+               delay = endtime - GetNowFloat();
+               if (delay >= 1.0)
+                       pg_usleep(1000000L);
+               else if (delay > 0.0)
+                       pg_usleep((long) ceil(delay * 1000000.0));
+               else
+                       break;
+       }
+
+       PG_RETURN_VOID();
+}
index 6eb5f72d9fa6487f73060767d9a003be5ea92795..258a9956f4a20293a17d11dfbf0848f32fcdaf0e 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.309 2006/01/08 07:00:25 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.310 2006/01/11 20:12:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200601081
+#define CATALOG_VERSION_NO     200601111
 
 #endif
index 7b78e78fcc39bcd4930034904c0ac68df48b994a..6f5ec17c45178ee281b5b0fc9bbb7e4b9b5ea8bd 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.390 2006/01/08 07:00:25 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.391 2006/01/11 20:12:39 tgl Exp $
  *
  * NOTES
  *       The script catalog/genbki.sh reads this file and generates .bki
@@ -3025,6 +3025,8 @@ DATA(insert OID = 2624 ( pg_read_file             PGNSP PGUID 12 f f t f v 3 25 "25 20 20"
 DESCR("Read text from a file");
 DATA(insert OID = 2625 ( pg_ls_dir                     PGNSP PGUID 12 f f t t v 1 25 "25" _null_ _null_ _null_ pg_ls_dir - _null_ ));
 DESCR("List all files in a directory");
+DATA(insert OID = 2626 ( pg_sleep                      PGNSP PGUID 12 f f t f v 1 2278 "701" _null_ _null_ _null_ pg_sleep - _null_ ));
+DESCR("Sleep for the specified time in seconds");
 
 
 /* Aggregates (moved here from pg_aggregate for 7.3) */
index 97fbfdc341e8e4afcc6c6b79d300c78c596edd08..8ca212852c2c1e9a41c102495c168f4021aa02c5 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.269 2006/01/08 07:00:26 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.270 2006/01/11 20:12:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -387,6 +387,7 @@ extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
 extern Datum pg_reload_conf(PG_FUNCTION_ARGS);
 extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS);
 extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS);
+extern Datum pg_sleep(PG_FUNCTION_ARGS);
 
 /* not_in.c */
 extern Datum int4notin(PG_FUNCTION_ARGS);
index bd2e1328f8f39a0e4b1d4eef6eba75fa1ecf4200..d3495ffb481f522e266b2da9be7c660e79c56592 100644 (file)
@@ -36,8 +36,8 @@ SELECT count(*) FROM tenk2 WHERE unique1 = 1;
 (1 row)
 
 -- let stats collector catch up
-SELECT do_sleep(2);
do_sleep 
+SELECT pg_sleep(2.0);
pg_sleep 
 ----------
  
 (1 row)
index 14b90ca1a1b0089878136645ec8e2d15be614957..faa73156dc21afb7b11c2c5e9dbf5987b401115a 100644 (file)
@@ -52,11 +52,6 @@ CREATE FUNCTION set_ttdummy (int4)
         AS '@abs_builddir@/regress@DLSUFFIX@'
         LANGUAGE 'C' STRICT;
 
-CREATE FUNCTION do_sleep (int4)
-        RETURNS void
-        AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'C' STRICT;
-
 -- Things that shouldn't work:
 
 CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql
index 7511c3f8d6753e18cc6615c8e6e799d8a1f01342..ed275b1f482163701207b140a8fef4b255b69c96 100644 (file)
@@ -47,10 +47,6 @@ CREATE FUNCTION set_ttdummy (int4)
         RETURNS int4
         AS '@abs_builddir@/regress@DLSUFFIX@'
         LANGUAGE 'C' STRICT;
-CREATE FUNCTION do_sleep (int4)
-        RETURNS void
-        AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'C' STRICT;
 -- Things that shouldn't work:
 CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql
     AS 'SELECT ''not an integer'';';
index 97fe608602a87a60f63a07b55fb58ade81d44739..7c58f950cbb535548cbacac4361e18d57a4c44b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/src/test/regress/regress.c,v 1.64 2005/10/15 02:49:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/test/regress/regress.c,v 1.65 2006/01/11 20:12:43 tgl Exp $
  */
 
 #include "postgres.h"
@@ -26,7 +26,6 @@ extern char *reverse_name(char *string);
 extern int     oldstyle_length(int n, text *t);
 extern Datum int44in(PG_FUNCTION_ARGS);
 extern Datum int44out(PG_FUNCTION_ARGS);
-extern Datum do_sleep(PG_FUNCTION_ARGS);
 
 
 /*
@@ -735,18 +734,3 @@ int44out(PG_FUNCTION_ARGS)
        *--walk = '\0';
        PG_RETURN_CSTRING(result);
 }
-
-/*
- * do_sleep - delay for N seconds
- */
-PG_FUNCTION_INFO_V1(do_sleep);
-
-Datum
-do_sleep(PG_FUNCTION_ARGS)
-{
-       int32           secs = PG_GETARG_INT32(0);
-
-       pg_usleep(secs * 1000000L);
-
-       PG_RETURN_VOID();
-}
index 3589a0cf5ddf19845352598bd0c3a60ca89dab0c..75acee647d5aaf95b39265cfcd77a422daaa42b4 100644 (file)
@@ -26,7 +26,7 @@ SELECT count(*) FROM tenk2;
 SELECT count(*) FROM tenk2 WHERE unique1 = 1;
 
 -- let stats collector catch up
-SELECT do_sleep(2);
+SELECT pg_sleep(2.0);
 
 -- check effects
 SELECT st.seq_scan >= pr.seq_scan + 1,