/ Check-in [5e8611e1]
Login

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

Overview
Comment:Fix the origin APIs so that they correctly handle views and subqueries that cannot be flattened. (CVS 3072)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:5e8611e13de08d704cea6c9c4466c3af842a7a1a
User & Date: danielk1977 2006-02-10 07:07:14
Context
2006-02-10
08:24
Work around the case where the pending-byte page is also a a pointer-map page. Ticket #1667. (CVS 3073) check-in: 5ea87fbb user: danielk1977 tags: trunk
07:07
Fix the origin APIs so that they correctly handle views and subqueries that cannot be flattened. (CVS 3072) check-in: 5e8611e1 user: danielk1977 tags: trunk
04:33
Fix deadlock problem in the unix mutex. Ticket #1672. (CVS 3071) check-in: a6c30be2 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.384 2006/02/05 18:55:20 drh Exp $
           25  +** $Id: build.c,v 1.385 2006/02/10 07:07:14 danielk1977 Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   #include <ctype.h>
    29     29   
    30     30   /*
    31     31   ** This routine is called when a new SQL statement is beginning to
    32     32   ** be parsed.  Initialize the pParse structure as needed.
................................................................................
  2843   2843       Token *pTemp = pDatabase;
  2844   2844       pDatabase = pTable;
  2845   2845       pTable = pTemp;
  2846   2846     }
  2847   2847     pItem->zName = sqlite3NameFromToken(pTable);
  2848   2848     pItem->zDatabase = sqlite3NameFromToken(pDatabase);
  2849   2849     pItem->iCursor = -1;
         2850  +  pItem->isPopulated = 0;
  2850   2851     pList->nSrc++;
  2851   2852     return pList;
  2852   2853   }
  2853   2854   
  2854   2855   /*
  2855   2856   ** Assign cursors to all tables in a SrcList
  2856   2857   */

