/ Check-in [eb4f452e]
Login

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

Overview
Comment:Fix an RBU problem causing errors when updating tables with default collation sequences that require quoting (e.g. COLLATE "ICU_root-u-kn-on").
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: eb4f452e354065d610ff57a6a9312ad119b6b0cc467f9dff105f0718bc27ef01
User & Date: dan 2018-03-22 17:13:44
References
2018-03-22
17:17
Fix an RBU problem causing errors when updating tables with default collation sequences that require quoting (e.g. COLLATE "ICU_root-u-kn-on"). Cherrypick of [eb4f452e]. check-in: 5dd61e1c user: dan tags: branch-3.22
Context
2018-03-22
20:35
Add APIs to the sessions module for "rebasing" changesets. check-in: 509506c7 user: dan tags: trunk
17:17
Fix an RBU problem causing errors when updating tables with default collation sequences that require quoting (e.g. COLLATE "ICU_root-u-kn-on"). Cherrypick of [eb4f452e]. check-in: 5dd61e1c user: dan tags: branch-3.22
17:13
Fix an RBU problem causing errors when updating tables with default collation sequences that require quoting (e.g. COLLATE "ICU_root-u-kn-on"). check-in: eb4f452e user: dan tags: trunk
17:02
Fix a test script problem causing rbuvacuum.test to fail when run along with other tests. check-in: 901cb3b6 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added ext/rbu/rbucollate.test.































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 2018 March 22
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
#

source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbucollate

ifcapable !icu_collations {
  finish_test
  return
}

db close
sqlite3_shutdown
sqlite3_config_uri 1
reset_db
 
# Create a simple RBU database. That expects to write to a table:
#
#   CREATE TABLE t1(a PRIMARY KEY, b, c);
#
proc create_rbu1 {filename} {
  forcedelete $filename
  sqlite3 rbu1 $filename  
  rbu1 eval {
    CREATE TABLE data_t1(a, b, c, rbu_control);
    INSERT INTO data_t1 VALUES('a', 'one', 1, 0);
    INSERT INTO data_t1 VALUES('b', 'two', 2, 0);
    INSERT INTO data_t1 VALUES('c', 'three', 3, 0);
  }
  rbu1 close
  return $filename
}

do_execsql_test 1.0 {
  SELECT icu_load_collation('en_US', 'my-collate');
  CREATE TABLE t1(a COLLATE "my-collate" PRIMARY KEY, b, c);
} {{}}

do_test 1.2 {
  create_rbu1 testrbu.db
  sqlite3rbu rbu test.db testrbu.db
  rbu dbMain_eval { SELECT icu_load_collation('en_US', 'my-collate') }
  rbu dbRbu_eval { SELECT icu_load_collation('en_US', 'my-collate') }
  while 1 {
    set rc [rbu step]
    if {$rc!="SQLITE_OK"} break
  }
  rbu close
  db eval { SELECT * FROM t1 }
} {a one 1 b two 2 c three 3}

#forcedelete testrbu.db
finish_test

Changes to ext/rbu/sqlite3rbu.c.

1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
....
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877

    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
      int bKey = sqlite3_column_int(pXInfo, 5);
      if( bKey ){
        int iCid = sqlite3_column_int(pXInfo, 1);
        int bDesc = sqlite3_column_int(pXInfo, 3);
        const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
        zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, 
            iCid, pIter->azTblType[iCid], zCollate
        );
        zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
        zComma = ", ";
      }
    }
    zCols = rbuMPrintf(p, "%z, id INTEGER", zCols);
................................................................................
      );

      if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){
        /* If the target table column is an "INTEGER PRIMARY KEY", add
        ** "PRIMARY KEY" to the imposter table column declaration. */
        zPk = "PRIMARY KEY ";
      }
      zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", 
          zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
          (pIter->abNotNull[iCol] ? " NOT NULL" : "")
      );
      zComma = ", ";
    }

    if( pIter->eType==RBU_PK_WITHOUT_ROWID ){







|







 







|







1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
....
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877

    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
      int bKey = sqlite3_column_int(pXInfo, 5);
      if( bKey ){
        int iCid = sqlite3_column_int(pXInfo, 1);
        int bDesc = sqlite3_column_int(pXInfo, 3);
        const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
        zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, 
            iCid, pIter->azTblType[iCid], zCollate
        );
        zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
        zComma = ", ";
      }
    }
    zCols = rbuMPrintf(p, "%z, id INTEGER", zCols);
................................................................................
      );

      if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){
        /* If the target table column is an "INTEGER PRIMARY KEY", add
        ** "PRIMARY KEY" to the imposter table column declaration. */
        zPk = "PRIMARY KEY ";
      }
      zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s", 
          zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
          (pIter->abNotNull[iCol] ? " NOT NULL" : "")
      );
      zComma = ", ";
    }

    if( pIter->eType==RBU_PK_WITHOUT_ROWID ){

Changes to ext/rbu/test_rbu.c.

77
78
79
80
81
82
83

84
85
86
87
88
89
90
...
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
    {"bp_progress", 2, ""},          /* 5 */
    {"db", 3, "RBU"},                /* 6 */
    {"state", 2, ""},                /* 7 */
    {"progress", 2, ""},             /* 8 */
    {"close_no_error", 2, ""},       /* 9 */
    {"temp_size_limit", 3, "LIMIT"}, /* 10 */
    {"temp_size", 2, ""},            /* 11 */

    {0,0,0}
  };
  int iCmd;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "METHOD");
    return TCL_ERROR;
................................................................................
    case 3: /* savestate */ {
      int rc = sqlite3rbu_savestate(pRbu);
      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
      ret = (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
      break;
    }


    case 4: /* dbMain_eval */ {
      sqlite3 *db = sqlite3rbu_db(pRbu, 0);
      int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0);
      if( rc!=SQLITE_OK ){
        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1));
        ret = TCL_ERROR;
      }
      break;
    }







>







 







>
|
|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    {"bp_progress", 2, ""},          /* 5 */
    {"db", 3, "RBU"},                /* 6 */
    {"state", 2, ""},                /* 7 */
    {"progress", 2, ""},             /* 8 */
    {"close_no_error", 2, ""},       /* 9 */
    {"temp_size_limit", 3, "LIMIT"}, /* 10 */
    {"temp_size", 2, ""},            /* 11 */
    {"dbRbu_eval", 3, "SQL"},        /* 12 */
    {0,0,0}
  };
  int iCmd;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "METHOD");
    return TCL_ERROR;
................................................................................
    case 3: /* savestate */ {
      int rc = sqlite3rbu_savestate(pRbu);
      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
      ret = (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
      break;
    }

    case 12: /* dbRbu_eval */ 
    case 4:  /* dbMain_eval */ {
      sqlite3 *db = sqlite3rbu_db(pRbu, (iCmd==12));
      int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0);
      if( rc!=SQLITE_OK ){
        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1));
        ret = TCL_ERROR;
      }
      break;
    }