]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
All the code is now in place for SQLite to distinguish between NUMERIC and
authordrh <drh@noemail.net>
Fri, 5 Jul 2002 21:42:36 +0000 (21:42 +0000)
committerdrh <drh@noemail.net>
Fri, 5 Jul 2002 21:42:36 +0000 (21:42 +0000)
TEXT datatypes.  Still need to turn on the new code and test it. (CVS 659)

FossilOrigin-Name: b4737a16c997a6c139d616211fb6bc4b0fae181c

12 files changed:
manifest
manifest.uuid
src/build.c
src/delete.c
src/insert.c
src/parse.y
src/select.c
src/sqliteInt.h
src/update.c
src/util.c
src/vdbe.c
test/table.test

index 61265ffe64189ebc8687aefb0c645e2d4e96cdef..e8849d23c3a8d3aeadd41d16b0d8e5f2dc63587e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sfor\sticket\s#92:\sCorrect\sthe\ssqliteExprCompare()\sfunction\sso\sthat\sis\stakes\ninto\saccount\sthe\siTable\sand\siColumn\sfields\sof\sthe\sExpr\sstructure.\s\sOtherwise,\n"min(a)"\sand\s"min(b)"\swill\scompare\sequal\sto\seach\sother\sin\sviews.\s(CVS\s658)
-D 2002-07-02T13:05:05
+C All\sthe\scode\sis\snow\sin\splace\sfor\sSQLite\sto\sdistinguish\sbetween\sNUMERIC\sand\nTEXT\sdatatypes.\s\sStill\sneed\sto\sturn\son\sthe\snew\scode\sand\stest\sit.\s(CVS\s659)
+D 2002-07-05T21:42:36
 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
 F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -20,28 +20,28 @@ F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
 F src/btree.c 6aaa67d7eab70c2531dc13e5d9eb87e626c0b4d7
 F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
-F src/build.c 0834185cbe316dda5173de50886ed804b82e3ba6
-F src/delete.c 44c45460b1e03033756e35adc6d569ffbf30b725
+F src/build.c ea4a3bc15d6338294e68100f642edf48e4082403
+F src/delete.c 215492ffcea4262a993e55f3c4a67dc9fea4da9c
 F src/encode.c 346b12b46148506c32038524b95c4631ab46d760
 F src/expr.c 4b25ee5e65f351d40dea8575b998605762556d76
 F src/func.c 5eae8227a8b0d276a64d51a3880a6e86f238fedf
 F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72
 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
-F src/insert.c 4bb40ed9dbaba4516fc2abbcff3f08d5687b073c
+F src/insert.c 4511e06abce1688664ce90cbf09fa13433b82c43
 F src/main.c 6ac32ca71ab4728212c5b44aed25e26dc6cfe73c
 F src/md5.c 0ae1f3e2cac92d06fc6246d1b4b8f61a2fe66d3b
 F src/os.c 9cc40c5384baba4a85e160e67807645ca98ba3cc
 F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
 F src/pager.c 58ae9f569b3c664ea9205c6f6da432e3ae180f56
 F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
-F src/parse.y dcaf21965b6cba956d1ad014b87d849cee52af13
+F src/parse.y 35437ac29441ce2d34904d8e93f40b7d112147a9
 F src/printf.c 236ed7a79386feed4456fa728fff8be793f1547c
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
-F src/select.c 63a10ea636c8ac8cdf2fbb804fbfcfd372150717
+F src/select.c 1c7c0b42c27b9d115c955023074a292197a17b3b
 F src/shell.c 0b06e4421ddf34f30263a2674abe768a2b5fd538
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in 75c5bbb066d0faf34424b7d1babf8b44d5b31af2
-F src/sqliteInt.h 314a4feb08cccdeb90b434e6dde86b93d2f36b8e
+F src/sqliteInt.h 6a36f4fc32cbbf3e6bf15516137b113b3dc973aa
 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
 F src/tclsqlite.c e932591c0bb522b0a35ea7dc861c623ccb2e3aa8
 F src/test1.c a2f2b6b1df07d4e8b380323896c3ed34442cea91
