/ 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 Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
....
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
....
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.196 2004/05/28 12:33:31 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
          OP_Integer,   iDb,    0,
      0);
      sqlite3VdbeOp3(v, OP_OpenWrite, 1, 0,
                     (char*)&pIndex->keyInfo, P3_KEYINFO);
    }
    sqlite3VdbeAddOp(v, OP_String, 0, 0);
    if( pStart && pEnd ){
      sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", n);
      sqlite3VdbeAddOp(v, OP_String, 0, 0);
      n = Addr(pEnd->z) - Addr(pName->z) + 1;
      sqlite3VdbeChangeP3(v, -1, pName->z, n);
      sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
    }
    sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
................................................................................
    if( pTblName ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum);
      /* VdbeComment((v, "%s", pTab->zName)); */
      sqlite3VdbeAddOp(v, OP_SetNumColumns, 2, pTab->nCol);
      lbl2 = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2);
      lbl1 = sqlite3VdbeAddOp(v, OP_Recno, 2, 0);
      for(i=0; i<pIndex->nColumn; i++){
        int iCol = pIndex->aiColumn[i];
        if( pTab->iPKey==iCol ){
          sqlite3VdbeAddOp(v, OP_Dup, i, 0);
        }else{
          sqlite3VdbeAddOp(v, OP_Column, 2, iCol);
        }
      }
      sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
      sqlite3IndexAffinityStr(v, pIndex);
      sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None,
                      "indexed columns are not unique", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Next, 2, lbl1);
      sqlite3VdbeResolveLabel(v, lbl2);
      sqlite3VdbeAddOp(v, OP_Close, 2, 0);
      sqlite3VdbeAddOp(v, OP_Close, 1, 0);
    }







|







 







|







 







|
|
<
<
<
<
<
<
<
<
<







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
....
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
....
1886
1887
1888
1889
1890
1891
1892
1893
1894









1895
1896
1897
1898
1899
1900
1901
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.197 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
          OP_Integer,   iDb,    0,
      0);
      sqlite3VdbeOp3(v, OP_OpenWrite, 1, 0,
                     (char*)&pIndex->keyInfo, P3_KEYINFO);
    }
    sqlite3VdbeAddOp(v, OP_String, 0, 0);
    if( pStart && pEnd ){
      sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String, 0, 0);
      n = Addr(pEnd->z) - Addr(pName->z) + 1;
      sqlite3VdbeChangeP3(v, -1, pName->z, n);
      sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
    }
    sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
................................................................................
    if( pTblName ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum);
      /* VdbeComment((v, "%s", pTab->zName)); */
      sqlite3VdbeAddOp(v, OP_SetNumColumns, 2, pTab->nCol);
      lbl2 = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2);
      lbl1 = sqlite3VdbeCurrentAddr(v);
      sqlite3GenerateIndexKey(v, pIndex, 2);









      sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None,
                      "indexed columns are not unique", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Next, 2, lbl1);
      sqlite3VdbeResolveLabel(v, lbl2);
      sqlite3VdbeAddOp(v, OP_Close, 2, 0);
      sqlite3VdbeAddOp(v, OP_Close, 1, 0);
    }

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
375
376
377
378
379
380
381



















382
383
384
385
386
387
388
389
390
391
392
393
394
395
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.70 2004/05/26 10:11:05 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
){
  int i;
  Index *pIdx;

  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    int j;
    if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;



















    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    for(j=0; j<pIdx->nColumn; j++){
      int idx = pIdx->aiColumn[j];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_Dup, j, 0);
      }else{
        sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
      }
    }
    sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
    sqlite3IndexAffinityStr(v, pIdx);
    sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
  }
}







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
<
|
<
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411

412

**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.71 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
){
  int i;
  Index *pIdx;

  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    int j;
    if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
    sqlite3GenerateIndexKey(v, pIdx, iCur);
    sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
  }
}

/*
** Generate code that will assemble an index key and put it on the top
** of the tack.  The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
** the entry that needs indexing.
*/
void sqlite3GenerateIndexKey(
  Vdbe *v,           /* Generate code into this VDBE */
  Index *pIdx,       /* The index for which to generate a key */
  int iCur           /* Cursor number for the pIdx->pTable table */
){
  int j;
  Table *pTab = pIdx->pTable;

  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
  for(j=0; j<pIdx->nColumn; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite3VdbeAddOp(v, OP_Dup, j, 0);
    }else{
      sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
    }
  }
  sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
  sqlite3IndexAffinityStr(v, pIdx);

}

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.32 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Interpret the given string as a boolean value.
*/
................................................................................
            { OP_String,      0,  0,  "rowid "},
            { OP_Recno,       1,  0,  0},
            { OP_String,      0,  0,  " missing from index "},
            { OP_String,      0,  0,  0},    /* 4 */
            { OP_Concat,      4,  0,  0},
            { OP_Callback,    1,  0,  0},
          };
          sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
          for(k=0; k<pIdx->nColumn; k++){
            int idx = pIdx->aiColumn[k];
            if( idx==pTab->iPKey ){
              sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
            }else{
              sqlite3VdbeAddOp(v, OP_Column, 1, idx);
            }
          }
          sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
          sqlite3IndexAffinityStr(v, pIdx);
          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
          sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
        }
        sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
        sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));







