/ Check-in [94434a25]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 94434a252f0f2b57f325fd8fb82534f20cc1340ff13076cd88deeb47740ef6a2
User & Date: drh 2017-08-09 19:27:24
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: dcdf0913 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: a6256980 user: dan tags: reuse-schema
19:27
Various bug fixes for the new LSM1 virtual table design. check-in: 94434a25 user: drh tags: trunk
18:40
Work toward redesigning the interface to the LSM1 virtual table. check-in: 313df946 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs 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
...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
...
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
...
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
** 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>

................................................................................
*/
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,
................................................................................
      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;
................................................................................
    }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;
  }







|
|
>







 







|







 







|
|
|
|
|




>



>







 







>
|






|










|
<
<
<
<
|
|



|

|



|

|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
...
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
...
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
** 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>

................................................................................
*/
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,
................................................................................
      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;
................................................................................
    }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;