/ Check-in [9969cff2]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Fix a problem with creating virtual table with names specified using malformed utf-8 within utf-16 databases.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | malformed-vtab-name
Files: files | file ages | folders
SHA1: 9969cff2d0553c9bfa88a437e1bb0cc4200d49d7
User & Date: dan 2015-03-19 18:56:17
Context
2015-03-19
19:59
Fix a crash that can occur following an OOM condition within a CREATE VIRTUAL TABLE statement on a utf-16 database. Closed-Leaf check-in: 9453e7da user: dan tags: malformed-vtab-name
18:56
Fix a problem with creating virtual table with names specified using malformed utf-8 within utf-16 databases. check-in: 9969cff2 user: dan tags: malformed-vtab-name
16:25
Fix an FTS3/4 problem with handling empty tokenizer declarations (e.g. "CREATE VIRTUAL TABLE t(tokenize=);"). check-in: 26d2def8 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017






6018


6019
6020
6021
6022
6023
6024
6025
  rc = sqlite3VtabBegin(db, pVTab);
  if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 * * P4 *
**
** P4 is the name of a virtual table in database P1. Call the xCreate method
** for that table.
*/
case OP_VCreate: {






  rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);


  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VDestroy P1 * * P4 *
**







|

|
|


>
>
>
>
>
>
|
>
>







6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
  rc = sqlite3VtabBegin(db, pVTab);
  if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 P2 * * *
**
** P2 is a register that holds the name of a virtual table in database 
** P1. Call the xCreate method for that table.
*/
case OP_VCreate: {
  Mem sMem;          /* For storing the record being decoded */
  memset(&sMem, 0, sizeof(sMem));
  sMem.db = db;
  rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]);
  if( rc==SQLITE_OK ){
    const char *zTab = (const char*)sqlite3_value_text(&sMem);
    rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
  }
  sqlite3VdbeMemRelease(&sMem);
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VDestroy P1 * * P4 *
**

Changes to src/vtab.c.

385
386
387
388
389
390
391

392
393
394
395
396
397
398
...
419
420
421
422
423
424
425



426
427
428
429
430
431
432
433
434
  ** do additional initialization work and store the statement text
  ** in the sqlite_master table.
  */
  if( !db->init.busy ){
    char *zStmt;
    char *zWhere;
    int iDb;

    Vdbe *v;

    /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
    if( pEnd ){
      pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
    }
    zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
................................................................................
    sqlite3DbFree(db, zStmt);
    v = sqlite3GetVdbe(pParse);
    sqlite3ChangeCookie(pParse, iDb);

    sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
    zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
    sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);



    sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, 
                         pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
  }

  /* If we are rereading the sqlite_master table create the in-memory
  ** record of the table. The xConnect() method is not called until
  ** the first time the virtual table is used in an SQL statement. This
  ** allows a schema that contains virtual tables to be loaded before
  ** the required virtual table implementations are registered.  */







>







 







>
>
>
|
<







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
...
420
421
422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
  ** do additional initialization work and store the statement text
  ** in the sqlite_master table.
  */
  if( !db->init.busy ){
    char *zStmt;
    char *zWhere;
    int iDb;
    int iReg;
    Vdbe *v;

    /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
    if( pEnd ){
      pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
    }
    zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
................................................................................
    sqlite3DbFree(db, zStmt);
    v = sqlite3GetVdbe(pParse);
    sqlite3ChangeCookie(pParse, iDb);

    sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
    zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
    sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);

    iReg = ++pParse->nMem;
    sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0);
    sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);

  }

  /* If we are rereading the sqlite_master table create the in-memory
  ** record of the table. The xConnect() method is not called until
  ** the first time the virtual table is used in an SQL statement. This
  ** allows a schema that contains virtual tables to be loaded before
  ** the required virtual table implementations are registered.  */

Changes to test/vtab2.test.

6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
...
128
129
130
131
132
133
134
135

















136

#    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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# $Id: vtab2.test,v 1.9 2008/10/13 10:37:50 danielk1977 Exp $

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


ifcapable !vtab||!schema_pragmas {
  finish_test
  return
}

register_schema_module [sqlite3_connection_pointer db]
................................................................................
    UPDATE fkey 
    SET to_col = (SELECT name FROM v_col WHERE tablename = 't1' AND pk);
  }
} {}
do_test vtab2-4.5 {
  execsql { SELECT * FROM fkey }
} {t1 a}


















finish_test








<



>







 








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

>
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#    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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#


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

ifcapable !vtab||!schema_pragmas {
  finish_test
  return
}

register_schema_module [sqlite3_connection_pointer db]
................................................................................
    UPDATE fkey 
    SET to_col = (SELECT name FROM v_col WHERE tablename = 't1' AND pk);
  }
} {}
do_test vtab2-4.5 {
  execsql { SELECT * FROM fkey }
} {t1 a}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 5.1 {
  PRAGMA encoding='UTF16';
}

do_test 5.2 {
  sqlite3_exec_hex db { CREATE VIRTUAL TABLE %C8 USING fts3 }
} {0 {}}

do_test 5.3 {
  sqlite3_exec_hex db { CREATE VIRTUAL TABLE %C9 USING s }
} {/1 {malformed database schema.* already exists}/}



finish_test