SQLite

Check-in [94434a252f]
Login

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

Overview
Comment:Various bug fixes for the new LSM1 virtual table design.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 94434a252f0f2b57f325fd8fb82534f20cc1340ff13076cd88deeb47740ef6a2
User & Date: drh 2017-08-09 19:27:24.812
Context
2017-08-09
22:55
Preserve the error code from xConnect or xCreate methods in virtual table implementations when they are encountered during parsing. (check-in: dcdf091388 user: drh tags: trunk)
20:35
Add experimental sqlite3_open_v2() flag SQLITE_OPEN_REUSE_SCHEMA. For sharing identical in-memory schema objects between connections. (check-in: a625698048 user: dan tags: reuse-schema)
19:27
Various bug fixes for the new LSM1 virtual table design. (check-in: 94434a252f user: drh tags: trunk)
18:40
Work toward redesigning the interface to the LSM1 virtual table. (check-in: 313df94666 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/lsm1/lsm_vtab.c.
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
** values is T/6 and there is no content.  The type-value-0 integer format
** only works for integers in the range of 0 through 40.
**
** There is no content for NULL or type-0 integers.  For BLOB and TEXT
** values, the content is the blob data or the UTF-8 text data.  For
** non-negative integers X, the content is a variable-length integer X*2.
** For negative integers Y, the content is varaible-length integer (1-Y)*2+1.
** For FLOAT values, the content is the variable length encoding of the
** integer with the same bit pattern as the IEEE754 floating point value.

*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include "lsm.h"
#include <assert.h>
#include <string.h>








|
|
>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
** values is T/6 and there is no content.  The type-value-0 integer format
** only works for integers in the range of 0 through 40.
**
** There is no content for NULL or type-0 integers.  For BLOB and TEXT
** values, the content is the blob data or the UTF-8 text data.  For
** non-negative integers X, the content is a variable-length integer X*2.
** For negative integers Y, the content is varaible-length integer (1-Y)*2+1.
** For FLOAT values, the content is the IEEE754 floating point value in
** native byte-order.  This means that FLOAT values will be corrupted when
** database file is moved between big-endian and little-endian machines.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include "lsm.h"
#include <assert.h>
#include <string.h>

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
*/
static int lsm1PutSignedVarint64(u8 *z, sqlite3_int64 v){
  sqlite3_uint64 u;
  if( v>=0 ){
    u = (sqlite3_uint64)v;
    return lsm1PutVarint64(z, u*2);
  }else{
    u = (sqlite3_uint64)(1-v);
    return lsm1PutVarint64(z, u*2+1);
  }
}

/* Decoded a signed varint. */
static int lsm1GetSignedVarint64(
  const unsigned char *z,







|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
*/
static int lsm1PutSignedVarint64(u8 *z, sqlite3_int64 v){
  sqlite3_uint64 u;
  if( v>=0 ){
    u = (sqlite3_uint64)v;
    return lsm1PutVarint64(z, u*2);
  }else{
    u = (sqlite3_uint64)(-1-v);
    return lsm1PutVarint64(z, u*2+1);
  }
}

/* Decoded a signed varint. */
static int lsm1GetSignedVarint64(
  const unsigned char *z,
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
      case SQLITE_INTEGER: {
        sqlite3_int64 v;
        lsm1GetSignedVarint64(zData, nData, &v);
        sqlite3_result_int64(ctx, v);
        break;
      }
      case SQLITE_FLOAT: {
        sqlite3_uint64 v1 = 0;
        double v;
        lsm1GetVarint64(zData, nData, &v1);
        memcpy(&v, &v1, sizeof(v));
        sqlite3_result_double(ctx, v);

        break;
      }
      case SQLITE_TEXT: {
        sqlite3_result_text(ctx, (const char*)zData, nData, SQLITE_TRANSIENT);

      }
      case SQLITE_BLOB: {
        sqlite3_result_blob(ctx, zData, nData, SQLITE_TRANSIENT);

      }
      default: {
         /* A NULL.  Do nothing */
      }
    }
  }
  return SQLITE_OK;







<

|
|
|
>




>



>







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
      case SQLITE_INTEGER: {
        sqlite3_int64 v;
        lsm1GetSignedVarint64(zData, nData, &v);
        sqlite3_result_int64(ctx, v);
        break;
      }
      case SQLITE_FLOAT: {

        double v;
        if( nData==sizeof(v) ){
          memcpy(&v, zData, sizeof(v));
          sqlite3_result_double(ctx, v);
        }
        break;
      }
      case SQLITE_TEXT: {
        sqlite3_result_text(ctx, (const char*)zData, nData, SQLITE_TRANSIENT);
        break;
      }
      case SQLITE_BLOB: {
        sqlite3_result_blob(ctx, zData, nData, SQLITE_TRANSIENT);
        break;
      }
      default: {
         /* A NULL.  Do nothing */
      }
    }
  }
  return SQLITE_OK;
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
    }else{
      pVTab->zErrMsg = sqlite3_mprintf("key must be non-negative");
      return SQLITE_ERROR;
    }
  }
  memset(&val, 0, sizeof(val));
  for(i=0; i<p->nVal; i++){

    u8 eType = sqlite3_value_type(argv[3+i]);
    switch( eType ){
      case SQLITE_NULL: {
        lsm1VblobAppendVarint(&val, SQLITE_NULL);
        break;
      }
      case SQLITE_INTEGER: {
        sqlite3_int64 v = sqlite3_value_int64(argv[3+i]);
        if( v>=0 && v<=240/6 ){
          lsm1VblobAppendVarint(&val, v*6);
        }else{
          int n = lsm1PutSignedVarint64(pSpace, v);
          lsm1VblobAppendVarint(&val, SQLITE_INTEGER + n*6);
          lsm1VblobAppend(&val, pSpace, n);
        }
        break;
      }
      case SQLITE_FLOAT: {
        double r = sqlite3_value_double(argv[3+i]);
        sqlite3_uint64 u;
        int n;
        memcpy(&u, &r, 8);
        n = lsm1PutSignedVarint64(pSpace, u);
        lsm1VblobAppendVarint(&val, SQLITE_FLOAT + n*6);
        lsm1VblobAppend(&val, pSpace, n);
        break;
      }
      case SQLITE_BLOB: {
        int n = sqlite3_value_bytes(argv[3+i]);
        lsm1VblobAppendVarint(&val, n*6 + SQLITE_BLOB);
        lsm1VblobAppend(&val, sqlite3_value_blob(argv[2+i]), n);
        break;
      }
      case SQLITE_TEXT: {
        int n = sqlite3_value_bytes(argv[3+i]);
        lsm1VblobAppendVarint(&val, n*6 + SQLITE_TEXT);
        lsm1VblobAppend(&val, sqlite3_value_text(argv[2+i]), n);
        break;
      }
    }
  }
  if( val.errNoMem ){
    return SQLITE_NOMEM;
  }







