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

« back to all changes in this revision

Viewing changes to src/backend/access/heap/heapam.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:
8
8
 *
9
9
 *
10
10
 * IDENTIFICATION
11
 
 *        $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.277 2009/06/11 14:48:53 momjian Exp $
 
11
 *        $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.277.2.1 2009/08/24 02:18:40 tgl Exp $
12
12
 *
13
13
 *
14
14
 * INTERFACE ROUTINES
78
78
                                                bool allow_strat, bool allow_sync,
79
79
                                                bool is_bitmapscan);
80
80
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
81
 
                   ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move);
 
81
                   ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move,
 
82
                   bool all_visible_cleared, bool new_all_visible_cleared);
82
83
static bool HeapSatisfiesHOTUpdate(Relation relation, Bitmapset *hot_attrs,
83
84
                                           HeapTuple oldtup, HeapTuple newtup);
84
85
 
2760
2761
        /* record address of new tuple in t_ctid of old one */
2761
2762
        oldtup.t_data->t_ctid = heaptup->t_self;
2762
2763
 
 
2764
        /* clear PD_ALL_VISIBLE flags */
 
2765
        if (PageIsAllVisible(BufferGetPage(buffer)))
 
2766
        {
 
2767
                all_visible_cleared = true;
 
2768
                PageClearAllVisible(BufferGetPage(buffer));
 
2769
        }
 
2770
        if (newbuf != buffer && PageIsAllVisible(BufferGetPage(newbuf)))
 
2771
        {
 
2772
                all_visible_cleared_new = true;
 
2773
                PageClearAllVisible(BufferGetPage(newbuf));
 
2774
        }
 
2775
 
2763
2776
        if (newbuf != buffer)
2764
2777
                MarkBufferDirty(newbuf);
2765
2778
        MarkBufferDirty(buffer);
2766
2779
 
2767
 
        /*
2768
 
         * Note: we mustn't clear PD_ALL_VISIBLE flags before writing the WAL
2769
 
         * record, because log_heap_update looks at those flags to set the
2770
 
         * corresponding flags in the WAL record.
2771
 
         */
2772
 
 
2773
2780
        /* XLOG stuff */
2774
2781
        if (!relation->rd_istemp)
2775
2782
        {
2776
2783
                XLogRecPtr      recptr = log_heap_update(relation, buffer, oldtup.t_self,
2777
 
                                                                                         newbuf, heaptup, false);
 
2784
                                                                                         newbuf, heaptup, false,
 
2785
                                                                                         all_visible_cleared,
 
2786
                                                                                         all_visible_cleared_new);
2778
2787
 
2779
2788
                if (newbuf != buffer)
2780
2789
                {
2785
2794
                PageSetTLI(BufferGetPage(buffer), ThisTimeLineID);
2786
2795
        }
2787
2796
 
2788
 
        /* Clear PD_ALL_VISIBLE flags */
2789
 
        if (PageIsAllVisible(BufferGetPage(buffer)))
2790
 
        {
2791
 
                all_visible_cleared = true;
2792
 
                PageClearAllVisible(BufferGetPage(buffer));
2793
 
        }
2794
 
        if (newbuf != buffer && PageIsAllVisible(BufferGetPage(newbuf)))
2795
 
        {
2796
 
                all_visible_cleared_new = true;
2797
 
                PageClearAllVisible(BufferGetPage(newbuf));
2798
 
        }
2799
 
 
2800
2797
        END_CRIT_SECTION();
2801
2798
 
2802
2799
        if (newbuf != buffer)
3910
3907
 */
3911
3908
static XLogRecPtr
3912
3909
log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
3913
 
                                Buffer newbuf, HeapTuple newtup, bool move)
 
3910
                                Buffer newbuf, HeapTuple newtup, bool move,
 
3911
                                bool all_visible_cleared, bool new_all_visible_cleared)
3914
3912
{
3915
3913
        /*
3916
3914
         * Note: xlhdr is declared to have adequate size and correct alignment for
3946
3944
 
3947
3945
        xlrec.target.node = reln->rd_node;
3948
3946
        xlrec.target.tid = from;
3949
 
        xlrec.all_visible_cleared = PageIsAllVisible(BufferGetPage(oldbuf));
 
3947
        xlrec.all_visible_cleared = all_visible_cleared;
3950
3948
        xlrec.newtid = newtup->t_self;
3951
 
        xlrec.new_all_visible_cleared = PageIsAllVisible(BufferGetPage(newbuf));
 
3949
        xlrec.new_all_visible_cleared = new_all_visible_cleared;
3952
3950
 
3953
3951
        rdata[0].data = (char *) &xlrec;
3954
3952
        rdata[0].len = SizeOfHeapUpdate;
4015
4013
 */
4016
4014
XLogRecPtr
4017
4015
log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
4018
 
                          Buffer newbuf, HeapTuple newtup)
 
4016
                          Buffer newbuf, HeapTuple newtup,
 
4017
                          bool all_visible_cleared, bool new_all_visible_cleared)
4019
4018
{
4020
 
        return log_heap_update(reln, oldbuf, from, newbuf, newtup, true);
 
4019
        return log_heap_update(reln, oldbuf, from, newbuf, newtup, true,
 
4020
                                                   all_visible_cleared, new_all_visible_cleared);
4021
4021
}
4022
4022
 
4023
4023
/*
4222
4222
        blkno = ItemPointerGetBlockNumber(&(xlrec->target.tid));
4223
4223
 
4224
4224
        /*
4225
 
         * The visibility map always needs to be updated, even if the heap page is
 
4225
         * The visibility map may need to be fixed even if the heap page is
4226
4226
         * already up-to-date.
4227
4227
         */
4228
4228
        if (xlrec->all_visible_cleared)
4300
4300
        blkno = ItemPointerGetBlockNumber(&(xlrec->target.tid));
4301
4301
 
4302
4302
        /*
4303
 
         * The visibility map always needs to be updated, even if the heap page is
 
4303
         * The visibility map may need to be fixed even if the heap page is
4304
4304
         * already up-to-date.
4305
4305
         */
4306
4306
        if (xlrec->all_visible_cleared)
4412
4412
        Size            freespace;
4413
4413
 
4414
4414
        /*
4415
 
         * The visibility map always needs to be updated, even if the heap page is
 
4415
         * The visibility map may need to be fixed even if the heap page is
4416
4416
         * already up-to-date.
4417
4417
         */
4418
4418
        if (xlrec->all_visible_cleared)
4507
4507
newt:;
4508
4508
 
4509
4509
        /*
4510
 
         * The visibility map always needs to be updated, even if the heap page is
 
4510
         * The visibility map may need to be fixed even if the heap page is
4511
4511
         * already up-to-date.
4512
4512
         */
4513
4513
        if (xlrec->new_all_visible_cleared)