SET WITHOUT CLUSTER patch

Поиск
Список
Период
Сортировка
Искать
От
Christopher Kings-Lynne
Тема
SET WITHOUT CLUSTER patch
Дата
Msg-id
405A8472.90203@familyhealth.com.au
Список
Дерево обсуждения
SET WITHOUT CLUSTER patch Christopher Kings-Lynne <chriskl@familyhealth.com.au>
Re: SET WITHOUT CLUSTER patch Tom Lane <tgl@sss.pgh.pa.us>
Re: SET WITHOUT CLUSTER patch Christopher Kings-Lynne <chriskl@familyhealth.com.au>
Re: SET WITHOUT CLUSTER patch Bruce Momjian <pgman@candle.pha.pa.us>
Re: SET WITHOUT CLUSTER patch Christopher Kings-Lynne <chriskl@familyhealth.com.au>
Re: SET WITHOUT CLUSTER patch Bruce Momjian <pgman@candle.pha.pa.us>
Re: SET WITHOUT CLUSTER patch Christopher Kings-Lynne <chriskl@familyhealth.com.au>
Re: SET WITHOUT CLUSTER patch Bruce Momjian <pgman@candle.pha.pa.us>
Re: SET WITHOUT CLUSTER patch Alvaro Herrera <alvherre@dcc.uchile.cl>
Re: SET WITHOUT CLUSTER patch Bruce Momjian <pgman@candle.pha.pa.us>
Re: SET WITHOUT CLUSTER patch Tom Lane <tgl@sss.pgh.pa.us>
Hi,

I have done a patch for turning off clustering on a table entirely. 
Unforunately, of the three syntaxes I can think of, all cause 
shift/reduce errors:

SET WITHOUT CLUSTER;
DROP CLUSTER
CLUSTER ON NONE;

This is the new grammar that I added:

/* ALTER TABLE  SET WITHOUT CLUSTER */
| ALTER TABLE relation_expr SET WITHOUT CLUSTER
         {
                 AlterTableStmt *n = makeNode(AlterTableStmt);
                 n->subtype = 'L';
                 n->relation = $3;
                 n->name = NULL;
                 $$ = (Node *)n;
         }

Now, I have to change that relation_expr to qualified_name.  However, 
this causes shift/reduce errors. (Due to ALTER TABLE relation_expr SET 
WITHOUT OIDS.)

Even changing the syntax to "qualified_name DROP CLUSTER" doesn't work 
due to the existence of "relation_expr DROP ...".

What's the solution?  I can't figure it out...

Chris



Index: doc/src/sgml/ref/alter_table.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/ref/alter_table.sgml,v
retrieving revision 1.66
diff -c -r1.66 alter_table.sgml
*** doc/src/sgml/ref/alter_table.sgml	9 Mar 2004 16:57:47 -0000	1.66
--- doc/src/sgml/ref/alter_table.sgml	18 Mar 2004 03:51:41 -0000
***************
*** 47,52 ****
--- 47,54 ----
      OWNER TO new_owner
  ALTER TABLE name
      CLUSTER ON index_name
+ ALTER TABLE name
+     SET WITHOUT CLUSTER
  
   
  
***************
*** 219,224 ****
--- 221,235 ----
      
     
  
+    
+     SET WITHOUT CLUSTER
+     
+      
+       This form disables future  on a table. 
+      
+     
+    
+  
    
    
  
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/commands/tablecmds.c,v
retrieving revision 1.100
diff -c -r1.100 tablecmds.c
*** src/backend/commands/tablecmds.c	13 Mar 2004 22:09:13 -0000	1.100
--- src/backend/commands/tablecmds.c	18 Mar 2004 03:51:42 -0000
***************
*** 3970,3999 ****
  
  	rel = heap_open(relOid, AccessExclusiveLock);
  
- 	indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
- 
- 	if (!OidIsValid(indexOid))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_UNDEFINED_OBJECT),
- 				 errmsg("index \"%s\" for table \"%s\" does not exist",
- 						indexName, NameStr(rel->rd_rel->relname))));
- 
- 	indexTuple = SearchSysCache(INDEXRELID,
- 								ObjectIdGetDatum(indexOid),
- 								0, 0, 0);
- 	if (!HeapTupleIsValid(indexTuple))
- 		elog(ERROR, "cache lookup failed for index %u", indexOid);
- 	indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
- 
  	/*
! 	 * If this is the same index the relation was previously clustered on,
! 	 * no need to do anything.
  	 */
! 	if (indexForm->indisclustered)
! 	{
! 		ReleaseSysCache(indexTuple);
! 		heap_close(rel, NoLock);
! 		return;
  	}
  
  	pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
--- 3970,4010 ----
  
  	rel = heap_open(relOid, AccessExclusiveLock);
  
  	/*
! 	 * We only fetch the index if indexName is not null.  A null index
!          * name indicates that we're removing all clustering on this table.
  	 */
! 	if (indexName != NULL) {
! 		indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
! 
! 		if (!OidIsValid(indexOid))
! 			ereport(ERROR,
! 					(errcode(ERRCODE_UNDEFINED_OBJECT),
! 					 errmsg("index \"%s\" for table \"%s\" does not exist",
! 							indexName, NameStr(rel->rd_rel->relname))));
! 
! 		indexTuple = SearchSysCache(INDEXRELID,
! 									ObjectIdGetDatum(indexOid),
! 									0, 0, 0);
! 		if (!HeapTupleIsValid(indexTuple))
! 			elog(ERROR, "cache lookup failed for index %u", indexOid);
! 		indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
! 
! 		/*
! 		 * If this is the same index the relation was previously clustered on,
! 		 * no need to do anything.
! 		 */
! 		if (indexForm->indisclustered)
! 		{
! 			ReleaseSysCache(indexTuple);
! 			heap_close(rel, NoLock);
! 			return;
! 		}
! 	}
! 	else {
! 		/* Set to NULL to prevent compiler warnings */
! 		indexTuple = NULL;
! 		indexForm = NULL;
  	}
  
  	pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
