~ubuntu-branches/ubuntu/quantal/postgresql-9.1/quantal-updates

« back to all changes in this revision

Viewing changes to src/backend/optimizer/plan/subselect.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-06-04 06:47:45 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20120604064745-dvs00jnur0vgkwqs
Tags: 9.1.4-1
* Urgency medium due to security fixes.
* New upstream bug fix/security release:
  - Fix incorrect password transformation in "contrib/pgcrypto"'s DES
    crypt() function.
    If a password string contained the byte value 0x80, the remainder
    of the password was ignored, causing the password to be much weaker
    than it appeared. With this fix, the rest of the string is properly
    included in the DES hash. Any stored password values that are
    affected by this bug will thus no longer match, so the stored
    values may need to be updated. (CVE-2012-2143)
  - Ignore SECURITY DEFINER and SET attributes for a procedural
    language's call handler. Applying such attributes to a call handler
    could crash the server. (CVE-2012-2655)
  - Make "contrib/citext"'s upgrade script fix collations of citext
    arrays and domains over citext.
    Release 9.1.2 provided a fix for collations of citext columns and
    indexes in databases upgraded or reloaded from pre-9.1
    installations, but that fix was incomplete: it neglected to handle
    arrays and domains over citext. This release extends the module's
    upgrade script to handle these cases. As before, if you have
    already run the upgrade script, you'll need to run the collation
    update commands by hand instead. See the 9.1.2 release notes for
    more information about doing this.
  - Allow numeric timezone offsets in timestamp input to be up to 16
    hours away from UTC. Some historical time zones have offsets larger than
    15 hours, the previous limit. This could result in dumped data values
    being rejected during reload.
  - Fix timestamp conversion to cope when the given time is exactly the
    last DST transition time for the current timezone.
    This oversight has been there a long time, but was not noticed
    previously because most DST-using zones are presumed to have an
    indefinite sequence of future DST transitions.
  - Fix text to name and char to name casts to perform string
    truncation correctly in multibyte encodings.
  - Fix memory copying bug in to_tsquery().
  - Ensure txid_current() reports the correct epoch when executed in
    hot standby.
  - Fix planner's handling of outer PlaceHolderVars within subqueries.
    This bug concerns sub-SELECTs that reference variables coming from
    the nullable side of an outer join of the surrounding query. In
    9.1, queries affected by this bug would fail with "ERROR:
    Upper-level PlaceHolderVar found where not expected". But in 9.0
    and 8.4, you'd silently get possibly-wrong answers, since the value
    transmitted into the subquery wouldn't go to null when it should.
  - Fix planning of UNION ALL subqueries with output columns that are
    not simple variables.
    Planning of such cases got noticeably worse in 9.1 as a result of a
    misguided fix for "MergeAppend child's targetlist doesn't match
    MergeAppend" errors. Revert that fix and do it another way.
  - Fix slow session startup when pg_attribute is very large.
    If pg_attribute exceeds one-fourth of shared_buffers, cache
    rebuilding code that is sometimes needed during session start would
    trigger the synchronized-scan logic, causing it to take many times
    longer than normal. The problem was particularly acute if many new
    sessions were starting at once.
  - Ensure sequential scans check for query cancel reasonably often.
    A scan encountering many consecutive pages that contain no live
    tuples would not respond to interrupts meanwhile.
  - Ensure the Windows implementation of PGSemaphoreLock() clears
    ImmediateInterruptOK before returning.
    This oversight meant that a query-cancel interrupt received later
    in the same query could be accepted at an unsafe time, with
    unpredictable but not good consequences.
  - Show whole-row variables safely when printing views or rules.
    Corner cases involving ambiguous names (that is, the name could be
    either a table or column name of the query) were printed in an
    ambiguous way, risking that the view or rule would be interpreted
    differently after dump and reload. Avoid the ambiguous case by
    attaching a no-op cast.
  - Fix "COPY FROM" to properly handle null marker strings that
    correspond to invalid encoding.
    A null marker string such as E'\\0' should work, and did work in
    the past, but the case got broken in 8.4.
  - Fix "EXPLAIN VERBOSE" for writable CTEs containing RETURNING
    clauses.
  - Fix "PREPARE TRANSACTION" to work correctly in the presence of
    advisory locks.
    Historically, "PREPARE TRANSACTION" has simply ignored any
    session-level advisory locks the session holds, but this case was
    accidentally broken in 9.1.
  - Fix truncation of unlogged tables.
  - Ignore missing schemas during non-interactive assignments of
    search_path.
    This re-aligns 9.1's behavior with that of older branches.
    Previously 9.1 would throw an error for nonexistent schemas
    mentioned in search_path settings obtained from places such as
    "ALTER DATABASE SET".
  - Fix bugs with temporary or transient tables used in extension
    scripts.
    This includes cases such as a rewriting "ALTER TABLE" within an
    extension update script, since that uses a transient table behind
    the scenes.
  - Ensure autovacuum worker processes perform stack depth checking
    properly.
    Previously, infinite recursion in a function invoked by
    auto-"ANALYZE" could crash worker processes.
  - Fix logging collector to not lose log coherency under high load.
    The collector previously could fail to reassemble large messages if
    it got too busy.
  - Fix logging collector to ensure it will restart file rotation after
    receiving SIGHUP.
  - Fix "too many LWLocks taken" failure in GiST indexes.
  - Fix WAL replay logic for GIN indexes to not fail if the index was
    subsequently dropped.
  - Correctly detect SSI conflicts of prepared transactions after a
    crash.
  - Avoid synchronous replication delay when committing a transaction
    that only modified temporary tables.
    In such a case the transaction's commit record need not be flushed
    to standby servers, but some of the code didn't know that and
    waited for it to happen anyway.
  - Fix error handling in pg_basebackup.
  - Fix walsender to not go into a busy loop if connection is
    terminated.
  - Fix memory leak in PL/pgSQL's "RETURN NEXT" command.
  - Fix PL/pgSQL's "GET DIAGNOSTICS" command when the target is the
    function's first variable.
  - Ensure that PL/Perl package-qualifies the _TD variable.
    This bug caused trigger invocations to fail when they are nested
    within a function invocation that changes the current package.
  - Fix PL/Python functions returning composite types to accept a
    string for their result value.
    This case was accidentally broken by the 9.1 additions to allow a
    composite result value to be supplied in other formats, such as
    dictionaries.
  - Fix potential access off the end of memory in psql's expanded
    display ("\x") mode.
  - Fix several performance problems in pg_dump when the database
    contains many objects.
    pg_dump could get very slow if the database contained many schemas,
    or if many objects are in dependency loops, or if there are many
    owned sequences.
  - Fix memory and file descriptor leaks in pg_restore when reading a
    directory-format archive.
  - Fix pg_upgrade for the case that a database stored in a non-default
    tablespace contains a table in the cluster's default tablespace.
  - In ecpg, fix rare memory leaks and possible overwrite of one byte
    after the sqlca_t structure.
  - Fix "contrib/dblink"'s dblink_exec() to not leak temporary database
    connections upon error.
  - Fix "contrib/dblink" to report the correct connection name in error
    messages.
  - Fix "contrib/vacuumlo" to use multiple transactions when dropping
    many large objects.
    This change avoids exceeding max_locks_per_transaction when many
    objects need to be dropped. The behavior can be adjusted with the
    new -l (limit) option.
