Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a bug reported on the mailing list concerning a conflict between "INSERT INTO ... SELECT" statements and the "SELECT max(x) FROM tbl" optimization. (CVS 2227) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5a9da62ae303800ded99942aed30eade |
User & Date: | danielk1977 2005-01-17 08:57:09.000 |
Context
2005-01-17
| ||
22:08 | Infrastructure changes to handle name resolution differently. This is needed to fix various long-standing problems with column names in joins. It will also make the implementation of correlated subqueries easier. (CVS 2228) (check-in: 4a7534396a user: drh tags: trunk) | |
08:57 | Fix a bug reported on the mailing list concerning a conflict between "INSERT INTO ... SELECT" statements and the "SELECT max(x) FROM tbl" optimization. (CVS 2227) (check-in: 5a9da62ae3 user: danielk1977 tags: trunk) | |
07:53 | Fix some memory leak problems with corrupt.test and auto-vacuum databases. (CVS 2226) (check-in: 6244252915 user: danielk1977 tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.222 2005/01/17 08:57:09 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. |
︙ | ︙ | |||
2053 2054 2055 2056 2057 2058 2059 | int base; Vdbe *v; int seekOp; int cont; ExprList *pEList, *pList, eList; struct ExprList_item eListItem; SrcList *pSrc; | < | 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 | int base; Vdbe *v; int seekOp; int cont; ExprList *pEList, *pList, eList; struct ExprList_item eListItem; SrcList *pSrc; /* Check to see if this query is a simple min() or max() query. Return ** zero if it is not. */ if( p->pGroupBy || p->pHaving || p->pWhere ) return 0; pSrc = p->pSrc; if( pSrc->nSrc!=1 ) return 0; |
︙ | ︙ | |||
2126 2127 2128 2129 2130 2131 2132 2133 | if( pSrc->a[0].pSelect==0 ){ sqlite3OpenTableForReading(v, base, pTab); } cont = sqlite3VdbeMakeLabel(v); if( pIdx==0 ){ sqlite3VdbeAddOp(v, seekOp, base, 0); }else{ sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0); | > > > > > > > > | | | | | 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 | if( pSrc->a[0].pSelect==0 ){ sqlite3OpenTableForReading(v, base, pTab); } cont = sqlite3VdbeMakeLabel(v); if( pIdx==0 ){ sqlite3VdbeAddOp(v, seekOp, base, 0); }else{ /* Even though the cursor used to open the index here is closed ** as soon as a single value has been read from it, allocate it ** using (pParse->nTab++) to prevent the cursor id from being ** reused. This is important for statements of the form ** "INSERT INTO x SELECT max() FROM x". */ int iIdx; iIdx = pParse->nTab++; sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0); sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, (char*)&pIdx->keyInfo, P3_KEYINFO); if( seekOp==OP_Rewind ){ sqlite3VdbeAddOp(v, OP_String, 0, 0); sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0); seekOp = OP_MoveGt; } sqlite3VdbeAddOp(v, seekOp, iIdx, 0); sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0); sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } eList.nExpr = 1; memset(&eListItem, 0, sizeof(eListItem)); eList.a = &eListItem; eList.a[0].pExpr = pExpr; selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont, 0); |
︙ | ︙ |
Changes to test/insert.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement. # # $Id: insert.test,v 1.22 2005/01/17 08:57:09 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Try to insert into a non-existant table. # do_test insert-1.1 { |
︙ | ︙ | |||
299 300 301 302 303 304 305 306 307 308 309 | } } {} ifcapable {reindex} { do_test insert-6.7 { execsql REINDEX } {} } integrity_check insert-99.0 finish_test | > > > > > > > > > > > > > > > > > > > > > > > | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | } } {} ifcapable {reindex} { do_test insert-6.7 { execsql REINDEX } {} } # Test that the special optimization for queries of the form # "SELECT max(x) FROM tbl" where there is an index on tbl(x) works with # INSERT statments. do_test insert-7.1 { execsql { DROP TABLE t1; CREATE TABLE t1(a); INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(2); CREATE INDEX i1 ON t1(a); } } {} do_test insert-7.2 { execsql { INSERT INTO t1 SELECT max(a) FROM t1; } } {} do_test insert-7.3 { execsql { SELECT a FROM t1; } } {1 2 2} integrity_check insert-99.0 finish_test |