Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -1268,10 +1268,34 @@ (int)(pSpan->zEnd - pSpan->zStart)); } } sqlite3ExprDelete(db, pSpan->pExpr); } + +/* +** Backwards Compatibility Hack: +** +** Historical versions of SQLite accepted strings as column names in +** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example: +** +** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim) +** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC); +** +** This is goofy. But to preserve backwards compatibility we continue to +** accept it. This routine does the necessary conversion. It converts +** the expression given in its argument from a TK_STRING into a TK_ID +** if the expression is just a TK_STRING with an optional COLLATE clause. +** If the epxression is anything other than TK_STRING, the expression is +** unchanged. +*/ +static void sqlite3StringToId(Expr *p){ + if( p->op==TK_STRING ){ + p->op = TK_ID; + }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){ + p->pLeft->op = TK_ID; + } +} /* ** Designate the PRIMARY KEY for the table. pList is a list of names ** of columns that form the primary key. If pList is NULL, then the ** most recently added column of the table is the primary key. @@ -1315,10 +1339,11 @@ }else{ nTerm = pList->nExpr; for(i=0; ia[i].pExpr); assert( pCExpr!=0 ); + sqlite3StringToId(pCExpr); if( pCExpr->op==TK_ID ){ const char *zCName = pCExpr->u.zToken; for(iCol=0; iColnCol; iCol++){ if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY; @@ -2853,34 +2878,10 @@ *ppExtra = ((char*)p) + nByte; } return p; } -/* -** Backwards Compatibility Hack: -** -** Historical versions of SQLite accepted strings as column names in -** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example: -** -** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim) -** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC); -** -** This is goofy. But to preserve backwards compatibility we continue to -** accept it. This routine does the necessary conversion. It converts -** the expression given in its argument from a TK_STRING into a TK_ID -** if the expression is just a TK_STRING with an optional COLLATE clause. -** If the epxression is anything other than TK_STRING, the expression is -** unchanged. -*/ -static void sqlite3StringToId(Expr *p){ - if( p->op==TK_STRING ){ - p->op = TK_ID; - }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){ - p->pLeft->op = TK_ID; - } -} - /* ** Create a new index for an SQL table. pName1.pName2 is the name of the index ** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable Index: test/index3.test ================================================================== --- test/index3.test +++ test/index3.test @@ -60,10 +60,25 @@ } {5} do_execsql_test index3-2.2eqp { EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b='ab005xy' COLLATE nocase; } {/USING INDEX/} +do_execsql_test index3-2.3 { + SELECT name FROM sqlite_master WHERE tbl_name='t1' ORDER BY name +} {sqlite_autoindex_t1_1 sqlite_autoindex_t1_2 t1 t1c t1d} +do_execsql_test index3-2.4 { + CREATE TABLE t2a(a integer, b, PRIMARY KEY(a)); + CREATE TABLE t2b("a" integer, b, PRIMARY KEY("a")); + CREATE TABLE t2c([a] integer, b, PRIMARY KEY([a])); + CREATE TABLE t2d('a' integer, b, PRIMARY KEY('a')); +} +do_execsql_test index3-2.5 { + SELECT name FROM sqlite_master WHERE tbl_name LIKE 't2_' ORDER BY name +} {t2a t2b t2c t2d} + + + # This test corrupts the database file so it must be the last test # in the series. #