mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Support ALTER TABLESPACE name SET/RESET ( tablespace_options ).
This patch only supports seq_page_cost and random_page_cost as parameters, but it provides the infrastructure to scalably support many more. In particular, we may want to add support for effective_io_concurrency, but I'm leaving that as future work for now. Thanks to Tom Lane for design help and Alvaro Herrera for the review.
This commit is contained in:
		
							parent
							
								
									72559b49c0
								
							
						
					
					
						commit
						d86d51a958
					
				| @ -1,4 +1,4 @@ | |||||||
| <!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.241 2009/12/25 01:09:31 rhaas Exp $ --> | <!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.242 2010/01/05 21:53:58 rhaas Exp $ --> | ||||||
| 
 | 
 | ||||||
| <chapter Id="runtime-config"> | <chapter Id="runtime-config"> | ||||||
|   <title>Server Configuration</title> |   <title>Server Configuration</title> | ||||||
| @ -2000,6 +2000,9 @@ archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'  # Windows | |||||||
|        <para> |        <para> | ||||||
|         Sets the planner's estimate of the cost of a disk page fetch |         Sets the planner's estimate of the cost of a disk page fetch | ||||||
|         that is part of a series of sequential fetches.  The default is 1.0. |         that is part of a series of sequential fetches.  The default is 1.0. | ||||||
|  |         This value can be overriden for a particular tablespace by setting | ||||||
|  |         the tablespace parameter of the same name | ||||||
|  |         (see <xref linkend="sql-altertablespace">). | ||||||
|        </para> |        </para> | ||||||
|       </listitem> |       </listitem> | ||||||
|      </varlistentry> |      </varlistentry> | ||||||
| @ -2013,6 +2016,12 @@ archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'  # Windows | |||||||
|        <para> |        <para> | ||||||
|         Sets the planner's estimate of the cost of a |         Sets the planner's estimate of the cost of a | ||||||
|         non-sequentially-fetched disk page.  The default is 4.0. |         non-sequentially-fetched disk page.  The default is 4.0. | ||||||
|  |         This value can be overriden for a particular tablespace by setting | ||||||
|  |         the tablespace parameter of the same name | ||||||
|  |         (see <xref linkend="sql-altertablespace">). | ||||||
|  |        </para> | ||||||
|  | 
 | ||||||
|  | 	   <para> | ||||||
|         Reducing this value relative to <varname>seq_page_cost</> |         Reducing this value relative to <varname>seq_page_cost</> | ||||||
|         will cause the system to prefer index scans; raising it will |         will cause the system to prefer index scans; raising it will | ||||||
|         make index scans look relatively more expensive.  You can raise |         make index scans look relatively more expensive.  You can raise | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| <!-- | <!-- | ||||||
| $PostgreSQL: pgsql/doc/src/sgml/ref/alter_tablespace.sgml,v 1.5 2009/09/19 10:23:26 petere Exp $ | $PostgreSQL: pgsql/doc/src/sgml/ref/alter_tablespace.sgml,v 1.6 2010/01/05 21:53:58 rhaas Exp $ | ||||||
| PostgreSQL documentation | PostgreSQL documentation | ||||||
| --> | --> | ||||||
| 
 | 
 | ||||||
| @ -23,6 +23,8 @@ PostgreSQL documentation | |||||||
| <synopsis> | <synopsis> | ||||||
| ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> | ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> | ||||||
| ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> | ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> | ||||||
|  | ALTER TABLESPACE <replaceable>name</replaceable> SET ( <replaceable class="PARAMETER">tablespace_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) | ||||||
|  | ALTER TABLESPACE <replaceable>name</replaceable> RESET ( <replaceable class="PARAMETER">tablespace_option</replaceable> [, ... ] ) | ||||||
| </synopsis> | </synopsis> | ||||||
|  </refsynopsisdiv> |  </refsynopsisdiv> | ||||||
|    |    | ||||||
| @ -74,6 +76,24 @@ ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner | |||||||
|      </para> |      </para> | ||||||
|     </listitem> |     </listitem> | ||||||
|    </varlistentry> |    </varlistentry> | ||||||
|  | 
 | ||||||
|  |    <varlistentry> | ||||||
|  |     <term><replaceable class="parameter">tablespace_parameter</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> |   </variablelist> | ||||||
|  </refsect1> |  </refsect1> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.30 2010/01/02 16:57:33 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.31 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -21,6 +21,7 @@ | |||||||
| #include "access/reloptions.h" | #include "access/reloptions.h" | ||||||
| #include "catalog/pg_type.h" | #include "catalog/pg_type.h" | ||||||
| #include "commands/defrem.h" | #include "commands/defrem.h" | ||||||
|  | #include "commands/tablespace.h" | ||||||
| #include "nodes/makefuncs.h" | #include "nodes/makefuncs.h" | ||||||
| #include "utils/array.h" | #include "utils/array.h" | ||||||
| #include "utils/builtins.h" | #include "utils/builtins.h" | ||||||
| @ -179,6 +180,22 @@ static relopt_real realRelOpts[] = | |||||||
| 		}, | 		}, | ||||||
| 		-1, 0.0, 100.0 | 		-1, 0.0, 100.0 | ||||||
| 	}, | 	}, | ||||||
|  | 	{ | ||||||
|  | 		{ | ||||||
|  | 			"seq_page_cost", | ||||||
|  | 			"Sets the planner's estimate of the cost of a sequentially fetched disk page.", | ||||||
|  | 			RELOPT_KIND_TABLESPACE | ||||||
|  | 		}, | ||||||
|  | 		-1, 0.0, DBL_MAX | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		{ | ||||||
|  | 			"random_page_cost", | ||||||
|  | 			"Sets the planner's estimate of the cost of a nonsequentially fetched disk page.", | ||||||
|  | 			RELOPT_KIND_TABLESPACE | ||||||
|  | 		}, | ||||||
|  | 		-1, 0.0, DBL_MAX | ||||||
|  | 	}, | ||||||
| 	/* list terminator */ | 	/* list terminator */ | ||||||
| 	{{NULL}} | 	{{NULL}} | ||||||
| }; | }; | ||||||
| @ -1168,3 +1185,34 @@ index_reloptions(RegProcedure amoptions, Datum reloptions, bool validate) | |||||||
| 
 | 
 | ||||||
| 	return DatumGetByteaP(result); | 	return DatumGetByteaP(result); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Option parser for tablespace reloptions | ||||||
|  |  */ | ||||||
|  | bytea * | ||||||
|  | tablespace_reloptions(Datum reloptions, bool validate) | ||||||
|  | { | ||||||
|  | 	relopt_value *options; | ||||||
|  | 	TableSpaceOpts	*tsopts; | ||||||
|  | 	int			numoptions; | ||||||
|  | 	static const relopt_parse_elt tab[] = { | ||||||
|  | 		{"random_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, random_page_cost)}, | ||||||
|  | 		{"seq_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, seq_page_cost)} | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	options = parseRelOptions(reloptions, validate, RELOPT_KIND_TABLESPACE, | ||||||
|  | 							  &numoptions); | ||||||
|  | 
 | ||||||
|  | 	/* if none set, we're done */ | ||||||
|  | 	if (numoptions == 0) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	tsopts = allocateReloptStruct(sizeof(TableSpaceOpts), options, numoptions); | ||||||
|  | 
 | ||||||
|  | 	fillRelOptions((void *) tsopts, sizeof(TableSpaceOpts), options, numoptions, | ||||||
|  | 				   validate, tab, lengthof(tab)); | ||||||
|  | 
 | ||||||
|  | 	pfree(options); | ||||||
|  | 
 | ||||||
|  | 	return (bytea *) tsopts; | ||||||
|  | } | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.159 2010/01/02 16:57:36 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.160 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  *	  See acl.h. |  *	  See acl.h. | ||||||
| @ -2783,18 +2783,11 @@ ExecGrant_Tablespace(InternalGrant *istmt) | |||||||
| 		int			nnewmembers; | 		int			nnewmembers; | ||||||
| 		Oid		   *oldmembers; | 		Oid		   *oldmembers; | ||||||
| 		Oid		   *newmembers; | 		Oid		   *newmembers; | ||||||
| 		ScanKeyData entry[1]; |  | ||||||
| 		SysScanDesc scan; |  | ||||||
| 		HeapTuple	tuple; | 		HeapTuple	tuple; | ||||||
| 
 | 
 | ||||||
| 		/* There's no syscache for pg_tablespace, so must look the hard way */ | 		/* Search syscache for pg_tablespace */ | ||||||
| 		ScanKeyInit(&entry[0], | 		tuple = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(tblId), | ||||||
| 					ObjectIdAttributeNumber, | 							   0, 0, 0); | ||||||
| 					BTEqualStrategyNumber, F_OIDEQ, |  | ||||||
| 					ObjectIdGetDatum(tblId)); |  | ||||||
| 		scan = systable_beginscan(relation, TablespaceOidIndexId, true, |  | ||||||
| 								  SnapshotNow, 1, entry); |  | ||||||
| 		tuple = systable_getnext(scan); |  | ||||||
| 		if (!HeapTupleIsValid(tuple)) | 		if (!HeapTupleIsValid(tuple)) | ||||||
| 			elog(ERROR, "cache lookup failed for tablespace %u", tblId); | 			elog(ERROR, "cache lookup failed for tablespace %u", tblId); | ||||||
| 
 | 
 | ||||||
| @ -2865,8 +2858,7 @@ ExecGrant_Tablespace(InternalGrant *istmt) | |||||||
| 							  noldmembers, oldmembers, | 							  noldmembers, oldmembers, | ||||||
| 							  nnewmembers, newmembers); | 							  nnewmembers, newmembers); | ||||||
| 
 | 
 | ||||||
| 		systable_endscan(scan); | 		ReleaseSysCache(tuple); | ||||||
| 
 |  | ||||||
| 		pfree(new_acl); | 		pfree(new_acl); | ||||||
| 
 | 
 | ||||||
