SQLite

Check-in [aa6bd6df]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove the push-down optimization restriction that was added by check-in [1ad41840c5e0fa70] because it is no longer needed after the enhancements to compound query processing in check-in [27655c9353620aa5] This resolves the performance regression reported by forum post bcc4375032.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: aa6bd6dff751223e302575c60f335707e4bb820bff716cab3706b564e18ed7ed
User & Date: drh 2023-02-22 20:42:15
Context
2023-02-22
20:50
Update the version number to 3.42.0 to begin the next development cycle. (check-in: 65910216 user: drh tags: trunk)
20:42
Remove the push-down optimization restriction that was added by check-in [1ad41840c5e0fa70] because it is no longer needed after the enhancements to compound query processing in check-in [27655c9353620aa5] This resolves the performance regression reported by forum post bcc4375032. (check-in: aa6bd6df user: drh tags: trunk)
2023-02-21
20:08
Remove some unnecessary bind() calls in JS code. (check-in: 71215599 user: stephan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/select.c.
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
**              (17d2) DISTINCT
**        (17e) the subquery may not contain window functions, and
**        (17f) the subquery must not be the RHS of a LEFT JOIN.
**        (17g) either the subquery is the first element of the outer
**              query or there are no RIGHT or FULL JOINs in any arm
**              of the subquery.  (This is a duplicate of condition (27b).)
**        (17h) The corresponding result set expressions in all arms of the
**              compound must have the same affinity. (See restriction (9)
**              on the push-down optimization.)
**
**        The parent and sub-query may contain WHERE clauses. Subject to
**        rules (11), (13) and (14), they may also contain ORDER BY,
**        LIMIT and OFFSET clauses.  The subquery cannot use any compound
**        operator other than UNION ALL because all the other compound
**        operators have an implied DISTINCT which is disallowed by
**        restriction (4).







|
<







4234
4235
4236
4237
4238
4239
4240
4241

4242
4243
4244
4245
4246
4247
4248
**              (17d2) DISTINCT
**        (17e) the subquery may not contain window functions, and
**        (17f) the subquery must not be the RHS of a LEFT JOIN.
**        (17g) either the subquery is the first element of the outer
**              query or there are no RIGHT or FULL JOINs in any arm
**              of the subquery.  (This is a duplicate of condition (27b).)
**        (17h) The corresponding result set expressions in all arms of the
**              compound must have the same affinity.

**
**        The parent and sub-query may contain WHERE clauses. Subject to
**        rules (11), (13) and (14), they may also contain ORDER BY,
**        LIMIT and OFFSET clauses.  The subquery cannot use any compound
**        operator other than UNION ALL because all the other compound
**        operators have an implied DISTINCT which is disallowed by
**        restriction (4).
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
**       be materialized.  (This restriction is implemented in the calling
**       routine.)
**
**   (8) If the subquery is a compound that uses UNION, INTERSECT,
**       or EXCEPT, then all of the result set columns for all arms of
**       the compound must use the BINARY collating sequence.
**
**   (9) If the subquery is a compound, then all arms of the compound must
**       have the same affinity.  (This is the same as restriction (17h)
**       for query flattening.)
**       
**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
static int pushDownWhereTerms(
  Parse *pParse,        /* Parse context (for malloc() and error reporting) */
  Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */







<
<
<
<







5102
5103
5104
5105
5106
5107
5108




5109
5110
5111
5112
5113
5114
5115
**       be materialized.  (This restriction is implemented in the calling
**       routine.)
**
**   (8) If the subquery is a compound that uses UNION, INTERSECT,
**       or EXCEPT, then all of the result set columns for all arms of
**       the compound must use the BINARY collating sequence.
**




**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
static int pushDownWhereTerms(
  Parse *pParse,        /* Parse context (for malloc() and error reporting) */
  Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
      if( op!=TK_ALL && op!=TK_SELECT ){
        notUnionAll = 1;
      }
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( pSel->pWin ) return 0;    /* restriction (6b) */
#endif
    }
    if( compoundHasDifferentAffinities(pSubq) ){
      return 0;  /* restriction (9) */
    }
    if( notUnionAll ){
      /* If any of the compound arms are connected using UNION, INTERSECT,
      ** or EXCEPT, then we must ensure that none of the columns use a
      ** non-BINARY collating sequence. */
      for(pSel=pSubq; pSel; pSel=pSel->pPrior){
        int ii;
        const ExprList *pList = pSel->pEList;







<
<
<







5132
5133
5134
5135
5136
5137
5138



5139
5140
5141
5142
5143
5144
5145
      if( op!=TK_ALL && op!=TK_SELECT ){
        notUnionAll = 1;
      }
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( pSel->pWin ) return 0;    /* restriction (6b) */
#endif
    }



    if( notUnionAll ){
      /* If any of the compound arms are connected using UNION, INTERSECT,
      ** or EXCEPT, then we must ensure that none of the columns use a
      ** non-BINARY collating sequence. */
      for(pSel=pSubq; pSel; pSel=pSel->pPrior){
        int ii;
        const ExprList *pList = pSel->pEList;
Changes to test/pushdown.test.
118
119
120
121
122
123
124
125








































126
do_execsql_test 3.4 {
  SELECT a, quote(b), cd FROM (
    SELECT v1.a, v1.b, t0.c0 AS cd FROM t0 LEFT JOIN v0 ON v0.c0!=0, v1
  ) WHERE a=2 AND b=0 AND cd=0;
} {
  2 0     0
}
  








































finish_test







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
do_execsql_test 3.4 {
  SELECT a, quote(b), cd FROM (
    SELECT v1.a, v1.b, t0.c0 AS cd FROM t0 LEFT JOIN v0 ON v0.c0!=0, v1
  ) WHERE a=2 AND b=0 AND cd=0;
} {
  2 0     0
}

# 2023-02-22 https://sqlite.org/forum/forumpost/bcc4375032
# Performance regression caused by check-in [1ad41840c5e0fa70] from 2022-11-25.
# That check-in added a new restriction on push-down.  The new restriction is
# no longer necessary after check-in [27655c9353620aa5] from 2022-12-14.
#
do_execsql_test 3.5 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INT, b INT, c TEXT, PRIMARY KEY(a,b)) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES
    (1,100,'abc'),
    (2,200,'def'),
    (3,300,'abc');
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INT, b INT, c TEXT, PRIMARY KEY(a,b)) WITHOUT ROWID;
  INSERT INTO t2(a,b,c) VALUES
    (1,110,'efg'),
    (2,200,'hij'),
    (3,330,'klm');
  CREATE VIEW v3 AS
    SELECT a, b, c FROM t1
    UNION ALL
    SELECT a, b, 'xyz' FROM t2;
  SELECT * FROM v3 WHERE a=2 AND b=200;
} {2 200 def 2 200 xyz}
do_eqp_test 3.6 {
  SELECT * FROM v3 WHERE a=2 AND b=200;
} {
  QUERY PLAN
  |--CO-ROUTINE v3
  |  `--COMPOUND QUERY
  |     |--LEFT-MOST SUBQUERY
  |     |  `--SEARCH t1 USING PRIMARY KEY (a=? AND b=?)
  |     `--UNION ALL
  |        `--SEARCH t2 USING PRIMARY KEY (a=? AND b=?)
  `--SCAN v3
}
#                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# We want both arms of the compound subquery to use the
# primary key.

finish_test