SQLite

Check-in [b3581d2796]
Login

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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b3581d2796c8cb6581b7156774698a05fc8f800e
User & Date: danielk1977 2004-05-22 07:27:46.000
Context
2004-05-22
08:09
Store the text encoding in the database (as meta value 4). (CVS 1435) (check-in: 7f00ca5801 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: b3581d2796 user: danielk1977 tags: trunk)
03:05
Steps towards UTF-16 databases. Some tests are failing because of this commit. (CVS 1433) (check-in: c4a8246864 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** 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"

/*







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** 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"

/*
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  }

  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;
}








|







519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  }

  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;
}

1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
*/
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;
}







|







1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
*/
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;
}
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
  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().







|







1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
  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().
1480
1481
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
  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;







<

>







1480
1481
1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493
1494
1495
  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;
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337

2338
2339
2340
2341
2342
2343
2344
    {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.







|








>







2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
    {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.
2395
2396
2397
2398
2399
2400
2401




2402

2403
2404
2405
2406
2407
2408
2409
  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;
    }








>
>
>
>
|
>







2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
  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;
    }

4751
4752
4753
4754
4755
4756
4757



4758

4759
4760
4761
4762
4763
4764
4765
  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;
}







>
>
>
|
>







4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
  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;
}
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
  }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 *







|







4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
  }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