@@ -50,9 +50,9 @@ F src/test3.c 72ac6a9017a70e542954907a1dfd87ab6f7824e3
 F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
 F src/tokenize.c b5500e193a82b5b9888fbf947efd90d3b4858178
 F src/trigger.c d88ab4d68d68955c217b38fb6717e090fbbf54a4
-F src/update.c 06303bf3895032c7eccb748927f650ed02b9f0cf
-F src/util.c 876b259f9186e84b944b72e793dd3dad50e63e95
-F src/vdbe.c c83ece2aeb3a6ce7de9a1636c98c3feec9267499
+F src/update.c 494479cc4fe34165cb9ea97bccefb405e7b875d2
+F src/util.c 7a99e754c44dd220e881122e30581c08b6d6adef
+F src/vdbe.c 0169270bb73e8dec4174b90dffc7070c4cabe039
 F src/vdbe.h a9292f2b5fcecef924fa255fb74609e9cbc776c2
 F src/where.c 6a43aa6c80eab12221eeca754cba852a9ecd1e13
 F test/all.test e4d3821eeba751829b419cd47814bd20af4286d1
@@ -95,7 +95,7 @@ F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
 F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85
 F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
 F test/subselect.test 64e71b1be804dc57c72b61d2bd7b506dbc962c40
-F test/table.test 42511f98a3e9bbee62913e3ae1774777faa23d35
+F test/table.test bc571115def9be8adab6df93aca0b0c05c007eea
 F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
 F test/tclsqlite.test 6f4b9760681c7dbca52a18d0ab46a1679cdc79b9
 F test/temptable.test 9ed7ec0288f887e132de66d90c428ad109105f67
@@ -137,7 +137,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 3cac283de4939538f09cd11e2cbdc84e9a9602f2
-R dcd0974614e55fffecaf44a18cd6cd53
+P 85793a4f03250166c21007cab3525709592d0866
+R f77acd757b229f1cdb42ab7cac78b933
 U drh
