SQLite

Check-in [c96539beb5]
Login

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

Overview
Comment:Per /chat and forum discussions: (A) Remove the value type output pointer from text/blob_v2(). (B) Teach blob_v2() to return an opaque non-NULL pointer for length-0 blobs.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | column-text-blob-v2
Files: files | file ages | folders
SHA3-256: c96539beb5ca3c6a467e5388b942767765a3f071e009c1767d3b4f1b0fb5da9c
User & Date: stephan 2025-07-02 13:24:50.303
Context
2025-07-02
15:29
Correct mis-placed OOM checks in valueToTextV2(). (check-in: 9226a2a3c6 user: stephan tags: column-text-blob-v2)
13:24
Per /chat and forum discussions: (A) Remove the value type output pointer from text/blob_v2(). (B) Teach blob_v2() to return an opaque non-NULL pointer for length-0 blobs. (check-in: c96539beb5 user: stephan tags: column-text-blob-v2)
07:52
Add test1.c tcl bindings for sqlite3_column_text/blob_v2(). Replace, essentially randomly, some of the v1 API calls in capi2.test and capi2.test with the v2 calls to ensure identical results. Add a couple new tests comparing results between v1 and v2. (check-in: a3ca0adbaf user: stephan tags: column-text-blob-v2)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/wasm/api/sqlite3-api-glue.c-pp.js.
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    /* sqlite3_cancel_auto_extension() has a hand-written binding. */
    /* sqlite3_close_v2() is implemented by hand to perform some
       extra work. */
    ["sqlite3_changes", "int", "sqlite3*"],
    ["sqlite3_clear_bindings","int", "sqlite3_stmt*"],
    ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/],
    ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"],
    ["sqlite3_column_blob_v2", "int", "sqlite3_stmt*", "int", "**", "*", "*"],
    ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"],
    ["sqlite3_column_count", "int", "sqlite3_stmt*"],
    ["sqlite3_column_decltype", "string", "sqlite3_stmt*", "int"],
    ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
    ["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
    ["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
    ["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
    ["sqlite3_column_text_v2", "int", "sqlite3_stmt*", "int", "**", "*", "*"],
    ["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
    ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
    ["sqlite3_commit_hook", "void*", [
      "sqlite3*",
      new wasm.xWrap.FuncPtrAdapter({
        name: 'sqlite3_commit_hook',
        signature: 'i(p)',







|







|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    /* sqlite3_cancel_auto_extension() has a hand-written binding. */
    /* sqlite3_close_v2() is implemented by hand to perform some
       extra work. */
    ["sqlite3_changes", "int", "sqlite3*"],
    ["sqlite3_clear_bindings","int", "sqlite3_stmt*"],
    ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/],
    ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"],
    ["sqlite3_column_blob_v2", "int", "sqlite3_stmt*", "int", "**", "*"],
    ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"],
    ["sqlite3_column_count", "int", "sqlite3_stmt*"],
    ["sqlite3_column_decltype", "string", "sqlite3_stmt*", "int"],
    ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
    ["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
    ["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
    ["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
    ["sqlite3_column_text_v2", "int", "sqlite3_stmt*", "int", "**", "*"],
    ["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
    ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
    ["sqlite3_commit_hook", "void*", [
      "sqlite3*",
      new wasm.xWrap.FuncPtrAdapter({
        name: 'sqlite3_commit_hook',
        signature: 'i(p)',
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
       their first C-string arguments, so we cannot perform any value
       conversion on those. */
    ["sqlite3_uri_boolean", "int", "sqlite3_filename", "string", "int"],
    ["sqlite3_uri_key", "string", "sqlite3_filename", "int"],
    ["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"],
    ["sqlite3_user_data","void*", "sqlite3_context*"],
    ["sqlite3_value_blob", "*", "sqlite3_value*"],
    ["sqlite3_value_blob_v2", "int", "sqlite3_value*", "**", "*", "*"],
    ["sqlite3_value_bytes","int", "sqlite3_value*"],
    ["sqlite3_value_double","f64", "sqlite3_value*"],
    ["sqlite3_value_dup", "sqlite3_value*", "sqlite3_value*"],
    ["sqlite3_value_free", undefined, "sqlite3_value*"],
    ["sqlite3_value_frombind", "int", "sqlite3_value*"],
    ["sqlite3_value_int","int", "sqlite3_value*"],
    ["sqlite3_value_nochange", "int", "sqlite3_value*"],
    ["sqlite3_value_numeric_type", "int", "sqlite3_value*"],
    ["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
    ["sqlite3_value_subtype", "int", "sqlite3_value*"],
    ["sqlite3_value_text", "string", "sqlite3_value*"],
    ["sqlite3_value_text_v2", "int", "sqlite3_value*", "**", "*", "*"],
    ["sqlite3_value_type", "int", "sqlite3_value*"],
    ["sqlite3_vfs_find", "*", "string"],
    ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
    ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
  ]/*wasm.bindingSignatures*/;

  if( !!wasm.exports.sqlite3_progress_handler ){







|











|







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
       their first C-string arguments, so we cannot perform any value
       conversion on those. */
    ["sqlite3_uri_boolean", "int", "sqlite3_filename", "string", "int"],
    ["sqlite3_uri_key", "string", "sqlite3_filename", "int"],
    ["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"],
    ["sqlite3_user_data","void*", "sqlite3_context*"],
    ["sqlite3_value_blob", "*", "sqlite3_value*"],
    ["sqlite3_value_blob_v2", "int", "sqlite3_value*", "**", "*"],
    ["sqlite3_value_bytes","int", "sqlite3_value*"],
    ["sqlite3_value_double","f64", "sqlite3_value*"],
    ["sqlite3_value_dup", "sqlite3_value*", "sqlite3_value*"],
    ["sqlite3_value_free", undefined, "sqlite3_value*"],
    ["sqlite3_value_frombind", "int", "sqlite3_value*"],
    ["sqlite3_value_int","int", "sqlite3_value*"],
    ["sqlite3_value_nochange", "int", "sqlite3_value*"],
    ["sqlite3_value_numeric_type", "int", "sqlite3_value*"],
    ["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
    ["sqlite3_value_subtype", "int", "sqlite3_value*"],
    ["sqlite3_value_text", "string", "sqlite3_value*"],
    ["sqlite3_value_text_v2", "int", "sqlite3_value*", "**", "*"],
    ["sqlite3_value_type", "int", "sqlite3_value*"],
    ["sqlite3_vfs_find", "*", "string"],
    ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
    ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
  ]/*wasm.bindingSignatures*/;

  if( !!wasm.exports.sqlite3_progress_handler ){
Changes to ext/wasm/tester1.c-pp.js.
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454

3455
3456
3457
3458

3459
3460
3461
3462

3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490

3491
3492
3493
3494

3495
3496
3497
3498
3499
3500
3501
               "values(1,123),(2,null),(3,'hi world'),(4,X'232A'),(5,'')"]);
      const P = wasm.pstack;
      const stack = P.pointer;
      let q;
      try {
        let sv, rc;
        q = db.prepare("select a, b from t order by a");
        let [ppOut, pnOut, pType] = P.allocPtr(3);
        const clearPtrs = ()=>{
          wasm.pokePtr(ppOut, 0).poke32(pnOut, 0).poke32(pType, 0);
        };
        const next = ()=>{
          T.assert( q.step() );
          sv = capi.sqlite3_column_value(q, 1);
          T.assert( sv );
          clearPtrs();
          rc = capi.sqlite3_value_text_v2(sv, ppOut, pnOut, pType);
          T.assert( 0===rc );
          return sv;
        };
        const cmp = function(type,expect){
          const blob = wasm.peekPtr(ppOut);
          const len = wasm.peek32(pnOut);
          //log("blob=",wasm.cstrToJs(blob));
          const str = wasm.cstrToJs(blob);
          if( !blob ){
            T.assert( null===expect )
              .assert( 0===len );
            return;
          }
          T.assert(len === expect.length,
                   "Lengths don't match: got ["+str
                   +"] expected ["+expect+"]")
            .assert( str===expect, "String mismatch: got ["
                     +str+"] expected ["+expect+"]");
        };
        const cmp2 = (type,expect)=>{
          next();
          cmp(type,expect);
          clearPtrs();
          const rc = capi.sqlite3_column_text_v2(q, 1, ppOut, pnOut, pType);
          T.assert( 0==rc, "expecting column_text_v2() rc 0 but got "+rc );
          cmp(type,expect);
        };

        cmp2(capi.SQLITE_INTEGER,'123');
        cmp2(capi.SQLITE_NULL,null);
        cmp2(capi.SQLITE_TEXT,'hi world');
        cmp2(capi.SQLITE_BLOB, '#*');
        cmp2(capi.SQLITE_TEXT, ''); // empty strings are not null

        const checkRc = (name, descr, rc)=>{
          T.assert( capi[name] === rc,
                    descr+": expecting "+name+"("+
                    capi[name]+") but got "+rc);
        };

        /** The following tests cover the same code paths
            for both text_v2 and blob_v2, so are elided from
            the blob_v2 checks in the next test group. */

        // This does not set a persistent error flag on q:
        checkRc('SQLITE_RANGE', "column_text_v2() bad index",
                capi.sqlite3_column_text_v2(q, 11, ppOut, pnOut, 0) );
        checkRc('SQLITE_OK', "column_text_v2() valid index",
                capi.sqlite3_column_text_v2(q, 1, ppOut, 0, 0));

        checkRc('SQLITE_OK', "column null pnOut",
                capi.sqlite3_column_text_v2(q, 1, ppOut, 0, 0));

        /* The MISUSE returns only apply because we build with
           SQLITE_ENABLE_API_ARMOR. Without API_ARMOR, these result in
           null pointer dereferences. */
        checkRc('SQLITE_MISUSE', "value null ppOut",
                capi.sqlite3_value_text_v2(sv, 0, pnOut, 0));
        checkRc('SQLITE_MISUSE', "value null arg0",
                capi.sqlite3_value_text_v2(0, ppOut, pnOut, 0));
        checkRc('SQLITE_MISUSE', "column null ppOut",
                capi.sqlite3_column_text_v2(q, 1, 0, pnOut, 0));
        /* But a 0 pnOut is always okay. */
        checkRc('SQLITE_OK', "value null pnOut",
                capi.sqlite3_value_text_v2(sv, ppOut, 0, 0));

      }finally{
        if( q ) q.finalize();
        db.close();
        P.restore(stack);
      }
    })

  ////////////////////////////////////////////////////////////////////
    .t("value_blob_v2() and friends...", function(sqlite3){
      const db = new sqlite3.oo1.DB();
      db.exec(["create table t(a,b); insert into t(a,b) ",
               "values(1,123),(2,null),(3,'hi'),(4,X'23002A'),(5,'')"]);
      const P = wasm.pstack;
      const stack = P.pointer;
      let q;
      try {
        let sv, rc;
        q = db.prepare("select a, b from t order by a");
        let [ppOut, pnOut, pType] = P.allocPtr(3);
        const clearPtrs = ()=>{
          wasm.pokePtr(ppOut, 0).poke32(pnOut, 0).poke32(pType, 0);
        };

        const next = ()=>{

          T.assert( q.step() );
          sv = capi.sqlite3_column_value(q, 1);
          T.assert( sv );
          clearPtrs();

          rc = capi.sqlite3_value_blob_v2(sv, ppOut, pnOut, pType);
          T.assert( 0==rc, "expecting value_blob_v2() rc 0 but got "+rc );
          return sv;
        };

        const cmp = (type,byteList)=>{
          const blob = wasm.peekPtr(ppOut);
          const len = wasm.peek32(pnOut);
          //log("blob=",wasm.cstrToJs(blob));
          T.assert(len === byteList.length, "Lengths don't match")
          T.assert( len ? !!blob : !blob,
                    "Expecting len=non-0/blob=non-null or len=0/blob=null. "+
                    "Got len="+len+" blob=@"+blob );
          T.assert( type === wasm.peek32(pType),
                    "Expecting value_blob_v2 type "+type+" but got "
                    +wasm.peek32(pType)+". Value="+wasm.cstrToJs(blob));
          for( let i = 0; i < len; ++i ){
            T.assert( byteList[i] === wasm.peek8(blob+i),
                      "mismatch at offset "+i+": "+byteList[i]
                      +"!=="+wasm.peek8(blob+i) );
          }
        };
        const cmp2 = (type,byteList)=>{
          next();
          cmp(type,byteList);
          clearPtrs();
          const rc = capi.sqlite3_column_blob_v2(q, 1, ppOut, pnOut, pType);
          T.assert( 0==rc, "expecting column_blob_v2() rc 0 but got "+rc);
          cmp(type,byteList);
        };

        cmp2(capi.SQLITE_INTEGER, [49,50,51]); // 123
        cmp2(capi.SQLITE_NULL, []); // null

        cmp2(capi.SQLITE_TEXT, [104,105]); // "hi"
        cmp2(capi.SQLITE_BLOB, [0x23, 0, 0x2a]); // X'23002A'
        cmp2(capi.SQLITE_TEXT, []) /* length-0 non-NULL blobs are NULL
                                      but this one has type TEXT */;


        /** Tests which cover the same code paths for both text_v2 and
            blob_v2 are in the previous test group. */

      }finally{
        if( q ) q.finalize();
        db.close();







|

|






|



|















|

|

|

|


|
|
|
|
|













|

|


|





|

|

|
<
<
<



















|

|



>




>
|



>
|


<
|
|
<
<
<
<
<






|

|

|

|


|
|
>
|
|
|
<
>







3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426



3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465

3466
3467





3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488

3489
3490
3491
3492
3493
3494
3495
3496
               "values(1,123),(2,null),(3,'hi world'),(4,X'232A'),(5,'')"]);
      const P = wasm.pstack;
      const stack = P.pointer;
      let q;
      try {
        let sv, rc;
        q = db.prepare("select a, b from t order by a");
        let [ppOut, pnOut] = P.allocPtr(2);
        const clearPtrs = ()=>{
          wasm.pokePtr(ppOut, 0).poke32(pnOut, 0);
        };
        const next = ()=>{
          T.assert( q.step() );
          sv = capi.sqlite3_column_value(q, 1);
          T.assert( sv );
          clearPtrs();
          rc = capi.sqlite3_value_text_v2(sv, ppOut, pnOut);
          T.assert( 0===rc );
          return sv;
        };
        const cmp = function(expect){
          const blob = wasm.peekPtr(ppOut);
          const len = wasm.peek32(pnOut);
          //log("blob=",wasm.cstrToJs(blob));
          const str = wasm.cstrToJs(blob);
          if( !blob ){
            T.assert( null===expect )
              .assert( 0===len );
            return;
          }
          T.assert(len === expect.length,
                   "Lengths don't match: got ["+str
                   +"] expected ["+expect+"]")
            .assert( str===expect, "String mismatch: got ["
                     +str+"] expected ["+expect+"]");
        };
        const cmp2 = (expect)=>{
          next();
          cmp(expect);
          clearPtrs();
          const rc = capi.sqlite3_column_text_v2(q, 1, ppOut, pnOut);
          T.assert( 0==rc, "expecting column_text_v2() rc 0 but got "+rc );
          cmp(expect);
        };

        cmp2('123');
        cmp2(null);
        cmp2('hi world');
        cmp2('#*');
        cmp2(''); // empty strings are not null

        const checkRc = (name, descr, rc)=>{
          T.assert( capi[name] === rc,
                    descr+": expecting "+name+"("+
                    capi[name]+") but got "+rc);
        };

        /** The following tests cover the same code paths
            for both text_v2 and blob_v2, so are elided from
            the blob_v2 checks in the next test group. */

        // This does not set a persistent error flag on q:
        checkRc('SQLITE_RANGE', "column_text_v2() bad index",
                capi.sqlite3_column_text_v2(q, 11, ppOut, pnOut) );
        checkRc('SQLITE_OK', "column_text_v2() valid index",
                capi.sqlite3_column_text_v2(q, 1, ppOut, 0));

        checkRc('SQLITE_OK', "column null pnOut",
                capi.sqlite3_column_text_v2(q, 1, ppOut, 0));

        /* The MISUSE returns only apply because we build with
           SQLITE_ENABLE_API_ARMOR. Without API_ARMOR, these result in
           null pointer dereferences. */
        checkRc('SQLITE_MISUSE', "value null ppOut",
                capi.sqlite3_value_text_v2(sv, 0, pnOut));
        checkRc('SQLITE_MISUSE', "value null arg0",
                capi.sqlite3_value_text_v2(0, ppOut, pnOut));
        checkRc('SQLITE_MISUSE', "column null ppOut",
                capi.sqlite3_column_text_v2(q, 1, 0, pnOut));




      }finally{
        if( q ) q.finalize();
        db.close();
        P.restore(stack);
      }
    })

  ////////////////////////////////////////////////////////////////////
    .t("value_blob_v2() and friends...", function(sqlite3){
      const db = new sqlite3.oo1.DB();
      db.exec(["create table t(a,b); insert into t(a,b) ",
               "values(1,123),(2,null),(3,'hi'),(4,X'23002A'),(5,'')"]);
      const P = wasm.pstack;
      const stack = P.pointer;
      let q;
      try {
        let sv, rc;
        q = db.prepare("select a, b from t order by a");
        let [ppOut, pnOut] = P.allocPtr(2);
        const clearPtrs = ()=>{
          wasm.pokePtr(ppOut, 0).poke32(pnOut, 0);
        };

        const next = ()=>{
          ++next.n;
          T.assert( q.step() );
          sv = capi.sqlite3_column_value(q, 1);
          T.assert( sv );
          clearPtrs();
          T.assert( !wasm.peekPtr(ppOut) );
          rc = capi.sqlite3_value_blob_v2(sv, ppOut, pnOut);
          T.assert( 0==rc, "expecting value_blob_v2() rc 0 but got "+rc );
          return sv;
        };
        next.n = 0;
        const cmp = (byteList)=>{
          const blob = wasm.peekPtr(ppOut);
          const len = wasm.peek32(pnOut);

          T.assert(len === byteList.length, "Lengths don't match: "
                  +len +" != " + byteList.length)





          for( let i = 0; i < len; ++i ){
            T.assert( byteList[i] === wasm.peek8(blob+i),
                      "mismatch at offset "+i+": "+byteList[i]
                      +"!=="+wasm.peek8(blob+i) );
          }
        };
        const cmp2 = (byteList)=>{
          next();
          cmp(byteList);
          clearPtrs();
          const rc = capi.sqlite3_column_blob_v2(q, 1, ppOut, pnOut);
          T.assert( 0==rc, "expecting column_blob_v2() rc 0 but got "+rc);
          cmp(byteList);
        };

        cmp2([49,50,51]); // 123
        cmp2([]); // null
        T.assert( !wasm.peekPtr(ppOut), "Expecting NULL in row "+next.n);
        cmp2([104,105]); // "hi"
        cmp2([0x23, 0, 0x2a]); // X'23002A'
        cmp2([]) /* length-0 blob */;

        T.assert( wasm.peekPtr(ppOut), "Expecting non-NULL in row "+next.n);

        /** Tests which cover the same code paths for both text_v2 and
            blob_v2 are in the previous test group. */

      }finally{
        if( q ) q.finalize();
        db.close();
Changes to src/sqlite.h.in.
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
** and the second argument is the index of the column for which information
** should be returned. ^The leftmost column of the result set has the index 0.
** ^The number of columns in the result can be determined using
** [sqlite3_column_count()].
**
** ^The sqlite3_column_text_v2() and sqlite3_column_blob_v2()
** interfaces deliver most of their output via their 3rd, 4th, and 5th
** output-pointer arguments. The 3rd is an output pointer to the
** resulting memory (the same pointer which would be returned by their
** non-v2 counterparts). The 4th is an integer pointer into which, if
** it is not NULL, the length of the memory, in bytes, is written. The
** 5th argument is an integer pointer which, if not NULL, gets set to
** the [SQLITE_INTEGER | column's SQL type]. On success these
** interfaces return 0. On error they do not modify any of their
** output pointers and return SQLITE_NOMEM on allocation error and
** SQLITE_RANGE if the given column index is out of range. Results are
** undefined if either of their 1st or 3rd arguments are NULL.
**
** If the SQL statement does not currently point to a valid row, or if the
** column index is out of range, the result is undefined.
** These routines may only be called when the most recent call to
** [sqlite3_step()] has returned [SQLITE_ROW] and neither
** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
** If any of these routines are called after [sqlite3_reset()] or
** [sqlite3_finalize()] or after [sqlite3_step()] has returned
** something other than [SQLITE_ROW], the results are undefined.
** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
** are called from a different thread while any of these routines
** are pending, then the results are undefined.
**
** The interfaces (_blob, _double, _int, _int64, _text, and _text16)
** each return the value of a result column in a specific data format.  If
** the result column is not initially in the requested format (for example,
** if the query returns an integer but the sqlite3_column_text() interface
** is used to extract the value) then an automatic type conversion is performed.
**
** ^The interfaces (_text_v2, _blob_v2) interally function identically
** to their non-_v2 counterparts but have different interfaces. Their
** internal behaviors are the same for purposes of the following
** documentation except where specifically noted otherwise.
**
** ^The sqlite3_column_type() routine returns the
** [SQLITE_INTEGER | datatype code] for the initial data type
** of the result column.  ^The returned value is one of [SQLITE_INTEGER],
** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
** The return value of sqlite3_column_type() can be used to decide which
** of the first six interface should be used to extract the column value.







<
<
<
<
<
<
<
<
<
<
<
<
<


















|
|
|
|







5285
5286
5287
5288
5289
5290
5291













5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
** and the second argument is the index of the column for which information
** should be returned. ^The leftmost column of the result set has the index 0.
** ^The number of columns in the result can be determined using
** [sqlite3_column_count()].
**













** If the SQL statement does not currently point to a valid row, or if the
** column index is out of range, the result is undefined.
** These routines may only be called when the most recent call to
** [sqlite3_step()] has returned [SQLITE_ROW] and neither
** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
** If any of these routines are called after [sqlite3_reset()] or
** [sqlite3_finalize()] or after [sqlite3_step()] has returned
** something other than [SQLITE_ROW], the results are undefined.
** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
** are called from a different thread while any of these routines
** are pending, then the results are undefined.
**
** The interfaces (_blob, _double, _int, _int64, _text, and _text16)
** each return the value of a result column in a specific data format.  If
** the result column is not initially in the requested format (for example,
** if the query returns an integer but the sqlite3_column_text() interface
** is used to extract the value) then an automatic type conversion is performed.
**
** ^The (_blob_v2, _text_v2) interfaces behave like
** sqlite3_value_blob_v2() and sqlite3_value_text_v2(), with one
** exception: they return SQLITE_RANGE if the column index is out of
** bounds.
**
** ^The sqlite3_column_type() routine returns the
** [SQLITE_INTEGER | datatype code] for the initial data type
** of the result column.  ^The returned value is one of [SQLITE_INTEGER],
** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
** The return value of sqlite3_column_type() can be used to decide which
** of the first six interface should be used to extract the column value.
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
** other SQLite interface is called on the same [database connection].
**
** The previous paragraph does not apply to the text_v2 and blob_v2
** interfaces, which return SQLITE_NOMEM to the client for
** out-of-memory conditions.
*/
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_blob_v2(sqlite3_stmt*, int iCol, const void **, int*, int*);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
int sqlite3_column_text_v2(sqlite3_stmt*, int iCol, const unsigned char **, int*, int*);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);

/*







|




|







5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
** other SQLite interface is called on the same [database connection].
**
** The previous paragraph does not apply to the text_v2 and blob_v2
** interfaces, which return SQLITE_NOMEM to the client for
** out-of-memory conditions.
*/
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_blob_v2(sqlite3_stmt*, int iCol, const void **, int*);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
int sqlite3_column_text_v2(sqlite3_stmt*, int iCol, const unsigned char **, int*);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);

/*
5949
5950
5951
5952
5953
5954
5955










5956
5957
5958
5959
5960
5961
5962
** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
** Other interfaces might change the datatype for an sqlite3_value object.
** For example, if the datatype is initially SQLITE_INTEGER and
** sqlite3_value_text(V) is called to extract a text value for that
** integer, then subsequent calls to sqlite3_value_type(V) might return
** SQLITE_TEXT.  Whether or not a persistent internal datatype conversion
** occurs is undefined and may change from one release of SQLite to the next.










**
** ^(The sqlite3_value_numeric_type() interface attempts to apply
** numeric affinity to the value.  This means that an attempt is
** made to convert the value to an integer or floating point.  If
** such a conversion is possible without loss of information (in other
** words, if the value is a string that looks like a number)
** then the conversion is performed.  Otherwise no conversion occurs.







>
>
>
>
>
>
>
>
>
>







5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
** Other interfaces might change the datatype for an sqlite3_value object.
** For example, if the datatype is initially SQLITE_INTEGER and
** sqlite3_value_text(V) is called to extract a text value for that
** integer, then subsequent calls to sqlite3_value_type(V) might return
** SQLITE_TEXT.  Whether or not a persistent internal datatype conversion
** occurs is undefined and may change from one release of SQLite to the next.
**
** ^sqlite3_value_blob_v2() and sqlite3_value_text_v2() interfaces
** return their content via their 2nd and 3rd arguments, output
** pointers. They behave the same as their "v1" counterparts with one
** exception: sqlite3_value_blob_v2() resolves length-0 blobs to an
** opaque non-NULL pointer instead of NULL. Their 3rd argument, if not
** NULL, will get the length of the returned blob assigned to it. If
** these functions fail they return non-0 and do not modify their
** output pointers. On success they return 0 and will update their 2nd
** and (if not NULL) 3rd output pointer arguments.
**
** ^(The sqlite3_value_numeric_type() interface attempts to apply
** numeric affinity to the value.  This means that an attempt is
** made to convert the value to an integer or floating point.  If
** such a conversion is possible without loss of information (in other
** words, if the value is a string that looks like a number)
** then the conversion is performed.  Otherwise no conversion occurs.
5977
5978
5979
5980
5981
5982
5983
5984

5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
**
** ^The sqlite3_value_frombind(X) interface returns non-zero if the
** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
** interfaces.  ^If X comes from an SQL literal value, or a table column,
** or an expression, then sqlite3_value_frombind(X) returns zero.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or

** [sqlite3_value_text16()] can be invalidated by a subsequent call to
** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
** or [sqlite3_value_text16()].
**
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
**
** As long as the input parameter is correct, these routines can only
** fail if an out-of-memory error occurs during a format conversion.
** Only the following subset of interfaces are subject to out-of-memory







|
>


|







5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
**
** ^The sqlite3_value_frombind(X) interface returns non-zero if the
** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
** interfaces.  ^If X comes from an SQL literal value, or a table column,
** or an expression, then sqlite3_value_frombind(X) returns zero.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_blob_v2()],
** [sqlite3_value_text()], [sqlite3_value_text_v2()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
** [sqlite3_value_text_v2()], or [sqlite3_value_text16()].
**
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
**
** As long as the input parameter is correct, these routines can only
** fail if an out-of-memory error occurs during a format conversion.
** Only the following subset of interfaces are subject to out-of-memory
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
** other SQLite interface is called on the same [database connection].
**
** The previous paragraph does not apply to the text_v2 and blob_v2
** interfaces, which return SQLITE_NOMEM to the client for
** out-of-memory conditions.
*/
const void *sqlite3_value_blob(sqlite3_value*);
int sqlite3_value_blob_v2(sqlite3_value*, const void **, int*, int*);
double sqlite3_value_double(sqlite3_value*);
int sqlite3_value_int(sqlite3_value*);
sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
void *sqlite3_value_pointer(sqlite3_value*, const char*);
const unsigned char *sqlite3_value_text(sqlite3_value*);
int sqlite3_value_text_v2(sqlite3_value*, const unsigned char **, int*, int*);
const void *sqlite3_value_text16(sqlite3_value*);
const void *sqlite3_value_text16le(sqlite3_value*);
const void *sqlite3_value_text16be(sqlite3_value*);
int sqlite3_value_bytes(sqlite3_value*);
int sqlite3_value_bytes16(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);







|





|







6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
** other SQLite interface is called on the same [database connection].
**
** The previous paragraph does not apply to the text_v2 and blob_v2
** interfaces, which return SQLITE_NOMEM to the client for
** out-of-memory conditions.
*/
const void *sqlite3_value_blob(sqlite3_value*);
int sqlite3_value_blob_v2(sqlite3_value*, const void **, int*);
double sqlite3_value_double(sqlite3_value*);
int sqlite3_value_int(sqlite3_value*);
sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
void *sqlite3_value_pointer(sqlite3_value*, const char*);
const unsigned char *sqlite3_value_text(sqlite3_value*);
int sqlite3_value_text_v2(sqlite3_value*, const unsigned char **, int*);
const void *sqlite3_value_text16(sqlite3_value*);
const void *sqlite3_value_text16le(sqlite3_value*);
const void *sqlite3_value_text16be(sqlite3_value*);
int sqlite3_value_bytes(sqlite3_value*);
int sqlite3_value_bytes16(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);
Changes to src/sqliteInt.h.
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
void sqlite3FileSuffix3(const char*, char*);
#else
# define sqlite3FileSuffix3(X,Y)
#endif
u8 sqlite3GetBoolean(const char *z,u8);

const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueTextV2(sqlite3_value*, u8, const void **, int*, int*);

int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*));
int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
                        void(*)(void*));
void sqlite3ValueSetNull(sqlite3_value*);
void sqlite3ValueFree(sqlite3_value*);







|







5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
void sqlite3FileSuffix3(const char*, char*);
#else
# define sqlite3FileSuffix3(X,Y)
#endif
u8 sqlite3GetBoolean(const char *z,u8);

const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueTextV2(sqlite3_value*, u8, const void **, int*);

int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*));
int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
                        void(*)(void*));
void sqlite3ValueSetNull(sqlite3_value*);
void sqlite3ValueFree(sqlite3_value*);
Changes to src/test1.c.
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
    Tcl_WrongNumArgs(interp, 1, objv, "STMT column");
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;

  rc = sqlite3_column_blob_v2(pStmt, col, &pBlob, &len, 0);
  if( rc ) return TCL_ERROR;
  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
  return TCL_OK;
}

/*
** Usage: sqlite3_column_double STMT column







|







5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
    Tcl_WrongNumArgs(interp, 1, objv, "STMT column");
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;

  rc = sqlite3_column_blob_v2(pStmt, col, &pBlob, &len);
  if( rc ) return TCL_ERROR;
  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
  return TCL_OK;
}

/*
** Usage: sqlite3_column_double STMT column
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "STMT column");
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
  if( sqlite3_column_text_v2(pStmt, col, &zRet, &len, 0) ){
    return TCL_ERROR;
  }
  if( zRet ){
    Tcl_SetResult(interp, (char *)zRet, 0);
  }
  return TCL_OK;
}







|







5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "STMT column");
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
  if( sqlite3_column_text_v2(pStmt, col, &zRet, &len) ){
    return TCL_ERROR;
  }
  if( zRet ){
    Tcl_SetResult(interp, (char *)zRet, 0);
  }
  return TCL_OK;
}
Changes to src/vdbeapi.c.
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    }
    p->flags |= MEM_Blob;
    return p->n ? p->z : 0;
  }else{
    return sqlite3_value_text(pVal);
  }
}
int sqlite3_value_blob_v2(sqlite3_value *pVal, const void **pOut,
                          int *pnOut, int *pType){
  Mem *p = (Mem*)pVal;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVal==0 || pOut==0 ) return SQLITE_MISUSE_BKPT;
#endif
  if( p->flags & (MEM_Blob|MEM_Str) ){
    if( ExpandBlob(p)!=SQLITE_OK ){
      assert( p->flags==MEM_Null && p->z==0 );
      return SQLITE_NOMEM_BKPT;
    }
    p->flags |= MEM_Blob;
    *pOut = p->n ? p->z : 0;
    if( pnOut ) *pnOut = p->n;
    if( pType ) *pType = sqlite3_value_type(pVal);
    return 0;
  }
  return sqlite3_value_text_v2(pVal, (const unsigned char **)pOut,
                               pnOut, pType);
}
int sqlite3_value_bytes(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
int sqlite3_value_bytes16(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}







|
|

>









|

<


|
<







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211

212
213
214
215
216
217
218
    }
    p->flags |= MEM_Blob;
    return p->n ? p->z : 0;
  }else{
    return sqlite3_value_text(pVal);
  }
}
int sqlite3_value_blob_v2(sqlite3_value *pVal, const void **pOut, int *pnOut){
  static const unsigned char aZeroLength[] = {0,0};
  Mem *p = (Mem*)pVal;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVal==0 || pOut==0 ) return SQLITE_MISUSE_BKPT;
#endif
  if( p->flags & (MEM_Blob|MEM_Str) ){
    if( ExpandBlob(p)!=SQLITE_OK ){
      assert( p->flags==MEM_Null && p->z==0 );
      return SQLITE_NOMEM_BKPT;
    }
    p->flags |= MEM_Blob;
    *pOut = p->n ? p->z : (const void *)&aZeroLength[0];
    if( pnOut ) *pnOut = p->n;

    return 0;
  }
  return sqlite3_value_text_v2(pVal, (const unsigned char **)pOut, pnOut);

}
int sqlite3_value_bytes(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
int sqlite3_value_bytes16(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
  }else{
    return 0;
  }
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
  return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
int sqlite3_value_text_v2(sqlite3_value *pVal,
                          const unsigned char **pOut,
                          int *pnOut, int *pType){
  int n = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVal==0 || pOut==0 ) return SQLITE_MISUSE_BKPT;
#endif
  return sqlite3ValueTextV2(pVal, SQLITE_UTF8, (const void **)pOut,
                            pnOut ? pnOut : &n, pType);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
const void *sqlite3_value_text16be(sqlite3_value *pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16BE);







|
<
|





|







241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
  }else{
    return 0;
  }
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
  return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
int sqlite3_value_text_v2(sqlite3_value *pVal, const unsigned char **pOut,

                          int *pnOut){
  int n = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVal==0 || pOut==0 ) return SQLITE_MISUSE_BKPT;
#endif
  return sqlite3ValueTextV2(pVal, SQLITE_UTF8, (const void **)pOut,
                            pnOut ? pnOut : &n);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
const void *sqlite3_value_text16be(sqlite3_value *pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16BE);
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
**
** If bBlob is true, sqlite3_value_blob_v2() is used for the
** extraction, else sqlite3_value_text_v2() is used.
**
** This is expected to only be called by sqlite3_column_blob_v2(),
** sqlite3_column_text_v2(), or APIs with similar semantics.
**
** Design notes: per /chat discussion:
**
** sqlite3_column_text/blob_v2() can report SQLITE_RANGE and
** SQLITE_MISUSE, but must not perist those errors and must not take
** prior error state into account (e.g. do not propagate a
** SQLITE_RANGE error across calls). They unavoidably persist
** SQLITE_NOMEM errors via deeper APIs. This routine specifically does
** not call columnMallocFailure() to avoid calling sqlite3ApiExit().
*/
static int columnMemV2(sqlite3_stmt *pStmt, int iCol, int bBlob,
                       const void **pOut, int * pnOut, int *pType){
  int rc = 0;
  Vdbe * const pVm = (Vdbe*)pStmt;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVm==0 || pOut==0 ) return SQLITE_MISUSE_BKPT;
#endif
  assert( pVm->db );
  sqlite3_mutex_enter(pVm->db->mutex);
  if( pVm->pResultRow!=0 && iCol<pVm->nResColumn && iCol>=0 ){
    Mem * const pMem = &pVm->pResultRow[iCol];
    rc = bBlob
      ? sqlite3_value_blob_v2(pMem, pOut, pnOut, pType)
      : sqlite3_value_text_v2(pMem, (const unsigned char **)pOut,
                              pnOut, pType);
  }else{
    rc = pVm->pResultRow==0 ? SQLITE_MISUSE_BKPT : SQLITE_RANGE;
  }
  sqlite3_mutex_leave(pVm->db->mutex);
  return rc;
}








|









|











|

|







1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
**
** If bBlob is true, sqlite3_value_blob_v2() is used for the
** extraction, else sqlite3_value_text_v2() is used.
**
** This is expected to only be called by sqlite3_column_blob_v2(),
** sqlite3_column_text_v2(), or APIs with similar semantics.
**
** Design notes based on /chat discussions:
**
** sqlite3_column_text/blob_v2() can report SQLITE_RANGE and
** SQLITE_MISUSE, but must not perist those errors and must not take
** prior error state into account (e.g. do not propagate a
** SQLITE_RANGE error across calls). They unavoidably persist
** SQLITE_NOMEM errors via deeper APIs. This routine specifically does
** not call columnMallocFailure() to avoid calling sqlite3ApiExit().
*/
static int columnMemV2(sqlite3_stmt *pStmt, int iCol, int bBlob,
                       const void **pOut, int * pnOut){
  int rc = 0;
  Vdbe * const pVm = (Vdbe*)pStmt;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( pVm==0 || pOut==0 ) return SQLITE_MISUSE_BKPT;
#endif
  assert( pVm->db );
  sqlite3_mutex_enter(pVm->db->mutex);
  if( pVm->pResultRow!=0 && iCol<pVm->nResColumn && iCol>=0 ){
    Mem * const pMem = &pVm->pResultRow[iCol];
    rc = bBlob
      ? sqlite3_value_blob_v2(pMem, pOut, pnOut)
      : sqlite3_value_text_v2(pMem, (const unsigned char **)pOut,
                              pnOut);
  }else{
    rc = pVm->pResultRow==0 ? SQLITE_MISUSE_BKPT : SQLITE_RANGE;
  }
  sqlite3_mutex_leave(pVm->db->mutex);
  return rc;
}

1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
  ** need to call malloc() to expand the result of a zeroblob()
  ** expression.
  */
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_blob_v2(sqlite3_stmt *pStmt, int iCol,
                           const void **pOut, int *pnOut, int *pType){
  return columnMemV2(pStmt, iCol, 1, pOut, pnOut, pType);
}
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
  int val = sqlite3_value_bytes( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){







|
|







1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
  ** need to call malloc() to expand the result of a zeroblob()
  ** expression.
  */
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_blob_v2(sqlite3_stmt *pStmt, int iCol,
                           const void **pOut, int *pnOut){
  return columnMemV2(pStmt, iCol, 1, pOut, pnOut);
}
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
  int val = sqlite3_value_bytes( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
}
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
  const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_text_v2(sqlite3_stmt *pStmt, int iCol,
                           const unsigned char **pOut, int *pnOut,
                           int *pType){
  return columnMemV2(pStmt, iCol, 0, (const void **)pOut, pnOut, pType);
}
sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
  Mem *pOut = columnMem(pStmt, i);
  if( pOut->flags&MEM_Static ){
    pOut->flags &= ~MEM_Static;
    pOut->flags |= MEM_Ephem;
  }







|
<
|







1479
1480
1481
1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493
1494
}
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
  const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_text_v2(sqlite3_stmt *pStmt, int iCol,
                           const unsigned char **pOut, int *pnOut){

  return columnMemV2(pStmt, iCol, 0, (const void **)pOut, pnOut);
}
sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
  Mem *pOut = columnMem(pStmt, i);
  if( pOut->flags&MEM_Static ){
    pOut->flags &= ~MEM_Static;
    pOut->flags |= MEM_Ephem;
  }
Changes to src/vdbemem.c.
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
  }
}

/*
** This works like valueToText() but returns its result using
** different semantics. On success, return 0, set *pOut to a
** zero-terminated version of that string, and set *pnOut (which must
** not be NULL to the string-length of that memory. If pType is not
** NULL, it will be set to the sqlite3_value_type() of pVal.
**
** On error, return non-0 and do not modify pOut, pnOut, or pType.
**
** Maintenance note: this is almost a copy/paste clone of
** valueToText(), but the two should probably not be consolidated. The
** initial version of this API did so in [730c6a623e29b59b] and the
** CPU cycles doubled.
*/
static SQLITE_NOINLINE int valueToTextV2(sqlite3_value* pVal, u8 enc,
                                         const void **pOut, int *pnOut,
                                         int *pType){
  assert( pVal!=0 );
  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
  assert( !sqlite3VdbeMemIsRowSet(pVal) );
  assert( (pVal->flags & (MEM_Null))==0 );
  assert( pOut!=0 );
  assert( pnOut!=0 );







|
<

|







|
<







1356
1357
1358
1359
1360
1361
1362
1363

1364
1365
1366
1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
  }
}

/*
** This works like valueToText() but returns its result using
** different semantics. On success, return 0, set *pOut to a
** zero-terminated version of that string, and set *pnOut (which must
** not be NULL to the string-length of that memory.

**
** On error, return non-0 and do not modify pOut or pnOut.
**
** Maintenance note: this is almost a copy/paste clone of
** valueToText(), but the two should probably not be consolidated. The
** initial version of this API did so in [730c6a623e29b59b] and the
** CPU cycles doubled.
*/
static SQLITE_NOINLINE int valueToTextV2(sqlite3_value* pVal, u8 enc,
                                         const void **pOut, int *pnOut){

  assert( pVal!=0 );
  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
  assert( !sqlite3VdbeMemIsRowSet(pVal) );
  assert( (pVal->flags & (MEM_Null))==0 );
  assert( pOut!=0 );
  assert( pnOut!=0 );
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
  }
  assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
              || pVal->db->mallocFailed );
  if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
    assert( sqlite3VdbeMemValidStrRep(pVal) );
    *pOut = pVal->z;
    *pnOut = pVal->n;
    if( pType ) *pType = sqlite3_value_type(pVal);
    return 0;
  }
  return (pVal->db && pVal->db->mallocFailed)
    ? SQLITE_NOMEM_BKPT
    : SQLITE_ERROR;
}








