~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to src/bin/pg_dump/pg_dump.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-09-06 14:11:13 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090906141113-qf5f3hkw7n036jfy
Tags: 8.4.1-1
* Urgency medium due to security fix.
* New upstream security/bug fix release:
  - Disallow "RESET ROLE" and "RESET SESSION AUTHORIZATION" inside
    security-definer functions. This covers a case that was missed in the
    previous patch that disallowed "SET ROLE" and "SET SESSION
    AUTHORIZATION" inside security-definer functions. [CVE-2007-6600]
  - Fix WAL page header initialization at the end of archive recovery.
    This could lead to failure to process the WAL in a subsequent archive
    recovery.
  - Fix "cannot make new WAL entries during recovery" error.
  - Fix problem that could make expired rows visible after a crash.
    This bug involved a page status bit potentially not being set
    correctly after a server crash.
  - Make "LOAD" of an already-loaded loadable module into a no-op.
    Formerly, "LOAD" would attempt to unload and re-load the module,
    but this is unsafe and not all that useful.
  - Make window function PARTITION BY and ORDER BY items always be
    interpreted as simple expressions.
    In 8.4.0 these lists were parsed following the rules used for
    top-level GROUP BY and ORDER BY lists. But this was not correct per
    the SQL standard, and it led to possible circularity.
  - Fix several errors in planning of semi-joins. These led to wrong query
    results in some cases where IN or EXISTS was used together with another
    join.
  - Fix handling of whole-row references to subqueries that are within
    an outer join. An example is SELECT COUNT(ss.-) FROM ... LEFT JOIN
    (SELECT ...) ss ON .... Here, ss.- would be treated as
    ROW(NULL,NULL,...) for null-extended join rows, which is not the same as
    a simple NULL.  Now it is treated as a simple NULL.
  - Fix locale handling with plperl. This bug could cause the server's
    locale setting to change when a plperl function is called, leading to
    data corruption.
  - Fix handling of reloptions to ensure setting one option doesn't
    force default values for others.
  - Ensure that a "fast shutdown" request will forcibly terminate open
    sessions, even if a "smart shutdown" was already in progress.
  - Avoid memory leak for array_agg() in GROUP BY queries.
  - Treat to_char(..., 'TH') as an uppercase ordinal suffix with
    'HH'/'HH12'.  It was previously handled as 'th'.
  - Include the fractional part in the result of EXTRACT(second) and
    EXTRACT(milliseconds) for time and time with time zone inputs.
    This has always worked for floating-point datetime configurations,
    but was broken in the integer datetime code.
  - Fix overflow for INTERVAL 'x ms' when "x" is more than 2 million
    and integer datetimes are in use.
  - Improve performance when processing toasted values in index scans.
    This is particularly useful for PostGIS.
  - Fix a typo that disabled commit_delay.
  - Output early-startup messages to "postmaster.log" if the server is
    started in silent mode. Previously such error messages were discarded,
    leading to difficulty in debugging.
  - Remove translated FAQs. They are now on the wiki. The main FAQ was moved
    to the wiki some time ago.
  - Fix pg_ctl to not go into an infinite loop if "postgresql.conf" is
    empty.
  - Fix several errors in pg_dump's --binary-upgrade mode. pg_dump
    --binary-upgrade is used by pg_migrator.
  - Fix "contrib/xml2"'s xslt_process() to properly handle the maximum
    number of parameters (twenty).
  - Improve robustness of libpq's code to recover from errors during
    "COPY FROM STDIN".
  - Avoid including conflicting readline and editline header files when
    both libraries are installed.
  - Work around gcc bug that causes "floating-point exception" instead
    of "division by zero" on some platforms.
* debian/control: Bump Standards-Version to 3.8.3 (no changes necessary).

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 *      by PostgreSQL
13
13
 *
14
14
 * IDENTIFICATION
15
 
 *        $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.539 2009/06/11 14:49:07 momjian Exp $
 
15
 *        $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.539.2.2 2009/07/20 20:53:47 momjian Exp $
16
16
 *
17
17
 *-------------------------------------------------------------------------
18
18
 */
34
34
#include "access/sysattr.h"
35
35
#include "catalog/pg_cast.h"
36
36
#include "catalog/pg_class.h"
 
37
#include "catalog/pg_largeobject.h"
37
38
#include "catalog/pg_proc.h"
38
39
#include "catalog/pg_trigger.h"
39
40
#include "catalog/pg_type.h"
233
234
        static int      outputNoTablespaces = 0;