Changes to src/expr.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.253 2006/01/30 14:36:59 drh Exp $
           15  +** $Id: expr.c,v 1.254 2006/02/10 07:07:15 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   /*
    21     21   ** Return the 'affinity' of the expression pExpr if any.
    22     22   **
................................................................................
   491    491       struct SrcList_item *pOldItem = &p->a[i];
   492    492       Table *pTab;
   493    493       pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
   494    494       pNewItem->zName = sqliteStrDup(pOldItem->zName);
   495    495       pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
   496    496       pNewItem->jointype = pOldItem->jointype;
   497    497       pNewItem->iCursor = pOldItem->iCursor;
          498  +    pNewItem->isPopulated = pOldItem->isPopulated;
   498    499       pTab = pNewItem->pTab = pOldItem->pTab;
   499    500       if( pTab ){
   500    501         pTab->nRef++;
   501    502       }
   502    503       pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
   503    504       pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
   504    505       pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing);

Changes to src/select.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** to handle SELECT statements in SQLite.
    14     14   **
    15         -** $Id: select.c,v 1.303 2006/02/10 03:06:10 danielk1977 Exp $
           15  +** $Id: select.c,v 1.304 2006/02/10 07:07:16 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   
    20     20   /*
    21     21   ** Delete all the content of a Select structure but do not deallocate
    22     22   ** the select structure itself.
................................................................................
  2861   2861     */
  2862   2862   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  2863   2863     for(i=0; i<pTabList->nSrc; i++){
  2864   2864       const char *zSavedAuthContext = 0;
  2865   2865       int needRestoreContext;
  2866   2866       struct SrcList_item *pItem = &pTabList->a[i];
  2867   2867   
  2868         -    if( pItem->pSelect==0 ) continue;
         2868  +    if( pItem->pSelect==0 || pItem->isPopulated ) continue;
  2869   2869       if( pItem->zName!=0 ){
  2870   2870         zSavedAuthContext = pParse->zAuthContext;
  2871   2871         pParse->zAuthContext = pItem->zName;
  2872   2872         needRestoreContext = 1;
  2873   2873       }else{
  2874   2874         needRestoreContext = 0;
  2875   2875       }
................................................................................
  3255   3255     */
  3256   3256     if( pOrderBy ){
  3257   3257       generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
  3258   3258     }
  3259   3259   
  3260   3260   #ifndef SQLITE_OMIT_SUBQUERY
  3261   3261     /* If this was a subquery, we have now converted the subquery into a
  3262         -  ** temporary table.  So delete the subquery structure from the parent
  3263         -  ** to prevent this subquery from being evaluated again and to force the
  3264         -  ** the use of the temporary table.
         3262  +  ** temporary table.  So set the SrcList_item.isPopulated flag to prevent
         3263  +  ** this subquery from being evaluated again and to force the use of
         3264  +  ** the temporary table.
  3265   3265     */
  3266   3266     if( pParent ){
  3267   3267       assert( pParent->pSrc->nSrc>parentTab );
  3268   3268       assert( pParent->pSrc->a[parentTab].pSelect==p );
  3269         -    sqlite3SelectDelete(p);
  3270         -    pParent->pSrc->a[parentTab].pSelect = 0;
         3269  +    pParent->pSrc->a[parentTab].isPopulated = 1;
  3271   3270     }
  3272   3271   #endif
  3273   3272   
  3274   3273     /* Jump here to skip this query
  3275   3274     */
  3276   3275     sqlite3VdbeResolveLabel(v, iEnd);
  3277   3276   

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.479 2006/01/24 16:37:58 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.480 2006/02/10 07:07:16 danielk1977 Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Extra interface definitions for those who need them
    21     21   */
................................................................................
  1065   1065     i16 nAlloc;      /* Number of entries allocated in a[] below */
  1066   1066     struct SrcList_item {
  1067   1067       char *zDatabase;  /* Name of database holding this table */
  1068   1068       char *zName;      /* Name of the table */
  1069   1069       char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
  1070   1070       Table *pTab;      /* An SQL table corresponding to zName */
  1071   1071       Select *pSelect;  /* A SELECT statement used in place of a table name */
         1072  +    u8 isPopulated;   /* Temporary table associated with SELECT is populated */
  1072   1073       u8 jointype;      /* Type of join between this table and the next */
  1073   1074       i16 iCursor;      /* The VDBE cursor number used to access this table */
  1074   1075       Expr *pOn;        /* The ON clause of a join */
  1075   1076       IdList *pUsing;   /* The USING clause of a join */
  1076   1077       Bitmask colUsed;  /* Bit N (1<<N) set if column N or pTab is used */
  1077   1078     } a[1];             /* One entry for each identifier on the list */
  1078   1079   };

