/ Check-in [6661bb5f]
Login

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

Overview
Comment:Factor common code for generating index keys into a procedure. Other speed improvements and bug fixes. (CVS 1487)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6661bb5f9c1692f94b8b7d900b6be07f027e6324
User & Date: drh 2004-05-28 16:00:22
Context
2004-05-29
02:37
Allow CREATE and DROP TRIGGER on attached databases. (CVS 1488) check-in: 4060a37d user: danielk1977 tags: trunk
2004-05-28
16:00
Factor common code for generating index keys into a procedure. Other speed improvements and bug fixes. (CVS 1487) check-in: 6661bb5f user: drh tags: trunk
13:13
Fix a bug in the sqlite3_column_decltype() API. (CVS 1486) check-in: c8a40218 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **     PRAGMA
    25     25   **
    26         -** $Id: build.c,v 1.196 2004/05/28 12:33:31 danielk1977 Exp $
           26  +** $Id: build.c,v 1.197 2004/05/28 16:00:22 drh Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   #include <ctype.h>
    30     30   
    31     31   /*
    32     32   ** This routine is called when a new SQL statement is beginning to
    33     33   ** be parsed.  Check to see if the schema for the database needs
................................................................................
  1871   1871             OP_Integer,   iDb,    0,
  1872   1872         0);
  1873   1873         sqlite3VdbeOp3(v, OP_OpenWrite, 1, 0,
  1874   1874                        (char*)&pIndex->keyInfo, P3_KEYINFO);
  1875   1875       }
  1876   1876       sqlite3VdbeAddOp(v, OP_String, 0, 0);
  1877   1877       if( pStart && pEnd ){
  1878         -      sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", n);
         1878  +      sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC);
  1879   1879         sqlite3VdbeAddOp(v, OP_String, 0, 0);
  1880   1880         n = Addr(pEnd->z) - Addr(pName->z) + 1;
  1881   1881         sqlite3VdbeChangeP3(v, -1, pName->z, n);
  1882   1882         sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
  1883   1883       }
  1884   1884       sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
  1885   1885       sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
................................................................................
  1886   1886       if( pTblName ){
  1887   1887         sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  1888   1888         sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum);
  1889   1889         /* VdbeComment((v, "%s", pTab->zName)); */
  1890   1890         sqlite3VdbeAddOp(v, OP_SetNumColumns, 2, pTab->nCol);
  1891   1891         lbl2 = sqlite3VdbeMakeLabel(v);
  1892   1892         sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2);
  1893         -      lbl1 = sqlite3VdbeAddOp(v, OP_Recno, 2, 0);
  1894         -      for(i=0; i<pIndex->nColumn; i++){
  1895         -        int iCol = pIndex->aiColumn[i];
  1896         -        if( pTab->iPKey==iCol ){
  1897         -          sqlite3VdbeAddOp(v, OP_Dup, i, 0);
  1898         -        }else{
  1899         -          sqlite3VdbeAddOp(v, OP_Column, 2, iCol);
  1900         -        }
  1901         -      }
  1902         -      sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
  1903         -      sqlite3IndexAffinityStr(v, pIndex);
         1893  +      lbl1 = sqlite3VdbeCurrentAddr(v);
         1894  +      sqlite3GenerateIndexKey(v, pIndex, 2);
  1904   1895         sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None,
  1905   1896                         "indexed columns are not unique", P3_STATIC);
  1906   1897         sqlite3VdbeAddOp(v, OP_Next, 2, lbl1);
  1907   1898         sqlite3VdbeResolveLabel(v, lbl2);
  1908   1899         sqlite3VdbeAddOp(v, OP_Close, 2, 0);
  1909   1900         sqlite3VdbeAddOp(v, OP_Close, 1, 0);
  1910   1901       }