| 		/* prevent error when processing duplicate objects */ | 		/* prevent error when processing duplicate objects */ | ||||||
| @ -3696,9 +3688,6 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid, | |||||||
| 					  AclMode mask, AclMaskHow how) | 					  AclMode mask, AclMaskHow how) | ||||||
| { | { | ||||||
| 	AclMode		result; | 	AclMode		result; | ||||||
| 	Relation	pg_tablespace; |  | ||||||
| 	ScanKeyData entry[1]; |  | ||||||
| 	SysScanDesc scan; |  | ||||||
| 	HeapTuple	tuple; | 	HeapTuple	tuple; | ||||||
| 	Datum		aclDatum; | 	Datum		aclDatum; | ||||||
| 	bool		isNull; | 	bool		isNull; | ||||||
| @ -3711,17 +3700,9 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid, | |||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Get the tablespace's ACL from pg_tablespace | 	 * Get the tablespace's ACL from pg_tablespace | ||||||
| 	 * |  | ||||||
| 	 * There's no syscache for pg_tablespace, so must look the hard way |  | ||||||
| 	 */ | 	 */ | ||||||
| 	pg_tablespace = heap_open(TableSpaceRelationId, AccessShareLock); | 	tuple = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spc_oid), | ||||||
| 	ScanKeyInit(&entry[0], | 						   0, 0, 0); | ||||||
| 				ObjectIdAttributeNumber, |  | ||||||
| 				BTEqualStrategyNumber, F_OIDEQ, |  | ||||||
| 				ObjectIdGetDatum(spc_oid)); |  | ||||||
| 	scan = systable_beginscan(pg_tablespace, TablespaceOidIndexId, true, |  | ||||||
| 							  SnapshotNow, 1, entry); |  | ||||||
| 	tuple = systable_getnext(scan); |  | ||||||
| 	if (!HeapTupleIsValid(tuple)) | 	if (!HeapTupleIsValid(tuple)) | ||||||
| 		ereport(ERROR, | 		ereport(ERROR, | ||||||
| 				(errcode(ERRCODE_UNDEFINED_OBJECT), | 				(errcode(ERRCODE_UNDEFINED_OBJECT), | ||||||
| @ -3729,8 +3710,9 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid, | |||||||
| 
 | 
 | ||||||
| 	ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner; | 	ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner; | ||||||
| 
 | 
 | ||||||
| 	aclDatum = heap_getattr(tuple, Anum_pg_tablespace_spcacl, | 	aclDatum = SysCacheGetAttr(TABLESPACEOID, tuple, | ||||||
| 							RelationGetDescr(pg_tablespace), &isNull); | 								   Anum_pg_tablespace_spcacl, | ||||||
|  | 								   &isNull); | ||||||
| 
 | 
 | ||||||
| 	if (isNull) | 	if (isNull) | ||||||
| 	{ | 	{ | ||||||
| @ -3750,8 +3732,7 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid, | |||||||
| 	if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) | 	if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) | ||||||
| 		pfree(acl); | 		pfree(acl); | ||||||
| 
 | 
 | ||||||
| 	systable_endscan(scan); | 	ReleaseSysCache(tuple); | ||||||
| 	heap_close(pg_tablespace, AccessShareLock); |  | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| @ -4338,9 +4319,6 @@ pg_namespace_ownercheck(Oid nsp_oid, Oid roleid) | |||||||
| bool | bool | ||||||
| pg_tablespace_ownercheck(Oid spc_oid, Oid roleid) | pg_tablespace_ownercheck(Oid spc_oid, Oid roleid) | ||||||
| { | { | ||||||
| 	Relation	pg_tablespace; |  | ||||||
| 	ScanKeyData entry[1]; |  | ||||||
| 	SysScanDesc scan; |  | ||||||
| 	HeapTuple	spctuple; | 	HeapTuple	spctuple; | ||||||
| 	Oid			spcowner; | 	Oid			spcowner; | ||||||
| 
 | 
 | ||||||
| @ -4348,17 +4326,9 @@ pg_tablespace_ownercheck(Oid spc_oid, Oid roleid) | |||||||
| 	if (superuser_arg(roleid)) | 	if (superuser_arg(roleid)) | ||||||
| 		return true; | 		return true; | ||||||
| 
 | 
 | ||||||
| 	/* There's no syscache for pg_tablespace, so must look the hard way */ | 	/* Search syscache for pg_tablespace */ | ||||||
| 	pg_tablespace = heap_open(TableSpaceRelationId, AccessShareLock); | 	spctuple = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spc_oid), | ||||||
| 	ScanKeyInit(&entry[0], | 							  0, 0, 0); | ||||||
| 				ObjectIdAttributeNumber, |  | ||||||
| 				BTEqualStrategyNumber, F_OIDEQ, |  | ||||||
| 				ObjectIdGetDatum(spc_oid)); |  | ||||||
| 	scan = systable_beginscan(pg_tablespace, TablespaceOidIndexId, true, |  | ||||||
| 							  SnapshotNow, 1, entry); |  | ||||||
| 
 |  | ||||||
| 	spctuple = systable_getnext(scan); |  | ||||||
| 
 |  | ||||||
| 	if (!HeapTupleIsValid(spctuple)) | 	if (!HeapTupleIsValid(spctuple)) | ||||||
| 		ereport(ERROR, | 		ereport(ERROR, | ||||||
| 				(errcode(ERRCODE_UNDEFINED_OBJECT), | 				(errcode(ERRCODE_UNDEFINED_OBJECT), | ||||||
| @ -4366,8 +4336,7 @@ pg_tablespace_ownercheck(Oid spc_oid, Oid roleid) | |||||||
| 
 | 
 | ||||||
| 	spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner; | 	spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner; | ||||||
| 
 | 
 | ||||||
| 	systable_endscan(scan); | 	ReleaseSysCache(spctuple); | ||||||
| 	heap_close(pg_tablespace, AccessShareLock); |  | ||||||
| 
 | 
 | ||||||
| 	return has_privs_of_role(roleid, spcowner); | 	return has_privs_of_role(roleid, spcowner); | ||||||
| } | } | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.65 2010/01/02 16:57:37 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.66 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -49,6 +49,7 @@ | |||||||
| #include <sys/stat.h> | #include <sys/stat.h> | ||||||
| 
 | 
 | ||||||
| #include "access/heapam.h" | #include "access/heapam.h" | ||||||
|  | #include "access/reloptions.h" | ||||||
| #include "access/sysattr.h" | #include "access/sysattr.h" | ||||||
| #include "access/transam.h" | #include "access/transam.h" | ||||||
| #include "access/xact.h" | #include "access/xact.h" | ||||||
| @ -57,6 +58,7 @@ | |||||||
| #include "catalog/indexing.h" | #include "catalog/indexing.h" | ||||||
| #include "catalog/pg_tablespace.h" | #include "catalog/pg_tablespace.h" | ||||||
| #include "commands/comment.h" | #include "commands/comment.h" | ||||||
|  | #include "commands/defrem.h" | ||||||
| #include "commands/tablespace.h" | #include "commands/tablespace.h" | ||||||
| #include "miscadmin.h" | #include "miscadmin.h" | ||||||
| #include "postmaster/bgwriter.h" | #include "postmaster/bgwriter.h" | ||||||
| @ -70,6 +72,7 @@ | |||||||
| #include "utils/lsyscache.h" | #include "utils/lsyscache.h" | ||||||
| #include "utils/memutils.h" | #include "utils/memutils.h" | ||||||
| #include "utils/rel.h" | #include "utils/rel.h" | ||||||
|  | #include "utils/syscache.h" | ||||||
| #include "utils/tqual.h" | #include "utils/tqual.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -290,6 +293,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) | |||||||
| 	values[Anum_pg_tablespace_spclocation - 1] = | 	values[Anum_pg_tablespace_spclocation - 1] = | ||||||
| 		CStringGetTextDatum(location); | 		CStringGetTextDatum(location); | ||||||
| 	nulls[Anum_pg_tablespace_spcacl - 1] = true; | 	nulls[Anum_pg_tablespace_spcacl - 1] = true; | ||||||
|  | 	nulls[Anum_pg_tablespace_spcoptions - 1] = true; | ||||||
| 
 | 
 | ||||||
| 	tuple = heap_form_tuple(rel->rd_att, values, nulls); | 	tuple = heap_form_tuple(rel->rd_att, values, nulls); | ||||||
| 
 | 
 | ||||||
| @ -912,6 +916,73 @@ AlterTableSpaceOwner(const char *name, Oid newOwnerId) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Alter table space options | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) | ||||||
|  | { | ||||||
|  | 	Relation	rel; | ||||||
|  | 	ScanKeyData entry[1]; | ||||||
|  | 	HeapScanDesc scandesc; | ||||||
|  | 	HeapTuple	tup; | ||||||
|  | 	Datum		datum; | ||||||
|  | 	Datum		newOptions; | ||||||
|  | 	Datum		repl_val[Natts_pg_tablespace]; | ||||||
|  | 	bool		isnull; | ||||||
|  | 	bool		repl_null[Natts_pg_tablespace]; | ||||||
|  | 	bool		repl_repl[Natts_pg_tablespace]; | ||||||
|  | 	HeapTuple	newtuple; | ||||||
|  | 
 | ||||||
|  | 	/* Search pg_tablespace */ | ||||||
|  | 	rel = heap_open(TableSpaceRelationId, RowExclusiveLock); | ||||||
|  | 
 | ||||||
|  | 	ScanKeyInit(&entry[0], | ||||||
|  | 				Anum_pg_tablespace_spcname, | ||||||
|  | 				BTEqualStrategyNumber, F_NAMEEQ, | ||||||
|  | 				CStringGetDatum(stmt->tablespacename)); | ||||||
|  | 	scandesc = heap_beginscan(rel, SnapshotNow, 1, entry); | ||||||
|  | 	tup = heap_getnext(scandesc, ForwardScanDirection); | ||||||
|  | 	if (!HeapTupleIsValid(tup)) | ||||||
|  | 		ereport(ERROR, | ||||||
|  | 				(errcode(ERRCODE_UNDEFINED_OBJECT), | ||||||
|  | 				 errmsg("tablespace \"%s\" does not exist", | ||||||
|  | 					stmt->tablespacename))); | ||||||
|  | 
 | ||||||
|  | 	/* Must be owner of the existing object */ | ||||||
|  | 	if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId())) | ||||||
|  | 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE, | ||||||
|  | 					   stmt->tablespacename); | ||||||
|  | 
 | ||||||
|  | 	/* Generate new proposed spcoptions (text array) */ | ||||||
|  | 	datum = heap_getattr(tup, Anum_pg_tablespace_spcoptions, | ||||||
|  | 						 RelationGetDescr(rel), &isnull); | ||||||
|  | 	newOptions = transformRelOptions(isnull ? (Datum) 0 : datum, | ||||||
|  | 									 stmt->options, NULL, NULL, false, | ||||||
|  | 									 stmt->isReset); | ||||||
|  | 	(void) tablespace_reloptions(newOptions, true); | ||||||
|  | 
 | ||||||
|  | 	/* Build new tuple. */ | ||||||
|  | 	memset(repl_null, false, sizeof(repl_null)); | ||||||
|  | 	memset(repl_repl, false, sizeof(repl_repl)); | ||||||
|  | 	if (newOptions != (Datum) 0) | ||||||
|  | 		repl_val[Anum_pg_tablespace_spcoptions - 1] = newOptions; | ||||||
|  | 	else | ||||||
|  | 		repl_null[Anum_pg_tablespace_spcoptions - 1] = true; | ||||||
|  | 	repl_repl[Anum_pg_tablespace_spcoptions - 1] = true; | ||||||
|  | 	newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, | ||||||
|  | 								 repl_null, repl_repl); | ||||||
|  | 
 | ||||||
|  | 	/* Update system catalog. */ | ||||||
|  | 	simple_heap_update(rel, &newtuple->t_self, newtuple); | ||||||
|  | 	CatalogUpdateIndexes(rel, newtuple); | ||||||
|  | 	heap_freetuple(newtuple); | ||||||
|  | 
 | ||||||
|  | 	/* Conclude heap scan. */ | ||||||
|  | 	heap_endscan(scandesc); | ||||||
|  | 	heap_close(rel, NoLock); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Routines for handling the GUC variable 'default_tablespace'. |  * Routines for handling the GUC variable 'default_tablespace'. | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.458 2010/01/02 16:57:45 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.459 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -3064,6 +3064,18 @@ _copyDropTableSpaceStmt(DropTableSpaceStmt *from) | |||||||
| 	return newnode; | 	return newnode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static AlterTableSpaceOptionsStmt * | ||||||
|  | _copyAlterTableSpaceOptionsStmt(AlterTableSpaceOptionsStmt *from) | ||||||
|  | { | ||||||
|  | 	AlterTableSpaceOptionsStmt *newnode = makeNode(AlterTableSpaceOptionsStmt); | ||||||
|  | 
 | ||||||
|  | 	COPY_STRING_FIELD(tablespacename); | ||||||
|  | 	COPY_NODE_FIELD(options); | ||||||
|  | 	COPY_SCALAR_FIELD(isReset); | ||||||
|  | 
 | ||||||
|  | 	return newnode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static CreateFdwStmt * | static CreateFdwStmt * | ||||||
| _copyCreateFdwStmt(CreateFdwStmt *from) | _copyCreateFdwStmt(CreateFdwStmt *from) | ||||||
| { | { | ||||||
| @ -4028,6 +4040,9 @@ copyObject(void *from) | |||||||
| 		case T_DropTableSpaceStmt: | 		case T_DropTableSpaceStmt: | ||||||
| 			retval = _copyDropTableSpaceStmt(from); | 			retval = _copyDropTableSpaceStmt(from); | ||||||
| 			break; | 			break; | ||||||
|  | 		case T_AlterTableSpaceOptionsStmt: | ||||||
|  | 			retval = _copyAlterTableSpaceOptionsStmt(from); | ||||||
|  | 			break; | ||||||
| 		case T_CreateFdwStmt: | 		case T_CreateFdwStmt: | ||||||
| 			retval = _copyCreateFdwStmt(from); | 			retval = _copyCreateFdwStmt(from); | ||||||
| 			break; | 			break; | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ | |||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.379 2010/01/02 16:57:46 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.380 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -1568,6 +1568,17 @@ _equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b) | |||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool | ||||||
|  | _equalAlterTableSpaceOptionsStmt(AlterTableSpaceOptionsStmt *a, | ||||||
|  | 											 AlterTableSpaceOptionsStmt *b) | ||||||
|  | { | ||||||
|  | 	COMPARE_STRING_FIELD(tablespacename); | ||||||
|  | 	COMPARE_NODE_FIELD(options); | ||||||
|  | 	COMPARE_SCALAR_FIELD(isReset); | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static bool | static bool | ||||||
| _equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b) | _equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b) | ||||||
| { | { | ||||||
| @ -2720,6 +2731,9 @@ equal(void *a, void *b) | |||||||
| 		case T_DropTableSpaceStmt: | 		case T_DropTableSpaceStmt: | ||||||
| 			retval = _equalDropTableSpaceStmt(a, b); | 			retval = _equalDropTableSpaceStmt(a, b); | ||||||
| 			break; | 			break; | ||||||
|  | 		case T_AlterTableSpaceOptionsStmt: | ||||||
|  | 			retval = _equalAlterTableSpaceOptionsStmt(a, b); | ||||||
|  | 			break; | ||||||
| 		case T_CreateFdwStmt: | 		case T_CreateFdwStmt: | ||||||
| 			retval = _equalCreateFdwStmt(a, b); | 			retval = _equalCreateFdwStmt(a, b); | ||||||
| 			break; | 			break; | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.379 2010/01/02 16:57:46 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.380 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  *	  Every node type that can appear in stored rules' parsetrees *must* |  *	  Every node type that can appear in stored rules' parsetrees *must* | ||||||
| @ -1590,6 +1590,7 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node) | |||||||
| 	WRITE_NODE_FIELD(cheapest_total_path); | 	WRITE_NODE_FIELD(cheapest_total_path); | ||||||
| 	WRITE_NODE_FIELD(cheapest_unique_path); | 	WRITE_NODE_FIELD(cheapest_unique_path); | ||||||
| 	WRITE_UINT_FIELD(relid); | 	WRITE_UINT_FIELD(relid); | ||||||
|  | 	WRITE_UINT_FIELD(reltablespace); | ||||||
| 	WRITE_ENUM_FIELD(rtekind, RTEKind); | 	WRITE_ENUM_FIELD(rtekind, RTEKind); | ||||||
| 	WRITE_INT_FIELD(min_attr); | 	WRITE_INT_FIELD(min_attr); | ||||||
| 	WRITE_INT_FIELD(max_attr); | 	WRITE_INT_FIELD(max_attr); | ||||||
|  | |||||||
| @ -27,6 +27,11 @@ | |||||||
|  * detail.	Note that all of these parameters are user-settable, in case |  * detail.	Note that all of these parameters are user-settable, in case | ||||||
|  * the default values are drastically off for a particular platform. |  * the default values are drastically off for a particular platform. | ||||||
|  * |  * | ||||||
|  |  * seq_page_cost and random_page_cost can also be overridden for an individual | ||||||
|  |  * tablespace, in case some data is on a fast disk and other data is on a slow | ||||||
|  |  * disk.  Per-tablespace overrides never apply to temporary work files such as | ||||||
|  |  * an external sort or a materialize node that overflows work_mem. | ||||||
|  |  * | ||||||
|  * We compute two separate costs for each path: |  * We compute two separate costs for each path: | ||||||
|  *		total_cost: total estimated cost to fetch all tuples |  *		total_cost: total estimated cost to fetch all tuples | ||||||
|  *		startup_cost: cost that is expended before first tuple is fetched |  *		startup_cost: cost that is expended before first tuple is fetched | ||||||
| @ -54,7 +59,7 @@ | |||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.213 2010/01/02 16:57:46 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.214 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -76,6 +81,7 @@ | |||||||
| #include "parser/parsetree.h" | #include "parser/parsetree.h" | ||||||
| #include "utils/lsyscache.h" | #include "utils/lsyscache.h" | ||||||
| #include "utils/selfuncs.h" | #include "utils/selfuncs.h" | ||||||
|  | #include "utils/spccache.h" | ||||||
| #include "utils/tuplesort.h" | #include "utils/tuplesort.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -164,6 +170,7 @@ void | |||||||
| cost_seqscan(Path *path, PlannerInfo *root, | cost_seqscan(Path *path, PlannerInfo *root, | ||||||
| 			 RelOptInfo *baserel) | 			 RelOptInfo *baserel) | ||||||
| { | { | ||||||
|  | 	double		spc_seq_page_cost; | ||||||
| 	Cost		startup_cost = 0; | 	Cost		startup_cost = 0; | ||||||
| 	Cost		run_cost = 0; | 	Cost		run_cost = 0; | ||||||
| 	Cost		cpu_per_tuple; | 	Cost		cpu_per_tuple; | ||||||
| @ -175,10 +182,15 @@ cost_seqscan(Path *path, PlannerInfo *root, | |||||||
| 	if (!enable_seqscan) | 	if (!enable_seqscan) | ||||||
| 		startup_cost += disable_cost; | 		startup_cost += disable_cost; | ||||||
| 
 | 
 | ||||||
|  | 	/* fetch estimated page cost for tablespace containing table */ | ||||||
|  | 	get_tablespace_page_costs(baserel->reltablespace, | ||||||
|  | 							  NULL, | ||||||
|  | 							  &spc_seq_page_cost); | ||||||
|  | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * disk costs | 	 * disk costs | ||||||
| 	 */ | 	 */ | ||||||
| 	run_cost += seq_page_cost * baserel->pages; | 	run_cost += spc_seq_page_cost * baserel->pages; | ||||||
| 
 | 
 | ||||||
| 	/* CPU costs */ | 	/* CPU costs */ | ||||||
| 	startup_cost += baserel->baserestrictcost.startup; | 	startup_cost += baserel->baserestrictcost.startup; | ||||||
| @ -226,6 +238,8 @@ cost_index(IndexPath *path, PlannerInfo *root, | |||||||
| 	Selectivity indexSelectivity; | 	Selectivity indexSelectivity; | ||||||
| 	double		indexCorrelation, | 	double		indexCorrelation, | ||||||
| 				csquared; | 				csquared; | ||||||
|  | 	double		spc_seq_page_cost, | ||||||
|  | 				spc_random_page_cost; | ||||||
| 	Cost		min_IO_cost, | 	Cost		min_IO_cost, | ||||||
| 				max_IO_cost; | 				max_IO_cost; | ||||||
| 	Cost		cpu_per_tuple; | 	Cost		cpu_per_tuple; | ||||||
| @ -272,13 +286,18 @@ cost_index(IndexPath *path, PlannerInfo *root, | |||||||
| 	/* estimate number of main-table tuples fetched */ | 	/* estimate number of main-table tuples fetched */ | ||||||
| 	tuples_fetched = clamp_row_est(indexSelectivity * baserel->tuples); | 	tuples_fetched = clamp_row_est(indexSelectivity * baserel->tuples); | ||||||
| 
 | 
 | ||||||
|  | 	/* fetch estimated page costs for tablespace containing table */ | ||||||
|  | 	get_tablespace_page_costs(baserel->reltablespace, | ||||||
|  | 							  &spc_random_page_cost, | ||||||
|  | 							  &spc_seq_page_cost); | ||||||
|  | 
 | ||||||
| 	/*----------
 | 	/*----------
 | ||||||
| 	 * Estimate number of main-table pages fetched, and compute I/O cost. | 	 * Estimate number of main-table pages fetched, and compute I/O cost. | ||||||
| 	 * | 	 * | ||||||
| 	 * When the index ordering is uncorrelated with the table ordering, | 	 * When the index ordering is uncorrelated with the table ordering, | ||||||
| 	 * we use an approximation proposed by Mackert and Lohman (see | 	 * we use an approximation proposed by Mackert and Lohman (see | ||||||
| 	 * index_pages_fetched() for details) to compute the number of pages | 	 * index_pages_fetched() for details) to compute the number of pages | ||||||
| 	 * fetched, and then charge random_page_cost per page fetched. | 	 * fetched, and then charge spc_random_page_cost per page fetched. | ||||||
| 	 * | 	 * | ||||||
| 	 * When the index ordering is exactly correlated with the table ordering | 	 * When the index ordering is exactly correlated with the table ordering | ||||||
| 	 * (just after a CLUSTER, for example), the number of pages fetched should | 	 * (just after a CLUSTER, for example), the number of pages fetched should | ||||||
| @ -286,7 +305,7 @@ cost_index(IndexPath *path, PlannerInfo *root, | |||||||
| 	 * will be sequential fetches, not the random fetches that occur in the | 	 * will be sequential fetches, not the random fetches that occur in the | ||||||
| 	 * uncorrelated case.  So if the number of pages is more than 1, we | 	 * uncorrelated case.  So if the number of pages is more than 1, we | ||||||
| 	 * ought to charge | 	 * ought to charge | ||||||
| 	 *		random_page_cost + (pages_fetched - 1) * seq_page_cost | 	 *		spc_random_page_cost + (pages_fetched - 1) * spc_seq_page_cost | ||||||
| 	 * For partially-correlated indexes, we ought to charge somewhere between | 	 * For partially-correlated indexes, we ought to charge somewhere between | ||||||
| 	 * these two estimates.  We currently interpolate linearly between the | 	 * these two estimates.  We currently interpolate linearly between the | ||||||
| 	 * estimates based on the correlation squared (XXX is that appropriate?). | 	 * estimates based on the correlation squared (XXX is that appropriate?). | ||||||
| @ -309,7 +328,7 @@ cost_index(IndexPath *path, PlannerInfo *root, | |||||||
| 											(double) index->pages, | 											(double) index->pages, | ||||||
| 											root); | 											root); | ||||||
| 
 | 
 | ||||||
| 		max_IO_cost = (pages_fetched * random_page_cost) / num_scans; | 		max_IO_cost = (pages_fetched * spc_random_page_cost) / num_scans; | ||||||
| 
 | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * In the perfectly correlated case, the number of pages touched by | 		 * In the perfectly correlated case, the number of pages touched by | ||||||
| @ -328,7 +347,7 @@ cost_index(IndexPath *path, PlannerInfo *root, | |||||||
| 											(double) index->pages, | 											(double) index->pages, | ||||||
| 											root); | 											root); | ||||||
| 
 | 
 | ||||||
| 		min_IO_cost = (pages_fetched * random_page_cost) / num_scans; | 		min_IO_cost = (pages_fetched * spc_random_page_cost) / num_scans; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -342,13 +361,13 @@ cost_index(IndexPath *path, PlannerInfo *root, | |||||||
| 											root); | 											root); | ||||||
| 
 | 
 | ||||||
| 		/* max_IO_cost is for the perfectly uncorrelated case (csquared=0) */ | 		/* max_IO_cost is for the perfectly uncorrelated case (csquared=0) */ | ||||||
| 		max_IO_cost = pages_fetched * random_page_cost; | 		max_IO_cost = pages_fetched * spc_random_page_cost; | ||||||
| 
 | 
 | ||||||
| 		/* min_IO_cost is for the perfectly correlated case (csquared=1) */ | 		/* min_IO_cost is for the perfectly correlated case (csquared=1) */ | ||||||
| 		pages_fetched = ceil(indexSelectivity * (double) baserel->pages); | 		pages_fetched = ceil(indexSelectivity * (double) baserel->pages); | ||||||
| 		min_IO_cost = random_page_cost; | 		min_IO_cost = spc_random_page_cost; | ||||||
| 		if (pages_fetched > 1) | 		if (pages_fetched > 1) | ||||||
| 			min_IO_cost += (pages_fetched - 1) * seq_page_cost; | 			min_IO_cost += (pages_fetched - 1) * spc_seq_page_cost; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| @ -553,6 +572,8 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, | |||||||
| 	Cost		cost_per_page; | 	Cost		cost_per_page; | ||||||
| 	double		tuples_fetched; | 	double		tuples_fetched; | ||||||
| 	double		pages_fetched; | 	double		pages_fetched; | ||||||
|  | 	double		spc_seq_page_cost, | ||||||
|  | 				spc_random_page_cost; | ||||||
| 	double		T; | 	double		T; | ||||||
| 
 | 
 | ||||||
| 	/* Should only be applied to base relations */ | 	/* Should only be applied to base relations */ | ||||||
| @ -571,6 +592,11 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, | |||||||
| 
 | 
 | ||||||
| 	startup_cost += indexTotalCost; | 	startup_cost += indexTotalCost; | ||||||
| 
 | 
 | ||||||
|  | 	/* Fetch estimated page costs for tablespace containing table. */ | ||||||
|  | 	get_tablespace_page_costs(baserel->reltablespace, | ||||||
|  | 							  &spc_random_page_cost, | ||||||
|  | 							  &spc_seq_page_cost); | ||||||
|  | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Estimate number of main-table pages fetched. | 	 * Estimate number of main-table pages fetched. | ||||||
| 	 */ | 	 */ | ||||||
| @ -609,17 +635,18 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, | |||||||
| 		pages_fetched = ceil(pages_fetched); | 		pages_fetched = ceil(pages_fetched); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * For small numbers of pages we should charge random_page_cost apiece, | 	 * For small numbers of pages we should charge spc_random_page_cost apiece, | ||||||
| 	 * while if nearly all the table's pages are being read, it's more | 	 * while if nearly all the table's pages are being read, it's more | ||||||
| 	 * appropriate to charge seq_page_cost apiece.	The effect is nonlinear, | 	 * appropriate to charge spc_seq_page_cost apiece.	The effect is nonlinear, | ||||||
| 	 * too. For lack of a better idea, interpolate like this to determine the | 	 * too. For lack of a better idea, interpolate like this to determine the | ||||||
| 	 * cost per page. | 	 * cost per page. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (pages_fetched >= 2.0) | 	if (pages_fetched >= 2.0) | ||||||
| 		cost_per_page = random_page_cost - | 		cost_per_page = spc_random_page_cost - | ||||||
| 			(random_page_cost - seq_page_cost) * sqrt(pages_fetched / T); | 			(spc_random_page_cost - spc_seq_page_cost) | ||||||
|  | 			* sqrt(pages_fetched / T); | ||||||
| 	else | 	else | ||||||
| 		cost_per_page = random_page_cost; | 		cost_per_page = spc_random_page_cost; | ||||||
| 
 | 
 | ||||||
| 	run_cost += pages_fetched * cost_per_page; | 	run_cost += pages_fetched * cost_per_page; | ||||||
| 
 | 
 | ||||||
| @ -783,6 +810,7 @@ cost_tidscan(Path *path, PlannerInfo *root, | |||||||
| 	QualCost	tid_qual_cost; | 	QualCost	tid_qual_cost; | ||||||
| 	int			ntuples; | 	int			ntuples; | ||||||
| 	ListCell   *l; | 	ListCell   *l; | ||||||
|  | 	double		spc_random_page_cost; | ||||||
| 
 | 
 | ||||||
| 	/* Should only be applied to base relations */ | 	/* Should only be applied to base relations */ | ||||||
| 	Assert(baserel->relid > 0); | 	Assert(baserel->relid > 0); | ||||||
| @ -835,8 +863,13 @@ cost_tidscan(Path *path, PlannerInfo *root, | |||||||
| 	 */ | 	 */ | ||||||
| 	cost_qual_eval(&tid_qual_cost, tidquals, root); | 	cost_qual_eval(&tid_qual_cost, tidquals, root); | ||||||
| 
 | 
 | ||||||
|  | 	/* fetch estimated page cost for tablespace containing table */ | ||||||
|  | 	get_tablespace_page_costs(baserel->reltablespace, | ||||||
|  | 							  &spc_random_page_cost, | ||||||
|  | 							  NULL); | ||||||
|  | 
 | ||||||
| 	/* disk costs --- assume each tuple on a different page */ | 	/* disk costs --- assume each tuple on a different page */ | ||||||
| 	run_cost += random_page_cost * ntuples; | 	run_cost += spc_random_page_cost * ntuples; | ||||||
| 
 | 
 | ||||||
| 	/* CPU costs */ | 	/* CPU costs */ | ||||||
| 	startup_cost += baserel->baserestrictcost.startup + | 	startup_cost += baserel->baserestrictcost.startup + | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.161 2010/01/02 16:57:48 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.162 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -91,6 +91,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, | |||||||
| 
 | 
 | ||||||
| 	rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1; | 	rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1; | ||||||
| 	rel->max_attr = RelationGetNumberOfAttributes(relation); | 	rel->max_attr = RelationGetNumberOfAttributes(relation); | ||||||
|  | 	rel->reltablespace = RelationGetForm(relation)->reltablespace; | ||||||
| 
 | 
 | ||||||
| 	Assert(rel->max_attr >= rel->min_attr); | 	Assert(rel->max_attr >= rel->min_attr); | ||||||
| 	rel->attr_needed = (Relids *) | 	rel->attr_needed = (Relids *) | ||||||
| @ -183,6 +184,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, | |||||||
| 			info = makeNode(IndexOptInfo); | 			info = makeNode(IndexOptInfo); | ||||||
| 
 | 
 | ||||||
| 			info->indexoid = index->indexrelid; | 			info->indexoid = index->indexrelid; | ||||||
|  | 			info->reltablespace = | ||||||
|  | 				RelationGetForm(indexRelation)->reltablespace; | ||||||
| 			info->rel = rel; | 			info->rel = rel; | ||||||
| 			info->ncolumns = ncolumns = index->indnatts; | 			info->ncolumns = ncolumns = index->indnatts; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.701 2010/01/02 16:57:48 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.702 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  * HISTORY |  * HISTORY | ||||||
|  *	  AUTHOR			DATE			MAJOR EVENT |  *	  AUTHOR			DATE			MAJOR EVENT | ||||||
| @ -5687,6 +5687,24 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name | |||||||
| 					n->newname = $6; | 					n->newname = $6; | ||||||
| 					$$ = (Node *)n; | 					$$ = (Node *)n; | ||||||
| 				} | 				} | ||||||
|  | 			| ALTER TABLESPACE name SET reloptions | ||||||
|  | 				{ | ||||||
|  | 					AlterTableSpaceOptionsStmt *n = | ||||||
|  | 						makeNode(AlterTableSpaceOptionsStmt); | ||||||
|  | 					n->tablespacename = $3; | ||||||
|  | 					n->options = $5; | ||||||
|  | 					n->isReset = FALSE; | ||||||
|  | 					$$ = (Node *)n; | ||||||
|  | 				} | ||||||
|  | 			| ALTER TABLESPACE name RESET reloptions | ||||||
|  | 				{ | ||||||
|  | 					AlterTableSpaceOptionsStmt *n = | ||||||
|  | 						makeNode(AlterTableSpaceOptionsStmt); | ||||||
|  | 					n->tablespacename = $3; | ||||||
|  | 					n->options = $5; | ||||||
|  | 					n->isReset = TRUE; | ||||||
|  | 					$$ = (Node *)n; | ||||||
|  | 				} | ||||||
| 			| ALTER TEXT_P SEARCH PARSER any_name RENAME TO name | 			| ALTER TEXT_P SEARCH PARSER any_name RENAME TO name | ||||||
| 				{ | 				{ | ||||||
| 					RenameStmt *n = makeNode(RenameStmt); | 					RenameStmt *n = makeNode(RenameStmt); | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.326 2010/01/02 16:57:53 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.327 2010/01/05 21:53:58 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -218,6 +218,7 @@ check_xact_readonly(Node *parsetree) | |||||||
| 		case T_CreateUserMappingStmt: | 		case T_CreateUserMappingStmt: | ||||||
| 		case T_AlterUserMappingStmt: | 		case T_AlterUserMappingStmt: | ||||||
| 		case T_DropUserMappingStmt: | 		case T_DropUserMappingStmt: | ||||||
|  | 		case T_AlterTableSpaceOptionsStmt: | ||||||
| 			ereport(ERROR, | 			ereport(ERROR, | ||||||
| 					(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), | 					(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), | ||||||
| 					 errmsg("transaction is read-only"))); | 					 errmsg("transaction is read-only"))); | ||||||
| @ -528,6 +529,10 @@ standard_ProcessUtility(Node *parsetree, | |||||||
| 			DropTableSpace((DropTableSpaceStmt *) parsetree); | 			DropTableSpace((DropTableSpaceStmt *) parsetree); | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
|  | 		case T_AlterTableSpaceOptionsStmt: | ||||||
|  | 			AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
| 		case T_CreateFdwStmt: | 		case T_CreateFdwStmt: | ||||||
| 			CreateForeignDataWrapper((CreateFdwStmt *) parsetree); | 			CreateForeignDataWrapper((CreateFdwStmt *) parsetree); | ||||||
| 			break; | 			break; | ||||||
| @ -1456,6 +1461,10 @@ CreateCommandTag(Node *parsetree) | |||||||
| 			tag = "DROP TABLESPACE"; | 			tag = "DROP TABLESPACE"; | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
|  | 		case T_AlterTableSpaceOptionsStmt: | ||||||
|  | 			tag = "ALTER TABLESPACE"; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
| 		case T_CreateFdwStmt: | 		case T_CreateFdwStmt: | ||||||
| 			tag = "CREATE FOREIGN DATA WRAPPER"; | 			tag = "CREATE FOREIGN DATA WRAPPER"; | ||||||
| 			break; | 			break; | ||||||
| @ -2238,6 +2247,10 @@ GetCommandLogLevel(Node *parsetree) | |||||||
| 			lev = LOGSTMT_DDL; | 			lev = LOGSTMT_DDL; | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
|  | 		case T_AlterTableSpaceOptionsStmt: | ||||||
|  | 			lev = LOGSTMT_DDL; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
| 		case T_CreateFdwStmt: | 		case T_CreateFdwStmt: | ||||||
| 		case T_AlterFdwStmt: | 		case T_AlterFdwStmt: | ||||||
| 		case T_DropFdwStmt: | 		case T_DropFdwStmt: | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.267 2010/01/04 02:44:39 tgl Exp $ |  *	  $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.268 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -119,6 +119,7 @@ | |||||||
| #include "utils/nabstime.h" | #include "utils/nabstime.h" | ||||||
| #include "utils/pg_locale.h" | #include "utils/pg_locale.h" | ||||||
| #include "utils/selfuncs.h" | #include "utils/selfuncs.h" | ||||||
|  | #include "utils/spccache.h" | ||||||
| #include "utils/syscache.h" | #include "utils/syscache.h" | ||||||
| #include "utils/tqual.h" | #include "utils/tqual.h" | ||||||
| 
 | 
 | ||||||
| @ -5648,6 +5649,7 @@ genericcostestimate(PlannerInfo *root, | |||||||
| 	QualCost	index_qual_cost; | 	QualCost	index_qual_cost; | ||||||
| 	double		qual_op_cost; | 	double		qual_op_cost; | ||||||
| 	double		qual_arg_cost; | 	double		qual_arg_cost; | ||||||
|  | 	double		spc_random_page_cost; | ||||||
| 	List	   *selectivityQuals; | 	List	   *selectivityQuals; | ||||||
| 	ListCell   *l; | 	ListCell   *l; | ||||||
| 
 | 
 | ||||||
| @ -5756,6 +5758,11 @@ genericcostestimate(PlannerInfo *root, | |||||||
| 	else | 	else | ||||||
| 		numIndexPages = 1.0; | 		numIndexPages = 1.0; | ||||||
| 
 | 
 | ||||||
|  | 	/* fetch estimated page cost for schema containing index */ | ||||||
|  | 	get_tablespace_page_costs(index->reltablespace, | ||||||
|  | 							  &spc_random_page_cost, | ||||||
|  | 							  NULL); | ||||||
|  | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Now compute the disk access costs. | 	 * Now compute the disk access costs. | ||||||
| 	 * | 	 * | ||||||
| @ -5802,15 +5809,16 @@ genericcostestimate(PlannerInfo *root, | |||||||
| 		 * share for each outer scan.  (Don't pro-rate for ScalarArrayOpExpr, | 		 * share for each outer scan.  (Don't pro-rate for ScalarArrayOpExpr, | ||||||
| 		 * since that's internal to the indexscan.) | 		 * since that's internal to the indexscan.) | ||||||
| 		 */ | 		 */ | ||||||
| 		*indexTotalCost = (pages_fetched * random_page_cost) / num_outer_scans; | 		*indexTotalCost = (pages_fetched * spc_random_page_cost) | ||||||
|  | 							/ num_outer_scans; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * For a single index scan, we just charge random_page_cost per page | 		 * For a single index scan, we just charge spc_random_page_cost per | ||||||
| 		 * touched. | 		 * page touched. | ||||||
| 		 */ | 		 */ | ||||||
| 		*indexTotalCost = numIndexPages * random_page_cost; | 		*indexTotalCost = numIndexPages * spc_random_page_cost; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| @ -5825,11 +5833,11 @@ genericcostestimate(PlannerInfo *root, | |||||||
| 	 * | 	 * | ||||||
| 	 * We can deal with this by adding a very small "fudge factor" that | 	 * We can deal with this by adding a very small "fudge factor" that | ||||||
| 	 * depends on the index size.  The fudge factor used here is one | 	 * depends on the index size.  The fudge factor used here is one | ||||||
| 	 * random_page_cost per 100000 index pages, which should be small enough | 	 * spc_random_page_cost per 100000 index pages, which should be small | ||||||
| 	 * to not alter index-vs-seqscan decisions, but will prevent indexes of | 	 * enough to not alter index-vs-seqscan decisions, but will prevent | ||||||
| 	 * different sizes from looking exactly equally attractive. | 	 * indexes of different sizes from looking exactly equally attractive. | ||||||
| 	 */ | 	 */ | ||||||
| 	*indexTotalCost += index->pages * random_page_cost / 100000.0; | 	*indexTotalCost += index->pages * spc_random_page_cost / 100000.0; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * CPU cost: any complex expressions in the indexquals will need to be | 	 * CPU cost: any complex expressions in the indexquals will need to be | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								src/backend/utils/cache/Makefile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/backend/utils/cache/Makefile
									
									
									
									
										vendored
									
									
								
							| @ -4,7 +4,7 @@ | |||||||
| #    Makefile for utils/cache
 | #    Makefile for utils/cache
 | ||||||
| #
 | #
 | ||||||
| # IDENTIFICATION
 | # IDENTIFICATION
 | ||||||
| #    $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.23 2008/02/19 10:30:08 petere Exp $
 | #    $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.24 2010/01/05 21:53:59 rhaas Exp $
 | ||||||
| #
 | #
 | ||||||
| #-------------------------------------------------------------------------
 | #-------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| @ -13,6 +13,6 @@ top_builddir = ../../../.. | |||||||
| include $(top_builddir)/src/Makefile.global | include $(top_builddir)/src/Makefile.global | ||||||
| 
 | 
 | ||||||
| OBJS = catcache.o inval.o plancache.o relcache.o \
 | OBJS = catcache.o inval.o plancache.o relcache.o \
 | ||||||
| 	syscache.o lsyscache.o typcache.o ts_cache.o | 	spccache.o syscache.o lsyscache.o typcache.o ts_cache.o | ||||||
| 
 | 
 | ||||||
| include $(top_srcdir)/src/backend/common.mk | include $(top_srcdir)/src/backend/common.mk | ||||||
|  | |||||||
							
								
								
									
										183
									
								
								src/backend/utils/cache/spccache.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								src/backend/utils/cache/spccache.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,183 @@ | |||||||
|  | /*-------------------------------------------------------------------------
 | ||||||
|  |  * | ||||||
|  |  * spccache.c | ||||||
|  |  *	  Tablespace cache management. | ||||||
|  |  * | ||||||
|  |  * We cache the parsed version of spcoptions for each tablespace to avoid | ||||||
|  |  * needing to reparse on every lookup.  Right now, there doesn't appear to | ||||||
|  |  * be a measurable performance gain from doing this, but that might change | ||||||
|  |  * in the future as we add more options. | ||||||
|  |  * | ||||||
|  |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  |  * | ||||||
|  |  * IDENTIFICATION | ||||||
|  |  *	  $PostgreSQL: pgsql/src/backend/utils/cache/spccache.c,v 1.1 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  |  * | ||||||
|  |  *------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "postgres.h" | ||||||
|  | #include "access/reloptions.h" | ||||||
|  | #include "catalog/pg_tablespace.h" | ||||||
|  | #include "commands/tablespace.h" | ||||||
|  | #include "miscadmin.h" | ||||||
|  | #include "optimizer/cost.h" | ||||||
|  | #include "utils/catcache.h" | ||||||
|  | #include "utils/hsearch.h" | ||||||
|  | #include "utils/inval.h" | ||||||
|  | #include "utils/spccache.h" | ||||||
|  | #include "utils/syscache.h" | ||||||
|  | 
 | ||||||
|  | static HTAB *TableSpaceCacheHash = NULL; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	Oid			oid; | ||||||
|  | 	TableSpaceOpts *opts; | ||||||
|  | } TableSpace; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * InvalidateTableSpaceCacheCallback | ||||||
|  |  *		Flush all cache entries when pg_tablespace is updated. | ||||||
|  |  * | ||||||
|  |  * When pg_tablespace is updated, we must flush the cache entry at least | ||||||
|  |  * for that tablespace.  Currently, we just flush them all.  This is quick | ||||||
|  |  * and easy and doesn't cost much, since there shouldn't be terribly many | ||||||
|  |  * tablespaces, nor do we expect them to be frequently modified. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr) | ||||||
|  | { | ||||||
|  | 	HASH_SEQ_STATUS status; | ||||||
|  | 	TableSpace *spc; | ||||||
|  | 
 | ||||||
|  | 	hash_seq_init(&status, TableSpaceCacheHash); | ||||||
|  | 	while ((spc = (TableSpace *) hash_seq_search(&status)) != NULL) | ||||||
|  | 	{ | ||||||
|  | 		if (hash_search(TableSpaceCacheHash, (void *) &spc->oid, HASH_REMOVE, | ||||||
|  | 						NULL) == NULL) | ||||||
|  | 			elog(ERROR, "hash table corrupted"); | ||||||
|  | 		if (spc->opts) | ||||||
|  | 			pfree(spc->opts); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * InitializeTableSpaceCache | ||||||
|  |  *		Initiate the tablespace cache. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | InitializeTableSpaceCache(void) | ||||||
|  | { | ||||||
|  | 	HASHCTL ctl; | ||||||
|  | 
 | ||||||
|  | 	/* Initialize the hash table. */ | ||||||
|  | 	MemSet(&ctl, 0, sizeof(ctl)); | ||||||
|  | 	ctl.keysize = sizeof(Oid); | ||||||
|  | 	ctl.entrysize = sizeof(TableSpace); | ||||||
|  | 	ctl.hash = tag_hash; | ||||||
|  | 	TableSpaceCacheHash = | ||||||
|  | 		hash_create("TableSpace cache", 16, &ctl, | ||||||
|  | 				    HASH_ELEM | HASH_FUNCTION); | ||||||
|  | 
 | ||||||
|  | 	/* Make sure we've initialized CacheMemoryContext. */ | ||||||
|  | 	if (!CacheMemoryContext) | ||||||
|  | 		CreateCacheMemoryContext(); | ||||||
|  | 
 | ||||||
|  | 	/* Watch for invalidation events. */ | ||||||
|  | 	CacheRegisterSyscacheCallback(TABLESPACEOID, | ||||||
|  | 								  InvalidateTableSpaceCacheCallback, | ||||||
|  | 								  (Datum) 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * get_tablespace | ||||||
|  |  *		Fetch TableSpace structure for a specified table OID. | ||||||
|  |  * | ||||||
|  |  * Pointers returned by this function should not be stored, since a cache | ||||||
|  |  * flush will invalidate them. | ||||||
|  |  */ | ||||||
|  | static TableSpace * | ||||||
|  | get_tablespace(Oid spcid) | ||||||
|  | { | ||||||
|  | 	HeapTuple	tp; | ||||||
|  | 	TableSpace *spc; | ||||||
|  | 	bool		found; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Since spcid is always from a pg_class tuple, InvalidOid implies the | ||||||
|  | 	 * default. | ||||||
|  | 	 */ | ||||||
|  | 	if (spcid == InvalidOid) | ||||||
|  | 		spcid = MyDatabaseTableSpace; | ||||||
|  | 
 | ||||||
|  | 	/* Find existing cache entry, or create a new one. */ | ||||||
|  | 	if (!TableSpaceCacheHash) | ||||||
|  | 		InitializeTableSpaceCache(); | ||||||
|  | 	spc = (TableSpace *) hash_search(TableSpaceCacheHash, (void *) &spcid, | ||||||
|  | 									 HASH_ENTER, &found); | ||||||
|  | 	if (found) | ||||||
|  | 		return spc; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Not found in TableSpace cache.  Check catcache.  If we don't find a | ||||||
|  | 	 * valid HeapTuple, it must mean someone has managed to request tablespace | ||||||
|  | 	 * details for a non-existent tablespace.  We'll just treat that case as if | ||||||
|  | 	 * no options were specified. | ||||||
|  | 	 */ | ||||||
|  | 	tp = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spcid), 0, 0, 0); | ||||||
|  | 	if (!HeapTupleIsValid(tp)) | ||||||
|  | 		spc->opts = NULL; | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		Datum	datum; | ||||||
|  | 		bool	isNull; | ||||||
|  | 		MemoryContext octx; | ||||||
|  | 
 | ||||||
|  | 		datum = SysCacheGetAttr(TABLESPACEOID, | ||||||
|  | 								tp, | ||||||
|  | 								Anum_pg_tablespace_spcoptions, | ||||||
|  | 								&isNull); | ||||||
|  | 		if (isNull) | ||||||
|  | 			spc->opts = NULL; | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			octx = MemoryContextSwitchTo(CacheMemoryContext); | ||||||
|  | 			spc->opts = (TableSpaceOpts *) tablespace_reloptions(datum, false); | ||||||
|  | 			MemoryContextSwitchTo(octx); | ||||||
|  | 		} | ||||||
|  | 		ReleaseSysCache(tp); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Update new TableSpace cache entry with results of option parsing. */ | ||||||
|  | 	return spc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * get_tablespace_page_costs | ||||||
|  |  *		Return random and sequential page costs for a given tablespace. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | get_tablespace_page_costs(Oid spcid, double *spc_random_page_cost, | ||||||
|  | 							   double *spc_seq_page_cost) | ||||||
|  | { | ||||||
|  | 	TableSpace *spc = get_tablespace(spcid); | ||||||
|  | 
 | ||||||
|  | 	Assert(spc != NULL); | ||||||
|  | 
 | ||||||
|  | 	if (spc_random_page_cost) | ||||||
|  | 	{ | ||||||
|  | 		if (!spc->opts || spc->opts->random_page_cost < 0) | ||||||
|  | 			*spc_random_page_cost = random_page_cost; | ||||||
|  | 		else | ||||||
|  | 			*spc_random_page_cost = spc->opts->random_page_cost; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (spc_seq_page_cost) | ||||||
|  | 	{ | ||||||
|  | 		if (!spc->opts || spc->opts->seq_page_cost < 0) | ||||||
|  | 			*spc_seq_page_cost = seq_page_cost; | ||||||
|  | 		else | ||||||
|  | 			*spc_seq_page_cost = spc->opts->seq_page_cost; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								src/backend/utils/cache/syscache.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								src/backend/utils/cache/syscache.c
									
									
									
									
										vendored
									
									
								
							| @ -8,7 +8,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.123 2010/01/02 16:57:56 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.124 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  *	  These routines allow the parser/planner/executor to perform |  *	  These routines allow the parser/planner/executor to perform | ||||||
| @ -43,6 +43,7 @@ | |||||||
| #include "catalog/pg_proc.h" | #include "catalog/pg_proc.h" | ||||||
| #include "catalog/pg_rewrite.h" | #include "catalog/pg_rewrite.h" | ||||||
| #include "catalog/pg_statistic.h" | #include "catalog/pg_statistic.h" | ||||||
|  | #include "catalog/pg_tablespace.h" | ||||||
| #include "catalog/pg_ts_config.h" | #include "catalog/pg_ts_config.h" | ||||||
| #include "catalog/pg_ts_config_map.h" | #include "catalog/pg_ts_config_map.h" | ||||||
| #include "catalog/pg_ts_dict.h" | #include "catalog/pg_ts_dict.h" | ||||||
| @ -609,6 +610,18 @@ static const struct cachedesc cacheinfo[] = { | |||||||
| 		}, | 		}, | ||||||
| 		1024 | 		1024 | ||||||
| 	}, | 	}, | ||||||
|  | 	{TableSpaceRelationId,		/* TABLESPACEOID */ | ||||||
|  | 		TablespaceOidIndexId, | ||||||
|  | 		0, | ||||||
|  | 		1, | ||||||
|  | 		{ | ||||||
|  | 			ObjectIdAttributeNumber, | ||||||
|  | 			0, | ||||||
|  | 			0, | ||||||
|  | 			0, | ||||||
|  | 		}, | ||||||
|  | 		16 | ||||||
|  | 	}, | ||||||
| 	{TSConfigMapRelationId,		/* TSCONFIGMAP */ | 	{TSConfigMapRelationId,		/* TSCONFIGMAP */ | ||||||
| 		TSConfigMapIndexId, | 		TSConfigMapIndexId, | ||||||
| 		0, | 		0, | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ | |||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.129 2010/01/02 16:57:59 momjian Exp $ |  * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.130 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -956,19 +956,28 @@ dumpTablespaces(PGconn *conn) | |||||||
| 	 * Get all tablespaces except built-in ones (which we assume are named | 	 * Get all tablespaces except built-in ones (which we assume are named | ||||||
| 	 * pg_xxx) | 	 * pg_xxx) | ||||||
| 	 */ | 	 */ | ||||||
| 	if (server_version >= 80200) | 	if (server_version >= 80500) | ||||||
| 		res = executeQuery(conn, "SELECT spcname, " | 		res = executeQuery(conn, "SELECT spcname, " | ||||||
| 						 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " | 						 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " | ||||||
| 						   "spclocation, spcacl, " | 						   "spclocation, spcacl, " | ||||||
|  | 						   "array_to_string(spcoptions, ', ')," | ||||||
| 						"pg_catalog.shobj_description(oid, 'pg_tablespace') " | 						"pg_catalog.shobj_description(oid, 'pg_tablespace') " | ||||||
| 						   "FROM pg_catalog.pg_tablespace " | 						   "FROM pg_catalog.pg_tablespace " | ||||||
| 						   "WHERE spcname !~ '^pg_' " | 						   "WHERE spcname !~ '^pg_' " | ||||||
| 						   "ORDER BY 1"); | 						   "ORDER BY 1"); | ||||||
|  | 	else if (server_version >= 80200) | ||||||
|  | 		res = executeQuery(conn, "SELECT spcname, " | ||||||
|  | 						 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " | ||||||
|  | 						   "spclocation, spcacl, null, " | ||||||
|  | 						"pg_catalog.shobj_description(oid, 'pg_tablespace'), " | ||||||
|  | 						   "FROM pg_catalog.pg_tablespace " | ||||||
|  | 						   "WHERE spcname !~ '^pg_' " | ||||||
|  | 						   "ORDER BY 1"); | ||||||
| 	else | 	else | ||||||
| 		res = executeQuery(conn, "SELECT spcname, " | 		res = executeQuery(conn, "SELECT spcname, " | ||||||
| 						 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " | 						 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " | ||||||
| 						   "spclocation, spcacl, " | 						   "spclocation, spcacl, " | ||||||
| 						   "null " | 						   "null, null " | ||||||
| 						   "FROM pg_catalog.pg_tablespace " | 						   "FROM pg_catalog.pg_tablespace " | ||||||
| 						   "WHERE spcname !~ '^pg_' " | 						   "WHERE spcname !~ '^pg_' " | ||||||
| 						   "ORDER BY 1"); | 						   "ORDER BY 1"); | ||||||
| @ -983,7 +992,8 @@ dumpTablespaces(PGconn *conn) | |||||||
| 		char	   *spcowner = PQgetvalue(res, i, 1); | 		char	   *spcowner = PQgetvalue(res, i, 1); | ||||||
| 		char	   *spclocation = PQgetvalue(res, i, 2); | 		char	   *spclocation = PQgetvalue(res, i, 2); | ||||||
| 		char	   *spcacl = PQgetvalue(res, i, 3); | 		char	   *spcacl = PQgetvalue(res, i, 3); | ||||||
| 		char	   *spccomment = PQgetvalue(res, i, 4); | 		char	   *spcoptions = PQgetvalue(res, i, 4); | ||||||
|  | 		char	   *spccomment = PQgetvalue(res, i, 5); | ||||||
| 		char	   *fspcname; | 		char	   *fspcname; | ||||||
| 
 | 
 | ||||||
| 		/* needed for buildACLCommands() */ | 		/* needed for buildACLCommands() */ | ||||||
| @ -996,6 +1006,10 @@ dumpTablespaces(PGconn *conn) | |||||||
| 		appendStringLiteralConn(buf, spclocation, conn); | 		appendStringLiteralConn(buf, spclocation, conn); | ||||||
| 		appendPQExpBuffer(buf, ";\n"); | 		appendPQExpBuffer(buf, ";\n"); | ||||||
| 
 | 
 | ||||||
|  | 		if (spcoptions && spcoptions[0] != '\0') | ||||||
|  | 			appendPQExpBuffer(buf, "ALTER TABLESPACE %s SET (%s);\n", | ||||||
|  | 							  fspcname, spcoptions); | ||||||
|  | 
 | ||||||
| 		if (!skip_acls && | 		if (!skip_acls && | ||||||
| 			!buildACLCommands(fspcname, NULL, "TABLESPACE", spcacl, spcowner, | 			!buildACLCommands(fspcname, NULL, "TABLESPACE", spcacl, spcowner, | ||||||
| 							  "", server_version, buf)) | 							  "", server_version, buf)) | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| /*-------------------------------------------------------------------------
 | /*-------------------------------------------------------------------------
 | ||||||
|  * |  * | ||||||
|  * reloptions.h |  * reloptions.h | ||||||
|  *	  Core support for relation options (pg_class.reloptions) |  *	  Core support for relation and tablespace options (pg_class.reloptions | ||||||
|  |  *	  and pg_tablespace.spcoptions) | ||||||
|  * |  * | ||||||
|  * Note: the functions dealing with text-array reloptions values declare |  * Note: the functions dealing with text-array reloptions values declare | ||||||
|  * them as Datum, not ArrayType *, to avoid needing to include array.h |  * them as Datum, not ArrayType *, to avoid needing to include array.h | ||||||
| @ -11,7 +12,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.17 2010/01/02 16:58:00 momjian Exp $ |  * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.18 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -39,8 +40,9 @@ typedef enum relopt_kind | |||||||
| 	RELOPT_KIND_HASH = (1 << 3), | 	RELOPT_KIND_HASH = (1 << 3), | ||||||
| 	RELOPT_KIND_GIN = (1 << 4), | 	RELOPT_KIND_GIN = (1 << 4), | ||||||
| 	RELOPT_KIND_GIST = (1 << 5), | 	RELOPT_KIND_GIST = (1 << 5), | ||||||
|  | 	RELOPT_KIND_TABLESPACE = (1 << 6), | ||||||
| 	/* if you add a new kind, make sure you update "last_default" too */ | 	/* if you add a new kind, make sure you update "last_default" too */ | ||||||
| 	RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_GIST, | 	RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_TABLESPACE, | ||||||
| 	/* some compilers treat enums as signed ints, so we can't use 1 << 31 */ | 	/* some compilers treat enums as signed ints, so we can't use 1 << 31 */ | ||||||
| 	RELOPT_KIND_MAX = (1 << 30) | 	RELOPT_KIND_MAX = (1 << 30) | ||||||
| } relopt_kind; | } relopt_kind; | ||||||
| @ -264,5 +266,6 @@ extern bytea *default_reloptions(Datum reloptions, bool validate, | |||||||
| extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate); | extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate); | ||||||
| extern bytea *index_reloptions(RegProcedure amoptions, Datum reloptions, | extern bytea *index_reloptions(RegProcedure amoptions, Datum reloptions, | ||||||
| 				 bool validate); | 				 bool validate); | ||||||
|  | extern bytea *tablespace_reloptions(Datum reloptions, bool validate); | ||||||
| 
 | 
 | ||||||
| #endif   /* RELOPTIONS_H */ | #endif   /* RELOPTIONS_H */ | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.566 2010/01/04 12:50:49 heikki Exp $ |  * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.567 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -53,6 +53,6 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /*							yyyymmddN */ | /*							yyyymmddN */ | ||||||
| #define CATALOG_VERSION_NO	201001041 | #define CATALOG_VERSION_NO	201001051 | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.14 2010/01/05 01:06:57 tgl Exp $ |  * $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.15 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  *	  the genbki.pl script reads this file and generates .bki |  *	  the genbki.pl script reads this file and generates .bki | ||||||
| @ -34,6 +34,7 @@ CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION | |||||||
| 	Oid			spcowner;		/* owner of tablespace */ | 	Oid			spcowner;		/* owner of tablespace */ | ||||||
| 	text		spclocation;	/* physical location (VAR LENGTH) */ | 	text		spclocation;	/* physical location (VAR LENGTH) */ | ||||||
| 	aclitem		spcacl[1];		/* access permissions (VAR LENGTH) */ | 	aclitem		spcacl[1];		/* access permissions (VAR LENGTH) */ | ||||||
|  | 	text		spcoptions[1];	/* per-tablespace options */ | ||||||
| } FormData_pg_tablespace; | } FormData_pg_tablespace; | ||||||
| 
 | 
 | ||||||
| /* ----------------
 | /* ----------------
 | ||||||
| @ -48,14 +49,15 @@ typedef FormData_pg_tablespace *Form_pg_tablespace; | |||||||
|  * ---------------- |  * ---------------- | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #define Natts_pg_tablespace				4 | #define Natts_pg_tablespace				5 | ||||||
| #define Anum_pg_tablespace_spcname		1 | #define Anum_pg_tablespace_spcname		1 | ||||||
| #define Anum_pg_tablespace_spcowner		2 | #define Anum_pg_tablespace_spcowner		2 | ||||||
| #define Anum_pg_tablespace_spclocation	3 | #define Anum_pg_tablespace_spclocation	3 | ||||||
| #define Anum_pg_tablespace_spcacl		4 | #define Anum_pg_tablespace_spcacl		4 | ||||||
|  | #define Anum_pg_tablespace_spcoptions	5 | ||||||
| 
 | 
 | ||||||
| DATA(insert OID = 1663 ( pg_default PGUID "" _null_ )); | DATA(insert OID = 1663 ( pg_default PGUID "" _null_ _null_ )); | ||||||
| DATA(insert OID = 1664 ( pg_global	PGUID "" _null_ )); | DATA(insert OID = 1664 ( pg_global	PGUID "" _null_ _null_ )); | ||||||
| 
 | 
 | ||||||
| #define DEFAULTTABLESPACE_OID 1663 | #define DEFAULTTABLESPACE_OID 1663 | ||||||
| #define GLOBALTABLESPACE_OID 1664 | #define GLOBALTABLESPACE_OID 1664 | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.21 2010/01/02 16:58:03 momjian Exp $ |  * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.22 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -32,11 +32,17 @@ typedef struct xl_tblspc_drop_rec | |||||||
| 	Oid			ts_id; | 	Oid			ts_id; | ||||||
| } xl_tblspc_drop_rec; | } xl_tblspc_drop_rec; | ||||||
| 
 | 
 | ||||||
|  | typedef struct TableSpaceOpts | ||||||
|  | { | ||||||
|  | 	float8		random_page_cost; | ||||||
|  | 	float8		seq_page_cost; | ||||||
|  | } TableSpaceOpts; | ||||||
| 
 | 
 | ||||||
| extern void CreateTableSpace(CreateTableSpaceStmt *stmt); | extern void CreateTableSpace(CreateTableSpaceStmt *stmt); | ||||||
| extern void DropTableSpace(DropTableSpaceStmt *stmt); | extern void DropTableSpace(DropTableSpaceStmt *stmt); | ||||||
| extern void RenameTableSpace(const char *oldname, const char *newname); | extern void RenameTableSpace(const char *oldname, const char *newname); | ||||||
| extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId); | extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId); | ||||||
|  | extern void AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); | ||||||
| 
 | 
 | ||||||
| extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); | extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.232 2010/01/02 16:58:04 momjian Exp $ |  * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.233 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -346,6 +346,7 @@ typedef enum NodeTag | |||||||
| 	T_CreateUserMappingStmt, | 	T_CreateUserMappingStmt, | ||||||
| 	T_AlterUserMappingStmt, | 	T_AlterUserMappingStmt, | ||||||
| 	T_DropUserMappingStmt, | 	T_DropUserMappingStmt, | ||||||
|  | 	T_AlterTableSpaceOptionsStmt, | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * TAGS FOR PARSE TREE NODES (parsenodes.h) | 	 * TAGS FOR PARSE TREE NODES (parsenodes.h) | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.421 2010/01/02 16:58:04 momjian Exp $ |  * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.422 2010/01/05 21:53:59 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -1477,6 +1477,14 @@ typedef struct DropTableSpaceStmt | |||||||
| 	bool		missing_ok;		/* skip error if missing? */ | 	bool		missing_ok;		/* skip error if missing? */ | ||||||
| } DropTableSpaceStmt; | } DropTableSpaceStmt; | ||||||
| 
 | 
 | ||||||
|  | typedef struct AlterTableSpaceOptionsStmt | ||||||
|  | { | ||||||
|  | 	NodeTag		type; | ||||||
|  | 	char	   *tablespacename; | ||||||
|  | 	List	   *options; | ||||||
|  | 	bool		isReset; | ||||||
|  | } AlterTableSpaceOptionsStmt; | ||||||
|  | 
 | ||||||
| /* ----------------------
 | /* ----------------------
 | ||||||
|  *		Create/Drop FOREIGN DATA WRAPPER Statements |  *		Create/Drop FOREIGN DATA WRAPPER Statements | ||||||
|  * ---------------------- |  * ---------------------- | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.182 2010/01/02 16:58:07 momjian Exp $ |  * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.183 2010/01/05 21:54:00 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -371,6 +371,7 @@ typedef struct RelOptInfo | |||||||
| 
 | 
 | ||||||
| 	/* information about a base rel (not set for join rels!) */ | 	/* information about a base rel (not set for join rels!) */ | ||||||
| 	Index		relid; | 	Index		relid; | ||||||
|  | 	Oid			reltablespace;	/* containing tablespace */ | ||||||
| 	RTEKind		rtekind;		/* RELATION, SUBQUERY, or FUNCTION */ | 	RTEKind		rtekind;		/* RELATION, SUBQUERY, or FUNCTION */ | ||||||
| 	AttrNumber	min_attr;		/* smallest attrno of rel (often <0) */ | 	AttrNumber	min_attr;		/* smallest attrno of rel (often <0) */ | ||||||
| 	AttrNumber	max_attr;		/* largest attrno of rel */ | 	AttrNumber	max_attr;		/* largest attrno of rel */ | ||||||
| @ -435,6 +436,7 @@ typedef struct IndexOptInfo | |||||||
| 	NodeTag		type; | 	NodeTag		type; | ||||||
| 
 | 
 | ||||||
| 	Oid			indexoid;		/* OID of the index relation */ | 	Oid			indexoid;		/* OID of the index relation */ | ||||||
|  | 	Oid			reltablespace;	/* tablespace of index (not table) */ | ||||||
| 	RelOptInfo *rel;			/* back-link to index's table */ | 	RelOptInfo *rel;			/* back-link to index's table */ | ||||||
| 
 | 
 | ||||||
| 	/* statistics from pg_class */ | 	/* statistics from pg_class */ | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								src/include/utils/spccache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/include/utils/spccache.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | /*-------------------------------------------------------------------------
 | ||||||
|  |  * | ||||||
|  |  * spccache.h | ||||||
|  |  *	  Tablespace cache. | ||||||
|  |  * | ||||||
|  |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  |  * | ||||||
|  |  * $PostgreSQL: pgsql/src/include/utils/spccache.h,v 1.1 2010/01/05 21:54:00 rhaas Exp $ | ||||||
|  |  * | ||||||
|  |  *------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  | #ifndef SPCCACHE_H | ||||||
|  | #define SPCCACHE_H | ||||||
|  | 
 | ||||||
|  | void get_tablespace_page_costs(Oid spcid, float8 *spc_random_page_cost, | ||||||
|  | 					     float8 *spc_seq_page_cost); | ||||||
|  | 
 | ||||||
|  | #endif   /* SPCCACHE_H */ | ||||||
| @ -9,7 +9,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.77 2010/01/02 16:58:10 momjian Exp $ |  * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.78 2010/01/05 21:54:00 rhaas Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -71,6 +71,7 @@ enum SysCacheIdentifier | |||||||
| 	RELOID, | 	RELOID, | ||||||
| 	RULERELNAME, | 	RULERELNAME, | ||||||
| 	STATRELATTINH, | 	STATRELATTINH, | ||||||
|  | 	TABLESPACEOID, | ||||||
| 	TSCONFIGMAP, | 	TSCONFIGMAP, | ||||||
| 	TSCONFIGNAMENSP, | 	TSCONFIGNAMENSP, | ||||||
| 	TSCONFIGOID, | 	TSCONFIGOID, | ||||||
|  | |||||||
| @ -1,6 +1,12 @@ | |||||||
| -- create a tablespace we can use | -- create a tablespace we can use | ||||||
| CREATE TABLESPACE testspace LOCATION '@testtablespace@'; | CREATE TABLESPACE testspace LOCATION '@testtablespace@'; | ||||||
| 
 | 
 | ||||||
|  | -- try setting and resetting some properties for the new tablespace | ||||||
|  | ALTER TABLESPACE testspace SET (random_page_cost = 1.0); | ||||||
|  | ALTER TABLESPACE testspace SET (some_nonexistent_parameter = true);  -- fail | ||||||
|  | ALTER TABLESPACE testspace RESET (random_page_cost = 2.0); -- fail | ||||||
|  | ALTER TABLESPACE testspace RESET (random_page_cost, seq_page_cost); -- ok | ||||||
|  | 
 | ||||||
| -- create a schema we can use | -- create a schema we can use | ||||||
| CREATE SCHEMA testschema; | CREATE SCHEMA testschema; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,12 @@ | |||||||
| -- create a tablespace we can use | -- create a tablespace we can use | ||||||
| CREATE TABLESPACE testspace LOCATION '@testtablespace@'; | CREATE TABLESPACE testspace LOCATION '@testtablespace@'; | ||||||
|  | -- try setting and resetting some properties for the new tablespace | ||||||
|  | ALTER TABLESPACE testspace SET (random_page_cost = 1.0); | ||||||
|  | ALTER TABLESPACE testspace SET (some_nonexistent_parameter = true);  -- fail | ||||||
|  | ERROR:  unrecognized parameter "some_nonexistent_parameter" | ||||||
|  | ALTER TABLESPACE testspace RESET (random_page_cost = 2.0); -- fail | ||||||
|  | ERROR:  RESET must not include values for parameters | ||||||
|  | ALTER TABLESPACE testspace RESET (random_page_cost, seq_page_cost); -- ok | ||||||
| -- create a schema we can use | -- create a schema we can use | ||||||
| CREATE SCHEMA testschema; | CREATE SCHEMA testschema; | ||||||
| -- try a table | -- try a table | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user