/ Check-in [b3581d27]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:A few bugfixes related to UTF-16 databases. sqlite3_open() still assumes a UTF-8 database, and sqlite3_open16() still assumes a UTF-16 db. (CVS 1434)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b3581d2796c8cb6581b7156774698a05fc8f800e
User & Date: danielk1977 2004-05-22 07:27:46
Context
2004-05-22
08:09
Store the text encoding in the database (as meta value 4). (CVS 1435) check-in: 7f00ca58 user: danielk1977 tags: trunk
07:27
A few bugfixes related to UTF-16 databases. sqlite3_open() still assumes a UTF-8 database, and sqlite3_open16() still assumes a UTF-16 db. (CVS 1434) check-in: b3581d27 user: danielk1977 tags: trunk
03:05
Steps towards UTF-16 databases. Some tests are failing because of this commit. (CVS 1433) check-in: c4a82468 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
....
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
....
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
....
1480
1481
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
....
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337

2338
2339
2340
2341
2342
2343
2344
....
2395
2396
2397
2398
2399
2400
2401




2402

2403
2404
2405
2406
2407
2408
2409
....
4751
4752
4753
4754
4755
4756
4757



4758

4759
4760
4761
4762
4763
4764
4765
....
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
**
** 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.316 2004/05/22 03:05:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  }

  pVal = &pVm->pTos[(1-vals)+i];
  if( pVal->flags&MEM_Null ){
    return 0;
  }

  if( !pVal->flags&MEM_Blob ){
    Stringify(pVal);
    SetEncoding(pVal, MEM_Utf8|MEM_Term);
  }

  return pVal->z;
}

................................................................................
*/
case OP_Integer: {
  pTos++;
  pTos->i = pOp->p1;
  pTos->flags = MEM_Int;
  if( pOp->p3 ){
    pTos->z = pOp->p3;
    pTos->flags |= MEM_Utf8 | MEM_Str | MEM_Static;
    pTos->n = strlen(pOp->p3)+1;
    if( pTos->i==0 ){
      sqlite3GetInt64(pTos->z, &pTos->i);
    }
  }
  break;
}
................................................................................
  assert( z );
  assert( sqlite3IsNumber(z, 0) );

  pTos++;
  pTos->r = sqlite3AtoF(z, 0);
  pTos->z = z;
  pTos->n = strlen(z)+1;
  pTos->flags = MEM_Real|MEM_Str|MEM_Static|MEM_Utf8;
  break;
}

/* Opcode: Variable P1 * *
**
** Push the value of variable P1 onto the stack.  A variable is
** an unknown in the original SQL string as handed to sqlite3_compile().
................................................................................
  int i;
  Mem ts;

  ts = *pFrom;
  Deephemeralize(pTos);
  for(i=0; i<pOp->p1; i++, pFrom++){
    Deephemeralize(&pFrom[1]);
    *pFrom = pFrom[1];
    assert( (pFrom->flags & MEM_Ephem)==0 );

    if( pFrom->flags & MEM_Short ){
      assert( pFrom->flags & (MEM_Str|MEM_Blob) );
      assert( pFrom->z==pFrom[1].zShort );
      pFrom->z = pFrom->zShort;
    }
  }
  *pTos = ts;
................................................................................
    {MEM_Int, "INTEGER"},
    {MEM_Real, "REAL"},
    {MEM_Str, "TEXT"},
    {MEM_Blob, "BLOB"}
  };

  Release(pTos);
  pTos->flags = MEM_Str|MEM_Static|MEM_Utf8;

  for(i=0; i<5; i++){
    if( classes[i].mask&flags ){
      pTos->z = classes[i].zClass;
      break;
    }
  }
  assert( i<5 );

  break;
}

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
................................................................................
  if( i<0 ){
    char *zRec;     /* Pointer to record data from the stack. */
    int off = 0;    /* Offset in zRec to start of the columns data. */
    int off2 = 0;   /* Offset in zRec to the next serial type to read */
    u64 colType;    /* The serial type of the value being read. */

    assert( &pTos[i-1]>=p->aStack );




    assert( pTos[i].flags & MEM_Blob );

    assert( pTos[i-1].flags & MEM_Int );

    if( pTos[i].n==0 ){
      pTos->flags = MEM_Null;
      break;
    }

................................................................................
  Sorter *pSorter = p->pSort;
  CHECK_FOR_INTERRUPT;
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    pTos++;
    pTos->z = pSorter->pData;
    pTos->n = pSorter->nData;



    pTos->flags = MEM_Blob|MEM_Dyn;

    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}
