2222 *
2323 *
2424 * IDENTIFICATION
25- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.168 2000/09/18 06:47:46 pjw Exp $
25+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.169 2000/10/10 13:55:28 pjw Exp $
2626 *
2727 * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
2828 *
8787 *Remove 'isViewRule' since we check the relkind when getting tables.
8888 *Now uses temp table 'pgdump_oid' rather than 'pg_dump_oid' (errors otherwise).
8989 *
90+ * Modifications - 02-Oct-2000 - pjw@rhyme.com.au
91+ *
92+ * - Be more paranoid when getting views: call get_viewdef in separate statement
93+ *so we can be more informative in error messages.
94+ * - Support for 'isstrict' procedure attribute.
95+ * - Disable --blobs and --table since (a) it's a pain to get ONLY the blobs for the
96+ *table with the currently implementation, and (b) it's not clear how to restore
97+ *a partial BLOB backup (given the current OID-based BLOB implementation).
98+ *
9099 *-------------------------------------------------------------------------
91100 */
92101
@@ -702,6 +711,7 @@ main(int argc, char **argv)
702711case 'a' :/* Dump data only */
703712dataOnly = true;
704713break ;
714+
705715case 'b' :/* Dump blobs */
706716outputBlobs = true;
707717break ;
@@ -719,48 +729,63 @@ main(int argc, char **argv)
719729case 'd' :/* dump data as proper insert strings */
720730dumpData = true;
721731break ;
732+
722733case 'D' :/* dump data as proper insert strings with
723734 * attr names */
724735dumpData = true;
725736attrNames = true;
726737break ;
738+
727739case 'f' :
728740filename = optarg ;
729741break ;
742+
730743case 'F' :
731744format = optarg ;
732745break ;
746+
733747case 'h' :/* server host */
734748pghost = optarg ;
735749break ;
750+
736751case 'i' :/* ignore database version mismatch */
737752ignore_version = true;
738753break ;
754+
739755case 'n' :/* Do not force double-quotes on
740756 * identifiers */
741757force_quotes = false;
742758break ;
759+
743760case 'N' :/* Force double-quotes on identifiers */
744761force_quotes = true;
745762break ;
763+
746764case 'o' :/* Dump oids */
747765oids = true;
748766break ;
767+
768+
749769case 'O' :/* Don't reconnect to match owner */
750770outputNoOwner = 1 ;
751771break ;
772+
752773case 'p' :/* server port */
753774pgport = optarg ;
754775break ;
776+
755777case 'R' :/* No reconnect */
756778outputNoReconnect = 1 ;
757779break ;
780+
758781case 's' :/* dump schema only */
759782schemaOnly = true;
760783break ;
784+
761785case 'S' :/* Username for superuser in plain text output */
762786outputSuperuser = strdup (optarg );
763787break ;
788+
764789case 't' :/* Dump data for this table only */
765790{
766791int i ;
@@ -787,22 +812,28 @@ main(int argc, char **argv)
787812}
788813}
789814break ;
815+
790816case 'u' :
791817use_password = true;
792818break ;
819+
793820case 'v' :/* verbose */
794821g_verbose = true;
795822break ;
823+
796824case 'x' :/* skip ACL dump */
797825aclsSkip = true;
798826break ;
827+
799828case 'Z' :/* Compression Level */
800829compressLevel = atoi (optarg );
801830break ;
831+
802832case 'V' :
803833version ();
804834exit (0 );
805835break ;
836+
806837case '?' :
807838
808839/*
@@ -841,6 +872,14 @@ main(int argc, char **argv)
841872exit (1 );
842873}
843874
875+ if (outputBlobs && (tablename != NULL ) )
876+ {
877+ fprintf (stderr ,
878+ "%s: BLOB output is not supported for a single table. Use a full dump instead.\n" ,
879+ progname );
880+ exit (1 );
881+ }
882+
844883if (dumpData == true&& oids == true)
845884{
846885fprintf (stderr ,
@@ -1713,6 +1752,7 @@ getFuncs(int *numFuncs)
17131752int i_prosrc ;
17141753int i_probin ;
17151754int i_iscachable ;
1755+ int i_isstrict ;
17161756int i_usename ;
17171757
17181758/* find all user-defined funcs */
@@ -1721,7 +1761,7 @@ getFuncs(int *numFuncs)
17211761"SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
17221762"proretset, proargtypes, prosrc, probin, "
17231763"(select usename from pg_user where proowner = usesysid) as usename, "
1724- "proiscachable "
1764+ "proiscachable, proisstrict "
17251765"from pg_proc "
17261766"where pg_proc.oid > '%u'::oid" ,
17271767g_last_builtin_oid );
@@ -1753,6 +1793,7 @@ getFuncs(int *numFuncs)
17531793i_prosrc = PQfnumber (res ,"prosrc" );
17541794i_probin = PQfnumber (res ,"probin" );
17551795i_iscachable = PQfnumber (res ,"proiscachable" );
1796+ i_isstrict = PQfnumber (res ,"proisstrict" );
17561797i_usename = PQfnumber (res ,"usename" );
17571798
17581799for (i = 0 ;i < ntups ;i ++ )
@@ -1769,6 +1810,7 @@ getFuncs(int *numFuncs)
17691810finfo [i ].lang = atoi (PQgetvalue (res ,i ,i_prolang ));
17701811finfo [i ].usename = strdup (PQgetvalue (res ,i ,i_usename ));
17711812finfo [i ].iscachable = (strcmp (PQgetvalue (res ,i ,i_iscachable ),"t" )== 0 );
1813+ finfo [i ].isstrict = (strcmp (PQgetvalue (res ,i ,i_isstrict ),"t" )== 0 );
17721814
17731815if (strlen (finfo [i ].usename )== 0 )
17741816fprintf (stderr ,"WARNING: owner of function '%s' appears to be invalid\n" ,
@@ -1819,7 +1861,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
18191861int i_relchecks ;
18201862int i_reltriggers ;
18211863int i_relhasindex ;
1822- int i_viewdef ;
18231864
18241865char relkindview [2 ];
18251866
@@ -1839,9 +1880,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
18391880appendPQExpBuffer (query ,
18401881"SELECT pg_class.oid, relname, relkind, relacl, "
18411882"(select usename from pg_user where relowner = usesysid) as usename, "
1842- "relchecks, reltriggers, relhasindex, "
1843- "Case When relkind = '%c' then pg_get_viewdef(relname) "
1844- "Else NULL End as viewdef "
1883+ "relchecks, reltriggers, relhasindex "
18451884"from pg_class "
18461885"where relname !~ '^pg_' "
18471886"and relkind in ('%c', '%c', '%c') "
@@ -1872,7 +1911,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
18721911i_relchecks = PQfnumber (res ,"relchecks" );
18731912i_reltriggers = PQfnumber (res ,"reltriggers" );
18741913i_relhasindex = PQfnumber (res ,"relhasindex" );
1875- i_viewdef = PQfnumber (res ,"viewdef" );
18761914
18771915for (i = 0 ;i < ntups ;i ++ )
18781916{
@@ -1883,16 +1921,52 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
18831921tblinfo [i ].usename = strdup (PQgetvalue (res ,i ,i_usename ));
18841922tblinfo [i ].ncheck = atoi (PQgetvalue (res ,i ,i_relchecks ));
18851923tblinfo [i ].ntrig = atoi (PQgetvalue (res ,i ,i_reltriggers ));
1886- if (strcmp (PQgetvalue (res ,i ,i_relkind ),relkindview )== 0 ) {
1887- tblinfo [i ].viewdef = strdup (PQgetvalue (res ,i ,i_viewdef ));
1888- }else {
1889- tblinfo [i ].viewdef = NULL ;
1890- }
18911924
18921925if (strlen (tblinfo [i ].usename )== 0 )
18931926fprintf (stderr ,"WARNING: owner of table '%s' appears to be invalid\n" ,
18941927tblinfo [i ].relname );
18951928
1929+ /* Get view definition */
1930+ if (strcmp (PQgetvalue (res ,i ,i_relkind ),relkindview )== 0 )
1931+ {
1932+ PGresult * res2 ;
1933+
1934+ resetPQExpBuffer (query );
1935+ appendPQExpBuffer (query ,"SELECT pg_get_viewdef('%s') as viewdef " ,tblinfo [i ].relname );
1936+ res2 = PQexec (g_conn ,query -> data );
1937+ if (!res2 || PQresultStatus (res2 )!= PGRES_TUPLES_OK )
1938+ {
1939+ fprintf (stderr ,"getTables(): SELECT (for VIEW DEFINITION) failed. "
1940+ "Explanation from backend: %s" ,
1941+ PQerrorMessage (g_conn ));
1942+ exit_nicely (g_conn );
1943+ }
1944+
1945+ if (PQntuples (res2 )!= 1 )
1946+ {
1947+ if (PQntuples (res2 )< 1 )
1948+ {
1949+ fprintf (stderr ,"getTables(): SELECT (for VIEW %s) returned no definitions" ,
1950+ tblinfo [i ].relname );
1951+ }else {
1952+ fprintf (stderr ,"getTables(): SELECT (for VIEW %s) returned more than 1 definition" ,
1953+ tblinfo [i ].relname );
1954+ }
1955+ exit_nicely (g_conn );
1956+ }
1957+
1958+ tblinfo [i ].viewdef = strdup (PQgetvalue (res2 ,0 ,0 ));
1959+
1960+ if (strlen (tblinfo [i ].viewdef )== 0 )
1961+ {
1962+ fprintf (stderr ,"getTables(): SELECT (for VIEW %s) returned empty definition" ,
1963+ tblinfo [i ].relname );
1964+ exit_nicely (g_conn );
1965+ }
1966+ }
1967+ else
1968+ tblinfo [i ].viewdef = NULL ;
1969+
18961970/*
18971971 * Exclude inherited CHECKs from CHECK constraints total. If a
18981972 * constraint matches by name and condition with a constraint
@@ -2888,6 +2962,10 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
28882962int i_lanname ;
28892963char query [256 ];
28902964
2965+ char * listSep ;
2966+ char * listSepComma = "," ;
2967+ char * listSepNone = "" ;
2968+
28912969if (finfo [i ].dumped )
28922970return ;
28932971else
@@ -2961,9 +3039,21 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
29613039findTypeByOid (tinfo ,numTypes ,finfo [i ].prorettype ,zeroAsOpaque ),
29623040asPart -> data ,func_lang );
29633041
2964- if (finfo [i ].iscachable )/* OR in new attrs here */
3042+ if (finfo [i ].iscachable || finfo [ i ]. isstrict )/* OR in new attrs here */
29653043{
2966- appendPQExpBuffer (q ," WITH (iscachable)" );
3044+ appendPQExpBuffer (q ," WITH (" );
3045+ listSep = listSepNone ;
3046+
3047+ if (finfo [i ].iscachable ) {
3048+ appendPQExpBuffer (q ,"%s iscachable" ,listSep );
3049+ listSep = listSepComma ;
3050+ }
3051+
3052+ if (finfo [i ].isstrict ) {
3053+ appendPQExpBuffer (q ,"%s isstrict" ,listSep );
3054+ listSep = listSepComma ;
3055+ }
3056+ appendPQExpBuffer (q ," )" );
29673057}
29683058
29693059appendPQExpBuffer (q ,";\n" );