| | @@ -1403,13 +1403,13 @@ |
| 1403 | 1403 | qrfEqpAppend(p, iId, iPid, zo); |
| 1404 | 1404 | } |
| 1405 | 1405 | } |
| 1406 | 1406 | if( p->u.pGraph ) p->u.pGraph->nWidth = nWidth; |
| 1407 | 1407 | qrfStrErr(p, pLine); |
| 1408 | | - sqlite3_free(sqlite3_str_finish(pLine)); |
| 1408 | + sqlite3_str_free(pLine); |
| 1409 | 1409 | qrfStrErr(p, pStats); |
| 1410 | | - sqlite3_free(sqlite3_str_finish(pStats)); |
| 1410 | + sqlite3_str_free(pStats); |
| 1411 | 1411 | #endif |
| 1412 | 1412 | } |
| 1413 | 1413 | |
| 1414 | 1414 | |
| 1415 | 1415 | /* |
| | @@ -2921,10 +2921,25 @@ |
| 2921 | 2921 | sumW -= gain; |
| 2922 | 2922 | pData->a[ix].w -= gain; |
| 2923 | 2923 | pData->bMultiRow = 1; |
| 2924 | 2924 | } |
| 2925 | 2925 | } |
| 2926 | + |
| 2927 | +/* |
| 2928 | +** Invoke sqlite3_str_finish(). But if it returns NULL, try to allocate |
| 2929 | +** an empty string to replace the result. |
| 2930 | +** |
| 2931 | +** The result might still be an empty string, but only after an OOM and |
| 2932 | +** in that case qrfOom() has been called already and so it is safe to |
| 2933 | +** return immediately. |
| 2934 | +*/ |
| 2935 | +static char *qrfStrFinish(Qrf *p, sqlite3_str *pStr){ |
| 2936 | + char *z = sqlite3_str_finish(pStr); |
| 2937 | + if( z==0 ) z = sqlite3_mprintf(""); |
| 2938 | + if( z==0 ) qrfOom(p); |
| 2939 | + return z; |
| 2940 | +} |
| 2926 | 2941 | |
| 2927 | 2942 | /* |
| 2928 | 2943 | ** Columnar modes require that the entire query be evaluated first, with |
| 2929 | 2944 | ** results written into memory, so that we can compute appropriate column |
| 2930 | 2945 | ** widths. |
| | @@ -2985,11 +3000,12 @@ |
| 2985 | 3000 | int n, w; |
| 2986 | 3001 | pStr = sqlite3_str_new(p->db); |
| 2987 | 3002 | qrfEncodeText(p, pStr, z ? z : ""); |
| 2988 | 3003 | n = sqlite3_str_length(pStr); |
| 2989 | 3004 | qrfStrErr(p, pStr); |
| 2990 | | - z = data.az[data.n] = sqlite3_str_finish(pStr); |
| 3005 | + z = data.az[data.n] = qrfStrFinish(p, pStr); |
| 3006 | + if( z==0 ) goto columnar_done; |
| 2991 | 3007 | if( p->spec.nTitleLimit ){ |
| 2992 | 3008 | nNL = 0; |
| 2993 | 3009 | data.aiWth[data.n] = w = qrfTitleLimit(data.az[data.n], |
| 2994 | 3010 | p->spec.nTitleLimit ); |
| 2995 | 3011 | }else{ |
| | @@ -3014,11 +3030,12 @@ |
| 3014 | 3030 | int eType = sqlite3_column_type(p->pStmt,i); |
| 3015 | 3031 | pStr = sqlite3_str_new(p->db); |
| 3016 | 3032 | qrfRenderValue(p, pStr, i); |
| 3017 | 3033 | n = sqlite3_str_length(pStr); |
| 3018 | 3034 | qrfStrErr(p, pStr); |
| 3019 | | - z = data.az[data.n] = sqlite3_str_finish(pStr); |
| 3035 | + z = data.az[data.n] = qrfStrFinish(p,pStr); |
| 3036 | + if( z==0 ) goto columnar_done; |
| 3020 | 3037 | data.abNum[data.n] = eType==SQLITE_INTEGER || eType==SQLITE_FLOAT; |
| 3021 | 3038 | data.aiWth[data.n] = w = qrfDisplayWidth(z, n, &nNL); |
| 3022 | 3039 | data.n++; |
| 3023 | 3040 | if( w>data.a[i].mxW ) data.a[i].mxW = w; |
| 3024 | 3041 | if( nNL ) data.bMultiRow = 1; |
| | @@ -3302,10 +3319,11 @@ |
| 3302 | 3319 | sqlite3_int64 n = p->nRow; |
| 3303 | 3320 | sqlite3_str_appendf(p->pOut, "(%lld row%s)\n", n, n==1 ? "" : "s"); |
| 3304 | 3321 | } |
| 3305 | 3322 | qrfWrite(p); |
| 3306 | 3323 | |
| 3324 | +columnar_done: |
| 3307 | 3325 | qrfColDataFree(&data); |
| 3308 | 3326 | return; |
| 3309 | 3327 | } |
| 3310 | 3328 | |
| 3311 | 3329 | /* |
| | @@ -3733,11 +3751,11 @@ |
| 3733 | 3751 | zVal += iNext; |
| 3734 | 3752 | }while( zVal[0] ); |
| 3735 | 3753 | sqlite3_str_reset(pVal); |
| 3736 | 3754 | } |
| 3737 | 3755 | qrfStrErr(p, pVal); |
| 3738 | | - sqlite3_free(sqlite3_str_finish(pVal)); |
| 3756 | + sqlite3_str_free(pVal); |
| 3739 | 3757 | qrfWrite(p); |
| 3740 | 3758 | break; |
| 3741 | 3759 | } |
| 3742 | 3760 | case QRF_STYLE_Eqp: { |
| 3743 | 3761 | const char *zEqpLine = (const char*)sqlite3_column_text(p->pStmt,3); |
| | @@ -4016,16 +4034,16 @@ |
| 4016 | 4034 | qrfOom(p); |
| 4017 | 4035 | }else{ |
| 4018 | 4036 | p->spec.pzOutput[0] = zCombined; |
| 4019 | 4037 | memcpy(zCombined+sz, sqlite3_str_value(p->pOut), n+1); |
| 4020 | 4038 | } |
| 4021 | | - sqlite3_free(sqlite3_str_finish(p->pOut)); |
| 4039 | + sqlite3_str_free(p->pOut); |
| 4022 | 4040 | }else{ |
| 4023 | | - p->spec.pzOutput[0] = sqlite3_str_finish(p->pOut); |
| 4041 | + p->spec.pzOutput[0] = qrfStrFinish(p, p->pOut); |
| 4024 | 4042 | } |
| 4025 | 4043 | }else if( p->pOut ){ |
| 4026 | | - sqlite3_free(sqlite3_str_finish(p->pOut)); |
| 4044 | + sqlite3_str_free(p->pOut); |
| 4027 | 4045 | } |
| 4028 | 4046 | if( p->expMode>0 ){ |
| 4029 | 4047 | sqlite3_stmt_explain(p->pStmt, p->expMode-1); |
| 4030 | 4048 | } |
| 4031 | 4049 | if( p->actualWidth ){ |
| | @@ -6948,12 +6966,13 @@ |
| 6948 | 6966 | sqlite3_value **argv |
| 6949 | 6967 | ){ |
| 6950 | 6968 | UNUSED_PARAMETER(argc); |
| 6951 | 6969 | if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){ |
| 6952 | 6970 | int N; |
| 6971 | + Decimal *pA; |
| 6953 | 6972 | if( decimalSafeInt(context, argv[0], &N) ) return; |
| 6954 | | - Decimal *pA = decimalPow2(N); |
| 6973 | + pA = decimalPow2(N); |
| 6955 | 6974 | if( pA ){ |
| 6956 | 6975 | decimal_result_sci(context, pA, 0); |
| 6957 | 6976 | decimal_free(pA); |
| 6958 | 6977 | } |
| 6959 | 6978 | } |
| | @@ -8420,10 +8439,11 @@ |
| 8420 | 8439 | sqlite3_int64 iTerm; /* Terminal value to actually use */ |
| 8421 | 8440 | sqlite3_uint64 iStep; /* The step size */ |
| 8422 | 8441 | sqlite3_int64 iValue; /* Current value */ |
| 8423 | 8442 | u8 bDesc; /* iStep is really negative */ |
| 8424 | 8443 | u8 bDone; /* True if stepped past last element */ |
| 8444 | + u8 bLimit; /* There exists a limit clause */ |
| 8425 | 8445 | }; |
| 8426 | 8446 | |
| 8427 | 8447 | /* |
| 8428 | 8448 | ** Computed the difference between two 64-bit signed integers using a |
| 8429 | 8449 | ** convoluted computation designed to work around the silly restriction |
| | @@ -8531,14 +8551,14 @@ |
| 8531 | 8551 | series_cursor *pCur = (series_cursor*)cur; |
| 8532 | 8552 | if( pCur->iValue==pCur->iTerm ){ |
| 8533 | 8553 | pCur->bDone = 1; |
| 8534 | 8554 | }else if( pCur->bDesc ){ |
| 8535 | 8555 | pCur->iValue = sub64(pCur->iValue, pCur->iStep); |
| 8536 | | - assert( pCur->iValue>=pCur->iTerm ); |
| 8556 | + assert( pCur->iValue>=pCur->iTerm || pCur->bLimit ); |
| 8537 | 8557 | }else{ |
| 8538 | 8558 | pCur->iValue = add64(pCur->iValue, pCur->iStep); |
| 8539 | | - assert( pCur->iValue<=pCur->iTerm ); |
| 8559 | + assert( pCur->iValue<=pCur->iTerm || pCur->bLimit ); |
| 8540 | 8560 | } |
| 8541 | 8561 | return SQLITE_OK; |
| 8542 | 8562 | } |
| 8543 | 8563 | |
| 8544 | 8564 | /* |
| | @@ -8764,10 +8784,11 @@ |
| 8764 | 8784 | if( idxNum & 0x20 ){ |
| 8765 | 8785 | iLimit = sqlite3_value_int64(argv[iArg++]); |
| 8766 | 8786 | if( idxNum & 0x40 ){ |
| 8767 | 8787 | iOffset = sqlite3_value_int64(argv[iArg++]); |
| 8768 | 8788 | } |
| 8789 | + if( iLimit>0 ) pCur->bLimit = 1; |
| 8769 | 8790 | } |
| 8770 | 8791 | |
| 8771 | 8792 | /* Narrow the range of iMin and iMax (the minimum and maximum outputs) |
| 8772 | 8793 | ** based on equality and inequality constraints on the "value" column. |
| 8773 | 8794 | */ |
| | @@ -16235,16 +16256,25 @@ |
| 16235 | 16256 | char *zName = 0; /* Index name */ |
| 16236 | 16257 | int collisions = 0; |
| 16237 | 16258 | do{ |
| 16238 | 16259 | int i; |
| 16239 | 16260 | char *zFind; |
| 16240 | | - for(i=0; zCols[i]; i++){ |
| 16241 | | - h += ((h<<3) + zCols[i]); |
| 16242 | | - } |
| 16261 | + |
| 16243 | 16262 | sqlite3_free(zName); |
| 16244 | | - zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); |
| 16263 | + if( collisions<10 ){ |
| 16264 | + for(i=0; zCols[i]; i++){ |
| 16265 | + h += ((h<<3) + zCols[i]); |
| 16266 | + } |
| 16267 | + zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); |
| 16268 | + }else{ |
| 16269 | + /* After several hash attempts, generate a random name */ |
| 16270 | + sqlite3_uint64 u; |
| 16271 | + sqlite3_randomness(sizeof(u), &u); |
| 16272 | + zName = sqlite3_mprintf("%s_idx_%llx", zTable, u); |
| 16273 | + } |
| 16245 | 16274 | if( zName==0 ) break; |
| 16275 | + |
| 16246 | 16276 | /* Is is unique among table, view and index names? */ |
| 16247 | 16277 | zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q" |
| 16248 | 16278 | " AND type in ('index','table','view')"; |
| 16249 | 16279 | zFind = sqlite3_mprintf(zFmt, zName); |
| 16250 | 16280 | i = 0; |
| | @@ -16254,12 +16284,12 @@ |
| 16254 | 16284 | if( i==0 ){ |
| 16255 | 16285 | collisions = 0; |
| 16256 | 16286 | break; |
| 16257 | 16287 | } |
| 16258 | 16288 | ++collisions; |
| 16259 | | - }while( collisions<50 && zName!=0 ); |
| 16260 | | - if( collisions ){ |
| 16289 | + }while( ALWAYS(collisions<500) && zName!=0 ); |
| 16290 | + if( NEVER(collisions) ){ |
| 16261 | 16291 | /* This return means "Gave up trying to find a unique index name." */ |
| 16262 | 16292 | rc = SQLITE_BUSY_TIMEOUT; |
| 16263 | 16293 | }else if( zName==0 ){ |
| 16264 | 16294 | rc = SQLITE_NOMEM; |
| 16265 | 16295 | }else{ |
| | @@ -16277,13 +16307,13 @@ |
| 16277 | 16307 | rc = SQLITE_BUSY_TIMEOUT; |
| 16278 | 16308 | }else{ |
| 16279 | 16309 | idxHashAdd(&rc, &p->hIdx, zName, zIdx); |
| 16280 | 16310 | } |
| 16281 | 16311 | } |
| 16282 | | - sqlite3_free(zName); |
| 16283 | 16312 | sqlite3_free(zIdx); |
| 16284 | 16313 | } |
| 16314 | + sqlite3_free(zName); |
| 16285 | 16315 | } |
| 16286 | 16316 | |
| 16287 | 16317 | sqlite3_free(zCols); |
| 16288 | 16318 | } |
| 16289 | 16319 | return rc; |
| | @@ -34275,14 +34305,14 @@ |
| 34275 | 34305 | if( i+1>=nArg ){ |
| 34276 | 34306 | dotCmdError(p, i, "missing argument", 0); |
| 34277 | 34307 | return 1; |
| 34278 | 34308 | } |
| 34279 | 34309 | zW = azArg[++i]; |
| 34280 | | - /* Every width value takes at least 2 bytes in the input string to |
| 34281 | | - ** specify, so strlen(zW) bytes should be plenty of space to hold the |
| 34282 | | - ** result. */ |
| 34283 | | - aWidth = malloc( strlen(zW) ); |
| 34310 | + /* Every width value except a single-digit final value takes at |
| 34311 | + ** least 2 bytes in the input string to specify, so strlen(zW)+1 |
| 34312 | + ** entries is plenty of space to hold the result. */ |
| 34313 | + aWidth = malloc( strlen(zW)+1 ); |
| 34284 | 34314 | while( IsSpace(zW[0]) ) zW++; |
| 34285 | 34315 | while( zW[0] ){ |
| 34286 | 34316 | int w = 0; |
| 34287 | 34317 | int nDigit = 0; |
| 34288 | 34318 | k = zW[0]=='-' && IsDigit(zW[1]); |
| 34289 | 34319 | |