1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Use a hash table to improve the preformance of column name uniqueness checking.

FossilOrigin-Name: 5b08f29f458c600401860c7d70d8174cf61e69f8
This commit is contained in:
drh
2015-11-14 20:52:43 +00:00
parent ebed3fa3e1
commit 0315e3cc14
3 changed files with 25 additions and 27 deletions

View File

@@ -1602,7 +1602,9 @@ int sqlite3ColumnsFromExprList(
Expr *p; /* Expression for a single result column */
char *zName; /* Column name */
int nName; /* Size of name in zName[] */
Hash ht; /* Hash table of column names */
sqlite3HashInit(&ht);
if( pEList ){
nCol = pEList->nExpr;
aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
@@ -1614,7 +1616,7 @@ int sqlite3ColumnsFromExprList(
*pnCol = nCol;
*paCol = aCol;
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
/* Get an appropriate name for the column
*/
p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
@@ -1643,32 +1645,28 @@ int sqlite3ColumnsFromExprList(
zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
}
}
if( db->mallocFailed ){
sqlite3DbFree(db, zName);
break;
}
/* Make sure the column name is unique. If the name is not unique,
** append an integer to the name so that it becomes unique.
*/
nName = sqlite3Strlen30(zName);
for(j=cnt=0; j<i; j++){
if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
char *zNewName;
int k;
for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
if( k>=0 && zName[k]==':' ) nName = k;
zName[nName] = 0;
zNewName = sqlite3MPrintf(db, "%s:%u", zName, ++cnt);
sqlite3DbFree(db, zName);
zName = zNewName;
j = -1;
if( zName==0 ) break;
if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
}
cnt = 0;
while( zName && sqlite3HashFind(&ht, zName)!=0 ){
char *zNewName;
nName = sqlite3Strlen30(zName);
for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
if( zName[j]==':' ) nName = j;
zName[nName] = 0;
zNewName = sqlite3MPrintf(db, "%s:%u", zName, ++cnt);
sqlite3DbFree(db, zName);
zName = zNewName;
if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
}
pCol->zName = zName;
if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
db->mallocFailed = 1;
}
}
sqlite3HashClear(&ht);
if( db->mallocFailed ){
for(j=0; j<i; j++){
sqlite3DbFree(db, aCol[j].zName);