SQLite4
Check-in [5aca057cad]
Not logged in

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

Overview
SHA1 Hash:5aca057cad7bef78a357619569b22d7ee0481814
Date: 2014-02-17 09:26:10
User: dan
Comment:Have the bt backend support "PRAGMA page_size".
Tags And Properties
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/bt_main.c

5207
5208
5209
5210
5211
5212
5213








5214






5215
5216
5217
5218
5219
5220
5221
      int *pInt = (int*)pArg;
      ((BtLock*)db->pPager)->nBlksz = *pInt;
      break;
    }

    case BT_CONTROL_PAGESZ: {
      int *pInt = (int*)pArg;








      ((BtLock*)db->pPager)->nPgsz = *pInt;






      break;
    }

  }

  return rc;
}







>
>
>
>
>
>
>
>
|
>
>
>
>
>
>







5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
      int *pInt = (int*)pArg;
      ((BtLock*)db->pPager)->nBlksz = *pInt;
      break;
    }

    case BT_CONTROL_PAGESZ: {
      int *pInt = (int*)pArg;
      if( sqlite4BtPagerFilename(db->pPager, BT_PAGERFILE_DATABASE) ){
        int iCtx;                   /* ControlTransaction() context */
        rc = btControlTransaction(db, &iCtx);
        if( rc==SQLITE4_OK ){
          *pInt = (int)(sqlite4BtPagerDbhdr(db->pPager)->pgsz);
          btControlTransactionDone(db, iCtx);
        }
      }else{
        BtLock *pLock = (BtLock*)db->pPager;
        int nNew = *pInt;
        if( ((nNew-1)&nNew)==0 && nNew>=512 && nNew<=32768 ){
          pLock->nPgsz = nNew;
        }
        *pInt = pLock->nPgsz;
      }
      break;
    }

  }

  return rc;
}

Changes to src/bt_pager.c

1122
1123
1124
1125
1126
1127
1128



1129
1130
1131
1132
1133
1134
1135
  assert( p->iTransactionLevel>=1 );
  *piVal = p->pHdr->iCookie;
  return SQLITE4_OK;
}

