/ Check-in [cd110aa2]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Initial infrastructure for recognizing DESC indices and being able to read and write older databases that specify DESC indices but do not really use them. Nothing is close to working yet. (CVS 2822)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: cd110aa225b09591064405dd8952b3df37278c52
User & Date: drh 2005-12-16 01:06:17
Context
2005-12-16
06:54
Add the sqlite3_rollback_hook() API. Still requires further testing. (CVS 2823) check-in: 3baa3ff3 user: danielk1977 tags: trunk
01:06
Initial infrastructure for recognizing DESC indices and being able to read and write older databases that specify DESC indices but do not really use them. Nothing is close to working yet. (CVS 2822) check-in: cd110aa2 user: drh tags: trunk
2005-12-15
22:34
Fix the utf8 to utf16 conversion routine for short strings. Bug introduced by check-in (2817). (CVS 2821) check-in: 4fba2db3 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/alter.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that used to generate VDBE code
    13     13   ** that implements the ALTER TABLE command.
    14     14   **
    15         -** $Id: alter.c,v 1.11 2005/12/09 20:02:05 drh Exp $
           15  +** $Id: alter.c,v 1.12 2005/12/16 01:06:17 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   /*
    21     21   ** The code in this file only exists if we are not omitting the
    22     22   ** ALTER TABLE logic from the build.
................................................................................
   458    458       sqliteFree(zCol);
   459    459     }
   460    460   
   461    461     /* If the default value of the new column is NULL, then set the file
   462    462     ** format to 2. If the default value of the new column is not NULL,
   463    463     ** the file format becomes 3.
   464    464     */
   465         -  if( (v=sqlite3GetVdbe(pParse))!=0 ){
   466         -    int f = (pDflt?3:2);
   467         -
   468         -    /* Only set the file format to $f if it is currently less than $f. */
   469         -    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
   470         -    sqlite3VdbeAddOp(v, OP_Integer, f, 0);
   471         -    sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
   472         -    sqlite3VdbeAddOp(v, OP_Integer, f, 0);
   473         -    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
   474         -  }
          465  +  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
   475    466   
   476    467     /* Reload the schema of the modified table. */
   477    468     reloadTableSchema(pParse, pTab, pTab->zName);
   478    469   }
          470  +
          471  +/*
          472  +** Generate code to make sure the file format number is at least minFormat.
          473  +** The generated code will increase the file format number if necessary.
          474  +*/
          475  +void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
          476  +  Vdbe *v;
          477  +  v = sqlite3GetVdbe(pParse);
          478  +  if( v ){
          479  +    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
          480  +    sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
          481  +    sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
          482  +    sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
          483  +    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
          484  +  }
          485  +}
   479    486   
   480    487   
   481    488   /*
   482    489   ** This function is called by the parser after the table-name in
   483    490   ** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
   484    491   ** pSrc is the full-name of the table being altered.
   485    492   **

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.357 2005/12/09 20:02:05 drh Exp $
           25  +** $Id: build.c,v 1.358 2005/12/16 01:06:17 drh Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   #include <ctype.h>
    29     29   
    30     30   /*
    31     31   ** This routine is called when a new SQL statement is beginning to
    32     32   ** be parsed.  Initialize the pParse structure as needed.
................................................................................
   760    760   
   761    761       /* If the file format and encoding in the database have not been set, 
   762    762       ** set them now.
   763    763       */
   764    764       sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);   /* file_format */
   765    765       lbl = sqlite3VdbeMakeLabel(v);
   766    766       sqlite3VdbeAddOp(v, OP_If, 0, lbl);
   767         -    sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
          767  +    sqlite3VdbeAddOp(v, OP_Integer, 1, 0);   /* file format defaults to 1 */
   768    768       sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
   769    769       sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
   770    770       sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
   771    771       sqlite3VdbeResolveLabel(v, lbl);
   772    772   
   773    773       /* This just creates a place-holder record in the sqlite_master table.
   774    774       ** The record created does not contain anything yet.  It will be replaced
................................................................................
  1006   1006   ** If the key is not an INTEGER PRIMARY KEY, then create a unique
  1007   1007   ** index for the key.  No index is created for INTEGER PRIMARY KEYs.
  1008   1008   */
  1009   1009   void sqlite3AddPrimaryKey(
  1010   1010     Parse *pParse,    /* Parsing context */
  1011   1011     ExprList *pList,  /* List of field names to be indexed */
  1012   1012     int onError,      /* What to do with a uniqueness conflict */
  1013         -  int autoInc       /* True if the AUTOINCREMENT keyword is present */
         1013  +  int autoInc,      /* True if the AUTOINCREMENT keyword is present */
         1014  +  int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
  1014   1015   ){
  1015   1016     Table *pTab = pParse->pNewTable;
  1016   1017     char *zType = 0;
  1017   1018     int iCol = -1, i;
  1018   1019     if( pTab==0 ) goto primary_key_exit;
  1019   1020     if( pTab->hasPrimKey ){
  1020   1021       sqlite3ErrorMsg(pParse, 
................................................................................
  1037   1038         }
  1038   1039       }
  1039   1040       if( pList->nExpr>1 ) iCol = -1;
  1040   1041     }
  1041   1042     if( iCol>=0 && iCol<pTab->nCol ){
  1042   1043       zType = pTab->aCol[iCol].zType;
  1043   1044     }
  1044         -  if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){
         1045  +  if( zType && sqlite3StrICmp(zType, "INTEGER")==0
         1046  +        && sortOrder==SQLITE_SO_ASC ){
  1045   1047       pTab->iPKey = iCol;
  1046   1048       pTab->keyConf = onError;
  1047   1049       pTab->autoInc = autoInc;
  1048   1050     }else if( autoInc ){
  1049   1051   #ifndef SQLITE_OMIT_AUTOINCREMENT
  1050   1052       sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
  1051   1053          "INTEGER PRIMARY KEY");
  1052   1054   #endif
  1053   1055     }else{
  1054         -    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);
         1056  +    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder);
  1055   1057       pList = 0;
  1056   1058     }
  1057   1059   
  1058   1060   primary_key_exit:
  1059   1061     sqlite3ExprListDelete(pList);
  1060   1062     return;
  1061   1063   }
