Record within the Token structure itself whether or not the token has

been dequoted.  This steals one bit from the length of a token and
thus limits the size of tokens to 1GiB. (CVS 6589)

FossilOrigin-Name: 12bcb03d9b9e1a31c1a3c67cbb4263cc0af2f3d0
This commit is contained in:
drh 2009-05-01 21:13:36 +00:00
parent d51397a614
commit 24fb627afa
14 changed files with 76 additions and 110 deletions

View File

@ -1,5 +1,5 @@
C Fix\san\serror\smessage\sthat\sis\sgenerated\sif\sthe\snumber\sof\scolumns\sdo\snot\nmatch\son\san\sINSERT\sinto\sa\svirtual\stable\swith\shidden\scolumns.\s(CVS\s6588)
D 2009-05-01T15:17:48
C Record\swithin\sthe\sToken\sstructure\sitself\swhether\sor\snot\sthe\stoken\shas\nbeen\sdequoted.\s\sThis\ssteals\sone\sbit\sfrom\sthe\slength\sof\sa\stoken\sand\nthus\slimits\sthe\ssize\sof\stokens\sto\s1GiB.\s(CVS\s6589)
D 2009-05-01T21:13:37
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -109,12 +109,12 @@ F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
F src/btree.c 4bef945f2b711674608e8ffde709007ce29245cc
F src/btree.h 99fcc7e8c4a1e35afe271bcb38de1a698dfc904e
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
F src/build.c dca0ad77c88cb00f6a11cc080a4f3285672cfa37
F src/build.c a079f965feea2d0b469b293e09cd0ac41be1272f
F src/callback.c 73016376d6848ba987709e8c9048d4f0e0776036
F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0
F src/date.c d327ec7bb2f64b08d32b1035de82b9ba8675de91
F src/delete.c 5416059acea6e9f9798feb9588d474ec86bf7b3e
F src/expr.c dd763d6dc8f8329e895440d436c28aa7b5b3595e
F src/delete.c a0a0932eea77471ab243337026abbce444024c43
F src/expr.c 40b35167137c53777d15d3247d93615b4eefec2d
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c f667fe886309707c7178542073bb0ced00a9fae7
F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c
@ -148,7 +148,7 @@ F src/os_unix.c 9ad9f45049a3c9eb0b0713b162ff0d7024ff7259
F src/os_win.c 725c38a524d168ce280446ad8761d731bc516405
F src/pager.c 059490959c4481eaaf8f9d868b655603e2c8830c
F src/pager.h 73f481a308a873ccd626d97331c081db3b53e2e5
F src/parse.y b7e4341b21736a90b952aa6bb663ec98529b778e
F src/parse.y a0e8b8e5d646a6352098fccc9d3325b4234a05b9
F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d
F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324
F src/pcache1.c 35f8601c91c09a1e887a1914ebca07bb5afc7b89
@ -156,13 +156,13 @@ F src/pragma.c c26c16c49a80d03c8597f0e6c7daba53f283428f
F src/prepare.c 72d74e6d3b9c8eb0663b33ec6438aa718096ac79
F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d
F src/resolve.c d01b53d81ab9b28ba7161c1af9e02bc90bbd685b
F src/rowset.c 14d12b5e81b5907b87d511f6f4219805f96a4b55
F src/select.c 40748e8044b79d41ba04ce1014ae45434ed452d3
F src/select.c 84022ec5d41c321e98fa96e4f4d5e44de203a099
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
F src/sqlite.h.in 926985a312747e284c21ab32a8e8231a3bed9bd1
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 892933c96168a6606f931cf261eef2e0781a51e4
F src/sqliteInt.h 6ca6e40ee904ccdbbaaa3da82c0c92057459cf75
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
@ -197,11 +197,11 @@ F src/test_server.c f0a403b5f699c09bd2b1236b6f69830fd6221f6b
F src/test_tclvar.c 9e42fa59d3d2f064b7ab8628e7ab2dc8a9fe93d4
F src/test_thread.c b8a1ab7ca1a632f18e8a361880d5d65eeea08eac
F src/test_wsd.c 3ae5101de6cbfda2720152ab659ea84079719241
F src/tokenize.c 7bd3b6dd56566604ad24ed4aa017e6618166b500
F src/tokenize.c 286ce8a4bffe5ec81ad893e6243684d8f8846ed9
F src/trigger.c 448615bec40efcd6b3a9362a060f2e7067f25be5
F src/update.c 5062f0f042f67a4da0aff69949f145e2bc96e3cd
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
F src/util.c 828c552a22a1d5b650b8a5ea0009546715c45d93
F src/util.c b19471b83b77785635172a740b55a0efead3f921
F src/vacuum.c 07121a727beeee88f27d704a00313ad6a7c9bef0
F src/vdbe.c 5fe07cce9f010cd052535463bd0348e8d513b448
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
@ -209,10 +209,10 @@ F src/vdbeInt.h 8726f7b4e3b55c8acf6d304a5b5f727ac1b6c5ab
F src/vdbeapi.c 86aa27a5f3493aaffb8ac051782aa3b22670d7ed
F src/vdbeaux.c 34524d499fc6081e97771dcfdf6c2523d5877ef5
F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
F src/vdbemem.c 111d8193859d16aefd5d3cb57472808584ea5503
F src/vdbemem.c f5d7c0b7db32ab6939cbfa371b3b329d16a0ee21
F src/vtab.c 53355aa2381ec3ef2eaad25672cfd5877a02fe45
F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
F src/where.c de8984ae4c5283f55ec2081bbbdba0375b9e3aa9
F src/where.c 823891e165c20ce781762a0d26f68ec908439687
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
@ -291,7 +291,7 @@ F test/corrupt9.test 794d284109c65c8f10a2b275479045e02d163bae
F test/corruptA.test 99e95620b980161cb3e79f06a884a4bb8ae265ff
F test/corruptB.test 505331779fe7a96fe38ecbb817f19c63bc27d171
F test/corruptC.test 47d544f612b8a26a05900d65289abb1ae3b30837
F test/count.test 276b32260ecfa1f3c50799818fd1aea99888eea8
F test/count.test 99c78f584038fec8fe081447738307c9dc69e5e0
F test/crash.test 1b6ac8410689ff78028887f445062dc897c9ac89
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
F test/crash3.test 776f9363554c029fcce71d9e6600fa0ba6359ce7
@ -727,7 +727,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 26444f2a4426d2e51464ef69ed83d3c78be2c11f
R a7b7da6fb08bfdf4e4ff65e830279077
P 795b453c9a03c32d9d4cdf62823d2b9dd667cc44
R 994fb061d5b0d2325e7c5c8dbfd393af
U drh
Z 31a5607fdeaa1ad6f85e12d6d8547948
Z d49f301efd3673d168abb1e51c03747b