* debian/control: Bump debhelper build dependency to >= 8, as it does not
  build with earlier versions.
* debian/control: Move bzr branches to alioth, so that other members of
  pkg-postgresql can commit. Update Vcs-* tags.
* debian/control: Set Maintainer: to pkg-postgresql group, and move myself
  to Uploaders:.

Show diffs side-by-side

added added

removed removed

Lines of Context:
193
193
}
194
194
 
195
195
/*
 
196
 * Select a PARAM_EXEC number to identify the given PlaceHolderVar.
 
197
 * If the PlaceHolderVar already has a param slot, return that one.
 
198
 *
 
199
 * This is just like assign_param_for_var, except for PlaceHolderVars.
 
200
 */
 
201
static int
 
202
assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
 
203
{
 
204
        ListCell   *ppl;
 
205
        PlannerParamItem *pitem;
 
206
        Index           abslevel;
 
207
        int                     i;
 
208
 
 
209
        abslevel = root->query_level - phv->phlevelsup;
 
210
 
 
211
        /* If there's already a paramlist entry for this same PHV, just use it */
 
212
        i = 0;
 
213
        foreach(ppl, root->glob->paramlist)
 
214
        {
 
215
                pitem = (PlannerParamItem *) lfirst(ppl);
 
216
                if (pitem->abslevel == abslevel && IsA(pitem->item, PlaceHolderVar))
 
217
                {
 
218
                        PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item;
 
219
 
 
220
                        /* We assume comparing the PHIDs is sufficient */
 
221
                        if (pphv->phid == phv->phid)
 
222
                                return i;
 
223
                }
 
224
                i++;
 
225
        }
 
226
 
 
227
        /* Nope, so make a new one */
 
228
        phv = (PlaceHolderVar *) copyObject(phv);
 
229
        if (phv->phlevelsup != 0)
 
230
        {
 
231
                IncrementVarSublevelsUp((Node *) phv, -((int) phv->phlevelsup), 0);
 
232
                Assert(phv->phlevelsup == 0);
 
233
        }
 
234
 
 
235
        pitem = makeNode(PlannerParamItem);
 
236
        pitem->item = (Node *) phv;
 
237
        pitem->abslevel = abslevel;
 
238
 
 
239
        root->glob->paramlist = lappend(root->glob->paramlist, pitem);
 
240
 
 
241
        /* i is already the correct list index for the new item */
 
242
        return i;
 
243
}
 