................................................................................
  2090   2092     Parse *pParse,     /* All information about this parse */
  2091   2093     Token *pName1,     /* First part of index name. May be NULL */
  2092   2094     Token *pName2,     /* Second part of index name. May be NULL */
  2093   2095     SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  2094   2096     ExprList *pList,   /* A list of columns to be indexed */
  2095   2097     int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  2096   2098     Token *pStart,     /* The CREATE token that begins a CREATE TABLE statement */
  2097         -  Token *pEnd        /* The ")" that closes the CREATE INDEX statement */
         2099  +  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
         2100  +  int sortOrder      /* Sort order of primary key when pList==NULL */
  2098   2101   ){
  2099         -  Table *pTab = 0;   /* Table to be indexed */
  2100         -  Index *pIndex = 0; /* The index to be created */
  2101         -  char *zName = 0;
         2102  +  Table *pTab = 0;     /* Table to be indexed */
         2103  +  Index *pIndex = 0;   /* The index to be created */
         2104  +  char *zName = 0;     /* Name of the index */
         2105  +  int nName;           /* Number of characters in zName */
  2102   2106     int i, j;
  2103         -  Token nullId;    /* Fake token for an empty ID list */
  2104         -  DbFixer sFix;    /* For assigning database names to pTable */
         2107  +  Token nullId;        /* Fake token for an empty ID list */
         2108  +  DbFixer sFix;        /* For assigning database names to pTable */
         2109  +  int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
         2110  +  int descSeen = 0;    /* Changes to true if a DESC is seen */
  2105   2111     sqlite3 *db = pParse->db;
  2106         -
  2107         -  int iDb;          /* Index of the database that is being written */
  2108         -  Token *pName = 0; /* Unqualified name of the index to create */
         2112  +  Db *pDb;             /* The specific table containing the indexed database */
         2113  +  int iDb;             /* Index of the database that is being written */
         2114  +  Token *pName = 0;    /* Unqualified name of the index to create */
         2115  +  struct ExprList_item *pListItem; /* For looping over pList */
         2116  +  CollSeq *pCollSeq;               /* Collating sequence for one index column */
  2109   2117   
  2110   2118     if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto exit_create_index;
  2111   2119   
  2112   2120     /*
  2113   2121     ** Find the table that is to be indexed.  Return early if not found.
  2114   2122     */
  2115   2123     if( pTblName!=0 ){
................................................................................
  2144   2152       if( !pTab ) goto exit_create_index;
  2145   2153       assert( iDb==pTab->iDb );
  2146   2154     }else{
  2147   2155       assert( pName==0 );
  2148   2156       pTab =  pParse->pNewTable;
  2149   2157       iDb = pTab->iDb;
  2150   2158     }
         2159  +  pDb = &db->aDb[iDb];
  2151   2160   
  2152   2161     if( pTab==0 || pParse->nErr ) goto exit_create_index;
  2153   2162     if( pTab->readOnly ){
  2154   2163       sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
  2155   2164       goto exit_create_index;
  2156   2165     }
  2157   2166   #ifndef SQLITE_OMIT_VIEW
................................................................................
  2179   2188       if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
  2180   2189       if( zName==0 ) goto exit_create_index;
  2181   2190       if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
  2182   2191         goto exit_create_index;
  2183   2192       }
  2184   2193       if( !db->init.busy ){
  2185   2194         if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
  2186         -      if( sqlite3FindIndex(db, zName, db->aDb[iDb].zName)!=0 ){
         2195  +      if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
  2187   2196           sqlite3ErrorMsg(pParse, "index %s already exists", zName);
  2188   2197           goto exit_create_index;
  2189   2198         }
  2190   2199         if( sqlite3FindTable(db, zName, 0)!=0 ){
  2191   2200           sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
  2192   2201           goto exit_create_index;
  2193   2202         }
................................................................................
  2203   2212       if( zName==0 ) goto exit_create_index;
  2204   2213     }
  2205   2214   
  2206   2215     /* Check for authorization to create an index.
  2207   2216     */
  2208   2217   #ifndef SQLITE_OMIT_AUTHORIZATION
  2209   2218     {
  2210         -    const char *zDb = db->aDb[iDb].zName;
         2219  +    const char *zDb = pDb->zName;
  2211   2220       if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
  2212   2221         goto exit_create_index;
  2213   2222       }
  2214   2223       i = SQLITE_CREATE_INDEX;
  2215   2224       if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
  2216   2225       if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
  2217   2226         goto exit_create_index;