234
235
        static int      use_setsessauth = 0;
235
236
 
236
 
        struct option long_options[] = {
 
237
        static struct option long_options[] = {
237
238
                {"data-only", no_argument, NULL, 'a'},
238
239
                {"blobs", no_argument, NULL, 'b'},
239
240
                {"clean", no_argument, NULL, 'c'},
1733
1734
        if (binary_upgrade)
1734
1735
        {
1735
1736
                appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
1736
 
                appendPQExpBuffer(creaQry, "UPDATE pg_database\n"
 
1737
                appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
1737
1738
                                                  "SET datfrozenxid = '%u'\n"
1738
1739
                                                  "WHERE        datname = ",
1739
1740
                                                  frozenxid);
1740
1741
                appendStringLiteralAH(creaQry, datname, AH);
1741
1742
                appendPQExpBuffer(creaQry, ";\n");
 
1743
 
1742
1744
        }
1743
1745
 
1744
1746
        appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
1764
1766
                                 NULL,                  /* Dumper */
1765
1767
                                 NULL);                 /* Dumper Arg */
1766
1768
 
 
1769
        /*
 
1770
         *      pg_largeobject comes from the old system intact, so set
 
1771
         *      its relfrozenxid.
 
1772
         */
 
1773
        if (binary_upgrade)
 
1774
        {
 
1775
                PGresult   *lo_res;
 
1776
                PQExpBuffer loFrozenQry = createPQExpBuffer();
 
1777
                PQExpBuffer loOutQry = createPQExpBuffer();
 
1778
                int                     i_relfrozenxid;
 
1779
                
 
1780
                appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
 
1781
                                                        "FROM pg_catalog.pg_class\n"
 
1782
                                                        "WHERE oid = %d;\n",
 
1783
                                                        LargeObjectRelationId);
 
1784
 
 
1785
                lo_res = PQexec(g_conn, loFrozenQry->data);
 
1786
                check_sql_result(lo_res, g_conn, loFrozenQry->data, PGRES_TUPLES_OK);
 
1787
 
 
1788
                if (PQntuples(lo_res) != 1)
 
1789
                {
 
1790
                        write_msg(NULL, "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n");
 
1791
                        exit_nicely();
 
1792
                }
 
1793
 
 
1794
                i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
 
1795
 
 
1796
                appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid.\n");
 
1797
                appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
 
1798
                                                  "SET relfrozenxid = '%u'\n"
 
1799
                                                  "WHERE oid = %d;\n",
 
1800
                                                  atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
 
1801
                                                  LargeObjectRelationId);
 
1802
                ArchiveEntry(AH, nilCatalogId, createDumpId(),
 
1803
                                         "pg_largeobject", NULL, NULL, "",
 
1804
                                         false, "pg_largeobject", SECTION_PRE_DATA,
 
1805
                                         loOutQry->data, "", NULL,
 
1806
                                         NULL, 0,
 
1807
                                         NULL, NULL);
 
1808
                                                  
 
1809
                PQclear(lo_res);
 
1810
                destroyPQExpBuffer(loFrozenQry);
 
1811
                destroyPQExpBuffer(loOutQry);
 
1812
        }
 
1813
 
1767
1814
        /* Dump DB comment if any */
1768
1815
        if (g_fout->remoteVersion >= 80200)