-Z d34a13be1a939e0f9ee685ea0fba9ad6
+Z 6c4c383ead0a1302c4ea68955c9a4a90
index 1f4779246566f84b6009e1da0eeb23f1a0e1d93a..24b731aef6251228bf43db937b0b22124fca9245 100644 (file)
@@ -1 +1 @@
-85793a4f03250166c21007cab3525709592d0866
\ No newline at end of file
+b4737a16c997a6c139d616211fb6bc4b0fae181c
\ No newline at end of file
index 47bdf12d905814c7fbeaa187c87fe84826cbc487..9f1aa9cd20781db05b4bec32065a7229fadd7362 100644 (file)
@@ -25,7 +25,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.100 2002/06/28 12:18:47 drh Exp $
+** $Id: build.c,v 1.101 2002/07/05 21:42:36 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -463,6 +463,14 @@ void sqliteAddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
   pCol->sortOrder = SQLITE_SO_NUM;
   for(i=0; z[i]; i++){
     switch( z[i] ){
+      case 'b':
+      case 'B': {
+        if( sqliteStrNICmp(&z[i],"blob",4)==0 ){
+          pCol->sortOrder = SQLITE_SO_TEXT;
+          return;
+        }
+        break;
+      }
       case 'c':
       case 'C': {
         if( sqliteStrNICmp(&z[i],"char",4)==0 ||
@@ -1092,6 +1100,39 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
   sqliteViewResetAll(db);
 }
 
+/*
+** This routine constructs a P3 string suitable for an OP_MakeIdxKey
+** opcode and adds that P3 string to the most recently inserted instruction
+** in the virtual machine.  The P3 string consists of a single character
+** for each column in the index pIdx of table pTab.  If the column uses
+** a numeric sort order, then the P3 string character corresponding to
+** that column is 'n'.  If the column uses a text sort order, then the
+** P3 string is 't'.  See the OP_MakeIdxKey opcode documentation for
+** additional information.  See also the sqliteAddKeyType() routine.
+*/
+void sqliteAddIdxKeyType(Vdbe *v, Index *pIdx){
+  char *zType;
+  Table *pTab;
+  int i, n;
+  assert( pIdx!=0 && pIdx->pTable!=0 );
+  pTab = pIdx->pTable;
+  n = pIdx->nColumn;
+  zType = sqliteMalloc( n+1 );
+  if( zType==0 ) return;
+  for(i=0; i<n; i++){
+    int iCol = pIdx->aiColumn[i];
+    assert( iCol>=0 && iCol<pTab->nCol );
+    if( (pTab->aCol[iCol].sortOrder & SQLITE_SO_TYPEMASK)==SQLITE_SO_TEXT ){
+      zType[i] = 't';
+    }else{
+      zType[i] = 'n';
+    }
+  }
+  zType[n] = 0;
+  sqliteVdbeChangeP3(v, -1, zType, n);
+  sqliteFree(zType);
+}
+
 /*
 ** Create a new index for an SQL table.  pIndex is the name of the index 
 ** and pTable is the name of the table that is to be indexed.  Both will 
@@ -1355,6 +1396,7 @@ void sqliteCreateIndex(
         sqliteVdbeAddOp(v, OP_Column, 2, pIndex->aiColumn[i]);
       }
       sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
+      if( db->file_format>=3 ) sqliteAddIdxKeyType(v, pIndex);
       sqliteVdbeAddOp(v, OP_IdxPut, 1, pIndex->onError!=OE_None);
       sqliteVdbeAddOp(v, OP_Next, 2, lbl1);
       sqliteVdbeResolveLabel(v, lbl2);
index 1dfc7f244395f3293dbe53a951b49182a74de581..8e91e25eed21b0a726a85af163da5156899d9ede 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle DELETE FROM statements.
 **
-** $Id: delete.c,v 1.38 2002/06/19 14:27:05 drh Exp $
+** $Id: delete.c,v 1.39 2002/07/05 21:42:37 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -261,7 +261,7 @@ void sqliteDeleteFrom(
     }
 
     /* Delete the row */
-    sqliteGenerateRowDelete(v, pTab, base, pParse->trigStack==0);
+    sqliteGenerateRowDelete(db, v, pTab, base, pParse->trigStack==0);
 
     /* If there are row triggers, close all cursors then invoke
     ** the AFTER triggers
@@ -329,6 +329,7 @@ delete_from_cleanup:
 ** entries that point to that record.
 */
 void sqliteGenerateRowDelete(
+  sqlite *db,        /* The database containing the index */
   Vdbe *v,           /* Generate code into this VDBE */
   Table *pTab,       /* Table containing the row to be deleted */
   int base,          /* Cursor number for the table */
@@ -336,7 +337,7 @@ void sqliteGenerateRowDelete(
 ){
   int addr;
   addr = sqliteVdbeAddOp(v, OP_NotExists, base, 0);
-  sqliteGenerateRowIndexDelete(v, pTab, base, 0);
+  sqliteGenerateRowIndexDelete(db, v, pTab, base, 0);
   sqliteVdbeAddOp(v, OP_Delete, base, count);
   sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
 }
@@ -358,6 +359,7 @@ void sqliteGenerateRowDelete(
 **       deleted.
 */
 void sqliteGenerateRowIndexDelete(
+  sqlite *db,        /* The database containing the index */
   Vdbe *v,           /* Generate code into this VDBE */
   Table *pTab,       /* Table containing the row to be deleted */
   int base,          /* Cursor number for the table */
@@ -379,6 +381,7 @@ void sqliteGenerateRowIndexDelete(
       }
     }
     sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
+    if( db->file_format>=3 ) sqliteAddIdxKeyType(v, pIdx);
     sqliteVdbeAddOp(v, OP_IdxDelete, base+i, 0);
   }
 }
index ee5b31f92d9b2b4be0c6a47991ded12516711225..a6b2e858ed9c609fea4962356e07668a9a8ccdda 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.62 2002/06/19 20:32:44 drh Exp $
+** $Id: insert.c,v 1.63 2002/07/05 21:42:37 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -616,6 +616,7 @@ void sqliteGenerateConstraintChecks(
       }
     }
     jumpInst1 = sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
+    if( pParse->db->file_format>=3 ) sqliteAddIdxKeyType(v, pIdx);
     onError = pIdx->onError;
     if( onError==OE_None ) continue;
     if( overrideError!=OE_Default ){
@@ -640,7 +641,7 @@ void sqliteGenerateConstraintChecks(
         break;
       }
       case OE_Replace: {
-        sqliteGenerateRowDelete(v, pTab, base, 0);
+        sqliteGenerateRowDelete(pParse->db, v, pTab, base, 0);
         if( isUpdate ){
           sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
           sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
index 0eadf3570cf86067873e9165cbfccf51327601de..6a2e3dc86fa48b3d48e179f1384f8ef7c19c2eea 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.76 2002/07/01 12:27:09 drh Exp $
+** @(#) $Id: parse.y,v 1.77 2002/07/05 21:42:37 drh Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -394,9 +394,9 @@ sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
   A = sqliteExprListAppend(X,Y,0);
   if( A ) A->a[A->nExpr-1].sortOrder = C+Z;
 }
-sortlist(A) ::= sortitem(Y) sortorder(Z). {
+sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
   A = sqliteExprListAppend(0,Y,0);
-  if( A ) A->a[0].sortOrder = Z;
+  if( A ) A->a[0].sortOrder = C+Z;
 }
 sortitem(A) ::= expr(X).   {A = X;}
 
index 92fa302a529c7100bad53ec579d97c55ba325f48..882e8885c3c0fe3dab2419aed314bb172aded4f8 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.102 2002/06/29 02:20:08 drh Exp $
+** $Id: select.c,v 1.103 2002/07/05 21:42:37 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -315,7 +315,24 @@ static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
   zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
   if( zSortOrder==0 ) return;
   for(i=0; i<pOrderBy->nExpr; i++){
-    zSortOrder[i] = pOrderBy->a[i].sortOrder ? '-' : '+';
+    int order = pOrderBy->a[i].sortOrder;
+    int type;
+    int c;
+    if( (order & SQLITE_SO_TYPEMASK)==SQLITE_SO_TEXT ){
+      type = SQLITE_SO_TEXT;
+    }else if( (order & SQLITE_SO_TYPEMASK)==SQLITE_SO_NUM ){
+      type = SQLITE_SO_NUM;
+    }else if( pParse->db->file_format>=3 ){
+      type = sqliteExprType(pOrderBy->a[i].pExpr);
+    }else{
+      type = SQLITE_SO_NUM;
+    }
+    if( (order & SQLITE_SO_DIRMASK)==SQLITE_SO_ASC ){
+      c = type==SQLITE_SO_TEXT ? 'A' : '+';
+    }else{
+      c = type==SQLITE_SO_TEXT ? 'D' : '-';
+    }
+    zSortOrder[i] = c;
     sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
   }
   zSortOrder[pOrderBy->nExpr] = 0;
@@ -325,13 +342,37 @@ static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
   sqliteVdbeAddOp(v, OP_SortPut, 0, 0);
 }
 
+/*
+** This routine adds a P3 argument to the last VDBE opcode that was
+** inserted. The P3 argument added is a string suitable for the 
+** OP_MakeKey or OP_MakeIdxKey opcodes.  The string consists of
+** characters 't' or 'n' depending on whether or not the various
+** fields of the key to be generated should be treated as numeric
+** or as text.  See the OP_MakeKey and OP_MakeIdxKey opcode
+** documentation for additional information about the P3 string.
+** See also the sqliteAddIdxKeyType() routine.
+*/
+void sqliteAddKeyType(Vdbe *v, ExprList *pEList){
+  int nColumn = pEList->nExpr;
+  char *zType = sqliteMalloc( nColumn+1 );
+  int i;
+  if( zType==0 ) return;
+  for(i=0; i<nColumn; i++){
+    zType[i] = sqliteExprType(pEList->a[i].pExpr)==SQLITE_SO_NUM ? 'n' : 't';
+  }
+  zType[i] = 0;
+  sqliteVdbeChangeP3(v, -1, zType, nColumn);
+  sqliteFree(zType);
+}
+
 /*
 ** This routine generates the code for the inside of the inner loop
 ** of a SELECT.
 **
-** The pEList is used to determine the values for each column in the
-** result row.  Except  if pEList==NULL, then we just read nColumn
-** elements from the srcTab table.
+** If srcTab and nColumn are both zero, then the pEList expressions
+** are evaluated in order to get the data for this row.  If nColumn>0
+** then data is pulled from srcTab and pEList is used only to get the
+** datatypes for each column.
 */
 static int selectInnerLoop(
   Parse *pParse,          /* The parser context */
@@ -348,7 +389,9 @@ static int selectInnerLoop(
 ){
   Vdbe *v = pParse->pVdbe;
   int i;
+
   if( v==0 ) return 0;
+  assert( pEList!=0 );
 
   /* If there was a LIMIT clause on the SELECT statement, then do the check
   ** to see if this row should be output.
@@ -366,15 +409,15 @@ static int selectInnerLoop(
 
   /* Pull the requested columns.
   */
-  if( pEList ){
-    for(i=0; i<pEList->nExpr; i++){
-      sqliteExprCode(pParse, pEList->a[i].pExpr);
-    }
-    nColumn = pEList->nExpr;
-  }else{
+  if( nColumn>0 ){
     for(i=0; i<nColumn; i++){
       sqliteVdbeAddOp(v, OP_Column, srcTab, i);
     }
+  }else{
+    nColumn = pEList->nExpr;
+    for(i=0; i<pEList->nExpr; i++){
+      sqliteExprCode(pParse, pEList->a[i].pExpr);
+    }
   }
 
   /* If the DISTINCT keyword was present on the SELECT statement
@@ -386,6 +429,7 @@ static int selectInnerLoop(
     sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
 #endif
     sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1);
+    if( pParse->db->file_format>=3 ) sqliteAddKeyType(v, pEList);
     sqliteVdbeAddOp(v, OP_Distinct, distinct, sqliteVdbeCurrentAddr(v)+3);
     sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
     sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
@@ -1119,7 +1163,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
         iCont = sqliteVdbeMakeLabel(v);
         sqliteVdbeAddOp(v, OP_Rewind, unionTab, iBreak);
         iStart = sqliteVdbeCurrentAddr(v);
-        rc = selectInnerLoop(pParse, p, 0, unionTab, p->pEList->nExpr,
+        rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
                              p->pOrderBy, -1, eDest, iParm, 
                              iCont, iBreak);
         if( rc ) return 1;
@@ -1175,7 +1219,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
       sqliteVdbeAddOp(v, OP_Rewind, tab1, iBreak);
       iStart = sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
       sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
-      rc = selectInnerLoop(pParse, p, 0, tab1, p->pEList->nExpr,
+      rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
                              p->pOrderBy, -1, eDest, iParm, 
                              iCont, iBreak);
       if( rc ) return 1;
@@ -1547,7 +1591,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
   eList.a = &eListItem;
   eList.a[0].pExpr = pExpr;
   cont = sqliteVdbeMakeLabel(v);
-  selectInnerLoop(pParse, p, &eList, base, 1, 0, -1, eDest, iParm, cont, cont);
+  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont);
   sqliteVdbeResolveLabel(v, cont);
   sqliteVdbeAddOp(v, OP_Close, base, 0);
   return 1;
@@ -1914,6 +1958,7 @@ int sqliteSelect(
         sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
       }
       sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
+      if( pParse->db->file_format>=3 ) sqliteAddKeyType(v, pGroupBy);
       lbl1 = sqliteVdbeMakeLabel(v);
       sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1);
       for(i=0; i<pParse->nAgg; i++){
index 5f842e0c03dea8d4a8669ec34f054fda2492f7f6..7b7e1423210fde786dc75da61eff55f82e799a9c 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.133 2002/06/29 02:20:09 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.134 2002/07/05 21:42:37 drh Exp $
 */
 #include "sqlite.h"
 #include "hash.h"
@@ -871,6 +871,8 @@ void sqliteIdListDelete(IdList*);
 void sqliteSrcListDelete(SrcList*);
 void sqliteCreateIndex(Parse*, Token*, Token*, IdList*, int, Token*, Token*);
 void sqliteDropIndex(Parse*, Token*);
+void sqliteAddKeyType(Vdbe*, ExprList*);
+void sqliteAddIdxKeyType(Vdbe*, Index*);
 int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
 Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
                         int,int,int);
@@ -909,8 +911,8 @@ char *sqlite_mprintf(const char *, ...);
 int sqliteExprIsConstant(Expr*);
 int sqliteExprIsInteger(Expr*, int*);
 int sqliteIsRowid(const char*);
-void sqliteGenerateRowDelete(Vdbe*, Table*, int, int);
-void sqliteGenerateRowIndexDelete(Vdbe*, Table*, int, char*);
+void sqliteGenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
+void sqliteGenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
 void sqliteGenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
 void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int);
 void sqliteBeginWriteOperation(Parse*, int);
index 0a6f6db203d210a91bedbaf7c15ad52c3a886728..656b8edfd92dd32a29b60ab53edd4f2bd8d946b0 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.46 2002/06/29 02:20:09 drh Exp $
+** $Id: update.c,v 1.47 2002/07/05 21:42:37 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -319,7 +319,7 @@ void sqliteUpdate(
 
   /* Delete the old indices for the current record.
   */
-  sqliteGenerateRowIndexDelete(v, pTab, base, aIdxUsed);
+  sqliteGenerateRowIndexDelete(db, v, pTab, base, aIdxUsed);
 
   /* If changing the record number, delete the old record.
   */
index 007dd5aa1dddab81d3c9f9725d29c1033825f157..21736e9ea348e3ee1801a0d420a990e9ea107c76 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.46 2002/06/14 20:58:45 drh Exp $
+** $Id: util.c,v 1.47 2002/07/05 21:42:37 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -705,11 +705,15 @@ int sqliteCompare(const char *atext, const char *btext){
 ** returns negative, zero, or positive if the first argument is less
 ** than, equal to, or greater than the first.  (Result is a-b).
 **
-** Every string begins with either a "+" or "-" character.  If the
-** character is "-" then the return value is negated.  This is done
-** to implement a sort in descending order.
+** Each string begins with one of the characters "+", "-", "A", "D".
+** This character determines the sort order and collating sequence:
 **
-** For sorting purposes, pur numeric strings (strings for which the
+**     +      Sort numerically in ascending order
+**     -      Sort numerically in descending order
+**     A      Sort as strings in ascending order
+**     D      Sort as strings in descending order.
+**
+** For the "+" and "-" sorting, pure numeric strings (strings for which the
 ** isNum() function above returns TRUE) always compare less than strings
 ** that are not pure numerics.  Within non-numeric strings, substrings
 ** of digits compare in numerical order.  Finally, case is used only
@@ -721,6 +725,10 @@ int sqliteCompare(const char *atext, const char *btext){
 ** lexigraphical order.  This routine does the additional processing
 ** to sort substrings of digits into numerical order and to use case
 ** only as a tie-breaker.
+**
+** The special rules above apply only to numeric sorting, when the
+** prefix is "+" or "-".  If the prefix is "A" or "D" then plain old
+** "strcmp()" is used for the comparison.
 */
 int sqliteSortCompare(const char *a, const char *b){
   int len;
@@ -728,6 +736,7 @@ int sqliteSortCompare(const char *a, const char *b){
   int isNumA, isNumB;
 
   while( res==0 && *a && *b ){
+    assert( a[0]==b[0] );
     if( a[1]==0 ){
       res = -1;
       break;
@@ -735,41 +744,46 @@ int sqliteSortCompare(const char *a, const char *b){
       res = +1;
       break;
     }
-    isNumA = sqliteIsNumber(&a[1]);
-    isNumB = sqliteIsNumber(&b[1]);
-    if( isNumA ){
-      double rA, rB;
-      if( !isNumB ){
-        res = -1;
-        break;
-      }
-      rA = atof(&a[1]);
-      rB = atof(&b[1]);
-      if( rA<rB ){
-        res = -1;
-        break;
-      }
-      if( rA>rB ){
-        res = +1;
-        break;
-      }
-    }else if( isNumB ){
-      res = +1;
-      break;
+    if( a[0]=='A' || a[0]=='D' ){
+      res = strcmp(&a[1],&b[1]);
+      if( res ) break;
     }else{
-      res = sortStrCmp(&a[1],&b[1],0);
-      if( res==0 ){
-        res = sortStrCmp(&a[1],&b[1],1);
-      }
-      if( res!=0 ){
+      isNumA = sqliteIsNumber(&a[1]);
+      isNumB = sqliteIsNumber(&b[1]);
+      if( isNumA ){
+        double rA, rB;
+        if( !isNumB ){
+          res = -1;
+          break;
+        }
+        rA = atof(&a[1]);
+        rB = atof(&b[1]);
+        if( rA<rB ){
+          res = -1;
+          break;
+        }
+        if( rA>rB ){
+          res = +1;
+          break;
+        }
+      }else if( isNumB ){
+        res = +1;
         break;
+      }else{
+        res = sortStrCmp(&a[1],&b[1],0);
+        if( res==0 ){
+          res = sortStrCmp(&a[1],&b[1],1);
+        }
+        if( res!=0 ){
+          break;
+        }
       }
     }
     len = strlen(&a[1]) + 2;
     a += len;
     b += len;
   }
-  if( *a=='-' ) res = -res;
+  if( *a=='-' || *a=='D' ) res = -res;
   return res;
 }
 
index 83b36d90ce92ae0f3af52ae2997a974887d4cc63..3700a4baa6a73e603d79bc7853ea73d40d78035f 100644 (file)
@@ -30,7 +30,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.163 2002/06/29 02:20:09 drh Exp $
+** $Id: vdbe.c,v 1.164 2002/07/05 21:42:37 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2632,7 +2632,7 @@ case OP_MakeRecord: {
 ** P3 is a string that is P1 characters long.  Each character is either
 ** an 'n' or a 't' to indicates if the argument should be numeric or
 ** text.  The first character corresponds to the lowest element on the
-** stack.
+** stack.  If P3 is NULL then all arguments are assumed to be numeric.
 **
 ** See also: MakeIdxKey, SortMakeKey
 */
@@ -2661,7 +2661,7 @@ case OP_MakeRecord: {
 ** P3 is a string that is P1 characters long.  Each character is either
 ** an 'n' or a 't' to indicates if the argument should be numeric or
 ** text.  The first character corresponds to the lowest element on the
-** stack.
+** stack.  If P3 is null then all arguments are assumed to be numeric.
 **
 ** See also:  MakeKey, SortMakeKey
 */
index 6c8c00bb7876bd078ead075b95ed98351ffcfd84..c4b432070fb76324465dbdac34862a2821fc74de 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the CREATE TABLE statement.
 #
-# $Id: table.test,v 1.17 2002/06/02 18:19:00 drh Exp $
+# $Id: table.test,v 1.18 2002/07/05 21:42:38 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -434,6 +434,31 @@ do_test table-10.8 {
   }
 } {0 {}}
 
-
+# Test for the "typeof" function.
+#
+do_test table-11.1 {
+  execsql {
+    CREATE TABLE t7(
+       a integer primary key,
+       b number(5,10),
+       c character varying (8),
+       d VARCHAR(9),
+       e clob,
+       f BLOB,
+       g Text,
+       h
+    );
+    INSERT INTO t7(a) VALUES(1);
+    SELECT typeof(a), typeof(b), typeof(c), typeof(d),
+           typeof(e), typeof(f), typeof(g), typeof(h)
+    FROM t7 LIMIT 1;
+  }
+} {numeric numeric text text text text text numeric}
+do_test table-11.2 {
+  execsql {
+    SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
+    FROM t7 LIMIT 1;
+  }
+} {numeric text numeric text}
 
 finish_test