................................................................................
  2224   2233     ** So create a fake list to simulate this.
  2225   2234     */
  2226   2235     if( pList==0 ){
  2227   2236       nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName;
  2228   2237       nullId.n = strlen((char*)nullId.z);
  2229   2238       pList = sqlite3ExprListAppend(0, 0, &nullId);
  2230   2239       if( pList==0 ) goto exit_create_index;
         2240  +    pList->a[0].sortOrder = sortOrder;
  2231   2241     }
  2232   2242   
  2233   2243     /* 
  2234   2244     ** Allocate the index structure. 
  2235   2245     */
  2236         -  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + sizeof(int) +
  2237         -                        (sizeof(int)*2 + sizeof(CollSeq*))*pList->nExpr );
         2246  +  nName = strlen(zName);
         2247  +  pIndex = sqliteMalloc( sizeof(Index) + nName + 2 + sizeof(int) +
         2248  +                        (sizeof(int)*2 + sizeof(CollSeq*) + 1)*pList->nExpr );
  2238   2249     if( sqlite3Tsd()->mallocFailed ) goto exit_create_index;
  2239   2250     pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
  2240   2251     pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
  2241   2252     pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
         2253  +  pIndex->keyInfo.aSortOrder = &pIndex->zName[nName+1];
  2242   2254     strcpy(pIndex->zName, zName);
  2243   2255     pIndex->pTable = pTab;
  2244   2256     pIndex->nColumn = pList->nExpr;
  2245   2257     pIndex->onError = onError;
  2246   2258     pIndex->autoIndex = pName==0;
  2247   2259     pIndex->iDb = iDb;
         2260  +
         2261  +  /* Check to see if we should honor DESC requests on index columns
         2262  +  */
         2263  +  if( pDb->file_format>=4 || (pDb->descIndex && db->init.busy) ){
         2264  +#if 0
         2265  +    sortOrderMask = -1;   /* Honor DESC */
         2266  +#else
         2267  +    sortOrderMask = 0;
         2268  +#endif
         2269  +  }else{
         2270  +    sortOrderMask = 0;    /* Ignore DESC */
         2271  +  }
  2248   2272   
  2249   2273     /* Scan the names of the columns of the table to be indexed and
  2250   2274     ** load the column indices into the Index structure.  Report an error
  2251   2275     ** if any column is not found.
  2252   2276     */
  2253         -  for(i=0; i<pList->nExpr; i++){
  2254         -    for(j=0; j<pTab->nCol; j++){
  2255         -      if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
         2277  +  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
         2278  +    const char *zColName = pListItem->zName;
         2279  +    Column *pTabCol;
         2280  +    int sortOrder;
         2281  +    for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
         2282  +      if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
  2256   2283       }
  2257   2284       if( j>=pTab->nCol ){
  2258   2285         sqlite3ErrorMsg(pParse, "table %s has no column named %s",
  2259         -        pTab->zName, pList->a[i].zName);
         2286  +        pTab->zName, zColName);
  2260   2287         goto exit_create_index;
  2261   2288       }
  2262   2289       pIndex->aiColumn[i] = j;
  2263         -    if( pList->a[i].pExpr ){
  2264         -      assert( pList->a[i].pExpr->pColl );
  2265         -      pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl;
         2290  +    if( pListItem->pExpr ){
         2291  +      assert( pListItem->pExpr->pColl );
         2292  +      pIndex->keyInfo.aColl[i] = pListItem->pExpr->pColl;
  2266   2293       }else{
  2267   2294         pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;
  2268   2295       }
  2269   2296       assert( pIndex->keyInfo.aColl[i] );
  2270   2297       if( !db->init.busy && 
  2271   2298           sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i]) 
  2272   2299       ){
  2273   2300         goto exit_create_index;
  2274   2301       }
         2302  +    sortOrder = pListItem->sortOrder;
         2303  +    pDb->descIndex |= sortOrder;
         2304  +    sortOrder &= sortOrderMask;
         2305  +    pIndex->keyInfo.aSortOrder[i] = sortOrder;
         2306  +    descSeen |= sortOrder;
  2275   2307     }
  2276   2308     pIndex->keyInfo.nField = pList->nExpr;
  2277   2309     sqlite3DefaultRowEst(pIndex);
  2278   2310   
  2279   2311     if( pTab==pParse->pNewTable ){
  2280   2312       /* This routine has been called to create an automatic index as a
  2281   2313       ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
................................................................................
  2297   2329         assert( pIdx->autoIndex );
  2298   2330         assert( pIndex->onError!=OE_None );
  2299   2331   
  2300   2332         if( pIdx->nColumn!=pIndex->nColumn ) continue;
  2301   2333         for(k=0; k<pIdx->nColumn; k++){
  2302   2334           if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
  2303   2335           if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
         2336  +        if( pIdx->keyInfo.aSortOrder[k]!=pIndex->keyInfo.aSortOrder[k] ) break;
  2304   2337         }
  2305   2338         if( k==pIdx->nColumn ){
  2306   2339           if( pIdx->onError!=pIndex->onError ){
  2307   2340             /* This constraint creates the same index as a previous
  2308   2341             ** constraint specified somewhere in the CREATE TABLE statement.
  2309   2342             ** However the ON CONFLICT clauses are different. If both this 
  2310   2343             ** constraint and the previous equivalent constraint have explicit
................................................................................
  2359   2392     else if( db->init.busy==0 ){
  2360   2393       Vdbe *v;
  2361   2394       char *zStmt;
  2362   2395       int iMem = pParse->nMem++;
  2363   2396   
  2364   2397       v = sqlite3GetVdbe(pParse);
  2365   2398       if( v==0 ) goto exit_create_index;
         2399  +
         2400  +    /* Make sure the file_format is at least 4 if we have DESC indices. */
         2401  +    if( descSeen ){
         2402  +      sqlite3MinimumFileFormat(pParse, iDb, 4);
         2403  +    }
  2366   2404   
  2367   2405       /* Create the rootpage for the index
  2368   2406       */
  2369   2407       sqlite3BeginWriteOperation(pParse, 1, iDb);
  2370   2408       sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
  2371   2409       sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
  2372   2410   

Changes to src/parse.y.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains SQLite's grammar for SQL.  Process this file
    13     13   ** using the lemon parser generator to generate C code that runs
    14     14   ** the parser.  Lemon will also generate a header file containing
    15     15   ** numeric codes for all of the tokens.
    16     16   **
    17         -** @(#) $Id: parse.y,v 1.187 2005/12/09 20:02:05 drh Exp $
           17  +** @(#) $Id: parse.y,v 1.188 2005/12/16 01:06:17 drh Exp $
    18     18   */
    19     19   
    20     20   // All token codes are small integers with #defines that begin with "TK_"
    21     21   %token_prefix TK_
    22     22   
    23     23   // The type of the data attached to each token is Token.  This is also the
    24     24   // default type for non-terminals.
................................................................................
   253    253   }
   254    254   
   255    255   // In addition to the type name, we also care about the primary key and
   256    256   // UNIQUE constraints.
   257    257   //
   258    258   ccons ::= NULL onconf.
   259    259   ccons ::= NOT NULL onconf(R).               {sqlite3AddNotNull(pParse, R);}
   260         -ccons ::= PRIMARY KEY sortorder onconf(R) autoinc(I).
   261         -                                     {sqlite3AddPrimaryKey(pParse,0,R,I);}
   262         -ccons ::= UNIQUE onconf(R).          {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0);}
          260  +ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
          261  +                                     {sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
          262  +ccons ::= UNIQUE onconf(R).          {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0);}
   263    263   ccons ::= CHECK LP expr(X) RP.       {sqlite3AddCheckConstraint(pParse,X);}
   264    264   ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
   265    265                                   {sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
   266    266   ccons ::= defer_subclause(D).   {sqlite3DeferForeignKey(pParse,D);}
   267    267   ccons ::= COLLATE id(C).  {sqlite3AddCollateType(pParse, (char*)C.z, C.n);}
   268    268   
   269    269   // The optional AUTOINCREMENT keyword
................................................................................
   303    303   conslist_opt(A) ::= .                   {A.n = 0; A.z = 0;}
   304    304   conslist_opt(A) ::= COMMA(X) conslist.  {A = X;}
   305    305   conslist ::= conslist COMMA tcons.
   306    306   conslist ::= conslist tcons.
   307    307   conslist ::= tcons.
   308    308   tcons ::= CONSTRAINT nm.
   309    309   tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
   310         -                                         {sqlite3AddPrimaryKey(pParse,X,R,I);}
          310  +                                         {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
   311    311   tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
   312         -                                       {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0);}
          312  +                                 {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0);}
   313    313   tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E);}
   314    314   tcons ::= FOREIGN KEY LP idxlist(FA) RP
   315    315             REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
   316    316       sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
   317    317       sqlite3DeferForeignKey(pParse, D);
   318    318   }
   319    319   %type defer_subclause_opt {int}