1769
1816
        {
4712
4759
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, "
4713
4760
                                                   "a.atttypmod, -1 AS attstattarget, a.attstorage, "
4714
4761
                                                          "t.typstorage, a.attnotnull, a.atthasdef, "
4715
 
                                                          "false AS attisdropped, 0 AS attlen, "
4716
 
                                                          "' ' AS attalign, false AS attislocal, "
 
4762
                                                          "false AS attisdropped, a.attlen, "
 
4763
                                                          "a.attalign, false AS attislocal, "
4717
4764
                                                          "format_type(t.oid,a.atttypmod) AS atttypname "
4718
4765
                                                          "FROM pg_attribute a LEFT JOIN pg_type t "
4719
4766
                                                          "ON a.atttypid = t.oid "
4729
4776
                                                          "-1 AS attstattarget, attstorage, "
4730
4777
                                                          "attstorage AS typstorage, "
4731
4778
                                                          "attnotnull, atthasdef, false AS attisdropped, "
4732
 
                                                          "0 AS attlen, ' ' AS attalign, "
 
4779
                                                          "attlen, attalign, "
4733
4780
                                                          "false AS attislocal, "
4734
4781
                                                          "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname "
4735
4782
                                                          "FROM pg_attribute a "
4806
4853
 
4807
4854
                PQclear(res);
4808
4855
 
4809
 
 
4810
 
                /*
4811
 
                 * ALTER TABLE DROP COLUMN clears pg_attribute.atttypid, so we set the
4812
 
                 * column data type to 'TEXT;  we will later drop the column.
4813
 
                 */
4814
 
                if (binary_upgrade)
4815
 
                {
4816
 
                        for (j = 0; j < ntups; j++)
4817
 
                        {
4818
 
                                if (tbinfo->attisdropped[j])
4819
 
                                        tbinfo->atttypnames[j] = strdup("TEXT");
4820
 
                        }
4821
 
                }
4822
 
 
4823
4856
                /*
4824
4857
                 * Get info about column defaults
4825
4858
                 */
9783
9816
                actual_atts = 0;
9784
9817
                for (j = 0; j < tbinfo->numatts; j++)
9785
9818
                {
9786
 
                        /* Is this one of the table's own attrs, and not dropped ? */
9787
 
                        if (!tbinfo->inhAttrs[j] &&
9788
 
                                (!tbinfo->attisdropped[j] || binary_upgrade))
 
9819
                        /*
 
9820
                         * Normally, dump if it's one of the table's own attrs, and not
 
9821
                         * dropped.  But for binary upgrade, dump all the columns.
 
9822
                         */
 
9823
                        if ((!tbinfo->inhAttrs[j] && !tbinfo->attisdropped[j]) ||
 
9824
                                binary_upgrade)
9789
9825
                        {
9790
9826
                                /* Format properly if not first attr */
9791
9827
                                if (actual_atts > 0)
9792
9828
                                        appendPQExpBuffer(q, ",");
9793
9829
                                appendPQExpBuffer(q, "\n    ");
 
9830
                                actual_atts++;
9794
9831
 
9795
9832
                                /* Attribute name */
9796
9833
                                appendPQExpBuffer(q, "%s ",
9797
9834
                                                                  fmtId(tbinfo->attnames[j]));
9798
9835
 
 
9836
                                if (tbinfo->attisdropped[j])
 
9837
                                {
 
9838
                                        /*
 
9839
                                         * ALTER TABLE DROP COLUMN clears pg_attribute.atttypid,
 
9840
                                         * so we will not have gotten a valid type name; insert
 
9841
                                         * INTEGER as a stopgap.  We'll clean things up later.
 
9842
                                         */
 
9843
                                        appendPQExpBuffer(q, "INTEGER /* dummy */");
 
9844
                                        /* Skip all the rest, too */
 
9845
                                        continue;
 
9846
                                }
 
9847
 
9799
9848
                                /* Attribute type */
9800
9849
                                if (g_fout->remoteVersion >= 70100)
9801
9850
                                {
9811
9860
                                }
9812
9861
 
9813
9862
                                /*
9814
 
                                 * Default value --- suppress if inherited or to be printed
9815
 
                                 * separately.
 
9863
                                 * Default value --- suppress if inherited (except in
 
9864
                                 * binary-upgrade case, where we're not doing normal
 
9865
                                 * inheritance) or if it's to be printed separately.
9816
9866
                                 */
9817
9867
                                if (tbinfo->attrdefs[j] != NULL &&
9818
 
                                        !tbinfo->inhAttrDef[j] &&
 
9868
                                        (!tbinfo->inhAttrDef[j] || binary_upgrade) &&
9819
9869
                                        !tbinfo->attrdefs[j]->separate)
9820
9870
                                        appendPQExpBuffer(q, " DEFAULT %s",
9821
9871
                                                                          tbinfo->attrdefs[j]->adef_expr);
9822
9872
 
9823
9873
                                /*
9824
 
                                 * Not Null constraint --- suppress if inherited
 
9874
                                 * Not Null constraint --- suppress if inherited, except
 
9875
                                 * in binary-upgrade case.
9825
9876
                                 */
9826
 
                                if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
 
9877
                                if (tbinfo->notnull[j] &&
 
9878
                                        (!tbinfo->inhNotNull[j] || binary_upgrade))
9827
9879
                                        appendPQExpBuffer(q, " NOT NULL");
9828
 
 
9829
 
                                actual_atts++;
9830
9880
                        }
9831
9881
                }
9832
9882
 
9852
9902
 
9853
9903
                appendPQExpBuffer(q, "\n)");
9854
9904
 
9855
 
                if (numParents > 0)
 
9905
                if (numParents > 0 && !binary_upgrade)
9856
9906
                {
9857
9907
                        appendPQExpBuffer(q, "\nINHERITS (");
9858
9908
                        for (k = 0; k < numParents; k++)
9892
9942
                appendPQExpBuffer(q, ";\n");
9893
9943
 
9894
9944
                /*
9895
 
                 * For binary-compatible heap files, we create dropped columns above
9896
 
                 * and drop them here.
 
9945
                 * To create binary-compatible heap files, we have to ensure the
 
9946
                 * same physical column order, including dropped columns, as in the
 
9947
                 * original.  Therefore, we create dropped columns above and drop
 
9948
                 * them here, also updating their attlen/attalign values so that
 
9949
                 * the dropped column can be skipped properly.  (We do not bother
 
9950
                 * with restoring the original attbyval setting.)  Also, inheritance
 
9951
                 * relationships are set up by doing ALTER INHERIT rather than using
 
9952
                 * an INHERITS clause --- the latter would possibly mess up the
 
9953
                 * column order.  That also means we have to take care about setting
 
9954
                 * attislocal correctly, plus fix up any inherited CHECK constraints.
9897
9955
                 */
9898
9956
                if (binary_upgrade)
9899
9957
                {
9901
9959
                        {
9902
9960
                                if (tbinfo->attisdropped[j])
9903
9961
                                {
9904
 
                                        appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
9905
 
                                                                          fmtId(tbinfo->dobj.name));
9906
 
                                        appendPQExpBuffer(q, "DROP COLUMN %s;\n",
9907
 
                                                                          fmtId(tbinfo->attnames[j]));
9908
 
 
9909
 
                                        /*
9910
 
                                         * ALTER TABLE DROP COLUMN clears pg_attribute.atttypid,
9911
 
                                         * so we have to set pg_attribute.attlen and
9912
 
                                         * pg_attribute.attalign values because that is what is
9913
 
                                         * used to skip over dropped columns in the heap tuples.
9914
 
                                         * We have atttypmod, but it seems impossible to know the
9915
 
                                         * correct data type that will yield pg_attribute values
9916
 
                                         * that match the old installation. See comment in
9917
 
                                         * backend/catalog/heap.c::RemoveAttributeById()
9918
 
                                         */
9919
 
                                        appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column's length and alignment.\n");
9920
 
                                        appendPQExpBuffer(q, "UPDATE pg_attribute\n"
 
9962
                                        appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column.\n");
 
9963
                                        appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
9921
9964
                                                                          "SET attlen = %d, "
9922
 
                                                                          "attalign = '%c'\n"
9923
 
                                                                          "WHERE        attname = '%s'\n"
9924
 
                                                                          "     AND attrelid = \n"
9925
 
                                                                          "     (\n"
9926
 
                                                                          "             SELECT oid\n"
9927
 
                                                                          "             FROM pg_class\n"
9928
 
                                                                          "             WHERE   relnamespace = "
9929
 
                                                                          "(SELECT oid FROM pg_namespace "
9930
 
                                                                          "WHERE nspname = CURRENT_SCHEMA)\n"
9931
 
                                                                          "                     AND relname = ",
 
9965
                                                                          "attalign = '%c', attbyval = false\n"
 
9966
                                                                          "WHERE attname = ",
9932
9967
                                                                          tbinfo->attlen[j],
9933
 
                                                                          tbinfo->attalign[j],
9934
 
                                                                          tbinfo->attnames[j]);
9935
 
                                        appendStringLiteralAH(q, tbinfo->dobj.name, fout);
9936
 
                                        appendPQExpBuffer(q, "\n        );\n");
9937
 
                                }
9938
 
                        }
 
9968
                                                                          tbinfo->attalign[j]);
 
9969
                                        appendStringLiteralAH(q, tbinfo->attnames[j], fout);
 
9970
                                        appendPQExpBuffer(q, "\n  AND attrelid = ");
 
9971
                                        appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
 
9972
                                        appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
 
9973
 
 
9974
                                        appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
 
9975
                                                                          fmtId(tbinfo->dobj.name));
 