<







1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
  }
  assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
              || pVal->db->mallocFailed );
  if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
    assert( sqlite3VdbeMemValidStrRep(pVal) );
    *pOut = pVal->z;
    *pnOut = pVal->n;

    return 0;
  }
  return (pVal->db && pVal->db->mallocFailed)
    ? SQLITE_NOMEM_BKPT
    : SQLITE_ERROR;
}

1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
}

/* This works similarly to sqlite3ValueText() but returns its result
** with different semantics.
**
** On success, returns 0, sets *pOut to the underlying value (or NULL
** in the case of NULL), and sets *pnOut to the memory's usable
** length. If *pType is not NULL, it is set to the
** sqlite3_value_type() of pVal. On error, neither *pOut nor *pnOut
** nor *pType are modified.
**
** Results are undefined if pVal, pOut, or pnOut are NULL. pType may
** be NULL.
*/
int sqlite3ValueTextV2(sqlite3_value* pVal, u8 enc, const void **pOut,
                       int *pnOut, int *pType){
  /*if( !pVal ) return SQLITE_MISUSE_BKPT;*/
  assert( pVal!=0 );
  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
  assert( !sqlite3VdbeMemIsRowSet(pVal) );
  assert( pOut!=0 );
  assert( pnOut!=0 );
  if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
    assert( sqlite3VdbeMemValidStrRep(pVal) );
    *pOut = pVal->z;
    *pnOut = pVal->n;
    if( pType ) *pType = sqlite3_value_type( pVal );
    return 0;
  }
  if( pVal->flags&MEM_Null ){
    *pOut = 0;
    *pnOut = 0;
    if( pType ) *pType = sqlite3_value_type( pVal );
    return 0;
  }
  return valueToTextV2(pVal, enc, pOut, pnOut, pType);
}