const char *sqlite4BtPagerFilename(BtPager *p, int ePagerfile){
  const char *zTail;




  switch( ePagerfile ){
    case BT_PAGERFILE_DATABASE:
      zTail = "";
      break;

    case BT_PAGERFILE_LOG:







>
>
>







1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
  assert( p->iTransactionLevel>=1 );
  *piVal = p->pHdr->iCookie;
  return SQLITE4_OK;
}

const char *sqlite4BtPagerFilename(BtPager *p, int ePagerfile){
  const char *zTail;

  /* If the database file has not yet been opened, return a null pointer. */
  if( p->zFile==0 ) return 0;

  switch( ePagerfile ){
    case BT_PAGERFILE_DATABASE:
      zTail = "";
      break;

    case BT_PAGERFILE_LOG:

Changes to src/kvbt.c

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
249
250
251
252
253
254
255












































256
257
258
259
260
261
262
263



















264
265
266
267
268
269
270
typedef struct KVBtCsr KVBtCsr;

/*
** An instance of an open connection to a bt_db store.  A subclass of KVStore.
*/
struct KVBt {
  KVStore base;                   /* Base class, must be first */
  const char *zFilename;          /* File to open */
  int bOpen;                      /* See above */
  int openrc;                     /* See above */
  bt_db *pDb;                     /* Database handle */
};

/*
** An instance of an open cursor pointing into an LSM store.  A subclass
................................................................................
}

static int btPutMeta(KVStore *pKVStore, unsigned int iVal){
  KVBt *p = (KVBt *)pKVStore;
  assert( p->bOpen==1 );
  return sqlite4BtSetCookie(p->pDb, iVal);
}













































static int btGetMethod(
  sqlite4_kvstore *pKVStore, 
  const char *zMethod, 
  void **ppArg,
  void (**pxFunc)(sqlite4_context *, int, sqlite4_value **),
  void (**pxDestroy)(void *)
){



















  return SQLITE4_NOTFOUND;
}

int sqlite4OpenBtree(
  sqlite4_env *pEnv,              /* The environment to use */
  sqlite4_kvstore **ppKVStore,    /* OUT: New KV store returned here */
  const char *zFilename,          /* Name of database file to open */







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
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
330
331
332
333
typedef struct KVBtCsr KVBtCsr;

/*
** An instance of an open connection to a bt_db store.  A subclass of KVStore.
*/
struct KVBt {
  KVStore base;                   /* Base class, must be first */
  char *zFilename;                /* File to open */
  int bOpen;                      /* See above */
  int openrc;                     /* See above */
  bt_db *pDb;                     /* Database handle */
};

/*
** An instance of an open cursor pointing into an LSM store.  A subclass
................................................................................
}

static int btPutMeta(KVStore *pKVStore, unsigned int iVal){
  KVBt *p = (KVBt *)pKVStore;
  assert( p->bOpen==1 );
  return sqlite4BtSetCookie(p->pDb, iVal);
}

typedef struct BtPragmaCtx BtPragmaCtx;
struct BtPragmaCtx {
  sqlite4_kvstore *pKVStore;
  int ePragma;
};

/*
** Candidate values for BtPragmaCtx.ePragma
*/
#define BTPRAGMA_PAGESZ 1

static void btPragmaDestroy(void *pArg){
  BtPragmaCtx *p = (BtPragmaCtx*)pArg;
  sqlite4_free(p->pKVStore->pEnv, p);
}

static int btPragma(
  sqlite4_context *pCtx, 
  int nVal,
  sqlite4_value **apVal
){
  int rc = SQLITE4_OK;            /* Return code */
  BtPragmaCtx *p = (BtPragmaCtx*)sqlite4_context_appdata(pCtx);
  bt_db *db = ((KVBt*)(p->pKVStore))->pDb;

  switch( p->ePragma ){
    case BTPRAGMA_PAGESZ: {
      int pgsz = -1;
      if( nVal>0 ){
        pgsz = sqlite4_value_int(apVal[0]);
      }
      sqlite4BtControl(db, BT_CONTROL_PAGESZ, (void*)&pgsz);
      sqlite4_result_int(pCtx, pgsz);
      break;
    }

    default:
      assert( 0 );
  }

  return rc;
}


static int btGetMethod(
  sqlite4_kvstore *pKVStore, 
  const char *zMethod, 
  void **ppArg,
  void (**pxFunc)(sqlite4_context *, int, sqlite4_value **),
  void (**pxDestroy)(void*)
){
  struct PragmaMethod {
    const char *zPragma;
    int ePragma;
  } aPragma[] = {
    { "page_size", BTPRAGMA_PAGESZ },
  };
  int i;
  for(i=0; i<ArraySize(aPragma); i++){
    if( sqlite4_stricmp(aPragma[i].zPragma, zMethod)==0 ){
      BtPragmaCtx *pCtx = sqlite4_malloc(pKVStore->pEnv, sizeof(BtPragmaCtx));
      if( pCtx==0 ) return SQLITE4_NOMEM;
      pCtx->ePragma = aPragma[i].ePragma;
      pCtx->pKVStore = pKVStore;
      *ppArg = (void*)pCtx;
      *pxFunc = btPragma;
      *pxDestroy = btPragmaDestroy;
      return SQLITE4_OK;
    }
  }
  return SQLITE4_NOTFOUND;
}

int sqlite4OpenBtree(
  sqlite4_env *pEnv,              /* The environment to use */
  sqlite4_kvstore **ppKVStore,    /* OUT: New KV store returned here */
  const char *zFilename,          /* Name of database file to open */

Changes to test/bt1.test

79
80
81
82
83
84
85
86





































87
88
} {1 1}

do_test 2.2 { 
  hexio_write test.db  8 55555555
  sqlite4 db test.db
  execsql { SELECT * FROM t1 }
} {abcd}






































finish_test









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
} {1 1}

do_test 2.2 { 
  hexio_write test.db  8 55555555
  sqlite4 db test.db
  execsql { SELECT * FROM t1 }
} {abcd}

#-------------------------------------------------------------------------
#
do_test 3.1 {
  reset_db
  execsql {
    PRAGMA page_size = 4096;
    CREATE TABLE t1(x);
  }
  db close
  file size test.db
} {8192}

do_test 3.2 {
  sqlite4 db test.db
  execsql { PRAGMA page_size }
} {1024}

do_test 3.3 {
  execsql { SELECT * FROM t1 }
  execsql { PRAGMA page_size }
} {4096}

do_test 3.4 {
  execsql { PRAGMA page_size = 1024 }
} {4096}

do_test 3.5 {
  db close
  sqlite4 db test.db
  execsql { PRAGMA page_size = 2048 }
} {2048}

do_test 3.6 {
  execsql { SELECT * FROM t1 }
  execsql { PRAGMA page_size }
} {4096}

finish_test

Changes to test/createtab.test

31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
  sqlite4 db test.db

  # Create a table that spans multiple pages.  It is important
  # that part of the database be in pages beyond the root page.
  #
  do_test createtab-$av.1 {
    execsql "PRAGMA auto_vacuum=$av"

    execsql {
      PRAGMA page_size=1024;
      CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
      INSERT INTO t1 VALUES(1, hex(randomblob(200)));
      INSERT INTO t1 VALUES(2, hex(randomblob(200)));
      INSERT INTO t1 VALUES(3, hex(randomblob(200)));
      INSERT INTO t1 VALUES(4, hex(randomblob(200)));
      SELECT count(*) FROM t1;
    }







>

<







31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
  sqlite4 db test.db

  # Create a table that spans multiple pages.  It is important
  # that part of the database be in pages beyond the root page.
  #
  do_test createtab-$av.1 {
    execsql "PRAGMA auto_vacuum=$av"
    execsql { PRAGMA page_size=1024; }
    execsql {

      CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
      INSERT INTO t1 VALUES(1, hex(randomblob(200)));
      INSERT INTO t1 VALUES(2, hex(randomblob(200)));
      INSERT INTO t1 VALUES(3, hex(randomblob(200)));
      INSERT INTO t1 VALUES(4, hex(randomblob(200)));
      SELECT count(*) FROM t1;
    }

Changes to test/tkt-5e10420e8d.test

9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl


do_execsql_test tkt-5e10420e8d.1 {
  PRAGMA page_size = 1024;
  PRAGMA auto_vacuum = incremental;

  CREATE TABLE t1(x);
  CREATE TABLE t2(x);
  CREATE TABLE t3(x);
} {}








>

<







9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

execsql { PRAGMA page_size = 1024 }
do_execsql_test tkt-5e10420e8d.1 {

  PRAGMA auto_vacuum = incremental;

  CREATE TABLE t1(x);
  CREATE TABLE t2(x);
  CREATE TABLE t3(x);
} {}

Changes to test/tkt35xx.test

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
#
# $Id: tkt35xx.test,v 1.4 2009/06/05 17:09:12 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt35xx-1.1 {
  execsql {
    PRAGMA auto_vacuum = 0;
    PRAGMA page_size = 1024;
  }
} {}

# Trigger the problem using explicit rollback.
#
do_test tkt35xx-1.1 {
  execsql {
    PRAGMA auto_vacuum = 0;
................................................................................
# Trigger the problem using statement rollback.
#
db close
delete_file test.db
sqlite4 db test.db
set big [string repeat abcdefghij 22]    ;# 220 byte string
do_test tkt35xx-1.2.1 {

  execsql {
    PRAGMA auto_vacuum = 0;
    PRAGMA page_size = 1024;
    CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
    INSERT INTO t3 VALUES(1, $big);
    INSERT INTO t3 VALUES(2, $big);
    INSERT INTO t3 VALUES(3, $big);
    INSERT INTO t3 VALUES(4, $big);
    CREATE TABLE t4(c, d);
    INSERT INTO t4 VALUES(5, $big);







|
|
<
<







 







>


<







16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
..
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
#
# $Id: tkt35xx.test,v 1.4 2009/06/05 17:09:12 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt35xx-1.1 {
  execsql {  PRAGMA page_size = 1024; }
  execsql { PRAGMA auto_vacuum = 0; }


} {}

# Trigger the problem using explicit rollback.
#
do_test tkt35xx-1.1 {
  execsql {
    PRAGMA auto_vacuum = 0;
................................................................................
# Trigger the problem using statement rollback.
#
db close
delete_file test.db
sqlite4 db test.db
set big [string repeat abcdefghij 22]    ;# 220 byte string
do_test tkt35xx-1.2.1 {
  execsql {  PRAGMA page_size = 1024; }
  execsql {
    PRAGMA auto_vacuum = 0;

    CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
    INSERT INTO t3 VALUES(1, $big);
    INSERT INTO t3 VALUES(2, $big);
    INSERT INTO t3 VALUES(3, $big);
    INSERT INTO t3 VALUES(4, $big);
    CREATE TABLE t4(c, d);
    INSERT INTO t4 VALUES(5, $big);

Changes to test/tkt3918.test

11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
#
# $Id: tkt3918.test,v 1.1 2009/06/17 11:13:28 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt3918.1 {

  execsql {
    PRAGMA page_size = 1024;
    PRAGMA auto_vacuum = incremental;
    CREATE TABLE t1(i, x);
  }
} {}
do_test tkt3918.2 {
  execsql {
    INSERT INTO t1 VALUES(1, randstr(1000,1000));







>

<







11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
#
# $Id: tkt3918.test,v 1.1 2009/06/17 11:13:28 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt3918.1 {
  execsql { PRAGMA page_size = 1024; }
  execsql {

    PRAGMA auto_vacuum = incremental;
    CREATE TABLE t1(i, x);
  }
} {}
do_test tkt3918.2 {
  execsql {
    INSERT INTO t1 VALUES(1, randstr(1000,1000));

Changes to test/tkt3929.test

17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

do_test tkt3929-1.0 {

  execsql {
    PRAGMA page_size = 1024;
    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(a, b);
    CREATE TRIGGER t1_t1 AFTER INSERT ON t1 BEGIN
      UPDATE t1 SET b = 'value: ' || a WHERE t1.rowid = new.rowid;
    END;
  }
} {}







>

<







17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

do_test tkt3929-1.0 {
  execsql { PRAGMA page_size = 1024; }
  execsql {

    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(a, b);
    CREATE TRIGGER t1_t1 AFTER INSERT ON t1 BEGIN
      UPDATE t1 SET b = 'value: ' || a WHERE t1.rowid = new.rowid;
    END;
  }
} {}

Changes to test/trigger9.test

34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
}

proc has_rowdata {sql} {
  expr {[lsearch [execsql "explain $sql"] RowData]>=0}
}

do_test trigger9-1.1 {

  execsql {
    PRAGMA page_size = 1024;
    CREATE TABLE t1(x, y, z);
    INSERT INTO t1 VALUES('1', randstr(10000,10000), '2');
    INSERT INTO t1 VALUES('2', randstr(10000,10000), '4');
    INSERT INTO t1 VALUES('3', randstr(10000,10000), '6');
    CREATE TABLE t2(x);
  }
} {}







>

<







34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
}

proc has_rowdata {sql} {
  expr {[lsearch [execsql "explain $sql"] RowData]>=0}
}

do_test trigger9-1.1 {
  execsql { PRAGMA page_size = 1024; }
  execsql {

    CREATE TABLE t1(x, y, z);
    INSERT INTO t1 VALUES('1', randstr(10000,10000), '2');
    INSERT INTO t1 VALUES('2', randstr(10000,10000), '4');
    INSERT INTO t1 VALUES('3', randstr(10000,10000), '6');
    CREATE TABLE t2(x);
  }
} {}