/ Check-in [6d552af6]
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 couple of test cases and fixes for blob literals. (CVS 1474)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6d552af67cf6fa6935373ba39de5c47ebf613eb9
User & Date: danielk1977 2004-05-27 13:35:20
Context
2004-05-27
13:55
Test sqlite3_bind_blob(). (CVS 1475) check-in: 42247b2f user: danielk1977 tags: trunk
13:35
A couple of test cases and fixes for blob literals. (CVS 1474) check-in: 6d552af6 user: danielk1977 tags: trunk
12:11
Alter the Tcl eval sub-command so that it supports blobs. (CVS 1473) check-in: b5d5f0ad user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1347
1348
1349
1350
1351
1352
1353

**    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.254 2004/05/27 01:53:56 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
char const *sqlite3AffinityString(char affinity);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3atoi64(const char*, i64*);
void sqlite3Error(sqlite *, int, const char*,...);
int sqlite3utfTranslate(const void *, int , u8 , void **, int *, u8);
u8 sqlite3UtfReadBom(const void *zData, int nData);








|







 







>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1347
1348
1349
1350
1351
1352
1353
1354
**    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.255 2004/05/27 13:35:20 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
char const *sqlite3AffinityString(char affinity);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3atoi64(const char*, i64*);
void sqlite3Error(sqlite *, int, const char*,...);
int sqlite3utfTranslate(const void *, int , u8 , void **, int *, u8);
u8 sqlite3UtfReadBom(const void *zData, int nData);
char *sqlite3HexToBlob(const char *z);

