| 11160 | } |
| 11161 | |
| 11162 | static int idxCreateFromCons( |
| 11163 | sqlite3expert *p, |
| 11164 | IdxScan *pScan, |
| 11165 | IdxConstraint *pEq, |
| 11166 | IdxConstraint *pTail |
| 11167 | ){ |
| 11168 | sqlite3 *dbm = p->dbm; |
| 11169 | int rc = SQLITE_OK; |
| 11170 | if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){ |
| 11171 | IdxTable *pTab = pScan->pTab; |
| 11172 | char *zCols = 0; |
| 11173 | char *zIdx = 0; |
| 11174 | IdxConstraint *pCons; |
| 11175 | unsigned int h = 0; |
| 11176 | const char *zFmt; |
| 11177 | |
| 11178 | for(pCons=pEq; pCons; pCons=pCons->pLink){ |
| 11179 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
| 11180 | } |
| 11181 | for(pCons=pTail; pCons; pCons=pCons->pLink){ |
| 11182 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
| 11183 | } |
| 11184 | |
| 11185 | if( rc==SQLITE_OK ){ |
| 11186 | /* Hash the list of columns to come up with a name for the index */ |
| 11187 | const char *zTable = pScan->pTab->zName; |
| 11188 | int quoteTable = idxIdentifierRequiresQuotes(zTable); |
| 11189 | char *zName = 0; /* Index name */ |
| 11190 | int collisions = 0; |
| 11191 | do{ |
| 11192 | int i; |
| 11193 | char *zFind; |
| 11194 | for(i=0; zCols[i]; i++){ |
| 11195 | h += ((h<<3) + zCols[i]); |
| 11196 | } |
| 11197 | sqlite3_free(zName); |
| 11198 | zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); |
| 11199 | if( zName==0 ) break; |
| 11200 | /* Is is unique among table, view and index names? */ |
| 11201 | zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q" |
| 11202 | " AND type in ('index','table','view')"; |
| 11203 | zFind = sqlite3_mprintf(zFmt, zName); |
| 11204 | i = 0; |
| 11205 | rc = sqlite3_exec(dbm, zFind, countNonzeros, &i, 0); |
| 11206 | assert(rc==SQLITE_OK); |
| 11207 | sqlite3_free(zFind); |
| 11208 | if( i==0 ){ |
| 11209 | collisions = 0; |
| 11210 | break; |
| 11211 | } |
| 11212 | ++collisions; |
| 11213 | }while( collisions<50 && zName!=0 ); |
| 11214 | if( collisions ){ |
| 11215 | /* This return means "Gave up trying to find a unique index name." */ |
| 11216 | rc = SQLITE_BUSY_TIMEOUT; |
| 11217 | }else if( zName==0 ){ |
| 11218 | rc = SQLITE_NOMEM; |
| 11219 | }else{ |
no test coverage detected