|







 







|
<
<
<
<
<
<
<
<
<
<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
638
639
640
641
642
643
644
645










646
647
648
649
650
651
652
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.33 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Interpret the given string as a boolean value.
*/
................................................................................
            { OP_String,      0,  0,  "rowid "},
            { OP_Recno,       1,  0,  0},
            { OP_String,      0,  0,  " missing from index "},
            { OP_String,      0,  0,  0},    /* 4 */
            { OP_Concat,      4,  0,  0},
            { OP_Callback,    1,  0,  0},
          };
          sqlite3GenerateIndexKey(v, pIdx, 1);










          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
          sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
        }
        sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
        sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.259 2004/05/28 12:33:31 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
void sqlite3GenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);

void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
int sqlite3OpenTableAndIndices(Parse*, Table*, int);
void sqlite3BeginWriteOperation(Parse*, int, int);
void sqlite3EndWriteOperation(Parse*);
Expr *sqlite3ExprDup(Expr*);
void sqlite3TokenCopy(Token*, Token*);







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.260 2004/05/28 16:00:22 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
void sqlite3GenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
int sqlite3OpenTableAndIndices(Parse*, Table*, int);
void sqlite3BeginWriteOperation(Parse*, int, int);
void sqlite3EndWriteOperation(Parse*);
Expr *sqlite3ExprDup(Expr*);
void sqlite3TokenCopy(Token*, Token*);

Changes to src/utf.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.12 2004/05/27 09:28:43 danielk1977 Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
**  11110uuu  10uuzzzz  10yyyyyy  10xxxxxx   000uuuuu zzzzyyyy yyxxxxxx
**
**
** Notes on UTF-16:  (with wwww+1==uuuuu)
**
**      Word-0            Word-1             Value
**  110110wwwwxxxxxx 110111yyyyyyyyyy        000uuuuu xxxxxxyy yyyyyyyy
**  xxxxxxxxyyyyyyyy                         00000000 xxxxxxxx yyyyyyyy
**
**
** BOM or Byte Order Mark:
**     0xff 0xfe   little-endian utf-16 follows
**     0xfe 0xff   big-endian utf-16 follows
**
**







|












|
|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.13 2004/05/28 16:00:22 drh Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
**  11110uuu  10uuzzzz  10yyyyyy  10xxxxxx   000uuuuu zzzzyyyy yyxxxxxx
**
**
** Notes on UTF-16:  (with wwww+1==uuuuu)
**
**      Word-0               Word-1          Value
**  110110ww wwzzzzyy   110111yy yyxxxxxx    000uuuuu zzzzyyyy yyxxxxxx
**  zzzzyyyy yyxxxxxx                        00000000 zzzzyyyy yyxxxxxx
**
**
** BOM or Byte Order Mark:
**     0xff 0xfe   little-endian utf-16 follows
**     0xfe 0xff   big-endian utf-16 follows
**
**

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
....
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.93 2004/05/28 11:37:28 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
  sqliteFree(*pz);
  *pz = zResult = sqliteMallocRaw( nByte + 1 );
  if( zResult==0 ) return;
  va_start(ap, pz);
  while( (z = va_arg(ap, const char*))!=0 ){
    n = va_arg(ap, int);
    if( n<=0 ) n = strlen(z);
    strncpy(zResult, z, n);
    zResult += n;
  }
  *zResult = 0;
#ifdef MEMORY_DEBUG
#if MEMORY_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
................................................................................
      return 0;
    }

    zBlob[i/2] = c;
  }
  return zBlob;
}











|







 







|







 







<
<
<
<
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
....
1326
1327
1328
1329
1330
1331
1332




**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.94 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
  sqliteFree(*pz);
  *pz = zResult = sqliteMallocRaw( nByte + 1 );
  if( zResult==0 ) return;
  va_start(ap, pz);
  while( (z = va_arg(ap, const char*))!=0 ){
    n = va_arg(ap, int);
    if( n<=0 ) n = strlen(z);
    memcpy(zResult, z, n);
    zResult += n;
  }
  *zResult = 0;
