| Index: third_party/sqlite/sqlite-src-3100200/src/test8.c
|
| diff --git a/third_party/sqlite/src/src/test8.c b/third_party/sqlite/sqlite-src-3100200/src/test8.c
|
| similarity index 94%
|
| copy from third_party/sqlite/src/src/test8.c
|
| copy to third_party/sqlite/sqlite-src-3100200/src/test8.c
|
| index 8bc835d638c322ce4c0353bdfd2ed46d8d0b69dd..fb781ac8fdd02b8ad77ab291ce5589a7dc610196 100644
|
| --- a/third_party/sqlite/src/src/test8.c
|
| +++ b/third_party/sqlite/sqlite-src-3100200/src/test8.c
|
| @@ -206,8 +206,8 @@ static int getColumnNames(
|
| zSpace = (char *)(&aCol[nCol]);
|
| for(ii=0; ii<nCol; ii++){
|
| aCol[ii] = zSpace;
|
| - zSpace += sprintf(zSpace, "%s", sqlite3_column_name(pStmt, ii));
|
| - zSpace++;
|
| + sqlite3_snprintf(nBytes, zSpace, "%s", sqlite3_column_name(pStmt,ii));
|
| + zSpace += (int)strlen(zSpace) + 1;
|
| }
|
| assert( (zSpace-nBytes)==(char *)aCol );
|
| }
|
| @@ -648,12 +648,12 @@ static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
| ** indeed the hash of the supplied idxStr.
|
| */
|
| static int hashString(const char *zString){
|
| - int val = 0;
|
| + u32 val = 0;
|
| int ii;
|
| for(ii=0; zString[ii]; ii++){
|
| val = (val << 3) + (int)zString[ii];
|
| }
|
| - return val;
|
| + return (int)(val&0x7fffffff);
|
| }
|
|
|
| /*
|
| @@ -746,6 +746,34 @@ static void string_concat(char **pzStr, char *zAppend, int doFree, int *pRc){
|
| }
|
|
|
| /*
|
| +** This function returns a pointer to an sqlite3_malloc()ed buffer
|
| +** containing the select-list (the thing between keywords SELECT and FROM)
|
| +** to query the underlying real table with for the scan described by
|
| +** argument pIdxInfo.
|
| +**
|
| +** If the current SQLite version is earlier than 3.10.0, this is just "*"
|
| +** (select all columns). Or, for version 3.10.0 and greater, the list of
|
| +** columns identified by the pIdxInfo->colUsed mask.
|
| +*/
|
| +static char *echoSelectList(echo_vtab *pTab, sqlite3_index_info *pIdxInfo){
|
| + char *zRet = 0;
|
| + if( sqlite3_libversion_number()<3010000 ){
|
| + zRet = sqlite3_mprintf(", *");
|
| + }else{
|
| + int i;
|
| + for(i=0; i<pTab->nCol; i++){
|
| + if( pIdxInfo->colUsed & ((sqlite3_uint64)1 << (i>=63 ? 63 : i)) ){
|
| + zRet = sqlite3_mprintf("%z, %s", zRet, pTab->aCol[i]);
|
| + }else{
|
| + zRet = sqlite3_mprintf("%z, NULL", zRet);
|
| + }
|
| + if( !zRet ) break;
|
| + }
|
| + }
|
| + return zRet;
|
| +}
|
| +
|
| +/*
|
| ** The echo module implements the subset of query constraints and sort
|
| ** orders that may take advantage of SQLite indices on the underlying
|
| ** real table. For example, if the real table is declared as:
|
| @@ -770,6 +798,7 @@ static void string_concat(char **pzStr, char *zAppend, int doFree, int *pRc){
|
| static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
| int ii;
|
| char *zQuery = 0;
|
| + char *zCol = 0;
|
| char *zNew;
|
| int nArg = 0;
|
| const char *zSep = "WHERE";
|
| @@ -777,11 +806,11 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
| sqlite3_stmt *pStmt = 0;
|
| Tcl_Interp *interp = pVtab->interp;
|
|
|
| - int nRow;
|
| + int nRow = 0;
|
| int useIdx = 0;
|
| int rc = SQLITE_OK;
|
| int useCost = 0;
|
| - double cost;
|
| + double cost = 0;
|
| int isIgnoreUsable = 0;
|
| if( Tcl_GetVar(interp, "echo_module_ignore_usable", TCL_GLOBAL_ONLY) ){
|
| isIgnoreUsable = 1;
|
| @@ -817,10 +846,11 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
| }
|
| }
|
|
|
| - zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName);
|
| - if( !zQuery ){
|
| - return SQLITE_NOMEM;
|
| - }
|
| + zCol = echoSelectList(pVtab, pIdxInfo);
|
| + if( !zCol ) return SQLITE_NOMEM;
|
| + zQuery = sqlite3_mprintf("SELECT rowid%z FROM %Q", zCol, pVtab->zTableName);
|
| + if( !zQuery ) return SQLITE_NOMEM;
|
| +
|
| for(ii=0; ii<pIdxInfo->nConstraint; ii++){
|
| const struct sqlite3_index_constraint *pConstraint;
|
| struct sqlite3_index_constraint_usage *pUsage;
|
| @@ -833,7 +863,7 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
|
|
| iCol = pConstraint->iColumn;
|
| if( iCol<0 || pVtab->aIndex[iCol] ){
|
| - char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
| + char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
| char *zOp = 0;
|
| useIdx = 1;
|
| switch( pConstraint->op ){
|
| @@ -848,13 +878,26 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
| case SQLITE_INDEX_CONSTRAINT_GE:
|
| zOp = ">="; break;
|
| case SQLITE_INDEX_CONSTRAINT_MATCH:
|
| + /* Purposely translate the MATCH operator into a LIKE, which
|
| + ** will be used by the next block of code to construct a new
|
| + ** query. It should also be noted here that the next block
|
| + ** of code requires the first letter of this operator to be
|
| + ** in upper-case to trigger the special MATCH handling (i.e.
|
| + ** wrapping the bound parameter with literal '%'s).
|
| + */
|
| zOp = "LIKE"; break;
|
| + case SQLITE_INDEX_CONSTRAINT_LIKE:
|
| + zOp = "like"; break;
|
| + case SQLITE_INDEX_CONSTRAINT_GLOB:
|
| + zOp = "glob"; break;
|
| + case SQLITE_INDEX_CONSTRAINT_REGEXP:
|
| + zOp = "regexp"; break;
|
| }
|
| if( zOp[0]=='L' ){
|
| zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')",
|
| - zSep, zCol);
|
| + zSep, zNewCol);
|
| } else {
|
| - zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zCol, zOp);
|
| + zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zNewCol, zOp);
|
| }
|
| string_concat(&zQuery, zNew, 1, &rc);
|
|
|
| @@ -872,9 +915,9 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
| pIdxInfo->aOrderBy->iColumn<0 ||
|
| pVtab->aIndex[pIdxInfo->aOrderBy->iColumn]) ){
|
| int iCol = pIdxInfo->aOrderBy->iColumn;
|
| - char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
| + char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
| char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC";
|
| - zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir);
|
| + zNew = sqlite3_mprintf(" ORDER BY %s %s", zNewCol, zDir);
|
| string_concat(&zQuery, zNew, 1, &rc);
|
| pIdxInfo->orderByConsumed = 1;
|
| }
|
| @@ -927,7 +970,7 @@ int echoUpdate(
|
| sqlite3 *db = pVtab->db;
|
| int rc = SQLITE_OK;
|
|
|
| - sqlite3_stmt *pStmt;
|
| + sqlite3_stmt *pStmt = 0;
|
| char *z = 0; /* SQL statement to execute */
|
| int bindArgZero = 0; /* True to bind apData[0] to sql var no. nData */
|
| int bindArgOne = 0; /* True to bind apData[1] to sql var no. 1 */
|
|
|