OLD | NEW |
1 /* | 1 /* |
2 ** 2006 June 10 | 2 ** 2006 June 10 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 /* Figure out how much space to allocate for the array of column names | 185 /* Figure out how much space to allocate for the array of column names |
186 ** (including space for the strings themselves). Then allocate it. | 186 ** (including space for the strings themselves). Then allocate it. |
187 */ | 187 */ |
188 nBytes = sizeof(char *) * nCol; | 188 nBytes = sizeof(char *) * nCol; |
189 for(ii=0; ii<nCol; ii++){ | 189 for(ii=0; ii<nCol; ii++){ |
190 const char *zName = sqlite3_column_name(pStmt, ii); | 190 const char *zName = sqlite3_column_name(pStmt, ii); |
191 if( !zName ){ | 191 if( !zName ){ |
192 rc = SQLITE_NOMEM; | 192 rc = SQLITE_NOMEM; |
193 goto out; | 193 goto out; |
194 } | 194 } |
195 nBytes += strlen(zName)+1; | 195 nBytes += (int)strlen(zName)+1; |
196 } | 196 } |
197 aCol = (char **)sqlite3MallocZero(nBytes); | 197 aCol = (char **)sqlite3MallocZero(nBytes); |
198 if( !aCol ){ | 198 if( !aCol ){ |
199 rc = SQLITE_NOMEM; | 199 rc = SQLITE_NOMEM; |
200 goto out; | 200 goto out; |
201 } | 201 } |
202 | 202 |
203 /* Copy the column names into the allocated space and set up the | 203 /* Copy the column names into the allocated space and set up the |
204 ** pointers in the aCol[] array. | 204 ** pointers in the aCol[] array. |
205 */ | 205 */ |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 } | 258 } |
259 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); | 259 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
260 sqlite3_free(zSql); | 260 sqlite3_free(zSql); |
261 | 261 |
262 /* For each index, figure out the left-most column and set the | 262 /* For each index, figure out the left-most column and set the |
263 ** corresponding entry in aIndex[] to 1. | 263 ** corresponding entry in aIndex[] to 1. |
264 */ | 264 */ |
265 while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ | 265 while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ |
266 const char *zIdx = (const char *)sqlite3_column_text(pStmt, 1); | 266 const char *zIdx = (const char *)sqlite3_column_text(pStmt, 1); |
267 sqlite3_stmt *pStmt2 = 0; | 267 sqlite3_stmt *pStmt2 = 0; |
| 268 if( zIdx==0 ) continue; |
268 zSql = sqlite3_mprintf("PRAGMA index_info(%s)", zIdx); | 269 zSql = sqlite3_mprintf("PRAGMA index_info(%s)", zIdx); |
269 if( !zSql ){ | 270 if( !zSql ){ |
270 rc = SQLITE_NOMEM; | 271 rc = SQLITE_NOMEM; |
271 goto get_index_array_out; | 272 goto get_index_array_out; |
272 } | 273 } |
273 rc = sqlite3_prepare(db, zSql, -1, &pStmt2, 0); | 274 rc = sqlite3_prepare(db, zSql, -1, &pStmt2, 0); |
274 sqlite3_free(zSql); | 275 sqlite3_free(zSql); |
275 if( pStmt2 && sqlite3_step(pStmt2)==SQLITE_ROW ){ | 276 if( pStmt2 && sqlite3_step(pStmt2)==SQLITE_ROW ){ |
276 int cid = sqlite3_column_int(pStmt2, 1); | 277 int cid = sqlite3_column_int(pStmt2, 1); |
277 assert( cid>=0 && cid<nCol ); | 278 assert( cid>=0 && cid<nCol ); |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 const struct sqlite3_index_constraint *pConstraint; | 825 const struct sqlite3_index_constraint *pConstraint; |
825 struct sqlite3_index_constraint_usage *pUsage; | 826 struct sqlite3_index_constraint_usage *pUsage; |
826 int iCol; | 827 int iCol; |
827 | 828 |
828 pConstraint = &pIdxInfo->aConstraint[ii]; | 829 pConstraint = &pIdxInfo->aConstraint[ii]; |
829 pUsage = &pIdxInfo->aConstraintUsage[ii]; | 830 pUsage = &pIdxInfo->aConstraintUsage[ii]; |
830 | 831 |
831 if( !isIgnoreUsable && !pConstraint->usable ) continue; | 832 if( !isIgnoreUsable && !pConstraint->usable ) continue; |
832 | 833 |
833 iCol = pConstraint->iColumn; | 834 iCol = pConstraint->iColumn; |
834 if( pVtab->aIndex[iCol] || iCol<0 ){ | 835 if( iCol<0 || pVtab->aIndex[iCol] ){ |
835 char *zCol = pVtab->aCol[iCol]; | 836 char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid"; |
836 char *zOp = 0; | 837 char *zOp = 0; |
837 useIdx = 1; | 838 useIdx = 1; |
838 if( iCol<0 ){ | |
839 zCol = "rowid"; | |
840 } | |
841 switch( pConstraint->op ){ | 839 switch( pConstraint->op ){ |
842 case SQLITE_INDEX_CONSTRAINT_EQ: | 840 case SQLITE_INDEX_CONSTRAINT_EQ: |
843 zOp = "="; break; | 841 zOp = "="; break; |
844 case SQLITE_INDEX_CONSTRAINT_LT: | 842 case SQLITE_INDEX_CONSTRAINT_LT: |
845 zOp = "<"; break; | 843 zOp = "<"; break; |
846 case SQLITE_INDEX_CONSTRAINT_GT: | 844 case SQLITE_INDEX_CONSTRAINT_GT: |
847 zOp = ">"; break; | 845 zOp = ">"; break; |
848 case SQLITE_INDEX_CONSTRAINT_LE: | 846 case SQLITE_INDEX_CONSTRAINT_LE: |
849 zOp = "<="; break; | 847 zOp = "<="; break; |
850 case SQLITE_INDEX_CONSTRAINT_GE: | 848 case SQLITE_INDEX_CONSTRAINT_GE: |
(...skipping 12 matching lines...) Expand all Loading... |
863 zSep = "AND"; | 861 zSep = "AND"; |
864 pUsage->argvIndex = ++nArg; | 862 pUsage->argvIndex = ++nArg; |
865 pUsage->omit = 1; | 863 pUsage->omit = 1; |
866 } | 864 } |
867 } | 865 } |
868 | 866 |
869 /* If there is only one term in the ORDER BY clause, and it is | 867 /* If there is only one term in the ORDER BY clause, and it is |
870 ** on a column that this virtual table has an index for, then consume | 868 ** on a column that this virtual table has an index for, then consume |
871 ** the ORDER BY clause. | 869 ** the ORDER BY clause. |
872 */ | 870 */ |
873 if( pIdxInfo->nOrderBy==1 && pVtab->aIndex[pIdxInfo->aOrderBy->iColumn] ){ | 871 if( pIdxInfo->nOrderBy==1 && ( |
| 872 pIdxInfo->aOrderBy->iColumn<0 || |
| 873 pVtab->aIndex[pIdxInfo->aOrderBy->iColumn]) ){ |
874 int iCol = pIdxInfo->aOrderBy->iColumn; | 874 int iCol = pIdxInfo->aOrderBy->iColumn; |
875 char *zCol = pVtab->aCol[iCol]; | 875 char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid"; |
876 char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC"; | 876 char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC"; |
877 if( iCol<0 ){ | |
878 zCol = "rowid"; | |
879 } | |
880 zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir); | 877 zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir); |
881 string_concat(&zQuery, zNew, 1, &rc); | 878 string_concat(&zQuery, zNew, 1, &rc); |
882 pIdxInfo->orderByConsumed = 1; | 879 pIdxInfo->orderByConsumed = 1; |
883 } | 880 } |
884 | 881 |
885 appendToEchoModule(pVtab->interp, "xBestIndex");; | 882 appendToEchoModule(pVtab->interp, "xBestIndex");; |
886 appendToEchoModule(pVtab->interp, zQuery); | 883 appendToEchoModule(pVtab->interp, zQuery); |
887 | 884 |
888 if( !zQuery ){ | 885 if( !zQuery ){ |
889 return rc; | 886 return rc; |
890 } | 887 } |
891 pIdxInfo->idxNum = hashString(zQuery); | 888 pIdxInfo->idxNum = hashString(zQuery); |
892 pIdxInfo->idxStr = zQuery; | 889 pIdxInfo->idxStr = zQuery; |
893 pIdxInfo->needToFreeIdxStr = 1; | 890 pIdxInfo->needToFreeIdxStr = 1; |
894 if( useCost ){ | 891 if( useCost ){ |
895 pIdxInfo->estimatedCost = cost; | 892 pIdxInfo->estimatedCost = cost; |
896 }else if( useIdx ){ | 893 }else if( useIdx ){ |
897 /* Approximation of log2(nRow). */ | 894 /* Approximation of log2(nRow). */ |
898 for( ii=0; ii<(sizeof(int)*8); ii++ ){ | 895 for( ii=0; ii<(sizeof(int)*8)-1; ii++ ){ |
899 if( nRow & (1<<ii) ){ | 896 if( nRow & (1<<ii) ){ |
900 pIdxInfo->estimatedCost = (double)ii; | 897 pIdxInfo->estimatedCost = (double)ii; |
901 } | 898 } |
902 } | 899 } |
903 }else{ | 900 }else{ |
904 pIdxInfo->estimatedCost = (double)nRow; | 901 pIdxInfo->estimatedCost = (double)nRow; |
905 } | 902 } |
906 return rc; | 903 return rc; |
907 } | 904 } |
908 | 905 |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 | 1211 |
1215 static int echoRename(sqlite3_vtab *vtab, const char *zNewName){ | 1212 static int echoRename(sqlite3_vtab *vtab, const char *zNewName){ |
1216 int rc = SQLITE_OK; | 1213 int rc = SQLITE_OK; |
1217 echo_vtab *p = (echo_vtab *)vtab; | 1214 echo_vtab *p = (echo_vtab *)vtab; |
1218 | 1215 |
1219 if( simulateVtabError(p, "xRename") ){ | 1216 if( simulateVtabError(p, "xRename") ){ |
1220 return SQLITE_ERROR; | 1217 return SQLITE_ERROR; |
1221 } | 1218 } |
1222 | 1219 |
1223 if( p->isPattern ){ | 1220 if( p->isPattern ){ |
1224 int nThis = strlen(p->zThis); | 1221 int nThis = (int)strlen(p->zThis); |
1225 char *zSql = sqlite3_mprintf("ALTER TABLE %s RENAME TO %s%s", | 1222 char *zSql = sqlite3_mprintf("ALTER TABLE %s RENAME TO %s%s", |
1226 p->zTableName, zNewName, &p->zTableName[nThis] | 1223 p->zTableName, zNewName, &p->zTableName[nThis] |
1227 ); | 1224 ); |
1228 rc = sqlite3_exec(p->db, zSql, 0, 0, 0); | 1225 rc = sqlite3_exec(p->db, zSql, 0, 0, 0); |
1229 sqlite3_free(zSql); | 1226 sqlite3_free(zSql); |
1230 } | 1227 } |
1231 | 1228 |
1232 return rc; | 1229 return rc; |
1233 } | 1230 } |
1234 | 1231 |
| 1232 static int echoSavepoint(sqlite3_vtab *pVTab, int iSavepoint){ |
| 1233 assert( pVTab ); |
| 1234 return SQLITE_OK; |
| 1235 } |
| 1236 |
| 1237 static int echoRelease(sqlite3_vtab *pVTab, int iSavepoint){ |
| 1238 assert( pVTab ); |
| 1239 return SQLITE_OK; |
| 1240 } |
| 1241 |
| 1242 static int echoRollbackTo(sqlite3_vtab *pVTab, int iSavepoint){ |
| 1243 assert( pVTab ); |
| 1244 return SQLITE_OK; |
| 1245 } |
| 1246 |
1235 /* | 1247 /* |
1236 ** A virtual table module that merely "echos" the contents of another | 1248 ** A virtual table module that merely "echos" the contents of another |
1237 ** table (like an SQL VIEW). | 1249 ** table (like an SQL VIEW). |
1238 */ | 1250 */ |
1239 static sqlite3_module echoModule = { | 1251 static sqlite3_module echoModule = { |
1240 0, /* iVersion */ | 1252 1, /* iVersion */ |
1241 echoCreate, | 1253 echoCreate, |
1242 echoConnect, | 1254 echoConnect, |
1243 echoBestIndex, | 1255 echoBestIndex, |
| 1256 echoDisconnect, |
| 1257 echoDestroy, |
| 1258 echoOpen, /* xOpen - open a cursor */ |
| 1259 echoClose, /* xClose - close a cursor */ |
| 1260 echoFilter, /* xFilter - configure scan constraints */ |
| 1261 echoNext, /* xNext - advance a cursor */ |
| 1262 echoEof, /* xEof */ |
| 1263 echoColumn, /* xColumn - read data */ |
| 1264 echoRowid, /* xRowid - read data */ |
| 1265 echoUpdate, /* xUpdate - write data */ |
| 1266 echoBegin, /* xBegin - begin transaction */ |
| 1267 echoSync, /* xSync - sync transaction */ |
| 1268 echoCommit, /* xCommit - commit transaction */ |
| 1269 echoRollback, /* xRollback - rollback transaction */ |
| 1270 echoFindFunction, /* xFindFunction - function overloading */ |
| 1271 echoRename /* xRename - rename the table */ |
| 1272 }; |
| 1273 |
| 1274 static sqlite3_module echoModuleV2 = { |
| 1275 2, /* iVersion */ |
| 1276 echoCreate, |
| 1277 echoConnect, |
| 1278 echoBestIndex, |
1244 echoDisconnect, | 1279 echoDisconnect, |
1245 echoDestroy, | 1280 echoDestroy, |
1246 echoOpen, /* xOpen - open a cursor */ | 1281 echoOpen, /* xOpen - open a cursor */ |
1247 echoClose, /* xClose - close a cursor */ | 1282 echoClose, /* xClose - close a cursor */ |
1248 echoFilter, /* xFilter - configure scan constraints */ | 1283 echoFilter, /* xFilter - configure scan constraints */ |
1249 echoNext, /* xNext - advance a cursor */ | 1284 echoNext, /* xNext - advance a cursor */ |
1250 echoEof, /* xEof */ | 1285 echoEof, /* xEof */ |
1251 echoColumn, /* xColumn - read data */ | 1286 echoColumn, /* xColumn - read data */ |
1252 echoRowid, /* xRowid - read data */ | 1287 echoRowid, /* xRowid - read data */ |
1253 echoUpdate, /* xUpdate - write data */ | 1288 echoUpdate, /* xUpdate - write data */ |
1254 echoBegin, /* xBegin - begin transaction */ | 1289 echoBegin, /* xBegin - begin transaction */ |
1255 echoSync, /* xSync - sync transaction */ | 1290 echoSync, /* xSync - sync transaction */ |
1256 echoCommit, /* xCommit - commit transaction */ | 1291 echoCommit, /* xCommit - commit transaction */ |
1257 echoRollback, /* xRollback - rollback transaction */ | 1292 echoRollback, /* xRollback - rollback transaction */ |
1258 echoFindFunction, /* xFindFunction - function overloading */ | 1293 echoFindFunction, /* xFindFunction - function overloading */ |
1259 echoRename, /* xRename - rename the table */ | 1294 echoRename, /* xRename - rename the table */ |
| 1295 echoSavepoint, |
| 1296 echoRelease, |
| 1297 echoRollbackTo |
1260 }; | 1298 }; |
1261 | 1299 |
1262 /* | 1300 /* |
1263 ** Decode a pointer to an sqlite3 object. | 1301 ** Decode a pointer to an sqlite3 object. |
1264 */ | 1302 */ |
1265 extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); | 1303 extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); |
| 1304 extern const char *sqlite3ErrName(int); |
1266 | 1305 |
1267 static void moduleDestroy(void *p){ | 1306 static void moduleDestroy(void *p){ |
1268 sqlite3_free(p); | 1307 sqlite3_free(p); |
1269 } | 1308 } |
1270 | 1309 |
1271 /* | 1310 /* |
1272 ** Register the echo virtual table module. | 1311 ** Register the echo virtual table module. |
1273 */ | 1312 */ |
1274 static int register_echo_module( | 1313 static int register_echo_module( |
1275 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ | 1314 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
1276 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ | 1315 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
1277 int objc, /* Number of arguments */ | 1316 int objc, /* Number of arguments */ |
1278 Tcl_Obj *CONST objv[] /* Command arguments */ | 1317 Tcl_Obj *CONST objv[] /* Command arguments */ |
1279 ){ | 1318 ){ |
| 1319 int rc; |
1280 sqlite3 *db; | 1320 sqlite3 *db; |
1281 EchoModule *pMod; | 1321 EchoModule *pMod; |
1282 if( objc!=2 ){ | 1322 if( objc!=2 ){ |
1283 Tcl_WrongNumArgs(interp, 1, objv, "DB"); | 1323 Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
1284 return TCL_ERROR; | 1324 return TCL_ERROR; |
1285 } | 1325 } |
1286 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; | 1326 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
| 1327 |
| 1328 /* Virtual table module "echo" */ |
1287 pMod = sqlite3_malloc(sizeof(EchoModule)); | 1329 pMod = sqlite3_malloc(sizeof(EchoModule)); |
1288 pMod->interp = interp; | 1330 pMod->interp = interp; |
1289 sqlite3_create_module_v2(db, "echo", &echoModule, (void*)pMod, moduleDestroy); | 1331 rc = sqlite3_create_module_v2( |
| 1332 db, "echo", &echoModule, (void*)pMod, moduleDestroy |
| 1333 ); |
| 1334 |
| 1335 /* Virtual table module "echo_v2" */ |
| 1336 if( rc==SQLITE_OK ){ |
| 1337 pMod = sqlite3_malloc(sizeof(EchoModule)); |
| 1338 pMod->interp = interp; |
| 1339 rc = sqlite3_create_module_v2(db, "echo_v2", |
| 1340 &echoModuleV2, (void*)pMod, moduleDestroy |
| 1341 ); |
| 1342 } |
| 1343 |
| 1344 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC); |
1290 return TCL_OK; | 1345 return TCL_OK; |
1291 } | 1346 } |
1292 | 1347 |
1293 /* | 1348 /* |
1294 ** Tcl interface to sqlite3_declare_vtab, invoked as follows from Tcl: | 1349 ** Tcl interface to sqlite3_declare_vtab, invoked as follows from Tcl: |
1295 ** | 1350 ** |
1296 ** sqlite3_declare_vtab DB SQL | 1351 ** sqlite3_declare_vtab DB SQL |
1297 */ | 1352 */ |
1298 static int declare_vtab( | 1353 static int declare_vtab( |
1299 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ | 1354 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
(...skipping 21 matching lines...) Expand all Loading... |
1321 /* | 1376 /* |
1322 ** Register commands with the TCL interpreter. | 1377 ** Register commands with the TCL interpreter. |
1323 */ | 1378 */ |
1324 int Sqlitetest8_Init(Tcl_Interp *interp){ | 1379 int Sqlitetest8_Init(Tcl_Interp *interp){ |
1325 #ifndef SQLITE_OMIT_VIRTUALTABLE | 1380 #ifndef SQLITE_OMIT_VIRTUALTABLE |
1326 static struct { | 1381 static struct { |
1327 char *zName; | 1382 char *zName; |
1328 Tcl_ObjCmdProc *xProc; | 1383 Tcl_ObjCmdProc *xProc; |
1329 void *clientData; | 1384 void *clientData; |
1330 } aObjCmd[] = { | 1385 } aObjCmd[] = { |
1331 { "register_echo_module", register_echo_module, 0 }, | 1386 { "register_echo_module", register_echo_module, 0 }, |
1332 { "sqlite3_declare_vtab", declare_vtab, 0 }, | 1387 { "sqlite3_declare_vtab", declare_vtab, 0 }, |
1333 }; | 1388 }; |
1334 int i; | 1389 int i; |
1335 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ | 1390 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ |
1336 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, | 1391 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, |
1337 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); | 1392 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); |
1338 } | 1393 } |
1339 #endif | 1394 #endif |
1340 return TCL_OK; | 1395 return TCL_OK; |
1341 } | 1396 } |
OLD | NEW |