>
|






|










|
<
<
<
<
|
|



|

|



|

|







907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933




934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
    }else{
      pVTab->zErrMsg = sqlite3_mprintf("key must be non-negative");
      return SQLITE_ERROR;
    }
  }
  memset(&val, 0, sizeof(val));
  for(i=0; i<p->nVal; i++){
    sqlite3_value *pArg = argv[3+i];
    u8 eType = sqlite3_value_type(pArg);
    switch( eType ){
      case SQLITE_NULL: {
        lsm1VblobAppendVarint(&val, SQLITE_NULL);
        break;
      }
      case SQLITE_INTEGER: {
        sqlite3_int64 v = sqlite3_value_int64(pArg);
        if( v>=0 && v<=240/6 ){
          lsm1VblobAppendVarint(&val, v*6);
        }else{
          int n = lsm1PutSignedVarint64(pSpace, v);
          lsm1VblobAppendVarint(&val, SQLITE_INTEGER + n*6);
          lsm1VblobAppend(&val, pSpace, n);
        }
        break;
      }
      case SQLITE_FLOAT: {
        double r = sqlite3_value_double(pArg);




        lsm1VblobAppendVarint(&val, SQLITE_FLOAT + 8*6);
        lsm1VblobAppend(&val, (u8*)&r, sizeof(r));
        break;
      }
      case SQLITE_BLOB: {
        int n = sqlite3_value_bytes(pArg);
        lsm1VblobAppendVarint(&val, n*6 + SQLITE_BLOB);
        lsm1VblobAppend(&val, sqlite3_value_blob(pArg), n);
        break;
      }
      case SQLITE_TEXT: {
        int n = sqlite3_value_bytes(pArg);
        lsm1VblobAppendVarint(&val, n*6 + SQLITE_TEXT);
        lsm1VblobAppend(&val, sqlite3_value_text(pArg), n);
        break;
      }
    }
  }
  if( val.errNoMem ){
    return SQLITE_NOMEM;
  }
Changes to ext/lsm1/test/lsm1_simple.test.
26
27
28
29
30
31
32
33

34
35

36
37
38
39
40
41
42
  0 a UINT 0 {} 0 
  1 b {} 0 {} 0 
  2 c {} 0 {} 0 
  3 d {} 0 {} 0
}

do_execsql_test 1.1 {
  INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33);

  SELECT * FROM x1;
} {15 11 22 33}


do_catchsql_test 1.2 {
  UPDATE x1 SET d = d+1.0 WHERE a=15;
} {1 {cannot UPDATE}}

do_catchsql_test 1.3 {
  DELETE FROM x1 WHERE a=15;







|
>
|
<
>







26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
  0 a UINT 0 {} 0 
  1 b {} 0 {} 0 
  2 c {} 0 {} 0 
  3 d {} 0 {} 0
}

do_execsql_test 1.1 {
  INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33),(8,'banjo',x'333231',NULL),
      (12,NULL,3.25,-559281390);
  SELECT a, quote(b), quote(c), quote(d) FROM x1;

} {8 'banjo' X'333231' NULL 12 NULL 3.25 -559281390 15 11 22 33}

do_catchsql_test 1.2 {
  UPDATE x1 SET d = d+1.0 WHERE a=15;
} {1 {cannot UPDATE}}

do_catchsql_test 1.3 {
  DELETE FROM x1 WHERE a=15;