Changes to test/capi2.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script testing the callback-free C/C++ API.
    13     13   #
    14         -# $Id: capi2.test,v 1.29 2006/02/10 03:06:10 danielk1977 Exp $
           14  +# $Id: capi2.test,v 1.30 2006/02/10 07:07:16 danielk1977 Exp $
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Return the text values from the current row pointed at by STMT as a list.
    21     21   proc get_row_values {STMT} {
................................................................................
   718    718   } [list {main tab1 col2} {main tab1 col1}]
   719    719   do_test capi2-12.5 {
   720    720     check_origins {SELECT (SELECT col2 FROM view1), (SELECT col1 FROM view1)}
   721    721   } [list {main tab1 col2} {main tab1 col1}]
   722    722   do_test capi2-12.6 {
   723    723     check_origins {SELECT (SELECT col2), (SELECT col1) FROM view1}
   724    724   } [list {main tab1 col2} {main tab1 col1}]
   725         -db2 close
          725  +do_test capi2-12.7 {
          726  +  check_origins {SELECT * FROM view1}
          727  +} [list {main tab1 col1} {main tab1 col2}]
          728  +do_test capi2-12.8 {
          729  +  check_origins {select * from (select * from view1)}
          730  +} [list {main tab1 col1} {main tab1 col2}]
          731  +do_test capi2-12.9 {
          732  +  check_origins {select * from (select * from (select * from view1))}
          733  +} [list {main tab1 col1} {main tab1 col2}]
          734  +do_test capi2-12.10 {
          735  +  db close
          736  +  sqlite3 db test.db
          737  +  set ::DB [sqlite3_connection_pointer db]
          738  +  check_origins {select * from (select * from (select * from view1))}
          739  +} [list {main tab1 col1} {main tab1 col2}]
          740  +
          741  +# This view will thwart the flattening optimization.
          742  +do_test capi2-13.1 {
          743  +  execsql {
          744  +    CREATE VIEW view2 AS SELECT * FROM tab1 limit 10 offset 10;
          745  +  }
          746  +} {}
          747  +breakpoint
          748  +do_test capi2-13.2 {
          749  +  check_origins {SELECT col2, col1 FROM view2}
          750  +} [list {main tab1 col2} {main tab1 col1}]
          751  +do_test capi2-13.3 {
          752  +  check_origins {SELECT col2 AS hello, col1 AS world FROM view2}
          753  +} [list {main tab1 col2} {main tab1 col1}]
          754  +do_test capi2-13.4 {
          755  +  check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM view2)}
          756  +} [list {main tab1 col2} {main tab1 col1}]
          757  +do_test capi2-13.5 {
          758  +  check_origins {SELECT (SELECT col2 FROM view2), (SELECT col1 FROM view2)}
          759  +} [list {main tab1 col2} {main tab1 col1}]
          760  +do_test capi2-13.6 {
          761  +  check_origins {SELECT (SELECT col2), (SELECT col1) FROM view2}
          762  +} [list {main tab1 col2} {main tab1 col1}]
          763  +do_test capi2-13.7 {
          764  +  check_origins {SELECT * FROM view2}
          765  +} [list {main tab1 col1} {main tab1 col2}]
          766  +do_test capi2-13.8 {
          767  +  check_origins {select * from (select * from view2)}
          768  +} [list {main tab1 col1} {main tab1 col2}]
          769  +do_test capi2-13.9 {
          770  +  check_origins {select * from (select * from (select * from view2))}
          771  +} [list {main tab1 col1} {main tab1 col2}]
          772  +do_test capi2-13.10 {
          773  +  db close
          774  +  sqlite3 db test.db
          775  +  set ::DB [sqlite3_connection_pointer db]
          776  +  check_origins {select * from (select * from (select * from view2))}
          777  +} [list {main tab1 col1} {main tab1 col2}]
          778  +do_test capi2-13.11 {
          779  +  check_origins {select * from (select * from tab1 limit 10 offset 10)}
          780  +} [list {main tab1 col1} {main tab1 col2}]
          781  +
   726    782   
   727    783   } ;# ifcapable columnmetadata
   728    784   
          785  +db2 close
   729    786   finish_test