................................................................................
  }else{
    z = 0;
  }
  pTos++;
  if( z ){
    pTos->n = strlen(z) + 1;
    pTos->z = z;
    pTos->flags = MEM_Utf8 | MEM_Str | MEM_Ephem;
  }else{
    pTos->flags = MEM_Null;
  }
  break;
}

/* Opcode: MemStore P1 P2 *







|







 







|







 







|







 







|







 







<

>







 







|








>







 







>
>
>
>
|
>







 







>
>
>
|
>







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
....
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
....
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
....
1480
1481
1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493
1494
1495
....
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
....
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
....
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
....
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
**
** 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.317 2004/05/22 07:27:46 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  }

  pVal = &pVm->pTos[(1-vals)+i];
  if( pVal->flags&MEM_Null ){
    return 0;
  }

  if( !(pVal->flags&MEM_Blob) ){
    Stringify(pVal);
    SetEncoding(pVal, MEM_Utf8|MEM_Term);
  }

  return pVal->z;
}

................................................................................
*/
case OP_Integer: {
  pTos++;
  pTos->i = pOp->p1;
  pTos->flags = MEM_Int;
  if( pOp->p3 ){
    pTos->z = pOp->p3;
    pTos->flags |= MEM_Utf8 | MEM_Str | MEM_Static | MEM_Term;
    pTos->n = strlen(pOp->p3)+1;
    if( pTos->i==0 ){
      sqlite3GetInt64(pTos->z, &pTos->i);
    }
  }
  break;
}
................................................................................
  assert( z );
  assert( sqlite3IsNumber(z, 0) );

  pTos++;
  pTos->r = sqlite3AtoF(z, 0);
  pTos->z = z;
  pTos->n = strlen(z)+1;
  pTos->flags = MEM_Real|MEM_Str|MEM_Static|MEM_Utf8|MEM_Term;
  break;
}

/* Opcode: Variable P1 * *
**
** Push the value of variable P1 onto the stack.  A variable is
** an unknown in the original SQL string as handed to sqlite3_compile().
................................................................................
  int i;
  Mem ts;

  ts = *pFrom;
  Deephemeralize(pTos);
  for(i=0; i<pOp->p1; i++, pFrom++){
    Deephemeralize(&pFrom[1]);

    assert( (pFrom->flags & MEM_Ephem)==0 );
    *pFrom = pFrom[1];
    if( pFrom->flags & MEM_Short ){
      assert( pFrom->flags & (MEM_Str|MEM_Blob) );
      assert( pFrom->z==pFrom[1].zShort );
      pFrom->z = pFrom->zShort;
    }
  }
  *pTos = ts;
................................................................................
    {MEM_Int, "INTEGER"},
    {MEM_Real, "REAL"},
    {MEM_Str, "TEXT"},
    {MEM_Blob, "BLOB"}
  };

  Release(pTos);
  pTos->flags = MEM_Str|MEM_Static|MEM_Utf8|MEM_Term;

  for(i=0; i<5; i++){
    if( classes[i].mask&flags ){
      pTos->z = classes[i].zClass;
      break;
    }
  }
  assert( i<5 );
  pTos->n = strlen(classes[i].zClass);
  break;
}

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
................................................................................
  if( i<0 ){
    char *zRec;     /* Pointer to record data from the stack. */
    int off = 0;    /* Offset in zRec to start of the columns data. */
    int off2 = 0;   /* Offset in zRec to the next serial type to read */
    u64 colType;    /* The serial type of the value being read. */

    assert( &pTos[i-1]>=p->aStack );

    /* FIX ME: I don't understand this either. How is it related to
    ** OP_SortNext? (I thought it would be the commented out assert())
    */
    /* assert( pTos[i].flags & MEM_Blob ); */
    assert( pTos[i].flags & (MEM_Blob|MEM_Str) );
    assert( pTos[i-1].flags & MEM_Int );

    if( pTos[i].n==0 ){
      pTos->flags = MEM_Null;
      break;
    }

................................................................................
  Sorter *pSorter = p->pSort;
  CHECK_FOR_INTERRUPT;
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    pTos++;
    pTos->z = pSorter->pData;
    pTos->n = pSorter->nData;
    /* FIX ME: I don't understand this. What does the sorter return? 
    ** I thought it would be the commented out flags.
    */
    /* pTos->flags = MEM_Blob|MEM_Dyn; */
    pTos->flags = MEM_Str|MEM_Dyn|MEM_Utf8|MEM_Term;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}
................................................................................
  }else{
    z = 0;
  }
  pTos++;
  if( z ){
    pTos->n = strlen(z) + 1;
    pTos->z = z;
    pTos->flags = MEM_Utf8 | MEM_Str | MEM_Ephem | MEM_Term;
  }else{
    pTos->flags = MEM_Null;
  }
  break;
}