Changes to src/tclsqlite.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
811
812
813
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.74 2004/05/27 12:11:32 danielk1977 Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
        for(i=0; i<sqlite3_column_count(pStmt); i++){
          Tcl_Obj *pVal;
          
          /* Set pVal to contain the i'th column of this row. */
          if( SQLITE3_BLOB!=sqlite3_column_type(pStmt, i) ){
            pVal = Tcl_NewStringObj(sqlite3_column_text(pStmt, i), -1);
          }else{
            pVal = Tcl_NewByteArrayObj(
              sqlite3_column_blob(pStmt, i),
              sqlite3_column_bytes(pStmt, i)
            );

          }
  
          if( objc==5 ){
            Tcl_Obj *pName = Tcl_NewStringObj(sqlite3_column_name(pStmt, i), -1);
            Tcl_IncrRefCount(pName);
            if( !strcmp("", Tcl_GetString(objv[3])) ){
              Tcl_ObjSetVar2(interp, pName, 0, pVal, 0);







|







 







<
<
|
<
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
811
812
813
814
815
816
817


818

819
820
821
822
823
824
825
826
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.75 2004/05/27 13:35:20 danielk1977 Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
        for(i=0; i<sqlite3_column_count(pStmt); i++){
          Tcl_Obj *pVal;
          
          /* Set pVal to contain the i'th column of this row. */
          if( SQLITE3_BLOB!=sqlite3_column_type(pStmt, i) ){
            pVal = Tcl_NewStringObj(sqlite3_column_text(pStmt, i), -1);
          }else{


            int bytes = sqlite3_column_bytes(pStmt, i);

            pVal = Tcl_NewByteArrayObj(sqlite3_column_blob(pStmt, i), bytes);
          }
  
          if( objc==5 ){
            Tcl_Obj *pName = Tcl_NewStringObj(sqlite3_column_name(pStmt, i), -1);
            Tcl_IncrRefCount(pName);
            if( !strcmp("", Tcl_GetString(objv[3])) ){
              Tcl_ObjSetVar2(interp, pName, 0, pVal, 0);

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
373
374
375
376
377
378
379
380

381
382

383




384
385
386
387
388
389
390
391
392
393
394
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.71 2004/05/27 09:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
    }
    case '?': {
      *tokenType = TK_VARIABLE;
      return 1;
    }
    case 'x': case 'X': {
      if( z[1]=='\'' || z[1]=='"' ){
        int delim = z[0];

        for(i=1; z[i]; i++){
          if( z[i]==delim ){

            break;




          }
        }
        if( z[i] ) i++;
        *tokenType = TK_BLOB;
        return i;
      }
      /* Otherwise fall through to the next case */
    }
    default: {
      if( (*z&0x80)==0 && !isIdChar[*z] ){
        break;







|







 







|
>
|

>

>
>
>
>



<







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
373
374
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
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.72 2004/05/27 13:35:20 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
    }
    case '?': {
      *tokenType = TK_VARIABLE;
      return 1;
    }
    case 'x': case 'X': {
      if( z[1]=='\'' || z[1]=='"' ){
        int delim = z[1];
        *tokenType = TK_BLOB;
        for(i=2; z[i]; i++){
          if( z[i]==delim ){
            if( i%2 ) *tokenType = TK_ILLEGAL;
            break;
          }
          if( !isxdigit(z[i]) ){
            *tokenType = TK_ILLEGAL;
            return i;
          }
        }
        if( z[i] ) i++;

        return i;
      }
      /* Otherwise fall through to the next case */
    }
    default: {
      if( (*z&0x80)==0 && !isIdChar[*z] ){
        break;

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319

1320
1321
1322
1323
1324
1325
1326
1327
1328
1329

1330
1331
1332
1333
1334
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.91 2004/05/27 09:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
  char *zBlob;
  int i;
  int n = strlen(z);
  if( n%2 ) return 0;

  zBlob = (char *)sqliteMalloc(n/2);

  for(i=0; i<n; i+=2){
    u8 c;

    if     ( z[i]>47 && z[i]<58 ) c = (z[i]-48)<<4;
    else if( z[i]>64 && z[i]<71 ) c = (z[i]-55)<<4;
    else if( z[i]>96 && z[i]<103 ) c = (z[i]-87)<<4;
    else {
      sqliteFree(zBlob);
      return 0;
    }

    if     ( z[i]>47 && z[i]<58 ) c += (z[i]-48);
    else if( z[i]>64 && z[i]<71 ) c += (z[i]-55);
    else if( z[i]>96 && z[i]<103 ) c += (z[i]-87);
    else {
      sqliteFree(zBlob);
      return 0;
    }

    zBlob[i/2] = c;
  }

}











|







 







|









>










>





10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
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.92 2004/05/27 13:35:20 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
  char *zBlob;
  int i;
  int n = strlen(z);
  if( n%2 ) return 0;

  zBlob = (char *)sqliteMalloc(n/2);

  for(i=0; i<n; i++){
    u8 c;

    if     ( z[i]>47 && z[i]<58 ) c = (z[i]-48)<<4;
    else if( z[i]>64 && z[i]<71 ) c = (z[i]-55)<<4;
    else if( z[i]>96 && z[i]<103 ) c = (z[i]-87)<<4;
    else {
      sqliteFree(zBlob);
      return 0;
    }
    i++;
    if     ( z[i]>47 && z[i]<58 ) c += (z[i]-48);
    else if( z[i]>64 && z[i]<71 ) c += (z[i]-55);
    else if( z[i]>96 && z[i]<103 ) c += (z[i]-87);
    else {
      sqliteFree(zBlob);
      return 0;
    }

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




Changes to src/vdbeaux.c.

608
609
610
611
612
613
614


615
616
617
618
619
620
621
622
623
624
625
626
627



628



629
630
631
632
633
634
635
...
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709

/*
** If pOp is an OP_HexBlob opcode, then transform it to an OP_Blob
** opcode. 
*/
static int translateOp(Op *pOp){
  if( pOp->opcode==OP_HexBlob ){


    char *zBlob = sqlite3HexToBlob(pOp->p3);
    if( !zBlob ){
      if( sqlite3_malloc_failed ){
        return SQLITE_NOMEM;
      }
      return SQLITE_ERROR;
    }
    pOp->p1 = strlen(pOp->p3)/2;
    if( pOp->p3type==P3_DYNAMIC ){
      sqliteFree(pOp->p3);
    }
    pOp->p3 = zBlob;
    pOp->p3type = P3_DYNAMIC;



  }



}

/*
** Prepare a virtual machine for execution.  This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqlite3VdbeExec().  
................................................................................
    int i;
    for(i=0; i<p->nOp; i++){
      p->aOp[i].cnt = 0;
      p->aOp[i].cycles = 0;
    }
  }
#endif
  {
    int i;
    for(i=0; i<p->nOp; i++){
      translateOp(&p->aOp[i]);
    }
  }
}








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







 







|







608
609
610
611
612
613
614
615
616
617


618




619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711

/*
** If pOp is an OP_HexBlob opcode, then transform it to an OP_Blob
** opcode. 
*/
static int translateOp(Op *pOp){
  if( pOp->opcode==OP_HexBlob ){
    pOp->p1 = strlen(pOp->p3)/2;
    if( pOp->p1 ){
      char *zBlob = sqlite3HexToBlob(pOp->p3);


      if( !zBlob ) return SQLITE_NOMEM;




      if( pOp->p3type==P3_DYNAMIC ){
        sqliteFree(pOp->p3);
      }
      pOp->p3 = zBlob;
      pOp->p3type = P3_DYNAMIC;
    }else{
      pOp->p3type = P3_STATIC;
      pOp->p3 = "";
    }
    pOp->opcode = OP_Blob;
  }
  return SQLITE_OK;
}

/*
** Prepare a virtual machine for execution.  This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqlite3VdbeExec().  
................................................................................
    int i;
    for(i=0; i<p->nOp; i++){
      p->aOp[i].cnt = 0;
      p->aOp[i].cycles = 0;
    }
  }
#endif
  if( !isExplain ){
    int i;
    for(i=0; i<p->nOp; i++){
      translateOp(&p->aOp[i]);
    }
  }
}

Changes to src/vdbemem.c.

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
    pMem->flags = MEM_Null;
    pMem->type = SQLITE3_NULL;
    return SQLITE_OK;
  }

  pMem->z = (char *)z;
  if( eCopy ){
    pMem->flags = MEM_Ephem|MEM_Str;
  }else{
    pMem->flags = MEM_Static|MEM_Str;
  }
  pMem->enc = enc;
  pMem->type = enc==0 ? SQLITE3_BLOB : SQLITE3_TEXT;
  pMem->n = n;
  switch( enc ){
    case 0:
      pMem->flags |= MEM_Blob;
      break;

    case TEXT_Utf8:

      if( n<0 ){
        pMem->n = strlen(z);
        pMem->flags |= MEM_Term;
      }
      break;

    case TEXT_Utf16le:
    case TEXT_Utf16be:

      if( n<0 ){
        pMem->n = sqlite3utf16ByteLen(z,-1);
        pMem->flags |= MEM_Term;
      }
      break;

    default:







|

|










>








>







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
    pMem->flags = MEM_Null;
    pMem->type = SQLITE3_NULL;
    return SQLITE_OK;
  }

  pMem->z = (char *)z;
  if( eCopy ){
    pMem->flags = MEM_Ephem;
  }else{
    pMem->flags = MEM_Static;
  }
  pMem->enc = enc;
  pMem->type = enc==0 ? SQLITE3_BLOB : SQLITE3_TEXT;
  pMem->n = n;
  switch( enc ){
    case 0:
      pMem->flags |= MEM_Blob;
      break;

    case TEXT_Utf8:
      pMem->flags |= MEM_Str;
      if( n<0 ){
        pMem->n = strlen(z);
        pMem->flags |= MEM_Term;
      }
      break;

    case TEXT_Utf16le:
    case TEXT_Utf16be:
      pMem->flags |= MEM_Str;
      if( n<0 ){
        pMem->n = sqlite3utf16ByteLen(z,-1);
        pMem->flags |= MEM_Term;
      }
      break;

    default: