SQLite

Check-in [36693a5cb7]
Login

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

Overview
Comment:Add a new zErrMsg field to the sqlite3_vtab structure to support returning error messages from virtual table constructors. This change means that virtual table implementations compiled as loadable extensions for version 3.3.7 will need to be recompile for version 3.3.8 and will not be usable by both versions at one. The virtual table mechanism is still considered experimental so we feel justified in breaking backwards compatibility in this way. Additional interface changes might occurs in the future. (CVS 3401)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 36693a5cb72b4363010f9ab0866e1f7865f65275
User & Date: drh 2006-09-10 17:08:30.000
Context
2006-09-10
17:31
Add pzErr parameters to the xConnect and xCreate methods of virtual tables in order to provide better error reporting. This is an interface change for virtual tables. Prior virtual table implementations will need to be modified and recompiled. (CVS 3402) (check-in: f44b8bae97 user: drh tags: trunk)
17:08
Add a new zErrMsg field to the sqlite3_vtab structure to support returning error messages from virtual table constructors. This change means that virtual table implementations compiled as loadable extensions for version 3.3.7 will need to be recompile for version 3.3.8 and will not be usable by both versions at one. The virtual table mechanism is still considered experimental so we feel justified in breaking backwards compatibility in this way. Additional interface changes might occurs in the future. (CVS 3401) (check-in: 36693a5cb7 user: drh tags: trunk)
03:34
Add some simple test cases for the OR and NOT logic of the fts1 module. Fix lots of bugs discovered while developing these test cases. (CVS 3400) (check-in: 70bcff024b user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/sqlite.h.in.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.189 2006/08/24 14:59:46 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.190 2006/09/10 17:08:30 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
1701
1702
1703
1704
1705
1706
1707










1708
1709
1710
1711

1712
1713
1714
1715
1716
1717
1718

/*
** Every module implementation uses a subclass of the following structure
** to describe a particular instance of the module.  Each subclass will
** be taylored to the specific needs of the module implementation.   The
** purpose of this superclass is to define certain fields that are common
** to all module implementations.










*/
struct sqlite3_vtab {
  const sqlite3_module *pModule;  /* The module for this virtual table */
  int nRef;                       /* Used internally */

  /* Virtual table implementations will typically add additional fields */
};

/* Every module implementation uses a subclass of the following structure
** to describe cursors that point into the virtual table and are used
** to loop through the virtual table.  Cursors are created using the
** xOpen method of the module.  Each module implementation will define







>
>
>
>
>
>
>
>
>
>




>







1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729

/*
** Every module implementation uses a subclass of the following structure
** to describe a particular instance of the module.  Each subclass will
** be taylored to the specific needs of the module implementation.   The
** purpose of this superclass is to define certain fields that are common
** to all module implementations.
**
** Virtual tables methods can set an error message by assigning a
** string obtained from sqlite3_mprintf() to zErrMsg.  The method should
** take care that any prior string is freed by a call to sqlite3_free()
** prior to assigning a new string to zErrMsg.  After the error message
** is delivered up to the client application, the string will be automatically
** freed by sqlite3_free() and the zErrMsg field will be zeroed.  Note
** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field
** since virtual tables are commonly implemented in loadable extensions which
** do not have access to sqlite3MPrintf() or sqlite3Free().
*/
struct sqlite3_vtab {
  const sqlite3_module *pModule;  /* The module for this virtual table */
  int nRef;                       /* Used internally */
  char *zErrMsg;                  /* Error message text */
  /* Virtual table implementations will typically add additional fields */
};

/* Every module implementation uses a subclass of the following structure
** to describe cursors that point into the virtual table and are used
** to loop through the virtual table.  Cursors are created using the
** xOpen method of the module.  Each module implementation will define
Changes to src/vtab.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2006 June 10
**
** 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.
**
*************************************************************************
** This file contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.31 2006/09/02 20:57:52 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"

/*
** External API function used to create a new virtual-table module.
*/













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2006 June 10
**
** 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.
**
*************************************************************************
** This file contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.32 2006/09/10 17:08:30 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"

/*
** External API function used to create a new virtual-table module.
*/
55
56
57
58
59
60
61


62
63
64
65
66
67
68
/*
** Unlock a virtual table.  When the last lock is removed,
** disconnect the virtual table.
*/
void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
  pVtab->nRef--;
  if( pVtab->nRef==0 ){


    pVtab->pModule->xDisconnect(pVtab);
  }
}

/*
** Clear any and all virtual-table information from the Table record.
** This routine is called, for example, just before deleting the Table







>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
** Unlock a virtual table.  When the last lock is removed,
** disconnect the virtual table.
*/
void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
  pVtab->nRef--;
  if( pVtab->nRef==0 ){
    sqlite3_free(pVtab->zErrMsg);
    pVtab->zErrMsg = 0;
    pVtab->pModule->xDisconnect(pVtab);
  }
}

/*
** Clear any and all virtual-table information from the Table record.
** This routine is called, for example, just before deleting the Table
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
  Table *pTab,
  Module *pMod,
  int (*xConstruct)(sqlite3*, void *, int, char **, sqlite3_vtab **),
  char **pzErr
){
  int rc;
  int rc2;

  char **azArg = pTab->azModuleArg;
  int nArg = pTab->nModuleArg;
  char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);

  assert( !db->pVTab );
  assert( xConstruct );

  db->pVTab = pTab;
  rc = sqlite3SafetyOff(db);
  assert( rc==SQLITE_OK );
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
  rc2 = sqlite3SafetyOn(db);

  if( rc==SQLITE_OK && pTab->pVtab ){
    pTab->pVtab->pModule = pMod->pModule;
    pTab->pVtab->nRef = 1;
  }

  if( SQLITE_OK!=rc ){





    *pzErr = zErr;
    zErr = 0;

  } else if( db->pVTab ){
    const char *zFormat = "vtable constructor did not declare schema: %s";
    *pzErr = sqlite3MPrintf(zFormat, pTab->zName);
    rc = SQLITE_ERROR;
  } 
  if( rc==SQLITE_OK ){
    rc = rc2;
  }







>












>
|
|
|



>
>
>
>
>
|
|
>
|







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
  Table *pTab,
  Module *pMod,
  int (*xConstruct)(sqlite3*, void *, int, char **, sqlite3_vtab **),
  char **pzErr
){
  int rc;
  int rc2;
  sqlite3_vtab *pVtab;
  char **azArg = pTab->azModuleArg;
  int nArg = pTab->nModuleArg;
  char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);

  assert( !db->pVTab );
  assert( xConstruct );

  db->pVTab = pTab;
  rc = sqlite3SafetyOff(db);
  assert( rc==SQLITE_OK );
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
  rc2 = sqlite3SafetyOn(db);
  pVtab = pTab->pVtab;
  if( rc==SQLITE_OK && pVtab ){
    pVtab->pModule = pMod->pModule;
    pVtab->nRef = 1;
  }

  if( SQLITE_OK!=rc ){
    if( pVtab && pVtab->zErrMsg ){
      *pzErr = sqlite3MPrintf("%s", pVtab->zErrMsg);
      sqlite3_free(pVtab->zErrMsg);
      pVtab->zErrMsg = 0;
    }else{
      *pzErr = zErr;
      zErr = 0;
    }
  }else if( db->pVTab ){
    const char *zFormat = "vtable constructor did not declare schema: %s";
    *pzErr = sqlite3MPrintf(zFormat, pTab->zName);
    rc = SQLITE_ERROR;
  } 
  if( rc==SQLITE_OK ){
    rc = rc2;
  }