244
 
 
245
/*
 
246
 * Generate a Param node to replace the given PlaceHolderVar,
 
247
 * which is expected to have phlevelsup > 0 (ie, it is not local).
 
248
 *
 
249
 * This is just like replace_outer_var, except for PlaceHolderVars.
 
250
 */
 
251
static Param *
 
252
replace_outer_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
 
253
{
 
254
        Param      *retval;
 
255
        int                     i;
 
256
 
 
257
        Assert(phv->phlevelsup > 0 && phv->phlevelsup < root->query_level);
 
258
 
 
259
        /*
 
260
         * Find the PlaceHolderVar in root->glob->paramlist, or add it if not
 
261
         * present.
 
262
         */
 
263
        i = assign_param_for_placeholdervar(root, phv);
 
264
 
 
265
        retval = makeNode(Param);
 
266
        retval->paramkind = PARAM_EXEC;
 
267
        retval->paramid = i;
 
268
        retval->paramtype = exprType((Node *) phv->phexpr);
 
269
        retval->paramtypmod = exprTypmod((Node *) phv->phexpr);
 
270
        retval->paramcollid = exprCollation((Node *) phv->phexpr);
 
271
        retval->location = -1;
 
272
 
 
273
        return retval;
 
274
}
 
275
 
 
276
/*
196
277
 * Generate a Param node to replace the given PlaceHolderVar, which will be
197
278
 * supplied from an upper NestLoop join node.
198
279
 *
202
283
assign_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
203
284
{
204
285
        Param      *retval;
205
 
        ListCell   *ppl;
206
 
        PlannerParamItem *pitem;
207
 
        Index           abslevel;
208
286
        int                     i;
209
287
 
210
288
        Assert(phv->phlevelsup == 0);
211
 
        abslevel = root->query_level;
212
 
 
213
 
        /* If there's already a paramlist entry for this same PHV, just use it */
214
 
        /* We assume comparing the PHIDs is sufficient */
215
 
        i = 0;
216
 
        foreach(ppl, root->glob->paramlist)
217
 
        {
218
 
                pitem = (PlannerParamItem *) lfirst(ppl);
219
 
                if (pitem->abslevel == abslevel && IsA(pitem->item, PlaceHolderVar))
220
 
                {
221
 
                        PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item;
222
 
 
223
 
                        if (pphv->phid == phv->phid)
224
 
                                break;
225
 
                }
226
 
                i++;
227
 
        }
228
 
 
229
 
        if (ppl == NULL)
230
 
        {
231
 
                /* Nope, so make a new one */
232
 
                phv = (PlaceHolderVar *) copyObject(phv);
233
 
 
234
 
                pitem = makeNode(PlannerParamItem);
235
 
                pitem->item = (Node *) phv;
236
 
                pitem->abslevel = abslevel;
237
 
 
238
 
                root->glob->paramlist = lappend(root->glob->paramlist, pitem);
239
 
 
240
 
                /* i is already the correct list index for the new item */
241
 
        }
 
289
 
 
290
        i = assign_param_for_placeholdervar(root, phv);
242
291
 
243
292
        retval = makeNode(Param);
244
293
        retval->paramkind = PARAM_EXEC;
560
609
                        Node       *arg;
561
610
 
562
611
                        /*
563
 
                         * The Var or Aggref has already been adjusted to have the correct
564
 
                         * varlevelsup or agglevelsup.  We probably don't even need to
565
 
                         * copy it again, but be safe.
 
612
                         * The Var, PlaceHolderVar, or Aggref has already been adjusted to
 
613
                         * have the correct varlevelsup, phlevelsup, or agglevelsup.  We
 
614
                         * probably don't even need to copy it again, but be safe.
566
615
                         */
567
616
                        arg = copyObject(pitem->item);
568
617
 
569
618
                        /*
570
 
                         * If it's an Aggref, its arguments might contain SubLinks, which
571
 
                         * have not yet been processed.  Do that now.
 
619
                         * If it's a PlaceHolderVar or Aggref, its arguments might contain
 
620
                         * SubLinks, which have not yet been processed (see the comments
 
621
                         * for SS_replace_correlation_vars).  Do that now.
572
622
                         */
573
 
                        if (IsA(arg, Aggref))
 
