mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-28 11:55:03 +03:00 
			
		
		
		
	Add FILLFACTOR to CREATE INDEX.
ITAGAKI Takahiro
This commit is contained in:
		| @@ -11,7 +11,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.147 2006/05/02 22:25:10 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.148 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -566,6 +566,8 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace) | ||||
| 				tupdesc; | ||||
| 	Oid			OIDNewHeap; | ||||
| 	Relation	OldHeap; | ||||
| 	HeapTuple	tuple; | ||||
| 	ArrayType  *options; | ||||
|  | ||||
| 	OldHeap = heap_open(OIDOldHeap, AccessExclusiveLock); | ||||
| 	OldHeapDesc = RelationGetDescr(OldHeap); | ||||
| @@ -576,6 +578,26 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace) | ||||
| 	 */ | ||||
| 	tupdesc = CreateTupleDescCopyConstr(OldHeapDesc); | ||||
|  | ||||
| 	/* | ||||
| 	 * Use options of the old heap for new heap. | ||||
| 	 */ | ||||
| 	tuple = SearchSysCache(RELOID, | ||||
| 						   ObjectIdGetDatum(OIDOldHeap), | ||||
| 						   0, 0, 0); | ||||
| 	if (tuple) | ||||
| 	{ | ||||
| 		Datum	datum; | ||||
| 		bool	isNull; | ||||
| 		datum = SysCacheGetAttr(RELOID, tuple, | ||||
|             Anum_pg_class_reloptions, &isNull); | ||||
| 		options = isNull ? NULL : DatumGetArrayTypeP(datum); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* should not happen */ | ||||
| 		options = NULL; | ||||
| 	} | ||||
|  | ||||
| 	OIDNewHeap = heap_create_with_catalog(NewName, | ||||
| 										  RelationGetNamespace(OldHeap), | ||||
| 										  NewTableSpace, | ||||
| @@ -587,7 +609,10 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace) | ||||
| 										  true, | ||||
| 										  0, | ||||
| 										  ONCOMMIT_NOOP, | ||||
| 										  allowSystemTableMods); | ||||
| 										  allowSystemTableMods, | ||||
| 										  options); | ||||
|  | ||||
| 	ReleaseSysCache(tuple); | ||||
|  | ||||
| 	/* | ||||
| 	 * Advance command counter so that the newly-created relation's catalog | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.95 2006/03/14 22:48:18 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.96 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  *	  The "DefineFoo" routines take the parse tree and pick out the | ||||
| @@ -110,6 +110,7 @@ defGetNumeric(DefElem *def) | ||||
| 		case T_Integer: | ||||
| 			return (double) intVal(def->arg); | ||||
| 		case T_Float: | ||||
| 		case T_String:	/* XXX: needs strict check? */ | ||||
| 			return floatVal(def->arg); | ||||
| 		default: | ||||
| 			ereport(ERROR, | ||||
| @@ -127,14 +128,30 @@ bool | ||||
| defGetBoolean(DefElem *def) | ||||
| { | ||||
| 	/* | ||||
| 	 * Presently, boolean flags must simply be present or absent. Later we | ||||
| 	 * could allow 'flag = t', 'flag = f', etc. | ||||
| 	 * Presently, boolean flags must simply be present/absent or | ||||
| 	 * integer 0/1. Later we could allow 'flag = t', 'flag = f', etc. | ||||
| 	 */ | ||||
| 	if (def->arg == NULL) | ||||
| 		return true; | ||||
| 	switch (nodeTag(def->arg)) | ||||
| 	{ | ||||
| 		case T_Integer: | ||||
| 			switch (intVal(def->arg)) | ||||
| 			{ | ||||
| 			case 0: | ||||
| 				return false; | ||||
| 			case 1: | ||||
| 				return true; | ||||
| 			} | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	/* on error */ | ||||
| 	ereport(ERROR, | ||||
| 			(errcode(ERRCODE_SYNTAX_ERROR), | ||||
| 			 errmsg("%s does not take a parameter", | ||||
| 			 errmsg("%s requires a boolean value", | ||||
| 					def->defname))); | ||||
| 	return false;				/* keep compiler quiet */ | ||||
| } | ||||
| @@ -155,7 +172,7 @@ defGetInt64(DefElem *def) | ||||
| 		case T_Integer: | ||||
| 			return (int64) intVal(def->arg); | ||||
| 		case T_Float: | ||||
|  | ||||
| 		case T_String:	/* XXX: needs strict check? */ | ||||
| 			/* | ||||
| 			 * Values too large for int4 will be represented as Float | ||||
| 			 * constants by the lexer.	Accept these if they are valid int8 | ||||
| @@ -275,3 +292,12 @@ defGetTypeLength(DefElem *def) | ||||
| 					def->defname, defGetString(def)))); | ||||
| 	return 0;					/* keep compiler quiet */ | ||||
| } | ||||
|  | ||||
| DefElem * | ||||
| defWithOids(bool value) | ||||
| { | ||||
| 	DefElem *f = makeNode(DefElem); | ||||
| 	f->defname = "oids"; | ||||
| 	f->arg = (Node *)makeInteger(value); | ||||
| 	return f; | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.141 2006/06/07 17:20:17 momjian Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.142 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -77,6 +77,7 @@ static bool relationHasPrimaryKey(Relation rel); | ||||
|  * 'isconstraint': index is for a PRIMARY KEY or UNIQUE constraint, | ||||
|  *		so build a pg_constraint entry for it. | ||||
|  * 'is_alter_table': this is due to an ALTER rather than a CREATE operation. | ||||
|  * 'options': options passed by WITH. | ||||
|  * 'check_rights': check for CREATE rights in the namespace.  (This should | ||||
|  *		be true except when ALTER is deleting/recreating an index.) | ||||
|  * 'skip_build': make the catalog entries but leave the index file empty; | ||||
| @@ -92,6 +93,7 @@ DefineIndex(RangeVar *heapRelation, | ||||
| 			List *attributeList, | ||||
| 			Expr *predicate, | ||||
| 			List *rangetable, | ||||
| 			List *options, | ||||
| 			bool unique, | ||||
| 			bool primary, | ||||
| 			bool isconstraint, | ||||
| @@ -397,7 +399,7 @@ DefineIndex(RangeVar *heapRelation, | ||||
|  | ||||
| 	index_create(relationId, indexRelationName, indexRelationId, | ||||
| 				 indexInfo, accessMethodId, tablespaceId, classObjectId, | ||||
| 				 primary, false, isconstraint, | ||||
| 				 options, primary, false, isconstraint, | ||||
| 				 allowSystemTableMods, skip_build); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
|  * Copyright (c) 2002-2006, PostgreSQL Global Development Group | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.53 2006/06/20 22:51:59 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.54 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -196,6 +196,7 @@ ExecuteQuery(ExecuteStmt *stmt, ParamListInfo params, | ||||
| 					(errcode(ERRCODE_WRONG_OBJECT_TYPE), | ||||
| 					 errmsg("prepared statement is not a SELECT"))); | ||||
| 		query->into = copyObject(stmt->into); | ||||
| 		query->intoOptions = copyObject(stmt->intoOptions); | ||||
| 		query->intoHasOids = stmt->into_has_oids; | ||||
| 		query->intoOnCommit = stmt->into_on_commit; | ||||
| 		if (stmt->into_tbl_space) | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.132 2006/03/31 23:32:06 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.133 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -180,7 +180,7 @@ DefineSequence(CreateSeqStmt *seq) | ||||
| 	stmt->relation = seq->sequence; | ||||
| 	stmt->inhRelations = NIL; | ||||
| 	stmt->constraints = NIL; | ||||
| 	stmt->hasoids = MUST_NOT_HAVE_OIDS; | ||||
| 	stmt->options = list_make1(defWithOids(false)); | ||||
| 	stmt->oncommit = ONCOMMIT_NOOP; | ||||
| 	stmt->tablespacename = NULL; | ||||
|  | ||||
| @@ -205,7 +205,17 @@ DefineSequence(CreateSeqStmt *seq) | ||||
|  | ||||
| 	/* Now form & insert sequence tuple */ | ||||
| 	tuple = heap_formtuple(tupDesc, value, null); | ||||
| 	simple_heap_insert(rel, tuple); | ||||
|  | ||||
| 	{ | ||||
| 		/* | ||||
| 		 * HACK: Sequences insert only one tuple during initialize. | ||||
| 		 * We treat sequences as heaps then. | ||||
| 		 */ | ||||
| 		HeapOption opaque = { sizeof(HeapOption), 100 }; | ||||
| 		rel->rd_options = (bytea *) &opaque; | ||||
| 		simple_heap_insert(rel, tuple); | ||||
| 		rel->rd_options = NULL; | ||||
| 	} | ||||
|  | ||||
| 	Assert(ItemPointerGetOffsetNumber(&(tuple->t_self)) == FirstOffsetNumber); | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.189 2006/07/02 01:58:36 momjian Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.190 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -62,7 +62,6 @@ | ||||
| #include "utils/relcache.h" | ||||
| #include "utils/syscache.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * ON COMMIT action list | ||||
|  */ | ||||
| @@ -196,6 +195,7 @@ static void ATRewriteTables(List **wqueue); | ||||
| static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap); | ||||
| static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel); | ||||
| static void ATSimplePermissions(Relation rel, bool allowView); | ||||
| static void ATSimplePermissionsRelationOrIndex(Relation rel); | ||||
| static void ATSimpleRecursion(List **wqueue, Relation rel, | ||||
| 				  AlterTableCmd *cmd, bool recurse); | ||||
| static void ATOneLevelRecursion(List **wqueue, Relation rel, | ||||
| @@ -248,6 +248,7 @@ static void ATExecDropCluster(Relation rel); | ||||
| static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, | ||||
| 					char *tablespacename); | ||||
| static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace); | ||||
| static void ATExecSetOptions(Relation rel, List *newOptions); | ||||
| static void ATExecEnableDisableTrigger(Relation rel, char *trigname, | ||||
| 						   bool enable, bool skip_system); | ||||
| static void ATExecAddInherits(Relation rel, RangeVar *parent); | ||||
| @@ -285,6 +286,7 @@ DefineRelation(CreateStmt *stmt, char relkind) | ||||
| 	ListCell   *listptr; | ||||
| 	int			i; | ||||
| 	AttrNumber	attnum; | ||||
| 	ArrayType  *options; | ||||
|  | ||||
| 	/* | ||||
| 	 * Truncate relname to appropriate length (probably a waste of time, as | ||||
| @@ -366,7 +368,7 @@ DefineRelation(CreateStmt *stmt, char relkind) | ||||
| 	 */ | ||||
| 	descriptor = BuildDescForRelation(schema); | ||||
|  | ||||
| 	localHasOids = interpretOidsOption(stmt->hasoids); | ||||
| 	localHasOids = interpretOidsOption(stmt->options); | ||||
| 	descriptor->tdhasoid = (localHasOids || parentOidCount > 0); | ||||
|  | ||||
| 	if (old_constraints != NIL) | ||||
| @@ -426,6 +428,7 @@ DefineRelation(CreateStmt *stmt, char relkind) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	options = OptionBuild(NULL, stmt->options); | ||||
| 	relationId = heap_create_with_catalog(relname, | ||||
| 										  namespaceId, | ||||
| 										  tablespaceId, | ||||
| @@ -437,7 +440,10 @@ DefineRelation(CreateStmt *stmt, char relkind) | ||||
| 										  localHasOids, | ||||
| 										  parentOidCount, | ||||
| 										  stmt->oncommit, | ||||
| 										  allowSystemTableMods); | ||||
| 										  allowSystemTableMods, | ||||
| 										  options); | ||||
| 	if (options) | ||||
| 		pfree(options); | ||||
|  | ||||
| 	StoreCatalogInheritance(relationId, inheritOids); | ||||
|  | ||||
| @@ -2092,10 +2098,17 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, | ||||
| 			pass = AT_PASS_DROP; | ||||
| 			break; | ||||
| 		case AT_SetTableSpace:	/* SET TABLESPACE */ | ||||
| 			ATSimplePermissionsRelationOrIndex(rel); | ||||
| 			/* This command never recurses */ | ||||
| 			ATPrepSetTableSpace(tab, rel, cmd->name); | ||||
| 			pass = AT_PASS_MISC;	/* doesn't actually matter */ | ||||
| 			break; | ||||
| 		case AT_SetOptions:		/* SET (...) */ | ||||
| 			ATSimplePermissionsRelationOrIndex(rel); | ||||
| 			/* This command never recurses */ | ||||
| 			/* No command-specific prep needed */ | ||||
| 			pass = AT_PASS_MISC; | ||||
| 			break; | ||||
| 		case AT_EnableTrig:		/* ENABLE TRIGGER variants */ | ||||
| 		case AT_EnableTrigAll: | ||||
| 		case AT_EnableTrigUser: | ||||
| @@ -2266,6 +2279,9 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd) | ||||
| 			 * Nothing to do here; Phase 3 does the work | ||||
| 			 */ | ||||
| 			break; | ||||
| 		case AT_SetOptions:		/* SET (...) */ | ||||
| 			ATExecSetOptions(rel, (List *) cmd->def); | ||||
| 			break; | ||||
| 		case AT_EnableTrig:		/* ENABLE TRIGGER name */ | ||||
| 			ATExecEnableDisableTrigger(rel, cmd->name, true, false); | ||||
| 			break; | ||||
| @@ -2776,6 +2792,35 @@ ATSimplePermissions(Relation rel, bool allowView) | ||||
| 						RelationGetRelationName(rel)))); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * ATSimplePermissionsRelationOrIndex | ||||
|  * | ||||
|  * - Ensure that it is a relation or an index | ||||
|  * - Ensure this user is the owner | ||||
|  * - Ensure that it is not a system table | ||||
|  */ | ||||
| static void | ||||
| ATSimplePermissionsRelationOrIndex(Relation rel) | ||||
| { | ||||
| 	if (rel->rd_rel->relkind != RELKIND_RELATION && | ||||
| 		rel->rd_rel->relkind != RELKIND_INDEX) | ||||
| 		ereport(ERROR, | ||||
| 				(errcode(ERRCODE_WRONG_OBJECT_TYPE), | ||||
| 				 errmsg("\"%s\" is not a table or index", | ||||
| 						RelationGetRelationName(rel)))); | ||||
|  | ||||
| 	/* Permissions checks */ | ||||
| 	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) | ||||
| 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, | ||||
| 					   RelationGetRelationName(rel)); | ||||
|  | ||||
| 	if (!allowSystemTableMods && IsSystemRelation(rel)) | ||||
| 		ereport(ERROR, | ||||
| 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), | ||||
| 				 errmsg("permission denied: \"%s\" is a system catalog", | ||||
| 						RelationGetRelationName(rel)))); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * ATSimpleRecursion | ||||
|  * | ||||
| @@ -3804,6 +3849,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, | ||||
| 				stmt->indexParams,		/* parameters */ | ||||
| 				(Expr *) stmt->whereClause, | ||||
| 				stmt->rangetable, | ||||
| 				stmt->options, | ||||
| 				stmt->unique, | ||||
| 				stmt->primary, | ||||
| 				stmt->isconstraint, | ||||
| @@ -5690,28 +5736,6 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename) | ||||
| 	Oid			tablespaceId; | ||||
| 	AclResult	aclresult; | ||||
|  | ||||
| 	/* | ||||
| 	 * We do our own permission checking because we want to allow this on | ||||
| 	 * indexes. | ||||
| 	 */ | ||||
| 	if (rel->rd_rel->relkind != RELKIND_RELATION && | ||||
| 		rel->rd_rel->relkind != RELKIND_INDEX) | ||||
| 		ereport(ERROR, | ||||
| 				(errcode(ERRCODE_WRONG_OBJECT_TYPE), | ||||
| 				 errmsg("\"%s\" is not a table or index", | ||||
| 						RelationGetRelationName(rel)))); | ||||
|  | ||||
| 	/* Permissions checks */ | ||||
| 	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) | ||||
| 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, | ||||
| 					   RelationGetRelationName(rel)); | ||||
|  | ||||
| 	if (!allowSystemTableMods && IsSystemRelation(rel)) | ||||
| 		ereport(ERROR, | ||||
| 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), | ||||
| 				 errmsg("permission denied: \"%s\" is a system catalog", | ||||
| 						RelationGetRelationName(rel)))); | ||||
|  | ||||
| 	/* Check that the tablespace exists */ | ||||
| 	tablespaceId = get_tablespace_oid(tablespacename); | ||||
| 	if (!OidIsValid(tablespaceId)) | ||||
| @@ -5732,6 +5756,89 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename) | ||||
| 	tab->newTableSpace = tablespaceId; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * ALTER TABLE/INDEX SET (...) | ||||
|  */ | ||||
| static void | ||||
| ATExecSetOptions(Relation rel, List *newOptions) | ||||
| { | ||||
| 	Oid			relid; | ||||
| 	Relation	pgclass; | ||||
| 	HeapTuple	tuple; | ||||
| 	Datum		datum; | ||||
| 	bool		isnull; | ||||
| 	ArrayType  *mergedOptions; | ||||
| 	bytea	   *options; | ||||
|  | ||||
| 	if (list_length(newOptions) == 0) | ||||
| 		return; /* do nothing */ | ||||
|  | ||||
| 	relid = RelationGetRelid(rel); | ||||
| 	pgclass = heap_open(RelationRelationId, RowExclusiveLock); | ||||
| 	tuple = SearchSysCache(RELOID, | ||||
| 						   ObjectIdGetDatum(relid), | ||||
| 						   0, 0, 0); | ||||
| 	if (!HeapTupleIsValid(tuple)) | ||||
| 		elog(ERROR, "cache lookup failed for relation %u", relid); | ||||
|  | ||||
| 	datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull); | ||||
|  | ||||
| 	mergedOptions = OptionBuild( | ||||
| 		isnull ? NULL : DatumGetArrayTypeP(datum), newOptions); | ||||
|  | ||||
| 	switch (rel->rd_rel->relkind) | ||||
| 	{ | ||||
| 		case RELKIND_RELATION: | ||||
| 		case RELKIND_TOASTVALUE: | ||||
| 			options = heap_option(rel->rd_rel->relkind, mergedOptions); | ||||
| 			break; | ||||
| 		case RELKIND_INDEX: | ||||
| 			options = index_option(rel->rd_am->amoption, mergedOptions); | ||||
| 			break; | ||||
| 		default: | ||||
| 			elog(ERROR, "unexpected RELKIND=%c", rel->rd_rel->relkind); | ||||
| 			options = NULL;	/* keep compiler quiet */ | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	if (rel->rd_options != options) | ||||
| 	{ | ||||
| 		HeapTuple	newtuple; | ||||
| 		Datum		repl_val[Natts_pg_class]; | ||||
| 		char		repl_null[Natts_pg_class]; | ||||
| 		char		repl_repl[Natts_pg_class]; | ||||
|  | ||||
| 		/* XXX: This is not necessarily required. */ | ||||
| 		if (rel->rd_options) | ||||
| 			pfree(rel->rd_options); | ||||
| 		rel->rd_options = options; | ||||
|  | ||||
| 		memset(repl_repl, ' ', sizeof(repl_repl)); | ||||
| 		memset(repl_null, ' ', sizeof(repl_null)); | ||||
| 		repl_repl[Anum_pg_class_reloptions - 1] = 'r'; | ||||
|  | ||||
| 		if (mergedOptions) | ||||
| 			repl_val[Anum_pg_class_reloptions - 1] = | ||||
| 				PointerGetDatum(mergedOptions); | ||||
| 		else | ||||
| 			repl_null[Anum_pg_class_reloptions - 1] = 'n'; | ||||
|  | ||||
| 		newtuple = heap_modifytuple(tuple, RelationGetDescr(pgclass), | ||||
| 			repl_val, repl_null, repl_repl); | ||||
|  | ||||
| 		simple_heap_update(pgclass, &newtuple->t_self, newtuple); | ||||
| 		CatalogUpdateIndexes(pgclass, newtuple); | ||||
|  | ||||
| 		heap_freetuple(newtuple); | ||||
| 	} | ||||
|  | ||||
| 	if (mergedOptions) | ||||
| 		pfree(mergedOptions); | ||||
|  | ||||
| 	ReleaseSysCache(tuple); | ||||
| 	heap_close(pgclass, RowExclusiveLock); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple | ||||
|  * rewriting to be done, so we just want to copy the data as fast as possible. | ||||
| @@ -6553,7 +6660,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent) | ||||
| 										   true, | ||||
| 										   0, | ||||
| 										   ONCOMMIT_NOOP, | ||||
| 										   true); | ||||
| 										   true, | ||||
| 										   NULL); | ||||
|  | ||||
| 	/* make the toast relation visible, else index creation will fail */ | ||||
| 	CommandCounterIncrement(); | ||||
| @@ -6587,7 +6695,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent) | ||||
| 							   indexInfo, | ||||
| 							   BTREE_AM_OID, | ||||
| 							   rel->rd_rel->reltablespace, | ||||
| 							   classObjectId, | ||||
| 							   classObjectId, NIL, | ||||
| 							   true, true, false, true, false); | ||||
|  | ||||
| 	/* | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.91 2006/06/21 18:09:53 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.92 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  *	  The "DefineFoo" routines take the parse tree and pick out the | ||||
| @@ -1130,7 +1130,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) | ||||
| 	createStmt->tableElts = coldeflist; | ||||
| 	createStmt->inhRelations = NIL; | ||||
| 	createStmt->constraints = NIL; | ||||
| 	createStmt->hasoids = MUST_NOT_HAVE_OIDS; | ||||
| 	createStmt->options = list_make1(defWithOids(false)); | ||||
| 	createStmt->oncommit = ONCOMMIT_NOOP; | ||||
| 	createStmt->tablespacename = NULL; | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.330 2006/05/10 23:18:39 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.331 2006/07/02 02:23:19 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -242,6 +242,7 @@ static int	vac_cmp_blk(const void *left, const void *right); | ||||
| static int	vac_cmp_offno(const void *left, const void *right); | ||||
| static int	vac_cmp_vtlinks(const void *left, const void *right); | ||||
| static bool enough_space(VacPage vacpage, Size len); | ||||
| static Size	PageGetFreeSpaceWithFillFactor(Relation relation, Page page); | ||||
|  | ||||
|  | ||||
| /**************************************************************************** | ||||
| @@ -1282,7 +1283,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel, | ||||
| 					   relname, blkno))); | ||||
| 			PageInit(page, BufferGetPageSize(buf), 0); | ||||
| 			MarkBufferDirty(buf); | ||||
| 			vacpage->free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower; | ||||
| 			vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, page); | ||||
| 			free_space += vacpage->free; | ||||
| 			empty_pages++; | ||||
| 			empty_end_pages++; | ||||
| @@ -1297,7 +1298,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel, | ||||
| 		{ | ||||
| 			VacPage		vacpagecopy; | ||||
|  | ||||
| 			vacpage->free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower; | ||||
| 			vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, page); | ||||
| 			free_space += vacpage->free; | ||||
| 			empty_pages++; | ||||
| 			empty_end_pages++; | ||||
| @@ -1465,14 +1466,14 @@ scan_heap(VRelStats *vacrelstats, Relation onerel, | ||||
| 		{ | ||||
| 			/* Some tuples are removable; figure free space after removal */ | ||||
| 			PageRepairFragmentation(tempPage, NULL); | ||||
| 			vacpage->free = ((PageHeader) tempPage)->pd_upper - ((PageHeader) tempPage)->pd_lower; | ||||
| 			vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, tempPage); | ||||
| 			pfree(tempPage); | ||||
| 			do_reap = true; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* Just use current available space */ | ||||
| 			vacpage->free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower; | ||||
| 			vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, page); | ||||
| 			/* Need to reap the page if it has ~LP_USED line pointers */ | ||||
| 			do_reap = (vacpage->offsets_free > 0); | ||||
| 		} | ||||
| @@ -2709,8 +2710,7 @@ move_plain_tuple(Relation rel, | ||||
|  | ||||
| 	END_CRIT_SECTION(); | ||||
|  | ||||
| 	dst_vacpage->free = ((PageHeader) dst_page)->pd_upper - | ||||
| 		((PageHeader) dst_page)->pd_lower; | ||||
| 	dst_vacpage->free = PageGetFreeSpaceWithFillFactor(rel, dst_page); | ||||
| 	LockBuffer(dst_buf, BUFFER_LOCK_UNLOCK); | ||||
| 	LockBuffer(old_buf, BUFFER_LOCK_UNLOCK); | ||||
|  | ||||
| @@ -3119,6 +3119,8 @@ vac_update_fsm(Relation onerel, VacPageList fraged_pages, | ||||
| 	 * vacuumlazy.c does, we'd be skewing that statistic. | ||||
| 	 */ | ||||
| 	threshold = GetAvgFSMRequestSize(&onerel->rd_node); | ||||
| 	if (threshold < HeapGetPageFreeSpace(onerel)) | ||||
| 		threshold = HeapGetPageFreeSpace(onerel); | ||||
|  | ||||
| 	pageSpaces = (PageFreeSpaceInfo *) | ||||
| 		palloc(nPages * sizeof(PageFreeSpaceInfo)); | ||||
| @@ -3385,6 +3387,18 @@ enough_space(VacPage vacpage, Size len) | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| static Size | ||||
| PageGetFreeSpaceWithFillFactor(Relation relation, Page page) | ||||
| { | ||||
| 	PageHeader	pd = (PageHeader) page; | ||||
| 	Size		pagefree = HeapGetPageFreeSpace(relation); | ||||
| 	Size		freespace = pd->pd_upper - pd->pd_lower; | ||||
|  | ||||
| 	if (freespace > pagefree) | ||||
| 		return freespace - pagefree; | ||||
| 	else | ||||
| 		return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * vacuum_delay_point --- check for interrupts and cost-based delay. | ||||
|   | ||||
| @@ -31,7 +31,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.70 2006/05/02 22:25:10 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.71 2006/07/02 02:23:20 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -149,6 +149,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) | ||||
| 	/* Set threshold for interesting free space = average request size */ | ||||
| 	/* XXX should we scale it up or down?  Adjust vacuum.c too, if so */ | ||||
| 	vacrelstats->threshold = GetAvgFSMRequestSize(&onerel->rd_node); | ||||
| 	if (vacrelstats->threshold < HeapGetPageFreeSpace(onerel)) | ||||
| 		vacrelstats->threshold = HeapGetPageFreeSpace(onerel); | ||||
|  | ||||
| 	/* Open all indexes of the relation */ | ||||
| 	vac_open_indexes(onerel, ShareUpdateExclusiveLock, &nindexes, &Irel); | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.94 2006/03/14 22:48:18 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.95 2006/07/02 02:23:20 momjian Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -17,6 +17,7 @@ | ||||
| #include "access/heapam.h" | ||||
| #include "catalog/dependency.h" | ||||
| #include "catalog/namespace.h" | ||||
| #include "commands/defrem.h" | ||||
| #include "commands/tablecmds.h" | ||||
| #include "commands/view.h" | ||||
| #include "miscadmin.h" | ||||
| @@ -195,7 +196,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) | ||||
| 		createStmt->tableElts = attrList; | ||||
| 		createStmt->inhRelations = NIL; | ||||
| 		createStmt->constraints = NIL; | ||||
| 		createStmt->hasoids = MUST_NOT_HAVE_OIDS; | ||||
| 		createStmt->options = list_make1(defWithOids(false)); | ||||
| 		createStmt->oncommit = ONCOMMIT_NOOP; | ||||
| 		createStmt->tablespacename = NULL; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user