mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
Simplification and size reduction to the printf logic. Remove the bFlags
parameter from sqlite3VXPrintf() and sqlite3XPrintf(). Use sqlite3XPrintf() instead of sqlite3_snprintf() for rendering P4 values in EXPLAIN output. FossilOrigin-Name: 0bdb41c45aa1cc8e5c136aaa6605d54b401483bd
This commit is contained in:
@@ -8805,9 +8805,9 @@ static void checkAppendMsg(
|
||||
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
|
||||
}
|
||||
if( pCheck->zPfx ){
|
||||
sqlite3XPrintf(&pCheck->errMsg, 0, pCheck->zPfx, pCheck->v1, pCheck->v2);
|
||||
sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
|
||||
}
|
||||
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
|
||||
sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
|
||||
va_end(ap);
|
||||
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
|
||||
pCheck->mallocFailed = 1;
|
||||
@@ -9321,6 +9321,7 @@ char *sqlite3BtreeIntegrityCheck(
|
||||
sCheck.aPgRef = 0;
|
||||
sCheck.heap = 0;
|
||||
sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
|
||||
sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
|
||||
if( sCheck.nPage==0 ){
|
||||
goto integrity_ck_cleanup;
|
||||
}
|
||||
|
||||
@@ -4132,14 +4132,14 @@ void sqlite3UniqueConstraint(
|
||||
|
||||
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
|
||||
if( pIdx->aColExpr ){
|
||||
sqlite3XPrintf(&errMsg, 0, "index '%q'", pIdx->zName);
|
||||
sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
|
||||
}else{
|
||||
for(j=0; j<pIdx->nKeyCol; j++){
|
||||
char *zCol;
|
||||
assert( pIdx->aiColumn[j]>=0 );
|
||||
zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
|
||||
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
|
||||
sqlite3XPrintf(&errMsg, 0, "%s.%s", pTab->zName, zCol);
|
||||
sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol);
|
||||
}
|
||||
}
|
||||
zErr = sqlite3StrAccumFinish(&errMsg);
|
||||
|
||||
@@ -239,7 +239,8 @@ static void printfFunc(
|
||||
x.nUsed = 0;
|
||||
x.apArg = argv+1;
|
||||
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
|
||||
str.printfFlags = SQLITE_PRINTF_SQLFUNC;
|
||||
sqlite3XPrintf(&str, zFormat, &x);
|
||||
n = str.nChar;
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
|
||||
SQLITE_DYNAMIC);
|
||||
|
||||
48
src/printf.c
48
src/printf.c
@@ -171,7 +171,6 @@ static char *getTextArg(PrintfArguments *p){
|
||||
*/
|
||||
void sqlite3VXPrintf(
|
||||
StrAccum *pAccum, /* Accumulate results here */
|
||||
u32 bFlags, /* SQLITE_PRINTF_* flags */
|
||||
const char *fmt, /* Format string */
|
||||
va_list ap /* arguments */
|
||||
){
|
||||
@@ -211,11 +210,11 @@ void sqlite3VXPrintf(
|
||||
char buf[etBUFSIZE]; /* Conversion buffer */
|
||||
|
||||
bufpt = 0;
|
||||
if( bFlags ){
|
||||
if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
|
||||
if( pAccum->printfFlags ){
|
||||
if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
|
||||
pArgList = va_arg(ap, PrintfArguments*);
|
||||
}
|
||||
useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
|
||||
useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL;
|
||||
}else{
|
||||
bArgList = useIntern = 0;
|
||||
}
|
||||
@@ -766,9 +765,9 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
setStrAccumError(p, STRACCUM_TOOBIG);
|
||||
return N;
|
||||
}else{
|
||||
char *zOld = p->bMalloced ? p->zText : 0;
|
||||
char *zOld = isMalloced(p) ? p->zText : 0;
|
||||
i64 szNew = p->nChar;
|
||||
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
|
||||
assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
|
||||
szNew += N + 1;
|
||||
if( szNew+p->nChar<=p->mxAlloc ){
|
||||
/* Force exponential buffer size growth as long as it does not overflow,
|
||||
@@ -789,10 +788,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
}
|
||||
if( zNew ){
|
||||
assert( p->zText!=0 || p->nChar==0 );
|
||||
if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
|
||||
if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
|
||||
p->zText = zNew;
|
||||
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
|
||||
p->bMalloced = 1;
|
||||
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
|
||||
}else{
|
||||
sqlite3StrAccumReset(p);
|
||||
setStrAccumError(p, STRACCUM_NOMEM);
|
||||
@@ -810,7 +809,7 @@ void sqlite3AppendChar(StrAccum *p, int N, char c){
|
||||
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
|
||||
return;
|
||||
}
|
||||
assert( (p->zText==p->zBase)==(p->bMalloced==0) );
|
||||
assert( (p->zText==p->zBase)==!isMalloced(p) );
|
||||
while( (N--)>0 ) p->zText[p->nChar++] = c;
|
||||
}
|
||||
|
||||
@@ -828,7 +827,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
|
||||
memcpy(&p->zText[p->nChar], z, N);
|
||||
p->nChar += N;
|
||||
}
|
||||
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
|
||||
assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -864,13 +863,13 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
|
||||
*/
|
||||
char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
if( p->zText ){
|
||||
assert( (p->zText==p->zBase)==(p->bMalloced==0) );
|
||||
assert( (p->zText==p->zBase)==!isMalloced(p) );
|
||||
p->zText[p->nChar] = 0;
|
||||
if( p->mxAlloc>0 && p->bMalloced==0 ){
|
||||
if( p->mxAlloc>0 && !isMalloced(p) ){
|
||||
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
|
||||
if( p->zText ){
|
||||
memcpy(p->zText, p->zBase, p->nChar+1);
|
||||
p->bMalloced = 1;
|
||||
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
|
||||
}else{
|
||||
setStrAccumError(p, STRACCUM_NOMEM);
|
||||
}
|
||||
@@ -883,10 +882,10 @@ char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
** Reset an StrAccum string. Reclaim all malloced memory.
|
||||
*/
|
||||
void sqlite3StrAccumReset(StrAccum *p){
|
||||
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
|
||||
if( p->bMalloced ){
|
||||
assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
|
||||
if( isMalloced(p) ){
|
||||
sqlite3DbFree(p->db, p->zText);
|
||||
p->bMalloced = 0;
|
||||
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
|
||||
}
|
||||
p->zText = 0;
|
||||
}
|
||||
@@ -912,7 +911,7 @@ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
|
||||
p->nAlloc = n;
|
||||
p->mxAlloc = mx;
|
||||
p->accError = 0;
|
||||
p->bMalloced = 0;
|
||||
p->printfFlags = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -926,7 +925,8 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
|
||||
assert( db!=0 );
|
||||
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
|
||||
acc.printfFlags = SQLITE_PRINTF_INTERNAL;
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
if( acc.accError==STRACCUM_NOMEM ){
|
||||
db->mallocFailed = 1;
|
||||
@@ -966,7 +966,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
return z;
|
||||
}
|
||||
@@ -1011,7 +1011,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
||||
}
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
return sqlite3StrAccumFinish(&acc);
|
||||
}
|
||||
char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
|
||||
@@ -1042,7 +1042,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
|
||||
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
|
||||
|
||||
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
|
||||
sqlite3StrAccumFinish(&acc));
|
||||
}
|
||||
@@ -1071,7 +1071,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
char zBuf[500];
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
va_start(ap,zFormat);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
va_end(ap);
|
||||
sqlite3StrAccumFinish(&acc);
|
||||
fprintf(stdout,"%s", zBuf);
|
||||
@@ -1084,9 +1084,9 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
|
||||
** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
|
||||
*/
|
||||
void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
|
||||
void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
va_start(ap,zFormat);
|
||||
sqlite3VXPrintf(p, bFlags, zFormat, ap);
|
||||
sqlite3VXPrintf(p, zFormat, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -2978,10 +2978,16 @@ struct StrAccum {
|
||||
u32 nAlloc; /* Amount of space allocated in zText */
|
||||
u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
|
||||
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
|
||||
u8 bMalloced; /* zText points to allocated space */
|
||||
u8 printfFlags; /* SQLITE_PRINTF flags below */
|
||||
};
|
||||
#define STRACCUM_NOMEM 1
|
||||
#define STRACCUM_TOOBIG 2
|
||||
#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
|
||||
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
|
||||
#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
|
||||
|
||||
#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
|
||||
|
||||
|
||||
/*
|
||||
** A pointer to this structure is used to communicate information
|
||||
@@ -3298,10 +3304,8 @@ struct PrintfArguments {
|
||||
sqlite3_value **apArg; /* The argument values */
|
||||
};
|
||||
|
||||
#define SQLITE_PRINTF_INTERNAL 0x01
|
||||
#define SQLITE_PRINTF_SQLFUNC 0x02
|
||||
void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
|
||||
void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
|
||||
void sqlite3VXPrintf(StrAccum*, const char*, va_list);
|
||||
void sqlite3XPrintf(StrAccum*, const char*, ...);
|
||||
char *sqlite3MPrintf(sqlite3*,const char*, ...);
|
||||
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
||||
|
||||
@@ -63,7 +63,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
|
||||
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
|
||||
}
|
||||
va_start(ap, zFormat);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
va_end(ap);
|
||||
if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
|
||||
sqlite3StrAccumFinish(&acc);
|
||||
@@ -98,17 +98,17 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
|
||||
char zLine[1000];
|
||||
const struct Cte *pCte = &pWith->a[i];
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3XPrintf(&x, 0, "%s", pCte->zName);
|
||||
sqlite3XPrintf(&x, "%s", pCte->zName);
|
||||
if( pCte->pCols && pCte->pCols->nExpr>0 ){
|
||||
char cSep = '(';
|
||||
int j;
|
||||
for(j=0; j<pCte->pCols->nExpr; j++){
|
||||
sqlite3XPrintf(&x, 0, "%c%s", cSep, pCte->pCols->a[j].zName);
|
||||
sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
|
||||
cSep = ',';
|
||||
}
|
||||
sqlite3XPrintf(&x, 0, ")");
|
||||
sqlite3XPrintf(&x, ")");
|
||||
}
|
||||
sqlite3XPrintf(&x, 0, " AS");
|
||||
sqlite3XPrintf(&x, " AS");
|
||||
sqlite3StrAccumFinish(&x);
|
||||
sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
|
||||
sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
|
||||
@@ -159,20 +159,20 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
StrAccum x;
|
||||
char zLine[100];
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
|
||||
sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
|
||||
if( pItem->zDatabase ){
|
||||
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
}else if( pItem->zName ){
|
||||
sqlite3XPrintf(&x, 0, " %s", pItem->zName);
|
||||
sqlite3XPrintf(&x, " %s", pItem->zName);
|
||||
}
|
||||
if( pItem->pTab ){
|
||||
sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
|
||||
sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
|
||||
}
|
||||
if( pItem->zAlias ){
|
||||
sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
|
||||
sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
|
||||
}
|
||||
if( pItem->fg.jointype & JT_LEFT ){
|
||||
sqlite3XPrintf(&x, 0, " LEFT-JOIN");
|
||||
sqlite3XPrintf(&x, " LEFT-JOIN");
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
|
||||
|
||||
103
src/vdbeaux.c
103
src/vdbeaux.c
@@ -1117,28 +1117,27 @@ static int displayComment(
|
||||
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
|
||||
** that can be displayed in the P4 column of EXPLAIN output.
|
||||
*/
|
||||
static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
|
||||
static void displayP4Expr(StrAccum *p, Expr *pExpr){
|
||||
const char *zOp = 0;
|
||||
int n;
|
||||
switch( pExpr->op ){
|
||||
case TK_STRING:
|
||||
sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken);
|
||||
sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
|
||||
break;
|
||||
case TK_INTEGER:
|
||||
sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue);
|
||||
sqlite3XPrintf(p, "%d", pExpr->u.iValue);
|
||||
break;
|
||||
case TK_NULL:
|
||||
sqlite3_snprintf(nTemp, zTemp, "NULL");
|
||||
sqlite3XPrintf(p, "NULL");
|
||||
break;
|
||||
case TK_REGISTER: {
|
||||
sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable);
|
||||
sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
|
||||
break;
|
||||
}
|
||||
case TK_COLUMN: {
|
||||
if( pExpr->iColumn<0 ){
|
||||
sqlite3_snprintf(nTemp, zTemp, "rowid");
|
||||
sqlite3XPrintf(p, "rowid");
|
||||
}else{
|
||||
sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn);
|
||||
sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1170,21 +1169,19 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
|
||||
case TK_NOTNULL: zOp = "NOTNULL"; break;
|
||||
|
||||
default:
|
||||
sqlite3_snprintf(nTemp, zTemp, "%s", "expr");
|
||||
sqlite3XPrintf(p, "%s", "expr");
|
||||
break;
|
||||
}
|
||||
|
||||
if( zOp ){
|
||||
sqlite3_snprintf(nTemp, zTemp, "%s(", zOp);
|
||||
n = sqlite3Strlen30(zTemp);
|
||||
n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft);
|
||||
if( n<nTemp-1 && pExpr->pRight ){
|
||||
zTemp[n++] = ',';
|
||||
n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight);
|
||||
sqlite3XPrintf(p, "%s(", zOp);
|
||||
displayP4Expr(p, pExpr->pLeft);
|
||||
if( pExpr->pRight ){
|
||||
sqlite3StrAccumAppend(p, ",", 1);
|
||||
displayP4Expr(p, pExpr->pRight);
|
||||
}
|
||||
sqlite3_snprintf(nTemp-n, zTemp+n, ")");
|
||||
sqlite3StrAccumAppend(p, ")", 1);
|
||||
}
|
||||
return sqlite3Strlen30(zTemp);
|
||||
}
|
||||
#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
|
||||
|
||||
@@ -1196,72 +1193,57 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
|
||||
*/
|
||||
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
char *zP4 = zTemp;
|
||||
StrAccum x;
|
||||
assert( nTemp>=20 );
|
||||
sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
|
||||
switch( pOp->p4type ){
|
||||
case P4_KEYINFO: {
|
||||
int i, j;
|
||||
int j;
|
||||
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
|
||||
i = sqlite3Strlen30(zTemp);
|
||||
sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
|
||||
for(j=0; j<pKeyInfo->nField; j++){
|
||||
CollSeq *pColl = pKeyInfo->aColl[j];
|
||||
const char *zColl = pColl ? pColl->zName : "nil";
|
||||
int n = sqlite3Strlen30(zColl);
|
||||
if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
|
||||
zColl = "B";
|
||||
n = 1;
|
||||
}
|
||||
if( i+n>nTemp-7 ){
|
||||
memcpy(&zTemp[i],",...",4);
|
||||
i += 4;
|
||||
break;
|
||||
}
|
||||
zTemp[i++] = ',';
|
||||
if( pKeyInfo->aSortOrder[j] ){
|
||||
zTemp[i++] = '-';
|
||||
}
|
||||
memcpy(&zTemp[i], zColl, n+1);
|
||||
i += n;
|
||||
const char *zColl = pColl ? pColl->zName : "";
|
||||
if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
|
||||
sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
|
||||
}
|
||||
zTemp[i++] = ')';
|
||||
zTemp[i] = 0;
|
||||
assert( i<nTemp );
|
||||
sqlite3StrAccumAppend(&x, ")", 1);
|
||||
break;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
case P4_EXPR: {
|
||||
displayP4Expr(nTemp, zTemp, pOp->p4.pExpr);
|
||||
displayP4Expr(&x, pOp->p4.pExpr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case P4_COLLSEQ: {
|
||||
CollSeq *pColl = pOp->p4.pColl;
|
||||
sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
|
||||
sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
|
||||
break;
|
||||
}
|
||||
case P4_FUNCDEF: {
|
||||
FuncDef *pDef = pOp->p4.pFunc;
|
||||
sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
break;
|
||||
}
|
||||
#ifdef SQLITE_DEBUG
|
||||
case P4_FUNCCTX: {
|
||||
FuncDef *pDef = pOp->p4.pCtx->pFunc;
|
||||
sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case P4_INT64: {
|
||||
sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
|
||||
sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
|
||||
break;
|
||||
}
|
||||
case P4_INT32: {
|
||||
sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
|
||||
sqlite3XPrintf(&x, "%d", pOp->p4.i);
|
||||
break;
|
||||
}
|
||||
case P4_REAL: {
|
||||
sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
|
||||
sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
|
||||
break;
|
||||
}
|
||||
case P4_MEM: {
|
||||
@@ -1269,11 +1251,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
if( pMem->flags & MEM_Str ){
|
||||
zP4 = pMem->z;
|
||||
}else if( pMem->flags & MEM_Int ){
|
||||
sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
|
||||
sqlite3XPrintf(&x, "%lld", pMem->u.i);
|
||||
}else if( pMem->flags & MEM_Real ){
|
||||
sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
|
||||
sqlite3XPrintf(&x, "%.16g", pMem->u.r);
|
||||
}else if( pMem->flags & MEM_Null ){
|
||||
sqlite3_snprintf(nTemp, zTemp, "NULL");
|
||||
zP4 = "NULL";
|
||||
}else{
|
||||
assert( pMem->flags & MEM_Blob );
|
||||
zP4 = "(blob)";
|
||||
@@ -1283,30 +1265,24 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
case P4_VTAB: {
|
||||
sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
|
||||
sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
|
||||
sqlite3XPrintf(&x, "vtab:%p", pVtab);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case P4_INTARRAY: {
|
||||
int i, j;
|
||||
int i;
|
||||
int *ai = pOp->p4.ai;
|
||||
int n = ai[0]; /* The first element of an INTARRAY is always the
|
||||
** count of the number of elements to follow */
|
||||
for(i=1; i<n; i++){
|
||||
sqlite3XPrintf(&x, ",%d", ai[i]);
|
||||
}
|
||||
zTemp[0] = '[';
|
||||
for(i=j=1; i<n && j<nTemp-7; i++){
|
||||
if( j>1 ) zTemp[j++] = ',';
|
||||
sqlite3_snprintf(nTemp-j, zTemp+j, "%d", ai[i]);
|
||||
j += sqlite3Strlen30(zTemp+j);
|
||||
}
|
||||
if( i<n ){
|
||||
memcpy(zTemp+j, ",...]", 6);
|
||||
}else{
|
||||
memcpy(zTemp+j, "]", 2);
|
||||
}
|
||||
sqlite3StrAccumAppend(&x, "]", 1);
|
||||
break;
|
||||
}
|
||||
case P4_SUBPROGRAM: {
|
||||
sqlite3_snprintf(nTemp, zTemp, "program");
|
||||
sqlite3XPrintf(&x, "program");
|
||||
break;
|
||||
}
|
||||
case P4_ADVANCE: {
|
||||
@@ -1321,6 +1297,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
assert( zP4!=0 );
|
||||
return zP4;
|
||||
}
|
||||
|
||||
@@ -128,9 +128,9 @@ char *sqlite3VdbeExpandSql(
|
||||
if( pVar->flags & MEM_Null ){
|
||||
sqlite3StrAccumAppend(&out, "NULL", 4);
|
||||
}else if( pVar->flags & MEM_Int ){
|
||||
sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
|
||||
sqlite3XPrintf(&out, "%lld", pVar->u.i);
|
||||
}else if( pVar->flags & MEM_Real ){
|
||||
sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
|
||||
sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
|
||||
}else if( pVar->flags & MEM_Str ){
|
||||
int nOut; /* Number of bytes of the string text to include in output */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@@ -151,17 +151,17 @@ char *sqlite3VdbeExpandSql(
|
||||
while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
|
||||
}
|
||||
#endif
|
||||
sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z);
|
||||
sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( nOut<pVar->n ){
|
||||
sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
|
||||
sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
|
||||
#endif
|
||||
}else if( pVar->flags & MEM_Zero ){
|
||||
sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero);
|
||||
sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
|
||||
}else{
|
||||
int nOut; /* Number of bytes of the blob to include in output */
|
||||
assert( pVar->flags & MEM_Blob );
|
||||
@@ -171,12 +171,12 @@ char *sqlite3VdbeExpandSql(
|
||||
if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
|
||||
#endif
|
||||
for(i=0; i<nOut; i++){
|
||||
sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff);
|
||||
sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
|
||||
}
|
||||
sqlite3StrAccumAppend(&out, "'", 1);
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( nOut<pVar->n ){
|
||||
sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
|
||||
sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
|
||||
for(i=0; i<nEq; i++){
|
||||
const char *z = explainIndexColumnName(pIndex, i);
|
||||
if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
|
||||
sqlite3XPrintf(pStr, 0, i>=nSkip ? "%s=?" : "ANY(%s)", z);
|
||||
sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
|
||||
}
|
||||
|
||||
j = i;
|
||||
@@ -135,13 +135,13 @@ int sqlite3WhereExplainOneScan(
|
||||
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
|
||||
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
|
||||
if( pItem->pSelect ){
|
||||
sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
|
||||
sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
|
||||
}else{
|
||||
sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
|
||||
sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
|
||||
}
|
||||
|
||||
if( pItem->zAlias ){
|
||||
sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
|
||||
sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
|
||||
}
|
||||
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
|
||||
const char *zFmt = 0;
|
||||
@@ -165,7 +165,7 @@ int sqlite3WhereExplainOneScan(
|
||||
}
|
||||
if( zFmt ){
|
||||
sqlite3StrAccumAppend(&str, " USING ", 7);
|
||||
sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
|
||||
sqlite3XPrintf(&str, zFmt, pIdx->zName);
|
||||
explainIndexRange(&str, pLoop);
|
||||
}
|
||||
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
|
||||
@@ -180,17 +180,17 @@ int sqlite3WhereExplainOneScan(
|
||||
assert( flags&WHERE_TOP_LIMIT);
|
||||
zRangeOp = "<";
|
||||
}
|
||||
sqlite3XPrintf(&str, 0, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
|
||||
sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
|
||||
sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
|
||||
sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
|
||||
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
|
||||
}
|
||||
#endif
|
||||
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
|
||||
if( pLoop->nOut>=10 ){
|
||||
sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
|
||||
sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
|
||||
}else{
|
||||
sqlite3StrAccumAppend(&str, " (~1 row)", 9);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user