/* Opcode: MemStore P1 P2 *

Changes to src/vdbeaux.c.

637
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
663
664
665
666
667
668
669


670
671







672

673

674
675
676
677
678
679
680
  int rc = SQLITE_OK;
  static char *azColumnNames[] = {
     "addr", "opcode", "p1",  "p2",  "p3", 
     "int",  "text",   "int", "int", "text",
     0
  };

  assert( p->popStack==0 );
  assert( p->explain );














  p->azColName = azColumnNames;
  p->azResColumn = p->zArgv;
  for(i=0; i<5; i++) p->zArgv[i] = p->aStack[i].zShort;


  i = p->pc;
  if( i>=p->nOp ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
  }else if( db->flags & SQLITE_Interrupt ){
    db->flags &= ~SQLITE_Interrupt;
    if( db->magic!=SQLITE_MAGIC_BUSY ){
      p->rc = SQLITE_MISUSE;
................................................................................
    }else{
      p->rc = SQLITE_INTERRUPT;
    }
    rc = SQLITE_ERROR;
    sqlite3SetString(&p->zErrMsg, sqlite3_error_string(p->rc), (char*)0);
  }else{
    Op *pOp = &p->aOp[i];
    sprintf(p->zArgv[0],"%d",i);
    sprintf(p->zArgv[2],"%d", pOp->p1);
    sprintf(p->zArgv[3],"%d", pOp->p2);
    p->zArgv[4] =
          displayP3(pOp, p->aStack[4].zShort, sizeof(p->aStack[4].zShort));
    p->zArgv[1] = sqlite3OpcodeNames[pOp->opcode];


    p->pc = i+1;
    p->azResColumn = p->zArgv;







    p->nResColumn = 5;

    p->rc = SQLITE_OK;

    rc = SQLITE_ROW;
  }
  return rc;
}

/*
** Prepare a virtual machine for execution.  This involves things such







<

>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
<
>
>
|







 







|
|
|
<
<
|
>
>
|
|
>
>
>
>
>
>
>

>

>







637
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
663
664
665
666
667
668
669
...
670
671
672
673
674
675
676
677
678
679


680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
  int rc = SQLITE_OK;
  static char *azColumnNames[] = {
     "addr", "opcode", "p1",  "p2",  "p3", 
     "int",  "text",   "int", "int", "text",
     0
  };


  assert( p->explain );

  /* Even though this opcode does not put dynamic strings onto the
  ** the stack, they may become dynamic if the user calls
  ** sqlite3_column_data16(), causing a translation to UTF-16 encoding.
  */
  if( p->pTos==&p->aStack[4] ){
    for(i=0; i<5; i++){
      if( p->aStack[i].flags & MEM_Dyn ){
        sqliteFree(p->aStack[i].z);
      }
      p->aStack[i].flags = 0;
    }
  }

  p->azColName = azColumnNames;


  p->resOnStack = 0;

  i = p->pc++;
  if( i>=p->nOp ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
  }else if( db->flags & SQLITE_Interrupt ){
    db->flags &= ~SQLITE_Interrupt;
    if( db->magic!=SQLITE_MAGIC_BUSY ){
      p->rc = SQLITE_MISUSE;
................................................................................
    }else{
      p->rc = SQLITE_INTERRUPT;
    }
    rc = SQLITE_ERROR;
    sqlite3SetString(&p->zErrMsg, sqlite3_error_string(p->rc), (char*)0);
  }else{
    Op *pOp = &p->aOp[i];
    p->aStack[0].flags = MEM_Int;
    p->aStack[0].i = i;                                /* Program counter */
    p->aStack[1].flags = MEM_Static|MEM_Str|MEM_Utf8|MEM_Term;


    p->aStack[1].z = sqlite3OpcodeNames[pOp->opcode];  /* Opcode */
    p->aStack[2].flags = MEM_Int;
    p->aStack[2].i = pOp->p1;                          /* P1 */
    p->aStack[3].flags = MEM_Int;
    p->aStack[3].i = pOp->p2;                          /* P2 */
    p->aStack[4].flags = MEM_Str|MEM_Utf8|MEM_Term;    /* P3 */
    p->aStack[4].z = displayP3(pOp, p->aStack[4].zShort, NBFS);
    if( p->aStack[4].z==p->aStack[4].zShort ){
      p->aStack[4].flags |= MEM_Short;
    }else{
      p->aStack[4].flags |= MEM_Static;
    }
    p->nResColumn = 5;
    p->pTos = &p->aStack[4];
    p->rc = SQLITE_OK;
    p->resOnStack = 1;
    rc = SQLITE_ROW;
  }
  return rc;
}

/*
** Prepare a virtual machine for execution.  This involves things such