................................................................................
   830    830   
   831    831   ///////////////////////////// The CREATE INDEX command ///////////////////////
   832    832   //
   833    833   cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X) dbnm(D)
   834    834           ON nm(Y) LP idxlist(Z) RP(E) onconf(R). {
   835    835     if( U!=OE_None ) U = R;
   836    836     if( U==OE_Default) U = OE_Abort;
   837         -  sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(0,&Y,0),Z,U, &S, &E);
          837  +  sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(0,&Y,0), Z, U,
          838  +                      &S, &E, SQLITE_SO_ASC);
   838    839   }
   839    840   
   840    841   %type uniqueflag {int}
   841    842   uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
   842    843   uniqueflag(A) ::= .        {A = OE_None;}
   843    844   
   844    845   %type idxlist {ExprList*}
................................................................................
   845    846   %destructor idxlist {sqlite3ExprListDelete($$);}
   846    847   %type idxlist_opt {ExprList*}
   847    848   %destructor idxlist_opt {sqlite3ExprListDelete($$);}
   848    849   %type idxitem {Token}
   849    850   
   850    851   idxlist_opt(A) ::= .                         {A = 0;}
   851    852   idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
   852         -idxlist(A) ::= idxlist(X) COMMA idxitem(Y) collate(C) sortorder.  {
          853  +idxlist(A) ::= idxlist(X) COMMA idxitem(Y) collate(C) sortorder(Z).  {
   853    854     Expr *p = 0;
   854    855     if( C.n>0 ){
   855    856       p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
   856    857       if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
   857    858     }
   858    859     A = sqlite3ExprListAppend(X, p, &Y);
          860  +  if( A ) A->a[A->nExpr-1].sortOrder = Z;
   859    861   }
   860         -idxlist(A) ::= idxitem(Y) collate(C) sortorder. {
          862  +idxlist(A) ::= idxitem(Y) collate(C) sortorder(Z). {
   861    863     Expr *p = 0;
   862    864     if( C.n>0 ){
   863    865       p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
   864    866       if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
   865    867     }
   866    868     A = sqlite3ExprListAppend(0, p, &Y);
          869  +  if( A ) A->a[A->nExpr-1].sortOrder = Z;
   867    870   }
   868    871   idxitem(A) ::= nm(X).              {A = X;}
   869    872   
   870    873   
   871    874   ///////////////////////////// The DROP INDEX command /////////////////////////
   872    875   //
   873    876   cmd ::= DROP INDEX fullname(X).   {sqlite3DropIndex(pParse, X);}

Changes to src/prepare.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the implementation of the sqlite3_prepare()
    13     13   ** interface, and routines that contribute to loading the database schema
    14     14   ** from disk.
    15     15   **
    16         -** $Id: prepare.c,v 1.9 2005/12/15 03:04:11 drh Exp $
           16  +** $Id: prepare.c,v 1.10 2005/12/16 01:06:17 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "os.h"
    20     20   #include <ctype.h>
    21     21   
    22     22   /*
    23     23   ** Fill the InitData structure with an error message that indicates
................................................................................
   111    111   ** indicate success or failure.
   112    112   */
   113    113   static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   114    114     int rc;
   115    115     BtCursor *curMain;
   116    116     int size;
   117    117     Table *pTab;
          118  +  Db *pDb;
   118    119     char const *azArg[5];
   119    120     char zDbNum[30];
   120    121     int meta[10];
   121    122     InitData initData;
   122    123     char const *zMasterSchema;
   123    124     char const *zMasterName = SCHEMA_TABLE(iDb);
   124    125   
................................................................................
   180    181     if( pTab ){
   181    182       pTab->readOnly = 1;
   182    183     }
   183    184     sqlite3SafetyOn(db);
   184    185   
   185    186     /* Create a cursor to hold the database open
   186    187     */
   187         -  if( db->aDb[iDb].pBt==0 ){
          188  +  pDb = &db->aDb[iDb];
          189  +  if( pDb->pBt==0 ){
   188    190       if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
   189    191       return SQLITE_OK;
   190    192     }
   191         -  rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
          193  +  rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain);
   192    194     if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
   193    195       sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
   194    196       return rc;
   195    197     }
   196    198   
   197    199     /* Get the database meta information.
   198    200     **
................................................................................
   210    212     **
   211    213     ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
   212    214     ** the possible values of meta[4].
   213    215     */
   214    216     if( rc==SQLITE_OK ){
   215    217       int i;
   216    218       for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
   217         -      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, (u32 *)&meta[i]);
          219  +      rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
   218    220       }
   219    221       if( rc ){
   220    222         sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
   221    223         sqlite3BtreeCloseCursor(curMain);
   222    224         return rc;
   223    225       }
   224    226     }else{
   225    227       memset(meta, 0, sizeof(meta));
   226    228     }
   227         -  db->aDb[iDb].schema_cookie = meta[0];
          229  +  pDb->schema_cookie = meta[0];
   228    230   
   229    231     /* If opening a non-empty database, check the text encoding. For the
   230    232     ** main database, set sqlite3.enc to the encoding of the main database.
   231    233     ** For an attached db, it is an error if the encoding is not the same
   232    234     ** as sqlite3.enc.
   233    235     */
   234    236     if( meta[4] ){  /* text encoding */
................................................................................
   245    247           return SQLITE_ERROR;
   246    248         }
   247    249       }
   248    250     }
   249    251   
   250    252     size = meta[2];
   251    253     if( size==0 ){ size = MAX_PAGES; }
   252         -  db->aDb[iDb].cache_size = size;
   253         -
   254         -  if( iDb==0 ){
   255         -    db->file_format = meta[1];
   256         -    if( db->file_format==0 ){
   257         -      /* This happens if the database was initially empty */
   258         -      db->file_format = 1;
   259         -    }
   260         -
   261         -    if( db->file_format==2 || db->file_format==3 ){
   262         -      /* File format 2 is treated exactly as file format 1. New 
   263         -      ** databases are created with file format 1.
   264         -      */ 
   265         -      db->file_format = 1;
   266         -    }
   267         -  }
          254  +  pDb->cache_size = size;
          255  +  sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
   268    256   
   269    257     /*
   270    258     ** file_format==1    Version 3.0.0.
   271         -  ** file_format==2    Version 3.1.3.
   272         -  ** file_format==3    Version 3.1.4.
   273         -  **
   274         -  ** Version 3.0 can only use files with file_format==1. Version 3.1.3
   275         -  ** can read and write files with file_format==1 or file_format==2.
   276         -  ** Version 3.1.4 can read and write file formats 1, 2 and 3.
          259  +  ** file_format==2    Version 3.1.3.  // ALTER TABLE ADD COLUMN
          260  +  ** file_format==3    Version 3.1.4.  // ditto but with non-NULL defaults
          261  +  ** file_format==4    Version 3.3.0.  // DESC indices
   277    262     */
   278         -  if( meta[1]>3 ){
          263  +  pDb->file_format = meta[1];
          264  +  if( pDb->file_format==0 ){
          265  +    pDb->file_format = 1;
          266  +  }
          267  +  if( pDb->file_format>4 ){
   279    268       sqlite3BtreeCloseCursor(curMain);
   280    269       sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
   281    270       return SQLITE_ERROR;
   282    271     }
   283    272   
   284         -  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
   285    273   
   286    274     /* Read the schema information out of the schema tables
   287    275     */
   288    276     assert( db->init.busy );
   289    277     if( rc==SQLITE_EMPTY ){
   290    278       /* For an empty database, there is nothing to read */
   291    279       rc = SQLITE_OK;

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.437 2005/12/15 15:22:09 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.438 2005/12/16 01:06:17 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
    21     21   ** Setting NDEBUG makes the code smaller and run faster.  So the following
................................................................................
   352    352     Hash tblHash;        /* All tables indexed by name */
   353    353     Hash idxHash;        /* All (named) indices indexed by name */
   354    354     Hash trigHash;       /* All triggers indexed by name */
   355    355     Hash aFKey;          /* Foreign keys indexed by to-table */
   356    356     u16 flags;           /* Flags associated with this database */
   357    357     u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   358    358     u8 safety_level;     /* How aggressive at synching data to disk */
          359  +  u8 file_format;      /* Schema format version for this file */
          360  +  u8 descIndex;        /* True if any index uses the DESC attribute */
   359    361     int cache_size;      /* Number of pages to use in the cache */
   360    362     Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
   361    363     void *pAux;               /* Auxiliary data.  Usually NULL */
   362    364     void (*xFreeAux)(void*);  /* Routine to free pAux */
   363    365   };
   364    366   
   365    367   /*
................................................................................
   415    417   struct sqlite3 {
   416    418     int nDb;                      /* Number of backends currently in use */
   417    419     Db *aDb;                      /* All backends */
   418    420     int flags;                    /* Miscellanous flags. See below */
   419    421     int errCode;                  /* Most recent error code (SQLITE_*) */
   420    422     u8 enc;                       /* Text encoding for this database. */
   421    423     u8 autoCommit;                /* The auto-commit flag. */
   422         -  u8 file_format;               /* What file format version is this database? */
   423    424     u8 temp_store;                /* 1: file 2: memory 0: default */
   424    425     int nTable;                   /* Number of tables in the database */
   425    426     CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
   426    427     i64 lastRowid;                /* ROWID of most recent insert (see above) */
   427    428     i64 priorNewRowid;            /* Last randomly generated ROWID */
   428    429     int magic;                    /* Magic number for detect library misuse */
   429    430     int nChange;                  /* Value returned by sqlite3_changes() */
................................................................................
  1463   1464   void sqlite3RollbackInternalChanges(sqlite3*);
  1464   1465   void sqlite3CommitInternalChanges(sqlite3*);
  1465   1466   Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
  1466   1467   void sqlite3OpenMasterTable(Vdbe *v, int);
  1467   1468   void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
  1468   1469   void sqlite3AddColumn(Parse*,Token*);
  1469   1470   void sqlite3AddNotNull(Parse*, int);
  1470         -void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int);
         1471  +void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
  1471   1472   void sqlite3AddCheckConstraint(Parse*, Expr*);
  1472   1473   void sqlite3AddColumnType(Parse*,Token*);
  1473   1474   void sqlite3AddDefaultValue(Parse*,Expr*);
  1474   1475   void sqlite3AddCollateType(Parse*, const char*, int);
  1475   1476   void sqlite3EndTable(Parse*,Token*,Token*,Select*);
  1476   1477   
  1477   1478   #ifndef SQLITE_OMIT_VIEW
