2222 *
2323 *
2424 * IDENTIFICATION
25- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.230 2001/09/21 21:58:30 petere Exp $
25+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.231 2001/10/01 21:31:52 tgl Exp $
2626 *
2727 *-------------------------------------------------------------------------
2828 */
@@ -1763,22 +1763,14 @@ clearIndInfo(IndInfo *ind, int numIndexes)
17631763free (ind [i ].indexrelname );
17641764if (ind [i ].indrelname )
17651765free (ind [i ].indrelname );
1766- if (ind [i ].indamname )
1767- free (ind [i ].indamname );
1768- if (ind [i ].indproc )
1769- free (ind [i ].indproc );
1770- if (ind [i ].indisunique )
1771- free (ind [i ].indisunique );
1766+ if (ind [i ].indexdef )
1767+ free (ind [i ].indexdef );
17721768if (ind [i ].indisprimary )
17731769free (ind [i ].indisprimary );
1774- if (ind [i ].indhaspred )
1775- free (ind [i ].indhaspred );
17761770for (a = 0 ;a < INDEX_MAX_KEYS ;++ a )
17771771{
17781772if (ind [i ].indkey [a ])
17791773free (ind [i ].indkey [a ]);
1780- if (ind [i ].indclass [a ])
1781- free (ind [i ].indclass [a ]);
17821774}
17831775}
17841776free (ind );
@@ -2884,34 +2876,27 @@ getIndexes(int *numIndexes)
28842876int i_indreloid ;
28852877int i_indexrelname ;
28862878int i_indrelname ;
2887- int i_indamname ;
2888- int i_indproc ;
2889- int i_indkey ;
2890- int i_indclass ;
2891- int i_indisunique ;
2879+ int i_indexdef ;
28922880int i_indisprimary ;
2893- int i_indhaspred ;
2881+ int i_indkey ;
28942882
28952883/*
28962884 * find all the user-defined indexes.
28972885 *
28982886 * Notice we skip indexes on system classes
28992887 *
2900- * this is a 4-way join !!
2901- *
29022888 * XXXX: Use LOJ
29032889 */
29042890
29052891appendPQExpBuffer (query ,
29062892"SELECT i.indexrelid as indexreloid, "
29072893"i.indrelid as indreloid, "
29082894"t1.relname as indexrelname, t2.relname as indrelname, "
2909- "i.indproc :: oid AS indproc, i.indkey, i.indclass, "
2910- "a.amname as indamname, i.indisunique, i.indisprimary, "
2911- "length(i.indpred) > 0 as indhaspred "
2912- "from pg_index i, pg_class t1, pg_class t2, pg_am a "
2895+ "pg_get_indexdef(i.indexrelid) as indexdef, "
2896+ "i.indisprimary, i.indkey "
2897+ "from pg_index i, pg_class t1, pg_class t2 "
29132898"WHERE t1.oid = i.indexrelid and t2.oid = i.indrelid "
2914- "andt1.relam = a.oid and i.indexrelid > '%u'::oid "
2899+ "and i.indexrelid > '%u'::oid "
29152900"and t2.relname !~ '^pg_' " ,
29162901g_last_builtin_oid );
29172902
@@ -2938,31 +2923,21 @@ getIndexes(int *numIndexes)
29382923i_indreloid = PQfnumber (res ,"indreloid" );
29392924i_indexrelname = PQfnumber (res ,"indexrelname" );
29402925i_indrelname = PQfnumber (res ,"indrelname" );
2941- i_indamname = PQfnumber (res ,"indamname" );
2942- i_indproc = PQfnumber (res ,"indproc" );
2943- i_indkey = PQfnumber (res ,"indkey" );
2944- i_indclass = PQfnumber (res ,"indclass" );
2945- i_indisunique = PQfnumber (res ,"indisunique" );
2926+ i_indexdef = PQfnumber (res ,"indexdef" );
29462927i_indisprimary = PQfnumber (res ,"indisprimary" );
2947- i_indhaspred = PQfnumber (res ,"indhaspred " );
2928+ i_indkey = PQfnumber (res ,"indkey " );
29482929
29492930for (i = 0 ;i < ntups ;i ++ )
29502931{
29512932indinfo [i ].indexreloid = strdup (PQgetvalue (res ,i ,i_indexreloid ));
29522933indinfo [i ].indreloid = strdup (PQgetvalue (res ,i ,i_indreloid ));
29532934indinfo [i ].indexrelname = strdup (PQgetvalue (res ,i ,i_indexrelname ));
29542935indinfo [i ].indrelname = strdup (PQgetvalue (res ,i ,i_indrelname ));
2955- indinfo [i ].indamname = strdup (PQgetvalue (res ,i ,i_indamname ));
2956- indinfo [i ].indproc = strdup (PQgetvalue (res ,i ,i_indproc ));
2936+ indinfo [i ].indexdef = strdup (PQgetvalue (res ,i ,i_indexdef ));
2937+ indinfo [i ].indisprimary = strdup (PQgetvalue (res ,i ,i_indisprimary ));
29572938parseNumericArray (PQgetvalue (res ,i ,i_indkey ),
29582939indinfo [i ].indkey ,
29592940INDEX_MAX_KEYS );
2960- parseNumericArray (PQgetvalue (res ,i ,i_indclass ),
2961- indinfo [i ].indclass ,
2962- INDEX_MAX_KEYS );
2963- indinfo [i ].indisunique = strdup (PQgetvalue (res ,i ,i_indisunique ));
2964- indinfo [i ].indisprimary = strdup (PQgetvalue (res ,i ,i_indisprimary ));
2965- indinfo [i ].indhaspred = strdup (PQgetvalue (res ,i ,i_indhaspred ));
29662941}
29672942PQclear (res );
29682943
@@ -4346,23 +4321,18 @@ void
43464321dumpIndexes (Archive * fout ,IndInfo * indinfo ,int numIndexes ,
43474322TableInfo * tblinfo ,int numTables ,const char * tablename )
43484323{
4349- int i ,
4350- k ;
4324+ int i ;
43514325int tableInd ;
4352- PQExpBuffer attlist = createPQExpBuffer ();
43534326PQExpBuffer q = createPQExpBuffer ();
43544327PQExpBuffer delq = createPQExpBuffer ();
43554328PQExpBuffer id1 = createPQExpBuffer ();
4356- PQExpBuffer id2 = createPQExpBuffer ();
4357- char * classname [INDEX_MAX_KEYS ];
4358- char * funcname ;/* the name of the function to comput the
4359- * index key from */
4360- Oid indclass ;
4361- int nclass ;
4362- PGresult * res ;
43634329
43644330for (i = 0 ;i < numIndexes ;i ++ )
43654331{
4332+ if (tablename && tablename [0 ]&&
4333+ (strcmp (indinfo [i ].indrelname ,tablename )!= 0 ))
4334+ continue ;
4335+
43664336tableInd = findTableByName (tblinfo ,numTables ,
43674337indinfo [i ].indrelname );
43684338if (tableInd < 0 )
@@ -4380,14 +4350,14 @@ dumpIndexes(Archive *fout, IndInfo *indinfo, int numIndexes,
43804350
43814351PQExpBuffer consDef = getPKconstraint (& tblinfo [tableInd ],& indinfo [i ]);
43824352
4383- resetPQExpBuffer (attlist );
4353+ resetPQExpBuffer (q );
43844354
4385- appendPQExpBuffer (attlist ,"Alter Table %s Add %s;" ,
4355+ appendPQExpBuffer (q ,"Alter Table %s Add %s;" ,
43864356fmtId (tblinfo [tableInd ].relname ,force_quotes ),
43874357consDef -> data );
43884358
43894359ArchiveEntry (fout ,indinfo [i ].oid ,tblinfo [tableInd ].primary_key_name ,
4390- "CONSTRAINT" ,NULL ,attlist -> data ,"" ,
4360+ "CONSTRAINT" ,NULL ,q -> data ,"" ,
43914361"" ,tblinfo [tableInd ].usename ,NULL ,NULL );
43924362
43934363destroyPQExpBuffer (consDef );
@@ -4400,205 +4370,34 @@ dumpIndexes(Archive *fout, IndInfo *indinfo, int numIndexes,
44004370continue ;
44014371}
44024372
4373+ resetPQExpBuffer (id1 );
4374+ appendPQExpBuffer (id1 ,fmtId (indinfo [i ].indexrelname ,force_quotes ));
44034375
4404- if (strcmp (indinfo [i ].indproc ,"0" )== 0 )
4405- funcname = NULL ;
4406- else
4407- {
4408- int numFuncs ;
4409-
4410- /*
4411- * the indproc is an oid which we use to find the name of the
4412- * pg_proc. We need to do this because getFuncs() only reads
4413- * in the user-defined funcs not all the funcs. We might not
4414- * find what we want by looking in FuncInfo*
4415- */
4416- resetPQExpBuffer (q );
4417- appendPQExpBuffer (q ,
4418- "SELECT proname from pg_proc "
4419- "where pg_proc.oid = '%s'::oid" ,
4420- indinfo [i ].indproc );
4421- res = PQexec (g_conn ,q -> data );
4422- if (!res || PQresultStatus (res )!= PGRES_TUPLES_OK )
4423- {
4424- write_msg (NULL ,"query to get function name of oid %s failed: %s" ,
4425- indinfo [i ].indproc ,PQerrorMessage (g_conn ));
4426- exit_nicely ();
4427- }
4428-
4429- /* Sanity: Check we got only one tuple */
4430- numFuncs = PQntuples (res );
4431- if (numFuncs != 1 )
4432- {
4433- write_msg (NULL ,"query to get function name of oid %s returned %d rows; expected 1\n" ,
4434- indinfo [i ].indproc ,numFuncs );
4435- exit_nicely ();
4436- }
4437-
4438- funcname = strdup (PQgetvalue (res ,0 ,PQfnumber (res ,"proname" )));
4439- PQclear (res );
4440- }
4441-
4442- /* convert opclass oid(s) into names */
4443- for (nclass = 0 ;nclass < INDEX_MAX_KEYS ;nclass ++ )
4444- {
4445- int numRows ;
4446-
4447- indclass = atooid (indinfo [i ].indclass [nclass ]);
4448- if (indclass == 0 )
4449- break ;
4450- resetPQExpBuffer (q );
4451- appendPQExpBuffer (q ,
4452- "SELECT opcname from pg_opclass "
4453- "where pg_opclass.oid = '%u'::oid" ,
4454- indclass );
4455- res = PQexec (g_conn ,q -> data );
4456- if (!res || PQresultStatus (res )!= PGRES_TUPLES_OK )
4457- {
4458- write_msg (NULL ,"query to get operator class name of oid %u failed: %s" ,
4459- indclass ,PQerrorMessage (g_conn ));
4460- exit_nicely ();
4461- }
4462-
4463- /* Sanity: Check we got only one tuple */
4464- numRows = PQntuples (res );
4465- if (numRows != 1 )
4466- {
4467- write_msg (NULL ,"query to get operator class name of oid %u returned %d rows; expected 1\n" ,
4468- indclass ,numRows );
4469- exit_nicely ();
4470- }
4471-
4472- classname [nclass ]= strdup (PQgetvalue (res ,0 ,PQfnumber (res ,"opcname" )));
4473- PQclear (res );
4474- }
4475-
4476- if (funcname && nclass != 1 )
4477- {
4478- write_msg (NULL ,"There must be exactly one OpClass for functional index \"%s\".\n" ,
4479- indinfo [i ].indexrelname );
4480- exit_nicely ();
4481- }
4482-
4483- /* convert attribute numbers into attribute list */
4484- resetPQExpBuffer (attlist );
4485- for (k = 0 ;k < INDEX_MAX_KEYS ;k ++ )
4486- {
4487- int indkey ;
4488- const char * attname ;
4489-
4490- indkey = atoi (indinfo [i ].indkey [k ]);
4491- if (indkey == InvalidAttrNumber )
4492- break ;
4493- attname = getAttrName (indkey ,& tblinfo [tableInd ]);
4494- if (funcname )
4495- appendPQExpBuffer (attlist ,"%s%s" ,
4496- (k == 0 ) ?"" :", " ,
4497- fmtId (attname ,force_quotes ));
4498- else
4499- {
4500- if (k >=nclass )
4501- {
4502- write_msg (NULL ,"no operator class found for column \"%s\" of index \"%s\"\n" ,
4503- attname ,indinfo [i ].indexrelname );
4504- exit_nicely ();
4505- }
4506- resetPQExpBuffer (id1 );
4507- resetPQExpBuffer (id2 );
4508- appendPQExpBuffer (id1 ,fmtId (attname ,force_quotes ));
4509- appendPQExpBuffer (id2 ,fmtId (classname [k ],force_quotes ));
4510- appendPQExpBuffer (attlist ,"%s%s %s" ,
4511- (k == 0 ) ?"" :", " ,
4512- id1 -> data ,id2 -> data );
4513- free (classname [k ]);
4514- }
4515- }
4516-
4517- if (!tablename || (strcmp (indinfo [i ].indrelname ,tablename )== 0 )|| (strlen (tablename )== 0 ))
4518- {
4519- resetPQExpBuffer (id1 );
4520- resetPQExpBuffer (id2 );
4521- appendPQExpBuffer (id1 ,fmtId (indinfo [i ].indexrelname ,force_quotes ));
4522- appendPQExpBuffer (id2 ,fmtId (indinfo [i ].indrelname ,force_quotes ));
4523-
4524- resetPQExpBuffer (delq );
4525- appendPQExpBuffer (delq ,"DROP INDEX %s;\n" ,id1 -> data );
4526-
4527- resetPQExpBuffer (q );
4528- appendPQExpBuffer (q ,"CREATE %s INDEX %s on %s using %s (" ,
4529- (strcmp (indinfo [i ].indisunique ,"t" )== 0 ) ?"UNIQUE" :"" ,
4530- id1 -> data ,
4531- id2 -> data ,
4532- indinfo [i ].indamname );
4533- if (funcname )
4534- {
4535- /* need 2 printf's here cuz fmtId has static return area */
4536- appendPQExpBuffer (q ," %s" ,fmtId (funcname , false));
4537- appendPQExpBuffer (q ," (%s) %s )" ,attlist -> data ,
4538- fmtId (classname [0 ],force_quotes ));
4539- free (funcname );
4540- free (classname [0 ]);
4541- }
4542- else
4543- appendPQExpBuffer (q ," %s )" ,attlist -> data );
4544-
4545- if (strcmp (indinfo [i ].indhaspred ,"t" )== 0 )
4546- {
4547- /* There is an index predicate, so fetch and dump it */
4548- int numRows ;
4549- PQExpBuffer pred = createPQExpBuffer ();
4550-
4551- appendPQExpBuffer (pred ,"SELECT pg_get_expr(indpred,indrelid) as pred FROM pg_index WHERE indexrelid = '%s'::oid" ,
4552- indinfo [i ].indexreloid );
4553- res = PQexec (g_conn ,pred -> data );
4554- if (!res || PQresultStatus (res )!= PGRES_TUPLES_OK )
4555- {
4556- fprintf (stderr ,"dumpIndices(): SELECT (indpred) failed. "
4557- "Explanation from backend: '%s'.\n" ,
4558- PQerrorMessage (g_conn ));
4559- exit_nicely ();
4560- }
4561-
4562- /* Sanity: Check we got only one tuple */
4563- numRows = PQntuples (res );
4564- if (numRows != 1 )
4565- {
4566- fprintf (stderr ,"dumpIndices(): SELECT (indpred) for index %s returned %d tuples. Expected 1.\n" ,
4567- indinfo [i ].indrelname ,numRows );
4568- exit_nicely ();
4569- }
4570-
4571- appendPQExpBuffer (q ," WHERE %s" ,
4572- PQgetvalue (res ,0 ,PQfnumber (res ,"pred" )));
4573-
4574- PQclear (res );
4575- destroyPQExpBuffer (pred );
4576- }
4577- appendPQExpBuffer (q ,";\n" );
4376+ resetPQExpBuffer (q );
4377+ appendPQExpBuffer (q ,"%s;\n" ,indinfo [i ].indexdef );
45784378
4579- /*
4580- * We make the index belong to the owner of its table, which
4581- * is not necessarily right but should answer 99% of the time.
4582- * Would have to add owner name to IndInfo to do it right.
4583- */
4584- ArchiveEntry (fout ,indinfo [i ].indexreloid ,id1 -> data ,
4585- "INDEX" ,NULL ,q -> data ,delq -> data ,
4586- "" ,tblinfo [tableInd ].usename ,NULL ,NULL );
4379+ resetPQExpBuffer (delq );
4380+ appendPQExpBuffer (delq ,"DROP INDEX %s;\n" ,id1 -> data );
45874381
4588- /* Dump Index Comments */
4589- resetPQExpBuffer (q );
4590- appendPQExpBuffer (q ,"INDEX %s" ,id1 -> data );
4591- dumpComment (fout ,q -> data ,indinfo [i ].indexreloid ,
4592- "pg_class" ,0 ,NULL );
4382+ /*
4383+ * We make the index belong to the owner of its table, which
4384+ * is not necessarily right but should answer 99% of the time.
4385+ * Would have to add owner name to IndInfo to do it right.
4386+ */
4387+ ArchiveEntry (fout ,indinfo [i ].indexreloid ,id1 -> data ,
4388+ "INDEX" ,NULL ,q -> data ,delq -> data ,
4389+ "" ,tblinfo [tableInd ].usename ,NULL ,NULL );
45934390
4594- }
4391+ /* Dump Index Comments */
4392+ resetPQExpBuffer (q );
4393+ appendPQExpBuffer (q ,"INDEX %s" ,id1 -> data );
4394+ dumpComment (fout ,q -> data ,indinfo [i ].indexreloid ,
4395+ "pg_class" ,0 ,NULL );
45954396}
45964397
4597- destroyPQExpBuffer (attlist );
45984398destroyPQExpBuffer (q );
45994399destroyPQExpBuffer (delq );
46004400destroyPQExpBuffer (id1 );
4601- destroyPQExpBuffer (id2 );
46024401}
46034402
46044403/*