Changes to src/delete.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 are called by the parser
    13     13   ** to handle DELETE FROM statements.
    14     14   **
    15         -** $Id: delete.c,v 1.70 2004/05/26 10:11:05 danielk1977 Exp $
           15  +** $Id: delete.c,v 1.71 2004/05/28 16:00:22 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Look up every table that is named in pSrc.  If any table is not found,
    21     21   ** add an error message to pParse->zErrMsg and return NULL.  If all tables
    22     22   ** are found, return a pointer to the last table.
................................................................................
   375    375   ){
   376    376     int i;
   377    377     Index *pIdx;
   378    378   
   379    379     for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
   380    380       int j;
   381    381       if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
   382         -    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
   383         -    for(j=0; j<pIdx->nColumn; j++){
   384         -      int idx = pIdx->aiColumn[j];
   385         -      if( idx==pTab->iPKey ){
   386         -        sqlite3VdbeAddOp(v, OP_Dup, j, 0);
   387         -      }else{
   388         -        sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
   389         -      }
   390         -    }
   391         -    sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
   392         -    sqlite3IndexAffinityStr(v, pIdx);
          382  +    sqlite3GenerateIndexKey(v, pIdx, iCur);
   393    383       sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
   394    384     }
   395    385   }
          386  +
          387  +/*
          388  +** Generate code that will assemble an index key and put it on the top
          389  +** of the tack.  The key with be for index pIdx which is an index on pTab.
          390  +** iCur is the index of a cursor open on the pTab table and pointing to
          391  +** the entry that needs indexing.
          392  +*/
          393  +void sqlite3GenerateIndexKey(
          394  +  Vdbe *v,           /* Generate code into this VDBE */
          395  +  Index *pIdx,       /* The index for which to generate a key */
          396  +  int iCur           /* Cursor number for the pIdx->pTable table */
          397  +){
          398  +  int j;
          399  +  Table *pTab = pIdx->pTable;
          400  +
          401  +  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
          402  +  for(j=0; j<pIdx->nColumn; j++){
          403  +    int idx = pIdx->aiColumn[j];
          404  +    if( idx==pTab->iPKey ){
          405  +      sqlite3VdbeAddOp(v, OP_Dup, j, 0);
          406  +    }else{
          407  +      sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
          408  +    }
          409  +  }
          410  +  sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
          411  +  sqlite3IndexAffinityStr(v, pIdx);
          412  +}

Changes to src/pragma.c.

     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   ** This file contains code used to implement the PRAGMA command.
    13     13   **
    14         -** $Id: pragma.c,v 1.32 2004/05/26 10:11:06 danielk1977 Exp $
           14  +** $Id: pragma.c,v 1.33 2004/05/28 16:00:22 drh Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include <ctype.h>
    18     18   
    19     19   /*
    20     20   ** Interpret the given string as a boolean value.
    21     21   */
................................................................................
   638    638               { OP_String,      0,  0,  "rowid "},
   639    639               { OP_Recno,       1,  0,  0},
   640    640               { OP_String,      0,  0,  " missing from index "},
   641    641               { OP_String,      0,  0,  0},    /* 4 */
   642    642               { OP_Concat,      4,  0,  0},
   643    643               { OP_Callback,    1,  0,  0},
   644    644             };
   645         -          sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
   646         -          for(k=0; k<pIdx->nColumn; k++){
   647         -            int idx = pIdx->aiColumn[k];
   648         -            if( idx==pTab->iPKey ){
   649         -              sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
   650         -            }else{
   651         -              sqlite3VdbeAddOp(v, OP_Column, 1, idx);
   652         -            }
   653         -          }
   654         -          sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
   655         -          sqlite3IndexAffinityStr(v, pIdx);
          645  +          sqlite3GenerateIndexKey(v, pIdx, 1);
   656    646             jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
   657    647             addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
   658    648             sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
   659    649             sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
   660    650           }
   661    651           sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
   662    652           sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));

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.259 2004/05/28 12:33:31 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.260 2004/05/28 16:00:22 drh Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "parse.h"
    20     20   #include <stdio.h>
    21     21   #include <stdlib.h>