9976
                                        appendPQExpBuffer(q, "DROP COLUMN %s;\n",
 
9977
                                                                          fmtId(tbinfo->attnames[j]));
 
9978
                                }
 
9979
                                else if (!tbinfo->attislocal[j])
 
9980
                                {
 
9981
                                        appendPQExpBuffer(q, "\n-- For binary upgrade, recreate inherited column.\n");
 
9982
                                        appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
 
9983
                                                                          "SET attislocal = false\n"
 
9984
                                                                          "WHERE attname = ");
 
9985
                                        appendStringLiteralAH(q, tbinfo->attnames[j], fout);
 
9986
                                        appendPQExpBuffer(q, "\n  AND attrelid = ");
 
9987
                                        appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
 
9988
                                        appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
 
9989
                                }
 
9990
                        }
 
9991
 
 
9992
                        for (k = 0; k < tbinfo->ncheck; k++)
 
9993
                        {
 
9994
                                ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
 
9995
 
 
9996
                                if (constr->separate || constr->conislocal)
 
9997
                                        continue;
 
9998
 
 
9999
                                appendPQExpBuffer(q, "\n-- For binary upgrade, set up inherited constraint.\n");
 
10000
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
 
10001
                                                                  fmtId(tbinfo->dobj.name));
 
10002
                                appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
 