***************
*** 4016,4022 ****
  
  		/*
  		 * Unset the bit if set.  We know it's wrong because we checked
! 		 * this earlier.
  		 */
  		if (idxForm->indisclustered)
  		{
--- 4027,4033 ----
  
  		/*
  		 * Unset the bit if set.  We know it's wrong because we checked
! 		 * this earlier.  If we're removing all clustering, we do this too.
  		 */
  		if (idxForm->indisclustered)
  		{
***************
*** 4024,4030 ****
  			simple_heap_update(pg_index, &idxtuple->t_self, idxtuple);
  			CatalogUpdateIndexes(pg_index, idxtuple);
  		}
! 		else if (idxForm->indexrelid == indexForm->indexrelid)
  		{
  			idxForm->indisclustered = true;
  			simple_heap_update(pg_index, &idxtuple->t_self, idxtuple);
--- 4035,4045 ----
  			simple_heap_update(pg_index, &idxtuple->t_self, idxtuple);
  			CatalogUpdateIndexes(pg_index, idxtuple);
  		}
! 		/*
! 		 * If the index is the one we're clustering, set its cluster flag to true.
! 		 * However, we do this only if we're not removing all clustering.
! 		 */
! 		else if (indexName != NULL && idxForm->indexrelid == indexForm->indexrelid)
  		{
  			idxForm->indisclustered = true;
  			simple_heap_update(pg_index, &idxtuple->t_self, idxtuple);
***************
*** 4035,4041 ****
  
  	heap_close(pg_index, RowExclusiveLock);
  
! 	ReleaseSysCache(indexTuple);
  
  	heap_close(rel, NoLock);	/* close rel, but keep lock till commit */
  }
--- 4050,4056 ----
  
  	heap_close(pg_index, RowExclusiveLock);
  
! 	if (indexName != NULL) ReleaseSysCache(indexTuple);
  
  	heap_close(rel, NoLock);	/* close rel, but keep lock till commit */
  }
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/parser/gram.y,v
retrieving revision 2.449
diff -c -r2.449 gram.y
*** src/backend/parser/gram.y	17 Mar 2004 20:48:42 -0000	2.449
--- src/backend/parser/gram.y	18 Mar 2004 03:51:45 -0000
***************
*** 1248,1253 ****
--- 1248,1262 ----
  					n->name = $6;
  					$$ = (Node *)n;
  				}
+ 			/* ALTER TABLE  SET WITHOUT CLUSTER */
+ 			| ALTER TABLE relation_expr SET WITHOUT CLUSTER
+ 				{
+ 					AlterTableStmt *n = makeNode(AlterTableStmt);
+ 					n->subtype = 'L';
+ 					n->relation = $3;
+ 					n->name = NULL;
+ 					$$ = (Node *)n;
+ 				}
  		;
  
  alter_column_default:
Index: src/test/regress/expected/cluster.out
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/test/regress/expected/cluster.out,v
retrieving revision 1.14
diff -c -r1.14 cluster.out
*** src/test/regress/expected/cluster.out	2 Oct 2003 06:32:46 -0000	1.14
--- src/test/regress/expected/cluster.out	18 Mar 2004 03:51:45 -0000
***************
*** 297,302 ****
--- 297,313 ----
   clstr_tst_b_c
  (1 row)
  
+ -- Try turning off all clustering
+ ALTER TABLE clstr_tst SET WITHOUT CLUSTER;
+ SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2
+ WHERE pg_class.oid=indexrelid
+ 	AND indrelid=pg_class_2.oid
+ 	AND pg_class_2.relname = 'clstr_tst'
+  	AND indisclustered;
+   relname 
+  ---------
+  (0 rows)
+ 
  -- Verify that clustering all tables does in fact cluster the right ones
  CREATE USER clstr_user;
  CREATE TABLE clstr_1 (a INT PRIMARY KEY);
Index: src/test/regress/sql/cluster.sql
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/test/regress/sql/cluster.sql,v
retrieving revision 1.7
diff -c -r1.7 cluster.sql
*** src/test/regress/sql/cluster.sql	20 Mar 2003 18:52:48 -0000	1.7
--- src/test/regress/sql/cluster.sql	18 Mar 2004 03:51:46 -0000
***************
*** 95,100 ****
--- 95,108 ----
  	AND pg_class_2.relname = 'clstr_tst'
  	AND indisclustered;
  
+ -- Try turning off all clustering
+ ALTER TABLE clstr_tst SET WITHOUT CLUSTER;
+ SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2
+ WHERE pg_class.oid=indexrelid
+ 	AND indrelid=pg_class_2.oid
+ 	AND pg_class_2.relname = 'clstr_tst'
+ 	AND indisclustered;
+ 
  -- Verify that clustering all tables does in fact cluster the right ones
  CREATE USER clstr_user;
  CREATE TABLE clstr_1 (a INT PRIMARY KEY);
В списке pgsql-hackers по дате отправления
От: Larry Rosenman
Дата:
От: Tom Lane
Дата:
Сообщение: Re: SET WITHOUT CLUSTER patch
FAQ