mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
Bug fixes in the VIEW implementation. (CVS 396)
FossilOrigin-Name: 668ef6380eba256ef82477b63aef850249a619a0
This commit is contained in:
21
manifest
21
manifest
@ -1,5 +1,5 @@
|
|||||||
C Comment\schanges\sonly.\s(CVS\s395)
|
C Bug\sfixes\sin\sthe\sVIEW\simplementation.\s(CVS\s396)
|
||||||
D 2002-02-26T23:55:31
|
D 2002-02-27T01:47:12
|
||||||
F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
|
F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
|
||||||
F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
|
F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
|
||||||
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
||||||
@ -21,9 +21,9 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
|
|||||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||||
F src/btree.c 495275fe14f3b718cf2f691dce979d4c0e1f8e5d
|
F src/btree.c 495275fe14f3b718cf2f691dce979d4c0e1f8e5d
|
||||||
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
|
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
|
||||||
F src/build.c 1da051784be0155ae579d47890db74f0186f9b9f
|
F src/build.c 7ada2426caba70cb1072ba268bedb694b5018065
|
||||||
F src/delete.c 950d8f9097361419f1963875f9943344b469cf02
|
F src/delete.c 950d8f9097361419f1963875f9943344b469cf02
|
||||||
F src/expr.c ad07b7932a91a2aa3b2e40470c7ae8a974451ed5
|
F src/expr.c 4716119eea61b4f47225fca2338e75baa30b1315
|
||||||
F src/func.c bed0099aaa558f8bfc50d9349bf7da2c99903f47
|
F src/func.c bed0099aaa558f8bfc50d9349bf7da2c99903f47
|
||||||
F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
|
F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
|
||||||
F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
|
F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
|
||||||
@ -37,11 +37,11 @@ F src/pager.h b28f004e2f5541dc60cc32db01bf80cf4d056283
|
|||||||
F src/parse.y fc460cda6f475beae963c7f9c737cf13f44f3420
|
F src/parse.y fc460cda6f475beae963c7f9c737cf13f44f3420
|
||||||
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
|
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
|
||||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||||
F src/select.c 410e4dfff7d2cfb8712529519b94410e2c7e7930
|
F src/select.c c74b6349d5630e05aceef73aaa8ed5e09a793fc4
|
||||||
F src/shell.c 9f8249ca5b8f8aad40becd778c151b58c0d6109e
|
F src/shell.c 9f8249ca5b8f8aad40becd778c151b58c0d6109e
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in f1421919a4437a377fb712b98835a224482e776e
|
F src/sqlite.h.in f1421919a4437a377fb712b98835a224482e776e
|
||||||
F src/sqliteInt.h d20712633cd07c547c5dde24a4d4c43c368334f7
|
F src/sqliteInt.h 4076aef24feec5ad98a9aa98200af29428ef94ba
|
||||||
F src/table.c 203a09d5d0009eeeb1f670370d52b4ce163a3b52
|
F src/table.c 203a09d5d0009eeeb1f670370d52b4ce163a3b52
|
||||||
F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
|
F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
|
||||||
F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
|
F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
|
||||||
@ -50,7 +50,7 @@ F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
|
|||||||
F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
|
F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
|
||||||
F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af
|
F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af
|
||||||
F src/update.c 18971d265b0341574b7e3f73116e7947ddab0997
|
F src/update.c 18971d265b0341574b7e3f73116e7947ddab0997
|
||||||
F src/util.c f31f3d6198a0d1296a16f5a6ceec423a932cbbf6
|
F src/util.c 40a12067fa7b18c7e0461b3256b1353c755b59ac
|
||||||
F src/vdbe.c b2c51a114cff35b9ccb7bbfe57483dabf77ed63f
|
F src/vdbe.c b2c51a114cff35b9ccb7bbfe57483dabf77ed63f
|
||||||
F src/vdbe.h 98e445d624fb7d3442b5c06058dcb01182397d12
|
F src/vdbe.h 98e445d624fb7d3442b5c06058dcb01182397d12
|
||||||
F src/where.c 664be01b0ce9ffaecbde609afbd4d8d3e5ed1585
|
F src/where.c 664be01b0ce9ffaecbde609afbd4d8d3e5ed1585
|
||||||
@ -99,6 +99,7 @@ F test/trans.test 9e49495c06b1c41f889bf4f0fb195a015b126de0
|
|||||||
F test/unique.test 07776624b82221a80c8b4138ce0dd8b0853bb3ea
|
F test/unique.test 07776624b82221a80c8b4138ce0dd8b0853bb3ea
|
||||||
F test/update.test 3cf1ca0565f678063c2dfa9a7948d2d66ae1a778
|
F test/update.test 3cf1ca0565f678063c2dfa9a7948d2d66ae1a778
|
||||||
F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e
|
F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e
|
||||||
|
F test/view.test 4619ebede587102e577e19ce52e9852ec8293cbc
|
||||||
F test/where.test 032d581c3de4893eba33b569e581c46b941bb02a
|
F test/where.test 032d581c3de4893eba33b569e581c46b941bb02a
|
||||||
F tool/lemon.c d4b4e127e70633be1bbea49c2ccba5cdb4b77a5f
|
F tool/lemon.c d4b4e127e70633be1bbea49c2ccba5cdb4b77a5f
|
||||||
F tool/lempar.c 2ff255186fffb38a43a9f7b010e87eee6308edcc
|
F tool/lempar.c 2ff255186fffb38a43a9f7b010e87eee6308edcc
|
||||||
@ -126,7 +127,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
|
|||||||
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
||||||
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
|
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
|
||||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||||
P f2310f36d53e9176be7af620ecdf1e5a1dfd4388
|
P 63b87f2ea6cd78f039bf40026d21b18de20b3ba7
|
||||||
R d1216182a693349a4fd75460e56473d0
|
R 9c2c59a14c868fd7e37dce1c3892e2d4
|
||||||
U drh
|
U drh
|
||||||
Z 4fbfc9e2f698b673742701c28533e447
|
Z e0d30da2ff6970c032fa0a7ae0570fac
|
||||||
|
@ -1 +1 @@
|
|||||||
63b87f2ea6cd78f039bf40026d21b18de20b3ba7
|
668ef6380eba256ef82477b63aef850249a619a0
|
14
src/build.c
14
src/build.c
@ -25,7 +25,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.79 2002/02/23 02:32:10 drh Exp $
|
** $Id: build.c,v 1.80 2002/02/27 01:47:12 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -824,6 +824,7 @@ void sqliteCreateView(
|
|||||||
pSelTab->nCol = 0;
|
pSelTab->nCol = 0;
|
||||||
pSelTab->aCol = 0;
|
pSelTab->aCol = 0;
|
||||||
sqliteDeleteTable(0, pSelTab);
|
sqliteDeleteTable(0, pSelTab);
|
||||||
|
sqliteSelectUnbind(pSelect);
|
||||||
sEnd = pParse->sLastToken;
|
sEnd = pParse->sLastToken;
|
||||||
if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
|
if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
|
||||||
sEnd.z += sEnd.n;
|
sEnd.z += sEnd.n;
|
||||||
@ -1341,22 +1342,15 @@ void sqliteIdListDelete(IdList *pList){
|
|||||||
for(i=0; i<pList->nId; i++){
|
for(i=0; i<pList->nId; i++){
|
||||||
sqliteFree(pList->a[i].zName);
|
sqliteFree(pList->a[i].zName);
|
||||||
sqliteFree(pList->a[i].zAlias);
|
sqliteFree(pList->a[i].zAlias);
|
||||||
|
if( pList->a[i].pTab && pList->a[i].pTab->isTransient ){
|
||||||
/* If the pSelect field is set and is not pointing to the Select
|
|
||||||
** structure that defines a VIEW, then the Select is for a subquery
|
|
||||||
** and should be deleted. Do not delete VIEWs, however.
|
|
||||||
*/
|
|
||||||
if( pList->a[i].pSelect &&
|
|
||||||
(pList->a[i].pTab==0 || pList->a[i].pTab->pSelect==0) ){
|
|
||||||
sqliteSelectDelete(pList->a[i].pSelect);
|
|
||||||
sqliteDeleteTable(0, pList->a[i].pTab);
|
sqliteDeleteTable(0, pList->a[i].pTab);
|
||||||
}
|
}
|
||||||
|
sqliteSelectDelete(pList->a[i].pSelect);
|
||||||
}
|
}
|
||||||
sqliteFree(pList->a);
|
sqliteFree(pList->a);
|
||||||
sqliteFree(pList);
|
sqliteFree(pList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The COPY command is for compatibility with PostgreSQL and specificially
|
** The COPY command is for compatibility with PostgreSQL and specificially
|
||||||
** for the ability to read the output of pg_dump. The format is as
|
** for the ability to read the output of pg_dump. The format is as
|
||||||
|
87
src/expr.c
87
src/expr.c
@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.45 2002/02/26 23:55:31 drh Exp $
|
** $Id: expr.c,v 1.46 2002/02/27 01:47:12 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -147,6 +147,91 @@ void sqliteSelectMoveStrings(Select *pSelect, int offset){
|
|||||||
sqliteSelectMoveStrings(pSelect->pPrior, offset);
|
sqliteSelectMoveStrings(pSelect->pPrior, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The following group of routines make deep copies of expressions,
|
||||||
|
** expression lists, ID lists, and select statements. The copies can
|
||||||
|
** be deleted (by being passed to their respective ...Delete() routines)
|
||||||
|
** without effecting the originals.
|
||||||
|
**
|
||||||
|
** Note, however, that the Expr.token.z and Expr.span.z fields point to
|
||||||
|
** string space that is allocated separately from the expression tree
|
||||||
|
** itself. These routines do NOT duplicate that string space.
|
||||||
|
**
|
||||||
|
** The expression list and ID list return by sqliteExprListDup() and
|
||||||
|
** sqliteIdListDup() can not be further expanded by subsequent calls
|
||||||
|
** to sqliteExprListAppend() or sqliteIdListAppend().
|
||||||
|
**
|
||||||
|
** Any tables that the ID list might point to are not duplicated.
|
||||||
|
*/
|
||||||
|
Expr *sqliteExprDup(Expr *p){
|
||||||
|
Expr *pNew;
|
||||||
|
if( p==0 ) return 0;
|
||||||
|
pNew = sqliteMalloc( sizeof(*p) );
|
||||||
|
if( pNew==0 ) return 0;
|
||||||
|
pNew->op = p->op;
|
||||||
|
pNew->pLeft = sqliteExprDup(p->pLeft);
|
||||||
|
pNew->pRight = sqliteExprDup(p->pRight);
|
||||||
|
pNew->pList = sqliteExprListDup(p->pList);
|
||||||
|
pNew->token = p->token;
|
||||||
|
pNew->span = p->span;
|
||||||
|
pNew->pSelect = sqliteSelectDup(p->pSelect);
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
ExprList *sqliteExprListDup(ExprList *p){
|
||||||
|
ExprList *pNew;
|
||||||
|
int i;
|
||||||
|
if( p==0 ) return 0;
|
||||||
|
pNew = sqliteMalloc( sizeof(*pNew) );
|
||||||
|
if( pNew==0 ) return 0;
|
||||||
|
pNew->nExpr = p->nExpr;
|
||||||
|
pNew->a = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
|
||||||
|
for(i=0; i<p->nExpr; i++){
|
||||||
|
pNew->a[i].pExpr = sqliteExprDup(p->a[i].pExpr);
|
||||||
|
pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
|
||||||
|
pNew->a[i].sortOrder = p->a[i].sortOrder;
|
||||||
|
pNew->a[i].isAgg = p->a[i].isAgg;
|
||||||
|
pNew->a[i].done = 0;
|
||||||
|
}
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
IdList *sqliteIdListDup(IdList *p){
|
||||||
|
IdList *pNew;
|
||||||
|
int i;
|
||||||
|
if( p==0 ) return 0;
|
||||||
|
pNew = sqliteMalloc( sizeof(*pNew) );
|
||||||
|
if( pNew==0 ) return 0;
|
||||||
|
pNew->nId = p->nId;
|
||||||
|
pNew->a = sqliteMalloc( p->nId*sizeof(p->a[0]) );
|
||||||
|
for(i=0; i<p->nId; i++){
|
||||||
|
pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
|
||||||
|
pNew->a[i].zAlias = sqliteStrDup(p->a[i].zAlias);
|
||||||
|
pNew->a[i].idx = p->a[i].idx;
|
||||||
|
pNew->a[i].pTab = 0;
|
||||||
|
pNew->a[i].pSelect = sqliteSelectDup(p->a[i].pSelect);
|
||||||
|
}
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
Select *sqliteSelectDup(Select *p){
|
||||||
|
Select *pNew;
|
||||||
|
if( p==0 ) return 0;
|
||||||
|
pNew = sqliteMalloc( sizeof(*p) );
|
||||||
|
if( pNew==0 ) return 0;
|
||||||
|
pNew->isDistinct = p->isDistinct;
|
||||||
|
pNew->pEList = sqliteExprListDup(p->pEList);
|
||||||
|
pNew->pSrc = sqliteIdListDup(p->pSrc);
|
||||||
|
pNew->pWhere = sqliteExprDup(p->pWhere);
|
||||||
|
pNew->pGroupBy = sqliteExprListDup(p->pGroupBy);
|
||||||
|
pNew->pHaving = sqliteExprDup(p->pHaving);
|
||||||
|
pNew->pOrderBy = sqliteExprListDup(p->pOrderBy);
|
||||||
|
pNew->op = p->op;
|
||||||
|
pNew->pPrior = sqliteSelectDup(p->pPrior);
|
||||||
|
pNew->nLimit = p->nLimit;
|
||||||
|
pNew->nOffset = p->nOffset;
|
||||||
|
pNew->zSelect = 0;
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add a new element to the end of an expression list. If pList is
|
** Add a new element to the end of an expression list. If pList is
|
||||||
** initially NULL, then create a new expression list.
|
** initially NULL, then create a new expression list.
|
||||||
|
34
src/select.c
34
src/select.c
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.66 2002/02/24 03:25:16 drh Exp $
|
** $Id: select.c,v 1.67 2002/02/27 01:47:12 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -397,7 +397,7 @@ static int fillInColumnList(Parse *pParse, Select *p){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if( pTab->pSelect ){
|
if( pTab->pSelect ){
|
||||||
pTabList->a[i].pSelect = pTab->pSelect;
|
pTabList->a[i].pSelect = sqliteSelectDup(pTab->pSelect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,6 +456,36 @@ static int fillInColumnList(Parse *pParse, Select *p){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This routine recursively unlinks the Select.pSrc.a[].pTab pointers
|
||||||
|
** in a select structure. It just sets the pointers to NULL. This
|
||||||
|
** routine is recursive in the sense that if the Select.pSrc.a[].pSelect
|
||||||
|
** pointer is not NULL, this routine is called recursively on that pointer.
|
||||||
|
**
|
||||||
|
** This routine is called on the Select structure that defines a
|
||||||
|
** VIEW in order to undo any bindings to tables. This is necessary
|
||||||
|
** because those tables might be DROPed by a subsequent SQL command.
|
||||||
|
*/
|
||||||
|
void sqliteSelectUnbind(Select *p){
|
||||||
|
int i;
|
||||||
|
IdList *pSrc = p->pSrc;
|
||||||
|
Table *pTab;
|
||||||
|
if( p==0 ) return;
|
||||||
|
for(i=0; i<pSrc->nId; i++){
|
||||||
|
if( (pTab = pSrc->a[i].pTab)!=0 ){
|
||||||
|
if( pTab->isTransient ){
|
||||||
|
sqliteDeleteTable(0, pTab);
|
||||||
|
sqliteSelectDelete(pSrc->a[i].pSelect);
|
||||||
|
pSrc->a[i].pSelect = 0;
|
||||||
|
}
|
||||||
|
pSrc->a[i].pTab = 0;
|
||||||
|
if( pSrc->a[i].pSelect ){
|
||||||
|
sqliteSelectUnbind(pSrc->a[i].pSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine associates entries in an ORDER BY expression list with
|
** This routine associates entries in an ORDER BY expression list with
|
||||||
** columns in a result. For each ORDER BY expression, the opcode of
|
** columns in a result. For each ORDER BY expression, the opcode of
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.93 2002/02/24 03:25:16 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.94 2002/02/27 01:47:12 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqlite.h"
|
#include "sqlite.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
@ -605,6 +605,7 @@ int sqliteSelect(Parse*, Select*, int, int);
|
|||||||
Select *sqliteSelectNew(ExprList*,IdList*,Expr*,ExprList*,Expr*,ExprList*,
|
Select *sqliteSelectNew(ExprList*,IdList*,Expr*,ExprList*,Expr*,ExprList*,
|
||||||
int,int,int);
|
int,int,int);
|
||||||
void sqliteSelectDelete(Select*);
|
void sqliteSelectDelete(Select*);
|
||||||
|
void sqliteSelectUnbind(Select*);
|
||||||
Table *sqliteTableNameToTable(Parse*, const char*);
|
Table *sqliteTableNameToTable(Parse*, const char*);
|
||||||
IdList *sqliteTableTokenToIdList(Parse*, Token*);
|
IdList *sqliteTableTokenToIdList(Parse*, Token*);
|
||||||
void sqliteDeleteFrom(Parse*, Token*, Expr*);
|
void sqliteDeleteFrom(Parse*, Token*, Expr*);
|
||||||
@ -646,5 +647,9 @@ void sqliteEndWriteOperation(Parse*);
|
|||||||
void sqliteExprMoveStrings(Expr*, int);
|
void sqliteExprMoveStrings(Expr*, int);
|
||||||
void sqliteExprListMoveStrings(ExprList*, int);
|
void sqliteExprListMoveStrings(ExprList*, int);
|
||||||
void sqliteSelectMoveStrings(Select*, int);
|
void sqliteSelectMoveStrings(Select*, int);
|
||||||
|
Expr *sqliteExprDup(Expr*);
|
||||||
|
ExprList *sqliteExprListDup(ExprList*);
|
||||||
|
IdList *sqliteIdListDup(IdList*);
|
||||||
|
Select *sqliteSelectDup(Select*);
|
||||||
UserFunc *sqliteFindUserFunction(sqlite*,const char*,int,int,int);
|
UserFunc *sqliteFindUserFunction(sqlite*,const char*,int,int,int);
|
||||||
void sqliteRegisterBuildinFunctions(sqlite*);
|
void sqliteRegisterBuildinFunctions(sqlite*);
|
||||||
|
10
src/util.c
10
src/util.c
@ -14,7 +14,7 @@
|
|||||||
** This file contains functions for allocating memory, comparing
|
** This file contains functions for allocating memory, comparing
|
||||||
** strings, and stuff like that.
|
** strings, and stuff like that.
|
||||||
**
|
**
|
||||||
** $Id: util.c,v 1.37 2002/02/14 21:42:51 drh Exp $
|
** $Id: util.c,v 1.38 2002/02/27 01:47:12 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -183,12 +183,16 @@ void sqliteStrRealloc(char **pz){
|
|||||||
** Make a copy of a string in memory obtained from sqliteMalloc()
|
** Make a copy of a string in memory obtained from sqliteMalloc()
|
||||||
*/
|
*/
|
||||||
char *sqliteStrDup_(const char *z, char *zFile, int line){
|
char *sqliteStrDup_(const char *z, char *zFile, int line){
|
||||||
char *zNew = sqliteMalloc_(strlen(z)+1, zFile, line);
|
char *zNew;
|
||||||
|
if( z==0 ) return 0;
|
||||||
|
zNew = sqliteMalloc_(strlen(z)+1, zFile, line);
|
||||||
if( zNew ) strcpy(zNew, z);
|
if( zNew ) strcpy(zNew, z);
|
||||||
return zNew;
|
return zNew;
|
||||||
}
|
}
|
||||||
char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
|
char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
|
||||||
char *zNew = sqliteMalloc_(n+1, zFile, line);
|
char *zNew;
|
||||||
|
if( z==0 ) return 0;
|
||||||
|
zNew = sqliteMalloc_(n+1, zFile, line);
|
||||||
if( zNew ){
|
if( zNew ){
|
||||||
memcpy(zNew, z, n);
|
memcpy(zNew, z, n);
|
||||||
zNew[n] = 0;
|
zNew[n] = 0;
|
||||||
|
75
test/view.test
Normal file
75
test/view.test
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# 2002 February 26
|
||||||
|
#
|
||||||
|
# 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 VIEW statements.
|
||||||
|
#
|
||||||
|
# $Id: view.test,v 1.1 2002/02/27 01:47:12 drh Exp $
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
do_test view-1.0 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t1(a,b,c);
|
||||||
|
INSERT INTO t1 VALUES(1,2,3);
|
||||||
|
INSERT INTO t1 VALUES(4,5,6);
|
||||||
|
INSERT INTO t1 VALUES(7,8,9);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
|
} {1 2 3 4 5 6 7 8 9}
|
||||||
|
|
||||||
|
do_test view-1.1 {
|
||||||
|
execsql {
|
||||||
|
BEGIN;
|
||||||
|
CREATE VIEW v1 AS SELECT a,b FROM t1;
|
||||||
|
SELECT * FROM v1 ORDER BY a;
|
||||||
|
}
|
||||||
|
} {1 2 4 5 7 8}
|
||||||
|
do_test view-1.2 {
|
||||||
|
catchsql {
|
||||||
|
ROLLBACK;
|
||||||
|
SELECT * FROM v1 ORDER BY a;
|
||||||
|
}
|
||||||
|
} {1 {no such table: v1}}
|
||||||
|
do_test view-1.3 {
|
||||||
|
execsql {
|
||||||
|
CREATE VIEW v1 AS SELECT a,b FROM t1;
|
||||||
|
SELECT * FROM v1 ORDER BY a;
|
||||||
|
}
|
||||||
|
} {1 2 4 5 7 8}
|
||||||
|
do_test view-1.4 {
|
||||||
|
catchsql {
|
||||||
|
DROP VIEW v1;
|
||||||
|
SELECT * FROM v1 ORDER BY a;
|
||||||
|
}
|
||||||
|
} {1 {no such table: v1}}
|
||||||
|
do_test view-1.5 {
|
||||||
|
execsql {
|
||||||
|
CREATE VIEW v1 AS SELECT a,b FROM t1;
|
||||||
|
SELECT * FROM v1 ORDER BY a;
|
||||||
|
}
|
||||||
|
} {1 2 4 5 7 8}
|
||||||
|
do_test view-1.6 {
|
||||||
|
catchsql {
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT * FROM v1 ORDER BY a;
|
||||||
|
}
|
||||||
|
} {1 {no such table: t1}}
|
||||||
|
do_test view-1.7 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t1(x,a,b,c);
|
||||||
|
INSERT INTO t1 VALUES(1,2,3,4);
|
||||||
|
INSERT INTO t1 VALUES(4,5,6,7);
|
||||||
|
INSERT INTO t1 VALUES(7,8,9,10);
|
||||||
|
SELECT * FROM v1 ORDER BY a;
|
||||||
|
}
|
||||||
|
} {2 3 5 6 8 9}
|
||||||
|
|
||||||
|
finish_test
|
Reference in New Issue
Block a user