10003
                                                                  fmtId(constr->dobj.name));
 
10004
                                appendPQExpBuffer(q, "%s;\n", constr->condef);
 
10005
                                appendPQExpBuffer(q, "UPDATE pg_catalog.pg_constraint\n"
 
10006
                                                                  "SET conislocal = false\n"
 
10007
                                                                  "WHERE contype = 'c' AND conname = ");
 
10008
                                appendStringLiteralAH(q, constr->dobj.name, fout);
 
10009
                                appendPQExpBuffer(q, "\n  AND conrelid = ");
 
10010
                                appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
 
10011
                                appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
 
10012
                        }
 
10013
 
 
10014
                        if (numParents > 0)
 
10015
                        {
 
10016
                                appendPQExpBuffer(q, "\n-- For binary upgrade, set up inheritance this way.\n");
 
10017
                                for (k = 0; k < numParents; k++)
 
10018
                                {
 
10019
                                        TableInfo  *parentRel = parents[k];
 
10020
 
 
10021
                                        appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
 
10022
                                                                          fmtId(tbinfo->dobj.name));
 
10023
                                        if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
 
10024
                                                appendPQExpBuffer(q, "%s.",
 
10025
                                                                                  fmtId(parentRel->dobj.namespace->dobj.name));
 
10026
                                        appendPQExpBuffer(q, "%s;\n",
 
10027
                                                                          fmtId(parentRel->dobj.name));
 
10028
                                }
 
10029
                        }
 
10030
 
9939
10031
                        appendPQExpBuffer(q, "\n-- For binary upgrade, set relfrozenxid.\n");
9940
 
                        appendPQExpBuffer(q, "UPDATE pg_class\n"
 
10032
                        appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
9941
10033
                                                          "SET relfrozenxid = '%u'\n"
9942
 
                                                          "WHERE        relname = ",
 
10034
                                                          "WHERE oid = ",
9943
10035
                                                          tbinfo->frozenxid);
9944
 
                        appendStringLiteralAH(q, tbinfo->dobj.name, fout);
9945
 
                        appendPQExpBuffer(q, "\n        AND relnamespace = "
9946
 
                                                          "(SELECT oid FROM pg_namespace "
9947
 
                                                          "WHERE nspname = CURRENT_SCHEMA);\n");
 
10036
                        appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
 
10037
                        appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
9948
10038
                }
9949
10039
 
9950
10040
                /* Loop dumping statistics and storage statements */
10051
10141
        if (!tbinfo->dobj.dump || !adinfo->separate || dataOnly)
10052
10142
                return;
10053
10143
 
10054
 
        /* Don't print inherited defaults, either */
10055
 
        if (tbinfo->inhAttrDef[adnum - 1])
 
10144
        /* Don't print inherited defaults, either, except for binary upgrade */
 
10145
        if (tbinfo->inhAttrDef[adnum - 1] && !binary_upgrade)
10056
10146
                return;
10057
10147
 
10058
10148
        q = createPQExpBuffer();