| 9285 | } |
| 9286 | |
| 9287 | static int idxCreateFromCons( |
| 9288 | sqlite3expert *p, |
| 9289 | IdxScan *pScan, |
| 9290 | IdxConstraint *pEq, |
| 9291 | IdxConstraint *pTail |
| 9292 | ){ |
| 9293 | sqlite3 *dbm = p->dbm; |
| 9294 | int rc = SQLITE_OK; |
| 9295 | if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){ |
| 9296 | IdxTable *pTab = pScan->pTab; |
| 9297 | char *zCols = 0; |
| 9298 | char *zIdx = 0; |
| 9299 | IdxConstraint *pCons; |
| 9300 | unsigned int h = 0; |
| 9301 | const char *zFmt; |
| 9302 | |
| 9303 | for(pCons=pEq; pCons; pCons=pCons->pLink){ |
| 9304 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
| 9305 | } |
| 9306 | for(pCons=pTail; pCons; pCons=pCons->pLink){ |
| 9307 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
| 9308 | } |
| 9309 | |
| 9310 | if( rc==SQLITE_OK ){ |
| 9311 | /* Hash the list of columns to come up with a name for the index */ |
| 9312 | const char *zTable = pScan->pTab->zName; |
| 9313 | char *zName; /* Index name */ |
| 9314 | int i; |
| 9315 | for(i=0; zCols[i]; i++){ |
| 9316 | h += ((h<<3) + zCols[i]); |
| 9317 | } |
| 9318 | zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); |
| 9319 | if( zName==0 ){ |
| 9320 | rc = SQLITE_NOMEM; |
| 9321 | }else{ |
| 9322 | if( idxIdentifierRequiresQuotes(zTable) ){ |
| 9323 | zFmt = "CREATE INDEX '%q' ON %Q(%s)"; |
| 9324 | }else{ |
| 9325 | zFmt = "CREATE INDEX %s ON %s(%s)"; |
| 9326 | } |
| 9327 | zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols); |
| 9328 | if( !zIdx ){ |
| 9329 | rc = SQLITE_NOMEM; |
| 9330 | }else{ |
| 9331 | rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg); |
| 9332 | idxHashAdd(&rc, &p->hIdx, zName, zIdx); |
| 9333 | } |
| 9334 | sqlite3_free(zName); |
| 9335 | sqlite3_free(zIdx); |
| 9336 | } |
| 9337 | } |
| 9338 | |
| 9339 | sqlite3_free(zCols); |
| 9340 | } |
| 9341 | return rc; |
| 9342 | } |
| 9343 | |
| 9344 | /* |
no test coverage detected