623
                        if (IsA(arg, PlaceHolderVar) ||
 
624
                                IsA(arg, Aggref))
574
625
                                arg = SS_process_sublinks(root, arg, false);
575
626
 
576
627
                        splan->parParam = lappend_int(splan->parParam, paramid);
1678
1729
/*
1679
1730
 * Replace correlation vars (uplevel vars) with Params.
1680
1731
 *
1681
 
 * Uplevel aggregates are replaced, too.
 
1732
 * Uplevel PlaceHolderVars and aggregates are replaced, too.
1682
1733
 *
1683
1734
 * Note: it is critical that this runs immediately after SS_process_sublinks.
1684
 
 * Since we do not recurse into the arguments of uplevel aggregates, they will
1685
 
 * get copied to the appropriate subplan args list in the parent query with
1686
 
 * uplevel vars not replaced by Params, but only adjusted in level (see
1687
 
 * replace_outer_agg).  That's exactly what we want for the vars of the parent
1688
 
 * level --- but if an aggregate's argument contains any further-up variables,
1689
 
 * they have to be replaced with Params in their turn.  That will happen when
1690
 
 * the parent level runs SS_replace_correlation_vars.  Therefore it must do
1691
 
 * so after expanding its sublinks to subplans.  And we don't want any steps
1692
 
 * in between, else those steps would never get applied to the aggregate
1693
 
 * argument expressions, either in the parent or the child level.
 
1735
 * Since we do not recurse into the arguments of uplevel PHVs and aggregates,
 
1736
 * they will get copied to the appropriate subplan args list in the parent
 
1737
 * query with uplevel vars not replaced by Params, but only adjusted in level
 
1738
 * (see replace_outer_placeholdervar and replace_outer_agg).  That's exactly
 
1739
 * what we want for the vars of the parent level --- but if a PHV's or
 
1740
 * aggregate's argument contains any further-up variables, they have to be
 
1741
 * replaced with Params in their turn. That will happen when the parent level
 
1742
 * runs SS_replace_correlation_vars.  Therefore it must do so after expanding
 
1743
 * its sublinks to subplans.  And we don't want any steps in between, else
 
1744
 * those steps would never get applied to the argument expressions, either in
 
1745
 * the parent or the child level.
1694
1746
 *
1695
1747
 * Another fairly tricky thing going on here is the handling of SubLinks in
1696
 
 * the arguments of uplevel aggregates.  Those are not touched inside the
1697
 
 * intermediate query level, either.  Instead, SS_process_sublinks recurses
1698
 
 * on them after copying the Aggref expression into the parent plan level
 
1748
 * the arguments of uplevel PHVs/aggregates.  Those are not touched inside the
 
1749
 * intermediate query level, either.  Instead, SS_process_sublinks recurses on
 
1750
 * them after copying the PHV or Aggref expression into the parent plan level
1699
1751
 * (this is actually taken care of in build_subplan).
1700
1752
 */
1701
1753
Node *
1715
1767
                if (((Var *) node)->varlevelsup > 0)
1716
1768
                        return (Node *) replace_outer_var(root, (Var *) node);
1717
1769
        }
 
1770
        if (IsA(node, PlaceHolderVar))
 
1771
        {
 
1772
                if (((PlaceHolderVar *) node)->phlevelsup > 0)
 
1773
                        return (Node *) replace_outer_placeholdervar(root,
 
1774
                                                                                                        (PlaceHolderVar *) node);
 
1775
        }
1718
1776
        if (IsA(node, Aggref))
1719
1777
        {
1720
1778
                if (((Aggref *) node)->agglevelsup > 0)
1774
1832
        }
1775
1833
 
1776
1834
        /*
1777
 
         * Don't recurse into the arguments of an outer aggregate here. Any
1778
 
         * SubLinks in the arguments have to be dealt with at the outer query
1779
 
         * level; they'll be handled when build_subplan collects the Aggref into
1780
 
         * the arguments to be passed down to the current subplan.
 
1835
         * Don't recurse into the arguments of an outer PHV or aggregate here.
 
1836
         * Any SubLinks in the arguments have to be dealt with at the outer query
 
1837
         * level; they'll be handled when build_subplan collects the PHV or Aggref
 
1838
         * into the arguments to be passed down to the current subplan.
1781
1839
         */
1782
 
        if (IsA(node, Aggref))
 
1840
        if (IsA(node, PlaceHolderVar))
 
1841
        {
 
1842
                if (((PlaceHolderVar *) node)->phlevelsup > 0)
 
1843
                        return node;
 
1844
        }
 
1845
        else if (IsA(node, Aggref))
1783
1846
        {
1784
1847
                if (((Aggref *) node)->agglevelsup > 0)
1785
1848
                        return node;