View File

@ -1 +1 @@
795b453c9a03c32d9d4cdf62823d2b9dd667cc44
12bcb03d9b9e1a31c1a3c67cbb4263cc0af2f3d0

View File

@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
** $Id: build.c,v 1.532 2009/04/28 13:01:09 drh Exp $
** $Id: build.c,v 1.533 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
@ -579,10 +579,13 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
/*
** Given a token, return a string that consists of the text of that
** token with any quotations removed. Space to hold the returned string
** token. Space to hold the returned string
** is obtained from sqliteMalloc() and must be freed by the calling
** function.
**
** Any quotation marks (ex: "name", 'name', [name], or `name`) that
** surround the body of the token are removed.
**
** Tokens are often just pointers into the original SQL text and so
** are not \000 terminated and are not persistent. The returned string
** is \000 terminated and is persistent.
@ -591,7 +594,7 @@ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
char *zName;
if( pName ){
zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n);
sqlite3Dequote(zName);
if( pName->quoted ) sqlite3Dequote(zName);
}else{
zName = 0;
}

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.200 2009/04/30 00:11:10 drh Exp $
** $Id: delete.c,v 1.201 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
@ -87,6 +87,7 @@ void sqlite3MaterializeView(
pWhere = sqlite3ExprDup(db, pWhere, 0);
viewName.z = (u8*)pView->zName;
viewName.n = (unsigned int)sqlite3Strlen30((const char*)viewName.z);
viewName.quoted = 0;
pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName, pDup, 0,0);
pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
}

View File

@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.430 2009/04/28 12:08:15 danielk1977 Exp $
** $Id: expr.c,v 1.431 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
@ -407,21 +407,18 @@ Expr *sqlite3Expr(
int c;
assert( pToken->dyn==0 );
pNew->span = *pToken;
/* The pToken->z value is read-only. But the new expression
** node created here might be passed to sqlite3DequoteExpr() which
** will attempt to modify pNew->token.z. Hence, if the token
** is quoted, make a copy now so that DequoteExpr() will change
** the copy rather than the original text.
*/
if( pToken->n>=2
&& ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
sqlite3TokenCopy(db, &pNew->token, pToken);
if( pNew->token.z ){
pNew->token.n = sqlite3Dequote((char*)pNew->token.z);
assert( pNew->token.n==sqlite3Strlen30((char*)pNew->token.z) );
}
if( c=='"' ) pNew->flags |= EP_DblQuoted;
}else{
pNew->token = *pToken;
pNew->flags |= EP_Dequoted;
VVA_ONLY( pNew->vvaFlags |= EVVA_ReadOnlyToken; )
}
pNew->token.quoted = 0;
}else if( pLeft ){
if( pRight ){
if( pRight->span.dyn==0 && pLeft->span.dyn==0 ){
@ -658,18 +655,6 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
sqlite3DbFree(db, p);
}
/*
** The Expr.token field might be a string literal that is quoted.
** If so, remove the quotation marks.
*/
void sqlite3DequoteExpr(Expr *p){
if( !ExprHasAnyProperty(p, EP_Dequoted) ){
ExprSetProperty(p, EP_Dequoted);
assert( (p->vvaFlags & EVVA_ReadOnlyToken)==0 );
sqlite3Dequote((char*)p->token.z);
}
}
/*
** Return the number of bytes allocated for the expression structure
** passed as the first argument. This is always one of EXPR_FULLSIZE,
@ -1595,7 +1580,7 @@ void sqlite3CodeSubselect(
** value of this select in a memory cell and record the number
** of the memory cell in iColumn.
*/
static const Token one = { (u8*)"1", 0, 1 };
static const Token one = { (u8*)"1", 0, 0, 1 };
Select *pSel;
SelectDest dest;
@ -2082,8 +2067,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
break;
}
case TK_STRING: {
sqlite3DequoteExpr(pExpr);
sqlite3VdbeAddOp4(v,OP_String8, 0, target, 0,
sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0,
(char*)pExpr->token.z, pExpr->token.n);
break;
}
@ -2591,7 +2575,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
assert( pExpr->affinity==OE_Rollback ||
pExpr->affinity == OE_Abort ||
pExpr->affinity == OE_Fail );
sqlite3DequoteExpr(pExpr);
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->affinity, 0,
(char*)pExpr->token.z, pExpr->token.n);
} else {

View File

@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.274 2009/04/06 14:16:43 drh Exp $
** @(#) $Id: parse.y,v 1.275 2009/05/01 21:13:37 drh Exp $
*/
// All token codes are small integers with #defines that begin with "TK_"
@ -166,6 +166,8 @@ columnlist ::= column.
column(A) ::= columnid(X) type carglist. {
A.z = X.z;
A.n = (int)(pParse->sLastToken.z-X.z) + pParse->sLastToken.n;
A.quoted = 0;
A.dyn = 0;
}
columnid(A) ::= nm(X). {
sqlite3AddColumn(pParse,&X);

View File

@ -14,7 +14,7 @@
** resolve all identifiers by associating them with a particular
** table and column.
**
** $Id: resolve.c,v 1.20 2009/03/05 04:23:47 shane Exp $
** $Id: resolve.c,v 1.21 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
@ -319,7 +319,7 @@ static int lookupName(
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
sqlite3DbFree(db, zCol);
pExpr->op = TK_STRING;
pExpr->pTab = 0;

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.510 2009/04/24 15:46:22 drh Exp $
** $Id: select.c,v 1.511 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
@ -193,42 +193,7 @@ static void setToken(Token *p, const char *z){
p->z = (u8*)z;
p->n = z ? sqlite3Strlen30(z) : 0;
p->dyn = 0;
}
/*
** Set the token to the double-quoted and escaped version of the string pointed
** to by z. For example;
**
** {a"bc} -> {"a""bc"}
*/
static void setQuotedToken(Parse *pParse, Token *p, const char *z){
/* Check if the string appears to be quoted using "..." or `...`
** or [...] or '...' or if the string contains any " characters.
** If it does, then record a version of the string with the special
** characters escaped.
*/
const char *z2 = z;
if( *z2!='[' && *z2!='`' && *z2!='\'' ){
while( *z2 ){
if( *z2=='"' ) break;
z2++;
}
}
if( *z2 ){
/* String contains " characters - copy and quote the string. */
p->z = (u8 *)sqlite3MPrintf(pParse->db, "\"%w\"", z);
if( p->z ){
p->n = sqlite3Strlen30((char *)p->z);
p->dyn = 1;
}
}else{
/* String contains no " characters - copy the pointer. */
p->z = (u8*)z;
p->n = (int)(z2 - z);
p->dyn = 0;
}
p->quoted = 0;
}
/*
@ -3228,12 +3193,12 @@ static int selectExpander(Walker *pWalker, Select *p){
}
pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
if( pRight==0 ) break;
setQuotedToken(pParse, &pRight->token, zName);
setToken(&pRight->token, zName);
if( longNames || pTabList->nSrc>1 ){
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
if( pExpr==0 ) break;
setQuotedToken(pParse, &pLeft->token, zTabName);
setToken(&pLeft->token, zTabName);
setToken(&pExpr->span,
sqlite3MPrintf(db, "%s.%s", zTabName, zName));
pExpr->span.dyn = 1;

View File

@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.864 2009/04/30 12:25:10 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.865 2009/05/01 21:13:37 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@ -1354,8 +1354,9 @@ struct Index {
*/
struct Token {
const unsigned char *z; /* Text of the token. Not NULL-terminated! */
unsigned dyn : 1; /* True for malloced memory, false for static */
unsigned n : 31; /* Number of characters in this token */
unsigned dyn : 1; /* True for malloced memory, false for static */
unsigned quoted : 1; /* True if token still has its quotes */
unsigned n : 30; /* Number of characters in this token */
};
/*
@ -1517,7 +1518,7 @@ struct Expr {
#define EP_Error 0x0008 /* Expression contains one or more errors */
#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
#define EP_Dequoted 0x0040 /* True if the string has been dequoted */
#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
#define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */
@ -2360,8 +2361,7 @@ char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
void sqlite3SetString(char **, sqlite3*, const char*, ...);
void sqlite3ErrorMsg(Parse*, const char*, ...);
void sqlite3ErrorClear(Parse*);
void sqlite3Dequote(char*);
void sqlite3DequoteExpr(Expr*);
int sqlite3Dequote(char*);
int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
void sqlite3FinishCoding(Parse*);

View File

@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.155 2009/03/31 03:41:57 shane Exp $
** $Id: tokenize.c,v 1.156 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
@ -413,10 +413,12 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
assert( pParse->apVarExpr==0 );
enableLookaside = db->lookaside.bEnabled;
if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
pParse->sLastToken.quoted = 1;
while( !db->mallocFailed && zSql[i]!=0 ){
assert( i>=0 );
pParse->sLastToken.z = (u8*)&zSql[i];
assert( pParse->sLastToken.dyn==0 );
assert( pParse->sLastToken.quoted );
pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
i += pParse->sLastToken.n;
if( i>mxSqlLen ){

View File

@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.251 2009/04/17 15:18:48 drh Exp $
** $Id: util.c,v 1.252 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@ -203,21 +203,28 @@ void sqlite3ErrorClear(Parse *pParse){
** input does not begin with a quote character, then this routine
** is a no-op.
**
** The input string must be zero-terminated. A new zero-terminator
** is added to the dequoted string.
**
** The return value is -1 if no dequoting occurs or the length of the
** dequoted string, exclusive of the zero terminator, if dequoting does
** occur.
**
** 2002-Feb-14: This routine is extended to remove MS-Access style
** brackets from around identifers. For example: "[a-b-c]" becomes
** "a-b-c".
*/
void sqlite3Dequote(char *z){
int sqlite3Dequote(char *z){
char quote;
int i, j;
if( z==0 ) return;
if( z==0 ) return -1;
quote = z[0];
switch( quote ){
case '\'': break;
case '"': break;
case '`': break; /* For MySQL compatibility */
case '[': quote = ']'; break; /* For MS SqlServer compatibility */
default: return;
default: return -1;
}
for(i=1, j=0; z[i]; i++){
if( z[i]==quote ){
@ -225,13 +232,14 @@ void sqlite3Dequote(char *z){
z[j++] = quote;
i++;
}else{
z[j++] = 0;
break;
}
}else{
z[j++] = z[i];
}
}
z[j] = 0;
return j;
}
/* Convenient short-hand */

View File

@ -15,7 +15,7 @@
** only within the VDBE. Interface routines refer to a Mem using the
** name sqlite_value
**
** $Id: vdbemem.c,v 1.142 2009/04/22 02:15:49 drh Exp $
** $Id: vdbemem.c,v 1.143 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
@ -977,7 +977,6 @@ int sqlite3ValueFromExpr(
zVal = sqlite3DbStrNDup(db, (char*)pExpr->token.z, pExpr->token.n);
pVal = sqlite3ValueNew(db);
if( !zVal || !pVal ) goto no_mem;
sqlite3Dequote(zVal);
sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);

View File

@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.391 2009/04/29 11:50:54 danielk1977 Exp $
** $Id: where.c,v 1.392 2009/05/01 21:13:37 drh Exp $
*/
#include "sqliteInt.h"
@ -625,6 +625,7 @@ static int isLikeOrGlob(
Expr *pRight, *pLeft; /* Right and left size of LIKE operator */
ExprList *pList; /* List of operands to the LIKE operator */
int c; /* One character in z[] */
int n; /* Length of string z[] */
int cnt; /* Number of non-wildcard prefix characters */
char wc[3]; /* Wildcard characters */
CollSeq *pColl; /* Collating sequence for LHS */
@ -655,11 +656,13 @@ static int isLikeOrGlob(
(pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
return 0;
}
sqlite3DequoteExpr(pRight);
z = (char *)pRight->token.z;
z = (const char*)pRight->token.z;
cnt = 0;
if( z ){
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; }
n = pRight->token.n;
while( cnt<n && (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
}
}
if( cnt==0 || 255==(u8)z[cnt-1] ){
return 0;
@ -1160,7 +1163,6 @@ static void exprAnalyze(
if( pStr1 ){
sqlite3TokenCopy(db, &pStr1->token, &pRight->token);
pStr1->token.n = nPattern;
pStr1->flags = EP_Dequoted;
}
pStr2 = sqlite3ExprDup(db, pStr1, 0);
if( !db->mallocFailed ){

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing "SELECT count(*)" statements.
#
# $Id: count.test,v 1.4 2009/04/02 20:27:28 drh Exp $
# $Id: count.test,v 1.5 2009/05/01 21:13:37 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -155,6 +155,7 @@ ifcapable vtab {
}
do_test count-3.1 {
breakpoint
execsql {
CREATE TABLE t3(a, b);
SELECT a FROM (SELECT count(*) AS a FROM t3) WHERE a==0;