................................................................................
  1263   1263   void sqlite3CommitTransaction(Parse*);
  1264   1264   void sqlite3RollbackTransaction(Parse*);
  1265   1265   int sqlite3ExprIsConstant(Expr*);
  1266   1266   int sqlite3ExprIsInteger(Expr*, int*);
  1267   1267   int sqlite3IsRowid(const char*);
  1268   1268   void sqlite3GenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
  1269   1269   void sqlite3GenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
         1270  +void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
  1270   1271   void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
  1271   1272   void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
  1272   1273   int sqlite3OpenTableAndIndices(Parse*, Table*, int);
  1273   1274   void sqlite3BeginWriteOperation(Parse*, int, int);
  1274   1275   void sqlite3EndWriteOperation(Parse*);
  1275   1276   Expr *sqlite3ExprDup(Expr*);
  1276   1277   void sqlite3TokenCopy(Token*, Token*);

Changes to src/utf.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 routines used to translate between UTF-8, 
    13     13   ** UTF-16, UTF-16BE, and UTF-16LE.
    14     14   **
    15         -** $Id: utf.c,v 1.12 2004/05/27 09:28:43 danielk1977 Exp $
           15  +** $Id: utf.c,v 1.13 2004/05/28 16:00:22 drh Exp $
    16     16   **
    17     17   ** Notes on UTF-8:
    18     18   **
    19     19   **   Byte-0    Byte-1    Byte-2    Byte-3    Value
    20     20   **  0xxxxxxx                                 00000000 00000000 0xxxxxxx
    21     21   **  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
    22     22   **  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
    23     23   **  11110uuu  10uuzzzz  10yyyyyy  10xxxxxx   000uuuuu zzzzyyyy yyxxxxxx
    24     24   **
    25     25   **
    26     26   ** Notes on UTF-16:  (with wwww+1==uuuuu)
    27     27   **
    28         -**      Word-0            Word-1             Value
    29         -**  110110wwwwxxxxxx 110111yyyyyyyyyy        000uuuuu xxxxxxyy yyyyyyyy
    30         -**  xxxxxxxxyyyyyyyy                         00000000 xxxxxxxx yyyyyyyy
           28  +**      Word-0               Word-1          Value
           29  +**  110110ww wwzzzzyy   110111yy yyxxxxxx    000uuuuu zzzzyyyy yyxxxxxx
           30  +**  zzzzyyyy yyxxxxxx                        00000000 zzzzyyyy yyxxxxxx
    31     31   **
    32     32   **
    33     33   ** BOM or Byte Order Mark:
    34     34   **     0xff 0xfe   little-endian utf-16 follows
    35     35   **     0xfe 0xff   big-endian utf-16 follows
    36     36   **
    37     37   **

Changes to src/util.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Utility functions used throughout sqlite.
    13     13   **
    14     14   ** This file contains functions for allocating memory, comparing
    15     15   ** strings, and stuff like that.
    16     16   **
    17         -** $Id: util.c,v 1.93 2004/05/28 11:37:28 danielk1977 Exp $
           17  +** $Id: util.c,v 1.94 2004/05/28 16:00:22 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <stdarg.h>
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** If malloc() ever fails, this global variable gets set to 1.
................................................................................
   389    389     sqliteFree(*pz);
   390    390     *pz = zResult = sqliteMallocRaw( nByte + 1 );
   391    391     if( zResult==0 ) return;
   392    392     va_start(ap, pz);
   393    393     while( (z = va_arg(ap, const char*))!=0 ){
   394    394       n = va_arg(ap, int);
   395    395       if( n<=0 ) n = strlen(z);
   396         -    strncpy(zResult, z, n);
          396  +    memcpy(zResult, z, n);
   397    397       zResult += n;
   398    398     }
   399    399     *zResult = 0;
   400    400   #ifdef MEMORY_DEBUG
   401    401   #if MEMORY_DEBUG>1
   402    402     fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
   403    403   #endif
