Add CREATE TABLESPACE ... WITH ... Options
authorStephen Frost <[email protected]>
Sun, 19 Jan 2014 01:59:31 +0000 (20:59 -0500)
committerStephen Frost <[email protected]>
Sun, 19 Jan 2014 01:59:31 +0000 (20:59 -0500)
Tablespaces have a few options which can be set on them to give PG hints
as to how the tablespace behaves (perhaps it's faster for sequential
scans, or better able to handle random access, etc).  These options were
only available through the ALTER TABLESPACE command.

This adds the ability to set these options at CREATE TABLESPACE time,
removing the need to do both a CREATE TABLESPACE and ALTER TABLESPACE to
get the correct options set on the tablespace.

Vik Fearing, reviewed by Michael Paquier.

doc/src/sgml/ref/create_tablespace.sgml
src/backend/commands/tablespace.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/include/nodes/parsenodes.h
src/test/regress/input/tablespace.source
src/test/regress/output/tablespace.source

index 89c89072aed1e9ed83cbc8c21f6b47ae0d4b6b70..04c5fb8a1d5418ad56bffb031aa38a7d36707f9c 100644 (file)
@@ -21,7 +21,10 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> [ OWNER <replaceable class="parameter">user_name</replaceable> ] LOCATION '<replaceable class="parameter">directory</replaceable>'
+CREATE TABLESPACE <replaceable class="parameter">tablespace_name</replaceable>
+    [ OWNER <replaceable class="parameter">user_name</replaceable> ]
+    LOCATION '<replaceable class="parameter">directory</replaceable>'
+    [ WITH ( <replaceable class="PARAMETER">tablespace_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -87,6 +90,24 @@ CREATE TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> [
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term><replaceable class="parameter">tablespace_option</replaceable></term>
+      <listitem>
+       <para>
+        A tablespace parameter to be set or reset.  Currently, the only
+        available parameters are <varname>seq_page_cost</> and
+        <varname>random_page_cost</>.  Setting either value for a particular
+        tablespace will override the planner's usual estimate of the cost of
+        reading pages from tables in that tablespace, as established by
+        the configuration parameters of the same name (see
+        <xref linkend="guc-seq-page-cost">,
+        <xref linkend="guc-random-page-cost">).  This may be useful if one
+        tablespace is located on a disk which is faster or slower than the
+        remainder of the I/O subsystem.
+       </para>
+      </listitem>
+     </varlistentry>
   </variablelist>
  </refsect1>
 
index cb2499af7d2a8fbadce10b18ccc49233fe5e4f97..05a89f0bde213557b3006450f832c9f846689ef0 100644 (file)
@@ -239,6 +239,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
        Oid                     tablespaceoid;
        char       *location;
        Oid                     ownerId;
+       Datum           newOptions;
 
        /* Must be super user */
        if (!superuser())
@@ -322,7 +323,16 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
        values[Anum_pg_tablespace_spcowner - 1] =
                ObjectIdGetDatum(ownerId);
        nulls[Anum_pg_tablespace_spcacl - 1] = true;
-       nulls[Anum_pg_tablespace_spcoptions - 1] = true;
+
+       /* Generate new proposed spcoptions (text array) */
+       newOptions = transformRelOptions((Datum) 0,
+                                                                        stmt->options,
+                                                                        NULL, NULL, false, false);
+       (void) tablespace_reloptions(newOptions, true);
+       if (newOptions != (Datum) 0)
+               values[Anum_pg_tablespace_spcoptions - 1] = newOptions;
+       else
+               nulls[Anum_pg_tablespace_spcoptions - 1] = true;
 
        tuple = heap_form_tuple(rel->rd_att, values, nulls);
 
index 19e5f0495a87f8a8c1d8d09da356d6915d2b4194..bb356d0b26366c724d8da7aa86c7bd49f8c7788a 100644 (file)
@@ -3370,6 +3370,7 @@ _copyCreateTableSpaceStmt(const CreateTableSpaceStmt *from)
        COPY_STRING_FIELD(tablespacename);
        COPY_STRING_FIELD(owner);
        COPY_STRING_FIELD(location);
+       COPY_NODE_FIELD(options);
 
        return newnode;
 }
index 55c548d5e49fa4517447ba47f6b34797c769d30c..5908d9abcf91368e96b77cb4191bec3054f83a5f 100644 (file)
@@ -1610,6 +1610,7 @@ _equalCreateTableSpaceStmt(const CreateTableSpaceStmt *a, const CreateTableSpace
        COMPARE_STRING_FIELD(tablespacename);
        COMPARE_STRING_FIELD(owner);
        COMPARE_STRING_FIELD(location);
+       COMPARE_NODE_FIELD(options);
 
        return true;
 }
index 1b63d415318fd29deb6b8257e6e6180f3c4744bb..12a6bebfe2f6836410d688e70ecebd7450a2341d 100644 (file)
@@ -3588,12 +3588,13 @@ opt_procedural:
  *
  *****************************************************************************/
 
-CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
+CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst opt_reloptions
                                {
                                        CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt);
                                        n->tablespacename = $3;
                                        n->owner = $4;
                                        n->location = $6;
+                                       n->options = $7;
                                        $$ = (Node *) n;
                                }
                ;
index f86edc61c3adf8986f17fd65b3d2b0711b199a75..846c31aebdfdadf1112e6ed11d77642d5c543355 100644 (file)
@@ -1669,6 +1669,7 @@ typedef struct CreateTableSpaceStmt
        char       *tablespacename;
        char       *owner;
        char       *location;
+       List       *options;
 } CreateTableSpaceStmt;
 
 typedef struct DropTableSpaceStmt
index 8ee7efa5f816bdac99a5c20d80b55c1b350b0fb8..601522866d11a8e83a48c6153abb5cc21e051b99 100644 (file)
@@ -1,3 +1,13 @@
+-- create a tablespace using WITH clause
+CREATE TABLESPACE testspacewith LOCATION '@testtablespace@' WITH (some_nonexistent_parameter = true); -- fail
+CREATE TABLESPACE testspacewith LOCATION '@testtablespace@' WITH (random_page_cost = 3.0); -- ok
+
+-- check to see the parameter was used
+SELECT spcoptions FROM pg_tablespace WHERE spcname = 'testspacewith';
+
+-- drop the tablespace so we can re-use the location
+DROP TABLESPACE testspacewith;
+
 -- create a tablespace we can use
 CREATE TABLESPACE testspace LOCATION '@testtablespace@';
 
index cb5d139101cb3fb206446700d9d5deb4fcc3d4a1..27bc491e1959cfda79bc9136b0e3793321519148 100644 (file)
@@ -1,3 +1,16 @@
+-- create a tablespace using WITH clause
+CREATE TABLESPACE testspacewith LOCATION '@testtablespace@' WITH (some_nonexistent_parameter = true); -- fail
+ERROR:  unrecognized parameter "some_nonexistent_parameter"
+CREATE TABLESPACE testspacewith LOCATION '@testtablespace@' WITH (random_page_cost = 3.0); -- ok
+-- check to see the parameter was used
+SELECT spcoptions FROM pg_tablespace WHERE spcname = 'testspacewith';
+       spcoptions       
+------------------------
+ {random_page_cost=3.0}
+(1 row)
+
+-- drop the tablespace so we can re-use the location
+DROP TABLESPACE testspacewith;
 -- create a tablespace we can use
 CREATE TABLESPACE testspace LOCATION '@testtablespace@';
 -- try setting and resetting some properties for the new tablespace