mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-23 21:49:02 +03:00
Merge recent trunk changes into the fullscan-covering-index branch.
FossilOrigin-Name: 1c0bf0305ce9528a0d07c86a390c5872e16bdb57
This commit is contained in:
@@ -1662,6 +1662,7 @@ int sqlite3CodeSubselect(
|
||||
case TK_IN: {
|
||||
char affinity; /* Affinity of the LHS of the IN */
|
||||
KeyInfo keyInfo; /* Keyinfo for the generated table */
|
||||
static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
|
||||
int addr; /* Address of OP_OpenEphemeral instruction */
|
||||
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
|
||||
|
||||
@@ -1689,6 +1690,7 @@ int sqlite3CodeSubselect(
|
||||
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
|
||||
memset(&keyInfo, 0, sizeof(keyInfo));
|
||||
keyInfo.nField = 1;
|
||||
keyInfo.aSortOrder = &sortOrder;
|
||||
|
||||
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||
/* Case 1: expr IN (SELECT ...)
|
||||
@@ -1729,6 +1731,7 @@ int sqlite3CodeSubselect(
|
||||
affinity = SQLITE_AFF_NONE;
|
||||
}
|
||||
keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
|
||||
keyInfo.aSortOrder = &sortOrder;
|
||||
|
||||
/* Loop through each expression in <exprlist>. */
|
||||
r1 = sqlite3GetTempReg(pParse);
|
||||
|
||||
38
src/func.c
38
src/func.c
@@ -493,7 +493,7 @@ struct compareInfo {
|
||||
** whereas only characters less than 0x80 do in ASCII.
|
||||
*/
|
||||
#if defined(SQLITE_EBCDIC)
|
||||
# define sqlite3Utf8Read(A,C) (*(A++))
|
||||
# define sqlite3Utf8Read(A) (*((*A)++))
|
||||
# define GlogUpperToLower(A) A = sqlite3UpperToLower[A]
|
||||
#else
|
||||
# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
|
||||
@@ -550,18 +550,18 @@ static int patternCompare(
|
||||
u8 noCase = pInfo->noCase;
|
||||
int prevEscape = 0; /* True if the previous character was 'escape' */
|
||||
|
||||
while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){
|
||||
if( !prevEscape && c==matchAll ){
|
||||
while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll
|
||||
while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
|
||||
if( c==matchAll && !prevEscape ){
|
||||
while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
|
||||
|| c == matchOne ){
|
||||
if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){
|
||||
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if( c==0 ){
|
||||
return 1;
|
||||
}else if( c==esc ){
|
||||
c = sqlite3Utf8Read(zPattern, &zPattern);
|
||||
c = sqlite3Utf8Read(&zPattern);
|
||||
if( c==0 ){
|
||||
return 0;
|
||||
}
|
||||
@@ -573,25 +573,25 @@ static int patternCompare(
|
||||
}
|
||||
return *zString!=0;
|
||||
}
|
||||
while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){
|
||||
while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
|
||||
if( noCase ){
|
||||
GlogUpperToLower(c2);
|
||||
GlogUpperToLower(c);
|
||||
while( c2 != 0 && c2 != c ){
|
||||
c2 = sqlite3Utf8Read(zString, &zString);
|
||||
c2 = sqlite3Utf8Read(&zString);
|
||||
GlogUpperToLower(c2);
|
||||
}
|
||||
}else{
|
||||
while( c2 != 0 && c2 != c ){
|
||||
c2 = sqlite3Utf8Read(zString, &zString);
|
||||
c2 = sqlite3Utf8Read(&zString);
|
||||
}
|
||||
}
|
||||
if( c2==0 ) return 0;
|
||||
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}else if( !prevEscape && c==matchOne ){
|
||||
if( sqlite3Utf8Read(zString, &zString)==0 ){
|
||||
}else if( c==matchOne && !prevEscape ){
|
||||
if( sqlite3Utf8Read(&zString)==0 ){
|
||||
return 0;
|
||||
}
|
||||
}else if( c==matchSet ){
|
||||
@@ -599,20 +599,20 @@ static int patternCompare(
|
||||
assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
|
||||
seen = 0;
|
||||
invert = 0;
|
||||
c = sqlite3Utf8Read(zString, &zString);
|
||||
c = sqlite3Utf8Read(&zString);
|
||||
if( c==0 ) return 0;
|
||||
c2 = sqlite3Utf8Read(zPattern, &zPattern);
|
||||
c2 = sqlite3Utf8Read(&zPattern);
|
||||
if( c2=='^' ){
|
||||
invert = 1;
|
||||
c2 = sqlite3Utf8Read(zPattern, &zPattern);
|
||||
c2 = sqlite3Utf8Read(&zPattern);
|
||||
}
|
||||
if( c2==']' ){
|
||||
if( c==']' ) seen = 1;
|
||||
c2 = sqlite3Utf8Read(zPattern, &zPattern);
|
||||
c2 = sqlite3Utf8Read(&zPattern);
|
||||
}
|
||||
while( c2 && c2!=']' ){
|
||||
if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
|
||||
c2 = sqlite3Utf8Read(zPattern, &zPattern);
|
||||
c2 = sqlite3Utf8Read(&zPattern);
|
||||
if( c>=prior_c && c<=c2 ) seen = 1;
|
||||
prior_c = 0;
|
||||
}else{
|
||||
@@ -621,7 +621,7 @@ static int patternCompare(
|
||||
}
|
||||
prior_c = c2;
|
||||
}
|
||||
c2 = sqlite3Utf8Read(zPattern, &zPattern);
|
||||
c2 = sqlite3Utf8Read(&zPattern);
|
||||
}
|
||||
if( c2==0 || (seen ^ invert)==0 ){
|
||||
return 0;
|
||||
@@ -629,7 +629,7 @@ static int patternCompare(
|
||||
}else if( esc==c && !prevEscape ){
|
||||
prevEscape = 1;
|
||||
}else{
|
||||
c2 = sqlite3Utf8Read(zString, &zString);
|
||||
c2 = sqlite3Utf8Read(&zString);
|
||||
if( noCase ){
|
||||
GlogUpperToLower(c);
|
||||
GlogUpperToLower(c2);
|
||||
@@ -701,7 +701,7 @@ static void likeFunc(
|
||||
"ESCAPE expression must be a single character", -1);
|
||||
return;
|
||||
}
|
||||
escape = sqlite3Utf8Read(zEsc, &zEsc);
|
||||
escape = sqlite3Utf8Read(&zEsc);
|
||||
}
|
||||
if( zA && zB ){
|
||||
struct compareInfo *pInfo = sqlite3_user_data(context);
|
||||
|
||||
@@ -1892,6 +1892,7 @@ static int multiSelect(
|
||||
*apColl = db->pDfltColl;
|
||||
}
|
||||
}
|
||||
pKeyInfo->aSortOrder = (u8*)apColl;
|
||||
|
||||
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
|
||||
for(i=0; i<2; i++){
|
||||
|
||||
@@ -962,16 +962,13 @@ struct sqlite3 {
|
||||
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
|
||||
** These must be the low-order bits of the flags field.
|
||||
*/
|
||||
#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */
|
||||
#define SQLITE_ColumnCache 0x02 /* Disable the column cache */
|
||||
#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */
|
||||
#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */
|
||||
#define SQLITE_IndexCover 0x10 /* Disable index covering table */
|
||||
#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */
|
||||
#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */
|
||||
#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */
|
||||
#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */
|
||||
#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
|
||||
#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */
|
||||
#define SQLITE_ColumnCache 0x02 /* Disable the column cache */
|
||||
#define SQLITE_GroupByOrder 0x04 /* Disable GROUPBY cover of ORDERBY */
|
||||
#define SQLITE_FactorOutConst 0x08 /* Disable factoring out constants */
|
||||
#define SQLITE_IdxRealAsInt 0x10 /* Store REAL as INT in indices */
|
||||
#define SQLITE_DistinctOpt 0x20 /* DISTINCT using indexes */
|
||||
#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
|
||||
|
||||
/*
|
||||
** Possible values for the sqlite.magic field.
|
||||
@@ -2956,7 +2953,7 @@ int sqlite3GetInt32(const char *, int*);
|
||||
int sqlite3Atoi(const char*);
|
||||
int sqlite3Utf16ByteLen(const void *pData, int nChar);
|
||||
int sqlite3Utf8CharLen(const char *pData, int nByte);
|
||||
u32 sqlite3Utf8Read(const u8*, const u8**);
|
||||
u32 sqlite3Utf8Read(const u8**);
|
||||
|
||||
/*
|
||||
** Routines to read and write variable-length integers. These used to
|
||||
|
||||
@@ -5936,12 +5936,10 @@ static int optimization_control(
|
||||
{ "all", SQLITE_OptMask },
|
||||
{ "query-flattener", SQLITE_QueryFlattener },
|
||||
{ "column-cache", SQLITE_ColumnCache },
|
||||
{ "index-sort", SQLITE_IndexSort },
|
||||
{ "index-search", SQLITE_IndexSearch },
|
||||
{ "index-cover", SQLITE_IndexCover },
|
||||
{ "groupby-order", SQLITE_GroupByOrder },
|
||||
{ "factor-constants", SQLITE_FactorOutConst },
|
||||
{ "real-as-int", SQLITE_IdxRealAsInt },
|
||||
{ "distinct-opt", SQLITE_DistinctOpt },
|
||||
};
|
||||
|
||||
if( objc!=4 ){
|
||||
|
||||
16
src/utf.c
16
src/utf.c
@@ -164,25 +164,23 @@ static const unsigned char sqlite3Utf8Trans1[] = {
|
||||
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
|
||||
}
|
||||
u32 sqlite3Utf8Read(
|
||||
const unsigned char *zIn, /* First byte of UTF-8 character */
|
||||
const unsigned char **pzNext /* Write first byte past UTF-8 char here */
|
||||
const unsigned char **pz /* Pointer to string from which to read char */
|
||||
){
|
||||
unsigned int c;
|
||||
|
||||
/* Same as READ_UTF8() above but without the zTerm parameter.
|
||||
** For this routine, we assume the UTF8 string is always zero-terminated.
|
||||
*/
|
||||
c = *(zIn++);
|
||||
c = *((*pz)++);
|
||||
if( c>=0xc0 ){
|
||||
c = sqlite3Utf8Trans1[c-0xc0];
|
||||
while( (*zIn & 0xc0)==0x80 ){
|
||||
c = (c<<6) + (0x3f & *(zIn++));
|
||||
while( (*(*pz) & 0xc0)==0x80 ){
|
||||
c = (c<<6) + (0x3f & *((*pz)++));
|
||||
}
|
||||
if( c<0x80
|
||||
|| (c&0xFFFFF800)==0xD800
|
||||
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
|
||||
}
|
||||
*pzNext = zIn;
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -283,7 +281,6 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
|
||||
if( desiredEnc==SQLITE_UTF16LE ){
|
||||
/* UTF-8 -> UTF-16 Little-endian */
|
||||
while( zIn<zTerm ){
|
||||
/* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
|
||||
READ_UTF8(zIn, zTerm, c);
|
||||
WRITE_UTF16LE(z, c);
|
||||
}
|
||||
@@ -291,7 +288,6 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
|
||||
assert( desiredEnc==SQLITE_UTF16BE );
|
||||
/* UTF-8 -> UTF-16 Big-endian */
|
||||
while( zIn<zTerm ){
|
||||
/* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
|
||||
READ_UTF8(zIn, zTerm, c);
|
||||
WRITE_UTF16BE(z, c);
|
||||
}
|
||||
@@ -419,7 +415,7 @@ int sqlite3Utf8To8(unsigned char *zIn){
|
||||
u32 c;
|
||||
|
||||
while( zIn[0] && zOut<=zIn ){
|
||||
c = sqlite3Utf8Read(zIn, (const u8**)&zIn);
|
||||
c = sqlite3Utf8Read((const u8**)&zIn);
|
||||
if( c!=0xfffd ){
|
||||
WRITE_UTF8(zOut, c);
|
||||
}
|
||||
@@ -524,7 +520,7 @@ void sqlite3UtfSelfTest(void){
|
||||
assert( n>0 && n<=4 );
|
||||
z[0] = 0;
|
||||
z = zBuf;
|
||||
c = sqlite3Utf8Read(z, (const u8**)&z);
|
||||
c = sqlite3Utf8Read((const u8**)&z);
|
||||
t = i;
|
||||
if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
|
||||
if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
|
||||
|
||||
@@ -745,10 +745,9 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
|
||||
u8 *aSortOrder;
|
||||
memcpy((char*)pKeyInfo, zP4, nByte - nField);
|
||||
aSortOrder = pKeyInfo->aSortOrder;
|
||||
if( aSortOrder ){
|
||||
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
|
||||
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
|
||||
}
|
||||
assert( aSortOrder!=0 );
|
||||
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
|
||||
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
|
||||
pOp->p4type = P4_KEYINFO;
|
||||
}else{
|
||||
p->db->mallocFailed = 1;
|
||||
@@ -861,6 +860,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
case P4_KEYINFO: {
|
||||
int i, j;
|
||||
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
|
||||
i = sqlite3Strlen30(zTemp);
|
||||
for(j=0; j<pKeyInfo->nField; j++){
|
||||
@@ -872,7 +872,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
break;
|
||||
}
|
||||
zTemp[i++] = ',';
|
||||
if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
|
||||
if( pKeyInfo->aSortOrder[j] ){
|
||||
zTemp[i++] = '-';
|
||||
}
|
||||
memcpy(&zTemp[i], pColl->zName,n+1);
|
||||
@@ -2583,9 +2583,6 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
|
||||
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
|
||||
i64 i = pMem->u.i;
|
||||
u64 u;
|
||||
if( file_format>=4 && (i&1)==i ){
|
||||
return 8+(u32)i;
|
||||
}
|
||||
if( i<0 ){
|
||||
if( i<(-MAX_6BYTE) ) return 6;
|
||||
/* Previous test prevents: u = -(-9223372036854775808) */
|
||||
@@ -2593,7 +2590,9 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
|
||||
}else{
|
||||
u = i;
|
||||
}
|
||||
if( u<=127 ) return 1;
|
||||
if( u<=127 ){
|
||||
return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
|
||||
}
|
||||
if( u<=32767 ) return 2;
|
||||
if( u<=8388607 ) return 3;
|
||||
if( u<=2147483647 ) return 4;
|
||||
@@ -2878,6 +2877,7 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
|
||||
}
|
||||
|
||||
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
p->pKeyInfo = pKeyInfo;
|
||||
p->nField = pKeyInfo->nField + 1;
|
||||
return p;
|
||||
@@ -2971,6 +2971,7 @@ int sqlite3VdbeRecordCompare(
|
||||
idx1 = getVarint32(aKey1, szHdr1);
|
||||
d1 = szHdr1;
|
||||
nField = pKeyInfo->nField;
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
while( idx1<szHdr1 && i<pPKey2->nField ){
|
||||
u32 serial_type1;
|
||||
|
||||
@@ -2990,7 +2991,7 @@ int sqlite3VdbeRecordCompare(
|
||||
assert( mem1.zMalloc==0 ); /* See comment below */
|
||||
|
||||
/* Invert the result if we are using DESC sort order. */
|
||||
if( pKeyInfo->aSortOrder && i<nField && pKeyInfo->aSortOrder[i] ){
|
||||
if( i<nField && pKeyInfo->aSortOrder[i] ){
|
||||
rc = -rc;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user