................................................................................
  1326   1326         return 0;
  1327   1327       }
  1328   1328   
  1329   1329       zBlob[i/2] = c;
  1330   1330     }
  1331   1331     return zBlob;
  1332   1332   }
  1333         -
  1334         -
  1335         -
  1336         -

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.344 2004/05/28 11:37:28 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.345 2004/05/28 16:00:22 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  1865   1865     /* Read and parse the table header.  Store the results of the parse
  1866   1866     ** into the record header cache fields of the cursor.
  1867   1867     */
  1868   1868     if( pC && pC->cacheValid ){
  1869   1869       aType = pC->aType;
  1870   1870       aOffset = pC->aOffset;
  1871   1871     }else{
  1872         -    aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
         1872  +    if( pC && pC->aType ){
         1873  +      aType = pC->aType;
         1874  +    }else{
         1875  +      aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
         1876  +    }
  1873   1877       aOffset = &aType[nField];
  1874   1878       if( aType==0 ){
  1875   1879         goto no_mem;
  1876   1880       }
  1877   1881   
  1878   1882       /* Figure out how many bytes are in the header */
  1879   1883       if( zRec ){
................................................................................
  1940   1944       zData = &zRec[aOffset[p2]];
  1941   1945     }else{
  1942   1946       len = sqlite3VdbeSerialTypeLen(aType[p2]);
  1943   1947       sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
  1944   1948       zData = sMem.z;
  1945   1949     }
  1946   1950     sqlite3VdbeSerialGet(zData, aType[p2], pTos);
         1951  +  sqlite3VdbeMemMakeWriteable(pTos);
  1947   1952     pTos->enc = db->enc;
  1948   1953     if( rc!=SQLITE_OK ){
  1949   1954       goto abort_due_to_error;
  1950   1955     }
  1951   1956     Release(&sMem);
  1952   1957   
  1953   1958     /* Release the aType[] memory if we are not dealing with cursor */
................................................................................
  2045   2050     Mem *pRowid;
  2046   2051     int nData = 0;     /* Number of bytes of data space */
  2047   2052     int nHdr = 0;      /* Number of bytes of header space */
  2048   2053     int nByte = 0;     /* Space required for this record */
  2049   2054     int addRowid;      /* True to append a rowid column at the end */
  2050   2055     u32 serial_type;   /* Type field */
  2051   2056     int containsNull;  /* True if any of the data fields are NULL */
         2057  +  char zTemp[NBFS];  /* Space to hold small records */
  2052   2058   
  2053   2059     Mem *pData0 = &pTos[1-nField];
  2054   2060     assert( pData0>=p->aStack );
  2055   2061     zAffinity = pOp->p3;
  2056   2062     addRowid = pOp->opcode==OP_MakeIdxKey;
  2057   2063     containsNull = 0;
  2058   2064   
................................................................................
  2090   2096   
  2091   2097     if( nByte>MAX_BYTES_PER_ROW ){
  2092   2098       rc = SQLITE_TOOBIG;
  2093   2099       goto abort_due_to_error;
  2094   2100     }
  2095   2101   
  2096   2102     /* Allocate space for the new record. */
  2097         -  zNewRecord = sqliteMallocRaw(nByte);
  2098         -  if( !zNewRecord ){
  2099         -    goto no_mem;
         2103  +  if( nByte>sizeof(zTemp) ){
         2104  +    zNewRecord = sqliteMallocRaw(nByte);
         2105  +    if( !zNewRecord ){
         2106  +      goto no_mem;
         2107  +    }
         2108  +  }else{
         2109  +    zNewRecord = zTemp;
  2100   2110     }
  2101   2111   
  2102   2112     /* Write the record */
  2103   2113     zCsr = zNewRecord;
  2104   2114     zCsr += sqlite3PutVarint(zCsr, nHdr);
  2105   2115     for(pRec=pData0; pRec<=pTos; pRec++){
  2106   2116       serial_type = sqlite3VdbeSerialType(pRec);
................................................................................
  2127   2137   
  2128   2138     /* Pop nField entries from the stack and push the new entry on */
  2129   2139     if( addRowid || pOp->p2==0 ){
  2130   2140       popStack(&pTos, nField+addRowid);
  2131   2141     }
  2132   2142     pTos++;
  2133   2143     pTos->n = nByte;
  2134         -  pTos->z = zNewRecord;
  2135         -  pTos->flags = MEM_Blob | MEM_Dyn;
         2144  +  if( nByte<=sizeof(zTemp) ){
         2145  +    assert( zNewRecord==zTemp );
         2146  +    pTos->z = pTos->zShort;
         2147  +    memcpy(pTos->zShort, zTemp, nByte);
         2148  +    pTos->flags = MEM_Blob | MEM_Short;
         2149  +  }else{
         2150  +    assert( zNewRecord!=zTemp );
         2151  +    pTos->z = zNewRecord;
         2152  +    pTos->flags = MEM_Blob | MEM_Dyn;
         2153  +  }
  2136   2154   
  2137   2155     /* If P2 is non-zero, and if the key contains a NULL value, and if this
  2138   2156     ** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2.
  2139   2157     */
  2140   2158     if( pOp->p2 && containsNull && addRowid ){
  2141   2159       pc = pOp->p2 - 1;
  2142   2160     }

Changes to src/vdbeaux.c.

  1215   1215   }
  1216   1216   
  1217   1217   /*
  1218   1218   ** Return the length of the data corresponding to the supplied serial-type.
  1219   1219   */
  1220   1220   int sqlite3VdbeSerialTypeLen(u32 serial_type){
  1221   1221     assert( serial_type!=0 );
         1222  +  if( serial_type>6 ){
         1223  +    return (serial_type-12)/2;
         1224  +  }else{
         1225  +    static u8 aSize[] = { 0, 1, 2, 4, 8, 8, 0, };
         1226  +    return aSize[serial_type];
         1227  +  }
         1228  +#if 0
  1222   1229     switch(serial_type){
  1223   1230       case 6: return 0;                  /* NULL */
  1224   1231       case 1: return 1;                  /* 1 byte integer */
  1225   1232       case 2: return 2;                  /* 2 byte integer */
  1226   1233       case 3: return 4;                  /* 4 byte integer */
  1227   1234       case 4: return 8;                  /* 8 byte integer */
  1228   1235       case 5: return 8;                  /* 8 byte float */
  1229   1236     }
  1230   1237     assert( serial_type>=12 );
  1231   1238     return ((serial_type-12)>>1);        /* text or blob */
         1239  +#endif
  1232   1240   }
  1233   1241   
  1234   1242   /*
  1235   1243   ** Write the serialized data blob for the value stored in pMem into 
  1236   1244   ** buf. It is assumed that the caller has allocated sufficient space.
  1237   1245   ** Return the number of bytes written.
  1238   1246   */ 
................................................................................
  1325   1333     pMem->z = (char *)buf;
  1326   1334     pMem->n = len;
  1327   1335     if( serial_type&0x01 ){
  1328   1336       pMem->flags = MEM_Str | MEM_Ephem;
  1329   1337     }else{
  1330   1338       pMem->flags = MEM_Blob | MEM_Ephem;
  1331   1339     }
  1332         -  sqlite3VdbeMemMakeWriteable(pMem);
  1333   1340     return len;
  1334   1341   }
  1335   1342   
  1336   1343   /*
  1337   1344   ** The following is the comparison function for (non-integer)
  1338   1345   ** keys in the btrees.  This function returns negative, zero, or
  1339   1346   ** positive if the first key is less than, equal to, or greater than