................................................................................
  1489   1490   int sqlite3IdListIndex(IdList*,const char*);
  1490   1491   SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
  1491   1492   void sqlite3SrcListAddAlias(SrcList*, Token*);
  1492   1493   void sqlite3SrcListAssignCursors(Parse*, SrcList*);
  1493   1494   void sqlite3IdListDelete(IdList*);
  1494   1495   void sqlite3SrcListDelete(SrcList*);
  1495   1496   void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
  1496         -                        Token*);
         1497  +                        Token*, int);
  1497   1498   void sqlite3DropIndex(Parse*, SrcList*);
  1498   1499   void sqlite3AddKeyType(Vdbe*, ExprList*);
  1499   1500   void sqlite3AddIdxKeyType(Vdbe*, Index*);
  1500   1501   int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
  1501   1502   Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
  1502   1503                           int,Expr*,Expr*);
  1503   1504   void sqlite3SelectDelete(Select*);
................................................................................
  1672   1673   int sqlite3FindDb(sqlite3*, Token*);
  1673   1674   void sqlite3AnalysisLoad(sqlite3*,int iDB);
  1674   1675   void sqlite3DefaultRowEst(Index*);
  1675   1676   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  1676   1677   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
  1677   1678   SqliteTsd *sqlite3Tsd();
  1678   1679   void sqlite3AttachFunctions(sqlite3 *);
         1680  +void sqlite3MinimumFileFormat(Parse*, int, int);
  1679   1681   
  1680   1682   void sqlite3MallocClearFailed();
  1681   1683   #ifdef NDEBUG
  1682   1684     #define sqlite3MallocDisallow()
  1683   1685     #define sqlite3MallocAllow()
  1684   1686   #else
  1685   1687     void sqlite3MallocDisallow();

