|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.24 2000/04/12 17:15:23 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.25 2000/04/14 00:19:17 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -656,15 +656,26 @@ or_normalize(List *orlist)
|
656 | 656 | foreach(temp, distributable->args)
|
657 | 657 | {
|
658 | 658 | Expr *andclause = lfirst(temp);
|
| 659 | + List *neworlist; |
| 660 | + |
| 661 | + /* |
| 662 | + * We are going to insert the orlist into multiple places in the |
| 663 | + * result expression. For most expression types, it'd be OK to |
| 664 | + * just have multiple links to the same subtree, but this fails |
| 665 | + * badly for SubLinks (and perhaps other cases?). For safety, |
| 666 | + * we make a distinct copy for each place the orlist is inserted. |
| 667 | + */ |
| 668 | + if (lnext(temp) == NIL) |
| 669 | + neworlist = orlist; /* can use original tree at the end */ |
| 670 | + else |
| 671 | + neworlist = copyObject(orlist); |
659 | 672 |
|
660 | 673 | /*
|
661 | 674 | * pull_ors is needed here in case andclause has a top-level OR.
|
662 | 675 | * Then we recursively apply or_normalize, since there might be an
|
663 |
| - * AND subclause in the resulting OR-list. Note: we rely on |
664 |
| - * pull_ors to build a fresh list, and not damage the given |
665 |
| - * orlist. |
| 676 | + * AND subclause in the resulting OR-list. |
666 | 677 | */
|
667 |
| - andclause = or_normalize(pull_ors(lcons(andclause, orlist))); |
| 678 | + andclause = or_normalize(pull_ors(lcons(andclause, neworlist))); |
668 | 679 | andclauses = lappend(andclauses, andclause);
|
669 | 680 | }
|
670 | 681 |
|
@@ -773,15 +784,26 @@ and_normalize(List *andlist)
|
773 | 784 | foreach(temp, distributable->args)
|
774 | 785 | {
|
775 | 786 | Expr *orclause = lfirst(temp);
|
| 787 | + List *newandlist; |
| 788 | + |
| 789 | + /* |
| 790 | + * We are going to insert the andlist into multiple places in the |
| 791 | + * result expression. For most expression types, it'd be OK to |
| 792 | + * just have multiple links to the same subtree, but this fails |
| 793 | + * badly for SubLinks (and perhaps other cases?). For safety, |
| 794 | + * we make a distinct copy for each place the andlist is inserted. |
| 795 | + */ |
| 796 | + if (lnext(temp) == NIL) |
| 797 | + newandlist = andlist; /* can use original tree at the end */ |
| 798 | + else |
| 799 | + newandlist = copyObject(andlist); |
776 | 800 |
|
777 | 801 | /*
|
778 | 802 | * pull_ands is needed here in case orclause has a top-level AND.
|
779 | 803 | * Then we recursively apply and_normalize, since there might be
|
780 |
| - * an OR subclause in the resulting AND-list. Note: we rely on |
781 |
| - * pull_ands to build a fresh list, and not damage the given |
782 |
| - * andlist. |
| 804 | + * an OR subclause in the resulting AND-list. |
783 | 805 | */
|
784 |
| - orclause = and_normalize(pull_ands(lcons(orclause, andlist))); |
| 806 | + orclause = and_normalize(pull_ands(lcons(orclause, newandlist))); |
785 | 807 | orclauses = lappend(orclauses, orclause);
|
786 | 808 | }
|
787 | 809 |
|
@@ -932,6 +954,17 @@ count_bool_nodes(Expr *qual,
|
932 | 954 | count_bool_nodes(get_notclausearg(qual),
|
933 | 955 | nodes, cnfnodes, dnfnodes);
|
934 | 956 | }
|
| 957 | + else if (contain_subplans((Node *) qual)) |
| 958 | + { |
| 959 | + /* charge extra for subexpressions containing sub-SELECTs, |
| 960 | + * to discourage us from rearranging them in a way that might |
| 961 | + * generate N copies of a subselect rather than one. The magic |
| 962 | + * constant here interacts with the "4x maximum growth" heuristic |
| 963 | + * in canonicalize_qual(). |
| 964 | + */ |
| 965 | + *nodes = 1.0; |
| 966 | + *cnfnodes = *dnfnodes = 25.0; |
| 967 | + } |
935 | 968 | else
|
936 | 969 | {
|
937 | 970 | /* anything else counts 1 for my purposes */
|
|
0 commit comments