Changes to test/capi3.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script testing the callback-free C/C++ API.
    13     13   #
    14         -# $Id: capi3.test,v 1.42 2006/02/10 02:27:47 danielk1977 Exp $
           14  +# $Id: capi3.test,v 1.43 2006/02/10 07:07:16 danielk1977 Exp $
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Return the UTF-16 representation of the supplied UTF-8 string $str.
    21     21   # If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
   304    304   #
   305    305   # Example:
   306    306   #
   307    307   # set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY]
   308    308   # check_header test1.1 {1 2 3} {"" "" ""}
   309    309   #
   310    310   proc check_origin_header {STMT test dbs tables cols} {
   311         -  # Use the return value of sqlite3_column_count() to build
   312         -  # a list of column indexes. i.e. If sqlite3_column_count
   313         -  # is 3, build the list {0 1 2}.
   314         -  set ::idxlist [list]
   315         -  set ::numcols [sqlite3_column_count $STMT]
   316         -  for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i}
          311  +  # If sqlite3_column_origin_name() and friends are not compiled into
          312  +  # this build, this proc is a no-op.
          313  +ifcapable columnmetadata {
   317    314   
   318         -  # Database names in UTF-8
   319         -  do_test $test.8 {
   320         -    set cnamelist [list]
   321         -    foreach i $idxlist {
   322         -      lappend cnamelist [sqlite3_column_database_name $STMT $i]
   323         -    } 
   324         -    set cnamelist
   325         -  } $dbs
   326         -
   327         -  # Database names in UTF-16
   328         -  ifcapable {utf16} {
   329         -    do_test $test.9 {
          315  +    # Use the return value of sqlite3_column_count() to build
          316  +    # a list of column indexes. i.e. If sqlite3_column_count
          317  +    # is 3, build the list {0 1 2}.
          318  +    set ::idxlist [list]
          319  +    set ::numcols [sqlite3_column_count $STMT]
          320  +    for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i}
          321  +  
          322  +    # Database names in UTF-8
          323  +    do_test $test.8 {
   330    324         set cnamelist [list]
   331    325         foreach i $idxlist {
   332         -        lappend cnamelist [utf8 [sqlite3_column_database_name16 $STMT $i]]
   333         -      }
          326  +        lappend cnamelist [sqlite3_column_database_name $STMT $i]
          327  +      } 
   334    328         set cnamelist
   335    329       } $dbs
   336         -  }
   337         -
   338         -  # Table names in UTF-8
   339         -  do_test $test.10 {
   340         -    set cnamelist [list]
   341         -    foreach i $idxlist {lappend cnamelist [sqlite3_column_table_name $STMT $i]} 
   342         -    set cnamelist
   343         -  } $tables
   344         -
   345         -  # Table names in UTF-16
   346         -  ifcapable {utf16} {
   347         -    do_test $test.11 {
          330  +  
          331  +    # Database names in UTF-16
          332  +    ifcapable {utf16} {
          333  +      do_test $test.9 {
          334  +        set cnamelist [list]
          335  +        foreach i $idxlist {
          336  +          lappend cnamelist [utf8 [sqlite3_column_database_name16 $STMT $i]]
          337  +        }
          338  +        set cnamelist
          339  +      } $dbs
          340  +    }
          341  +  
          342  +    # Table names in UTF-8
          343  +    do_test $test.10 {
   348    344         set cnamelist [list]
   349    345         foreach i $idxlist {
   350         -        lappend cnamelist [utf8 [sqlite3_column_table_name16 $STMT $i]]
   351         -      }
          346  +        lappend cnamelist [sqlite3_column_table_name $STMT $i]
          347  +      } 
   352    348         set cnamelist
   353    349       } $tables
   354         -  }
   355         -
   356         -  # Origin names in UTF-8
   357         -  do_test $test.12 {
   358         -    set cnamelist [list]
   359         -    foreach i $idxlist {
   360         -      lappend cnamelist [sqlite3_column_origin_name $STMT $i]
   361         -    } 
   362         -    set cnamelist
   363         -  } $cols
   364         -
   365         -  # Origin declaration types in UTF-16
   366         -  ifcapable {utf16} {
   367         -    do_test $test.13 {
          350  +  
          351  +    # Table names in UTF-16
          352  +    ifcapable {utf16} {
          353  +      do_test $test.11 {
          354  +        set cnamelist [list]
          355  +        foreach i $idxlist {
          356  +          lappend cnamelist [utf8 [sqlite3_column_table_name16 $STMT $i]]
          357  +        }
          358  +        set cnamelist
          359  +      } $tables
          360  +    }
          361  +  
          362  +    # Origin names in UTF-8
          363  +    do_test $test.12 {
   368    364         set cnamelist [list]
   369    365         foreach i $idxlist {
   370         -        lappend cnamelist [utf8 [sqlite3_column_origin_name16 $STMT $i]]
   371         -      }
          366  +        lappend cnamelist [sqlite3_column_origin_name $STMT $i]
          367  +      } 
   372    368         set cnamelist
   373    369       } $cols
          370  +  
          371  +    # Origin declaration types in UTF-16
          372  +    ifcapable {utf16} {
          373  +      do_test $test.13 {
          374  +        set cnamelist [list]
          375  +        foreach i $idxlist {
          376  +          lappend cnamelist [utf8 [sqlite3_column_origin_name16 $STMT $i]]
          377  +        }
          378  +        set cnamelist
          379  +      } $cols
          380  +    }
   374    381     }
   375    382   }
   376    383   
   377    384   # This proc is used to test the following APIs:
   378    385   #
   379    386   # sqlite3_data_count
   380    387   # sqlite3_column_type