/ Check-in [1f413aca]
Login

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

Overview
Comment:Avoid leaking memory in an obscure case where the flattener adds an ORDER BY clause to the recursive part of a recursive query.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1f413aca00015100224273480e1ce39a76bf93ab
User & Date: dan 2014-03-21 19:27:54
Context
2014-03-21
19:56
Change the names of SRT_DistTable and SRT_Table used by CTE to more meaningful SRT_DistFifo and SRT_Fifo, respectively. Simplify the IgnorableOrderby() macro in the process. check-in: 45d8cc67 user: drh tags: trunk
19:27
Avoid leaking memory in an obscure case where the flattener adds an ORDER BY clause to the recursive part of a recursive query. check-in: 1f413aca user: dan tags: trunk
18:16
Fix the OFFSET clause so that it works correctly on queries that lack a FROM clause. Ticket [07d6a0453d4ed8]. check-in: 179ef816 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/select.c.

  1935   1935     p->pPrior = pSetup;
  1936   1936   
  1937   1937     /* Keep running the loop until the Queue is empty */
  1938   1938     sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
  1939   1939     sqlite3VdbeResolveLabel(v, addrBreak);
  1940   1940   
  1941   1941   end_of_recursive_query:
         1942  +  sqlite3ExprListDelete(pParse->db, p->pOrderBy);
  1942   1943     p->pOrderBy = pOrderBy;
  1943   1944     p->pLimit = pLimit;
  1944   1945     p->pOffset = pOffset;
  1945   1946     return;
  1946   1947   }
  1947   1948   #endif /* SQLITE_OMIT_CTE */
  1948   1949   
................................................................................
  4483   4484     db = pParse->db;
  4484   4485     if( p==0 || db->mallocFailed || pParse->nErr ){
  4485   4486       return 1;
  4486   4487     }
  4487   4488     if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  4488   4489     memset(&sAggInfo, 0, sizeof(sAggInfo));
  4489   4490   
         4491  +  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistTable );
         4492  +  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
         4493  +  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
  4490   4494     if( IgnorableOrderby(pDest) ){
  4491   4495       assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || 
  4492         -           pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
         4496  +           pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
         4497  +           pDest->eDest==SRT_Queue  || pDest->eDest==SRT_DistTable ||
         4498  +           pDest->eDest==SRT_DistQueue);
  4493   4499       /* If ORDER BY makes no difference in the output then neither does
  4494   4500       ** DISTINCT so it can be removed too. */
  4495   4501       sqlite3ExprListDelete(db, p->pOrderBy);
  4496   4502       p->pOrderBy = 0;
  4497   4503       p->selFlags &= ~SF_Distinct;
  4498   4504     }
  4499   4505     sqlite3SelectPrep(pParse, p, 0);

Changes to src/sqliteInt.h.

  2279   2279   */
  2280   2280   #define SRT_Union        1  /* Store result as keys in an index */
  2281   2281   #define SRT_Except       2  /* Remove result from a UNION index */
  2282   2282   #define SRT_Exists       3  /* Store 1 if the result is not empty */
  2283   2283   #define SRT_Discard      4  /* Do not save the results anywhere */
  2284   2284   
  2285   2285   /* The ORDER BY clause is ignored for all of the above */
  2286         -#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard)
         2286  +#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard || (X->eDest)>SRT_Table)
  2287   2287   
  2288   2288   #define SRT_Output       5  /* Output each row of result */
  2289   2289   #define SRT_Mem          6  /* Store result in a memory cell */
  2290   2290   #define SRT_Set          7  /* Store results as keys in an index */
  2291   2291   #define SRT_EphemTab     8  /* Create transient tab and store like SRT_Table */
  2292   2292   #define SRT_Coroutine    9  /* Generate a single row of result */
  2293   2293   #define SRT_Table       10  /* Store result as data with an automatic rowid */

Changes to test/with2.test.

   381    381   do_execsql_test 7.5 {
   382    382     SELECT * FROM t6 WHERE y IN (
   383    383       WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 )
   384    384       SELECT x FROM ss
   385    385     )
   386    386   } {14 28 42}
   387    387   
          388  +#-------------------------------------------------------------------------
          389  +# At one point the following was causing an assertion failure and a 
          390  +# memory leak.
          391  +#
          392  +do_execsql_test 8.1 {
          393  +  CREATE TABLE t7(y);
          394  +  INSERT INTO t7 VALUES(NULL);
          395  +  CREATE VIEW v AS SELECT * FROM t7 ORDER BY y;
          396  +}
          397  +
          398  +do_execsql_test 8.2 {
          399  +  WITH q(a) AS (
          400  +    SELECT 1
          401  +    UNION 
          402  +    SELECT a+1 FROM q, v WHERE a<5
          403  +  )
          404  +  SELECT * FROM q;
          405  +} {1 2 3 4 5}
          406  +
          407  +do_execsql_test 8.3 {
          408  +  WITH q(a) AS (
          409  +    SELECT 1
          410  +    UNION ALL
          411  +    SELECT a+1 FROM q, v WHERE a<5
          412  +  )
          413  +  SELECT * FROM q;
          414  +} {1 2 3 4 5}
   388    415   
   389    416   
   390    417   finish_test
   391    418