/* Return true if sqlit3_value object pVal is a string or blob value
** that uses the destructor specified in the second argument.
**
** TODO:  Maybe someday promote this interface into a published API so
** that third-party extensions can get access to it?







<
|
<

|
<


|











<





<


|







1438
1439
1440
1441
1442
1443
1444

1445

1446
1447

1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461

1462
1463
1464
1465
1466

1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
}

/* This works similarly to sqlite3ValueText() but returns its result
** with different semantics.
**
** On success, returns 0, sets *pOut to the underlying value (or NULL
** in the case of NULL), and sets *pnOut to the memory's usable

** length. On error, neither *pOut nor *pnOut are modified.

**
** Results are undefined if pVal, pOut, or pnOut are NULL.

*/
int sqlite3ValueTextV2(sqlite3_value* pVal, u8 enc, const void **pOut,
                       int *pnOut){
  /*if( !pVal ) return SQLITE_MISUSE_BKPT;*/
  assert( pVal!=0 );
  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
  assert( !sqlite3VdbeMemIsRowSet(pVal) );
  assert( pOut!=0 );
  assert( pnOut!=0 );
  if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
    assert( sqlite3VdbeMemValidStrRep(pVal) );
    *pOut = pVal->z;
    *pnOut = pVal->n;

    return 0;
  }
  if( pVal->flags&MEM_Null ){
    *pOut = 0;
    *pnOut = 0;

    return 0;
  }
  return valueToTextV2(pVal, enc, pOut, pnOut);
}

/* Return true if sqlit3_value object pVal is a string or blob value
** that uses the destructor specified in the second argument.
**
** TODO:  Maybe someday promote this interface into a published API so
** that third-party extensions can get access to it?