Changes to src/vdbeaux.c.

   431    431     if( zP3==0 ){
   432    432       pOp->p3 = 0;
   433    433       pOp->p3type = P3_NOTUSED;
   434    434     }else if( n==P3_KEYINFO ){
   435    435       KeyInfo *pKeyInfo;
   436    436       int nField, nByte;
   437    437   
   438         -    /* KeyInfo structures that include an KeyInfo.aSortOrder are always
   439         -    ** sent in using P3_KEYINFO_HANDOFF.  The KeyInfo.aSortOrder array
   440         -    ** is not duplicated when P3_KEYINFO is used. */
   441         -    /* assert( pKeyInfo->aSortOrder==0 ); */
   442    438       nField = ((KeyInfo*)zP3)->nField;
   443         -    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]);
          439  +    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
   444    440       pKeyInfo = sqliteMallocRaw( nByte );
   445    441       pOp->p3 = (char*)pKeyInfo;
   446    442       if( pKeyInfo ){
          443  +      char *aSortOrder;
   447    444         memcpy(pKeyInfo, zP3, nByte);
          445  +      aSortOrder = pKeyInfo->aSortOrder;
          446  +      if( aSortOrder ){
          447  +        pKeyInfo->aSortOrder = (char*)&pKeyInfo->aColl[nField];
          448  +        memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
          449  +      }
   448    450         pOp->p3type = P3_KEYINFO;
   449    451       }else{
   450    452         pOp->p3type = P3_NOTUSED;
   451    453       }
   452    454     }else if( n==P3_KEYINFO_HANDOFF ){
   453    455       pOp->p3 = (char*)zP3;
   454    456       pOp->p3type = P3_KEYINFO;

Changes to test/capi3.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script testing the callback-free C/C++ API.
    13     13   #
    14         -# $Id: capi3.test,v 1.34 2005/08/11 02:10:19 drh Exp $
           14  +# $Id: capi3.test,v 1.35 2005/12/16 01:06:18 drh Exp $
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Return the UTF-16 representation of the supplied UTF-8 string $str.
    21     21   # If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
   486    486   if {![sqlite3 -has-codec]} {
   487    487     # Test what happens when the library encounters a newer file format.
   488    488     # Do this by updating the file format via the btree layer.
   489    489     do_test capi3-7.1 {
   490    490       set ::bt [btree_open test.db 10 0]
   491    491       btree_begin_transaction $::bt
   492    492       set meta [btree_get_meta $::bt]
   493         -    lset meta 2 4
          493  +    lset meta 2 5
   494    494       eval [concat btree_update_meta $::bt [lrange $meta 0 end]]
   495    495       btree_commit $::bt
   496    496       btree_close $::bt
   497    497     } {}
   498    498     do_test capi3-7.2 {
   499    499       sqlite3 db test.db
   500    500       catchsql {