#ifdef MEMORY_DEBUG
#if MEMORY_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
................................................................................
      return 0;
    }

    zBlob[i/2] = c;
  }
  return zBlob;
}




Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1865
1866
1867
1868
1869
1870
1871



1872

1873
1874
1875
1876
1877
1878
1879
....
1940
1941
1942
1943
1944
1945
1946

1947
1948
1949
1950
1951
1952
1953
....
2045
2046
2047
2048
2049
2050
2051

2052
2053
2054
2055
2056
2057
2058
....
2090
2091
2092
2093
2094
2095
2096

2097
2098
2099



2100
2101
2102
2103
2104
2105
2106
....
2127
2128
2129
2130
2131
2132
2133







2134
2135

2136
2137
2138
2139
2140
2141
2142
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.344 2004/05/28 11:37:28 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( pC && pC->cacheValid ){
    aType = pC->aType;
    aOffset = pC->aOffset;
  }else{



    aType = sqliteMallocRaw( 2*nField*sizeof(aType) );

    aOffset = &aType[nField];
    if( aType==0 ){
      goto no_mem;
    }

    /* Figure out how many bytes are in the header */
    if( zRec ){
................................................................................
    zData = &zRec[aOffset[p2]];
  }else{
    len = sqlite3VdbeSerialTypeLen(aType[p2]);
    sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
    zData = sMem.z;
  }
  sqlite3VdbeSerialGet(zData, aType[p2], pTos);

  pTos->enc = db->enc;
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  Release(&sMem);

  /* Release the aType[] memory if we are not dealing with cursor */
................................................................................
  Mem *pRowid;
  int nData = 0;     /* Number of bytes of data space */
  int nHdr = 0;      /* Number of bytes of header space */
  int nByte = 0;     /* Space required for this record */
  int addRowid;      /* True to append a rowid column at the end */
  u32 serial_type;   /* Type field */
  int containsNull;  /* True if any of the data fields are NULL */


  Mem *pData0 = &pTos[1-nField];
  assert( pData0>=p->aStack );
  zAffinity = pOp->p3;
  addRowid = pOp->opcode==OP_MakeIdxKey;
  containsNull = 0;

................................................................................

  if( nByte>MAX_BYTES_PER_ROW ){
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }

  /* Allocate space for the new record. */

  zNewRecord = sqliteMallocRaw(nByte);
  if( !zNewRecord ){
    goto no_mem;



  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nHdr);
  for(pRec=pData0; pRec<=pTos; pRec++){
    serial_type = sqlite3VdbeSerialType(pRec);
................................................................................

  /* Pop nField entries from the stack and push the new entry on */
  if( addRowid || pOp->p2==0 ){
    popStack(&pTos, nField+addRowid);
  }
  pTos++;
  pTos->n = nByte;







  pTos->z = zNewRecord;
  pTos->flags = MEM_Blob | MEM_Dyn;


  /* If P2 is non-zero, and if the key contains a NULL value, and if this
  ** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2.
  */
  if( pOp->p2 && containsNull && addRowid ){
    pc = pOp->p2 - 1;
  }







|







 







>
>
>
|
>







 







>







 







>







 







>
|
|
|
>
>
>







 







>
>
>
>
>
>
>
|
|
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
....
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
....
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
....
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
....
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.345 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( pC && pC->cacheValid ){
    aType = pC->aType;
    aOffset = pC->aOffset;
  }else{
    if( pC && pC->aType ){
      aType = pC->aType;
    }else{
      aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
    }
    aOffset = &aType[nField];
    if( aType==0 ){
      goto no_mem;
    }

    /* Figure out how many bytes are in the header */
    if( zRec ){
................................................................................
    zData = &zRec[aOffset[p2]];
  }else{
    len = sqlite3VdbeSerialTypeLen(aType[p2]);
    sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
    zData = sMem.z;
  }
  sqlite3VdbeSerialGet(zData, aType[p2], pTos);
  sqlite3VdbeMemMakeWriteable(pTos);
  pTos->enc = db->enc;
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  Release(&sMem);

  /* Release the aType[] memory if we are not dealing with cursor */
................................................................................
  Mem *pRowid;
  int nData = 0;     /* Number of bytes of data space */
  int nHdr = 0;      /* Number of bytes of header space */
  int nByte = 0;     /* Space required for this record */
  int addRowid;      /* True to append a rowid column at the end */
  u32 serial_type;   /* Type field */
  int containsNull;  /* True if any of the data fields are NULL */
  char zTemp[NBFS];  /* Space to hold small records */

  Mem *pData0 = &pTos[1-nField];
  assert( pData0>=p->aStack );
  zAffinity = pOp->p3;
  addRowid = pOp->opcode==OP_MakeIdxKey;
  containsNull = 0;

................................................................................

  if( nByte>MAX_BYTES_PER_ROW ){
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }

  /* Allocate space for the new record. */
  if( nByte>sizeof(zTemp) ){
    zNewRecord = sqliteMallocRaw(nByte);
    if( !zNewRecord ){
      goto no_mem;
    }
  }else{
    zNewRecord = zTemp;
  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nHdr);
  for(pRec=pData0; pRec<=pTos; pRec++){
    serial_type = sqlite3VdbeSerialType(pRec);
................................................................................

  /* Pop nField entries from the stack and push the new entry on */
  if( addRowid || pOp->p2==0 ){
    popStack(&pTos, nField+addRowid);
  }
  pTos++;
  pTos->n = nByte;
  if( nByte<=sizeof(zTemp) ){
    assert( zNewRecord==zTemp );
    pTos->z = pTos->zShort;
    memcpy(pTos->zShort, zTemp, nByte);
    pTos->flags = MEM_Blob | MEM_Short;
  }else{
    assert( zNewRecord!=zTemp );
    pTos->z = zNewRecord;
    pTos->flags = MEM_Blob | MEM_Dyn;
  }

  /* If P2 is non-zero, and if the key contains a NULL value, and if this
  ** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2.
  */
  if( pOp->p2 && containsNull && addRowid ){
    pc = pOp->p2 - 1;
  }

Changes to src/vdbeaux.c.

1215
1216
1217
1218
1219
1220
1221







1222
1223
1224
1225
1226
1227
1228
1229
1230
1231

1232
1233
1234
1235
1236
1237
1238
....
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
}

/*
** Return the length of the data corresponding to the supplied serial-type.
*/
int sqlite3VdbeSerialTypeLen(u32 serial_type){
  assert( serial_type!=0 );







  switch(serial_type){
    case 6: return 0;                  /* NULL */
    case 1: return 1;                  /* 1 byte integer */
    case 2: return 2;                  /* 2 byte integer */
    case 3: return 4;                  /* 4 byte integer */
    case 4: return 8;                  /* 8 byte integer */
    case 5: return 8;                  /* 8 byte float */
  }
  assert( serial_type>=12 );
  return ((serial_type-12)>>1);        /* text or blob */

}

/*
** Write the serialized data blob for the value stored in pMem into 
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/ 
................................................................................
  pMem->z = (char *)buf;
  pMem->n = len;
  if( serial_type&0x01 ){
    pMem->flags = MEM_Str | MEM_Ephem;
  }else{
    pMem->flags = MEM_Blob | MEM_Ephem;
  }
  sqlite3VdbeMemMakeWriteable(pMem);
  return len;
}

/*
** The following is the comparison function for (non-integer)
** keys in the btrees.  This function returns negative, zero, or
** positive if the first key is less than, equal to, or greater than







>
>
>
>
>
>
>










>







 







<







1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
....
1333
1334
1335
1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346
}

/*
** Return the length of the data corresponding to the supplied serial-type.
*/
int sqlite3VdbeSerialTypeLen(u32 serial_type){
  assert( serial_type!=0 );
  if( serial_type>6 ){
    return (serial_type-12)/2;
  }else{
    static u8 aSize[] = { 0, 1, 2, 4, 8, 8, 0, };
    return aSize[serial_type];
  }
#if 0
  switch(serial_type){
    case 6: return 0;                  /* NULL */
    case 1: return 1;                  /* 1 byte integer */
    case 2: return 2;                  /* 2 byte integer */
    case 3: return 4;                  /* 4 byte integer */
    case 4: return 8;                  /* 8 byte integer */
    case 5: return 8;                  /* 8 byte float */
  }
  assert( serial_type>=12 );
  return ((serial_type-12)>>1);        /* text or blob */
#endif
}

/*
** Write the serialized data blob for the value stored in pMem into 
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/ 
................................................................................
  pMem->z = (char *)buf;
  pMem->n = len;
  if( serial_type&0x01 ){
    pMem->flags = MEM_Str | MEM_Ephem;
  }else{
    pMem->flags = MEM_Blob | MEM_Ephem;
  }

  return len;
}

/*
** The following is the comparison function for (non-integer)
** keys in the btrees.  This function returns negative, zero, or
** positive if the first key is less than, equal to, or greater than