From 5254958e924cd54f33d37026d85483fef986060d Mon Sep 17 00:00:00 2001 From: Stephen Frost <sfrost@snowman.net> Date: Sat, 18 Jan 2014 20:59:31 -0500 Subject: [PATCH] Add CREATE TABLESPACE ... WITH ... Options 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 | 23 ++++++++++++++++++++++- src/backend/commands/tablespace.c | 12 +++++++++++- src/backend/nodes/copyfuncs.c | 1 + src/backend/nodes/equalfuncs.c | 1 + src/backend/parser/gram.y | 3 ++- src/include/nodes/parsenodes.h | 1 + src/test/regress/input/tablespace.source | 10 ++++++++++ src/test/regress/output/tablespace.source | 13 +++++++++++++ 8 files changed, 61 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml index 89c89072aed..04c5fb8a1d5 100644 --- a/doc/src/sgml/ref/create_tablespace.sgml +++ b/doc/src/sgml/ref/create_tablespace.sgml @@ -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> diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index cb2499af7d2..05a89f0bde2 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -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); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 19e5f0495a8..bb356d0b263 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -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; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 55c548d5e49..5908d9abcf9 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -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; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 1b63d415318..12a6bebfe2f 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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; } ; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index f86edc61c3a..846c31aebdf 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1669,6 +1669,7 @@ typedef struct CreateTableSpaceStmt char *tablespacename; char *owner; char *location; + List *options; } CreateTableSpaceStmt; typedef struct DropTableSpaceStmt diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/input/tablespace.source index 8ee7efa5f81..601522866d1 100644 --- a/src/test/regress/input/tablespace.source +++ b/src/test/regress/input/tablespace.source @@ -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@'; diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/output/tablespace.source index cb5d139101c..27bc491e195 100644 --- a/src/test/regress/output/tablespace.source +++ b/src/test/regress/output/tablespace.source @@ -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 -- GitLab