]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add some tests (and fixes) for virtual tables and the authorization callback. Still...
authordanielk1977 <danielk1977@noemail.net>
Fri, 16 Jun 2006 08:01:02 +0000 (08:01 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 16 Jun 2006 08:01:02 +0000 (08:01 +0000)
FossilOrigin-Name: 9497c66e5533ec143d0efda4a419e4bdf922ae8c

manifest
manifest.uuid
src/auth.c
src/build.c
src/parse.y
src/sqlite.h.in
src/sqliteInt.h
src/tclsqlite.c
src/vtab.c
test/vtab3.test [new file with mode: 0644]

index bbd3c645e3c52d9332f93d5ae54b2ddbf564e347..14f9245d79a95c9911c2425a5d734ea21c4d78b5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Arrange\sfor\ssqlite3_last_insert_rowid()\sto\swork\swith\svirtual\stables.\s(CVS\s3259)
-D 2006-06-16T06:17:47
+C Add\ssome\stests\s(and\sfixes)\sfor\svirtual\stables\sand\sthe\sauthorization\scallback.\sStill\smore\sto\scome.\s(CVS\s3260)
+D 2006-06-16T08:01:03
 F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -33,10 +33,10 @@ F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
 F src/alter.c 451b34fc4eb2475ca76a2e86b21e1030a9428091
 F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
 F src/attach.c 27a31d3b89d7ebb5b358847607b1ec795384123c
-F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
+F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
 F src/btree.c ed343b3dbcbc7da9ac481ef2b98c4239fe6d9629
 F src/btree.h 40055cfc09defd1146bc5b922399c035f969e56d
-F src/build.c a295396a6a5624604c729c3b895902c8b2b1dc5e
+F src/build.c 28208a9049d7bf61f16fcb4bb850406857135953
 F src/callback.c fd9bb39f7ff6b52bad8365617abc61c720640429
 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
 F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
@@ -64,7 +64,7 @@ F src/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c 7ef4c5098b378d81d3687919d9de99ea99bbb6bb
 F src/pager.h 43f32f3847421f7502cfbb66f4eb2302b8033818
-F src/parse.y 14ce6fb228b5a06fd5c10999aed2cbbfafe630a7
+F src/parse.y e0831a269fbbd21414bb367fd0b806569c934683
 F src/pragma.c 27d5e395c5d950931c7ac4fe610e7c2993e2fa55
 F src/prepare.c 6dc945dab34cf97364c661d2b7a12be65d338267
 F src/printf.c 7029e5f7344a478394a02c52837ff296ee1ab240
@@ -72,11 +72,11 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
 F src/select.c 38eda11d950ed5e631ea9054f84a4a8b9e9b39d8
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36
-F src/sqlite.h.in 2fc589cf9b550c5bb8b0bac6414389e2057940d1
+F src/sqlite.h.in 77b42d1bb5deafa04ae156d24cd243c2d75800ac
 F src/sqlite3ext.h fc8647211af0caa9d8e49ab31624b357c1332380
-F src/sqliteInt.h 5eb64f1dd9a8b237d147962bc57637d87e044ff4
+F src/sqliteInt.h 2eb48bd25f5fccce86d80e6872b045ed61b91687
 F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
-F src/tclsqlite.c c03bf44bd9f629d4c8d6545788c647b2e846b523
+F src/tclsqlite.c c408a49ae44525fc69757b4ed39f6ca0f56549a5
 F src/test1.c 40f20775903bc76d3be3e7c026dddcbc221c1cb0
 F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
 F src/test3.c 86e99724ee898b119ed575ef9f98618afe7e5e5d
@@ -104,7 +104,7 @@ F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
 F src/vdbeaux.c 85f2184f536219d3c20c66f1403ef77321d1e715
 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
 F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
-F src/vtab.c 745148c6f83f7c146ce93cc22c6716ff05a246e2
+F src/vtab.c cb5a2b23a241e657a8ee7c2b03574f6afa27214a
 F src/where.c d7c3cc011834882b2d58ebb3a6a1a569ead7ebd7
 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -292,6 +292,7 @@ F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c
 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
 F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5
 F test/vtab1.test a31c323cf158bf7326b3a4af4156b1bdd98cf8a8
+F test/vtab3.test b3ea5dfdc36ba23ba5136928b6c307c5125ababc
 F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
 F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
 F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
@@ -367,7 +368,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P d65d83d38321258a7bb8c38f4b2657650b0f1033
-R cbf7f69fafe0127b012e719eed74f4d3
+P afa39a46320e9996a5478ea6e19eb4c2014327ac
+R e864f985538904b7098e2d0d1765152d
 U danielk1977
-Z 33e3dbe7c063b046d5656223c8b15932
+Z b35d7828e5c540d613e21e95c6dfce99
index a45225230e89d4a74c38dab64449d87e4de53641..0b1a8c6b44cbfe2cb950d6267d4d2f93463fce94 100644 (file)
@@ -1 +1 @@
-afa39a46320e9996a5478ea6e19eb4c2014327ac
\ No newline at end of file
+9497c66e5533ec143d0efda4a419e4bdf922ae8c
\ No newline at end of file
index 964ae66a6352c90680601b19041bba32a9f0b79c..fe05a68af10724d1396099efa16e52629691d5e9 100644 (file)
@@ -14,7 +14,7 @@
 ** systems that do not need this facility may omit it by recompiling
 ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
 **
-** $Id: auth.c,v 1.24 2006/01/13 13:55:45 drh Exp $
+** $Id: auth.c,v 1.25 2006/06/16 08:01:03 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -182,8 +182,10 @@ int sqlite3AuthCheck(
   sqlite3 *db = pParse->db;
   int rc;
 
-  /* Don't do any authorization checks if the database is initialising. */
-  if( db->init.busy ){
+  /* Don't do any authorization checks if the database is initialising
+  ** or if the parser is being invoked from within sqlite3_declare_vtab.
+  */
+  if( db->init.busy || IN_DECLARE_VTAB ){
     return SQLITE_OK;
   }
 
index 124f9a624778cb31258eab9bc2ee99b5ca14eda3..9f9eea17eed83b09a53fe658e05ef1d19e9a5890 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.401 2006/06/15 07:29:01 danielk1977 Exp $
+** $Id: build.c,v 1.402 2006/06/16 08:01:03 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -711,6 +711,7 @@ void sqlite3StartTable(
   Token *pName2,   /* Second part of the name of the table or view */
   int isTemp,      /* True if this is a TEMP table */
   int isView,      /* True if this is a VIEW */
+  int isVirtual,   /* True if this is a VIRTUAL table */
   int noErr        /* Do nothing if table already exists */
 ){
   Table *pTable;
@@ -774,7 +775,7 @@ void sqlite3StartTable(
         code = SQLITE_CREATE_TABLE;
       }
     }
-    if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
+    if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
       goto begin_table_error;
     }
   }
@@ -862,8 +863,8 @@ void sqlite3StartTable(
     ** The rowid value is needed by the code that sqlite3EndTable will
     ** generate.
     */
-#ifndef SQLITE_OMIT_VIEW
-    if( isView ){
+#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
+    if( isView || isVirtual ){
       sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
     }else
 #endif
@@ -1588,7 +1589,7 @@ void sqlite3CreateView(
     sqlite3SelectDelete(pSelect);
     return;
   }
-  sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0);
+  sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, 0);
   p = pParse->pNewTable;
   if( p==0 || pParse->nErr ){
     sqlite3SelectDelete(pSelect);
@@ -1886,6 +1887,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
     int code;
     const char *zTab = SCHEMA_TABLE(iDb);
     const char *zDb = db->aDb[iDb].zName;
+    const char *zArg2 = 0;
     if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
       goto exit_drop_table;
     }
@@ -1895,6 +1897,9 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
       }else{
         code = SQLITE_DROP_VIEW;
       }
+    }else if( IsVirtual(pTab) ){
+      code = SQLITE_DROP_VTABLE;
+      zArg2 = pTab->pMod->zName;
     }else{
       if( !OMIT_TEMPDB && iDb==1 ){
         code = SQLITE_DROP_TEMP_TABLE;
@@ -1902,7 +1907,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
         code = SQLITE_DROP_TABLE;
       }
     }
-    if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){
+    if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){
       goto exit_drop_table;
     }
     if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
@@ -2231,7 +2236,7 @@ void sqlite3CreateIndex(
   int nExtra = 0;
   char *zExtra;
 
-  if( pParse->nErr || sqlite3MallocFailed() ){
+  if( pParse->nErr || sqlite3MallocFailed() || IN_DECLARE_VTAB ){
     goto exit_create_index;
   }
 
index 9b760ecb10dae94789c03320f672acc9d07637e6..c346b6f78ee2b016f5fd15e83924a411a381166a 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.203 2006/06/13 15:37:26 drh Exp $
+** @(#) $Id: parse.y,v 1.204 2006/06/16 08:01:04 danielk1977 Exp $
 */
 
 // All token codes are small integers with #defines that begin with "TK_"
@@ -126,7 +126,7 @@ cmd ::= ROLLBACK trans_opt.    {sqlite3RollbackTransaction(pParse);}
 //
 cmd ::= create_table create_table_args.
 create_table ::= CREATE temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). {
-   sqlite3StartTable(pParse,&Y,&Z,T,0,E);
+   sqlite3StartTable(pParse,&Y,&Z,T,0,0,E);
 }
 %type ifnotexists {int}
 ifnotexists(A) ::= .              {A = 0;}
index f210bfa425571fc26377ea576aa610a53799d16c..6fefee6a588a303a3c63ae2d7a09eb8ce491d21b 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.178 2006/06/16 06:17:47 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.179 2006/06/16 08:01:04 danielk1977 Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -466,7 +466,8 @@ int sqlite3_set_authorizer(
 #define SQLITE_ALTER_TABLE          26   /* Database Name   Table Name      */
 #define SQLITE_REINDEX              27   /* Index Name      NULL            */
 #define SQLITE_ANALYZE              28   /* Table Name      NULL            */
-
+#define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
+#define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
 
 /*
 ** The return value of the authorization function should be one of the
index f51ead31756962f5dc44cc88d08786dd61048781..bec2be02c5747a15b679d6c6affa8d168db9b6f4 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.506 2006/06/15 04:28:13 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.507 2006/06/16 08:01:04 danielk1977 Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1560,7 +1560,7 @@ void sqlite3RollbackInternalChanges(sqlite3*);
 void sqlite3CommitInternalChanges(sqlite3*);
 Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
 void sqlite3OpenMasterTable(Parse *, int);
-void sqlite3StartTable(Parse*,Token*,Token*,int,int,int);
+void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
 void sqlite3AddColumn(Parse*,Token*);
 void sqlite3AddNotNull(Parse*, int);
 void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
index f988926f423a0545fa4412d19518375cf145decf..896738db0b7fe7a8cb58d59dd99aa339aa5ee418 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.159 2006/06/15 15:59:20 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.160 2006/06/16 08:01:04 danielk1977 Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -543,6 +543,8 @@ static int auth_callback(
     case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
     case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
     case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
+    case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;
+    case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;
     default                       : zCode="????"; break;
   }
   Tcl_DStringInit(&str);
index e870a2b3412697f039c3f1187010ee0a9817b521..2b647b12ea0f3d6a95508c0c2b9b251b827e0b8d 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.13 2006/06/15 07:29:01 danielk1977 Exp $
+** $Id: vtab.c,v 1.14 2006/06/16 08:01:04 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 #include "sqliteInt.h"
@@ -89,22 +89,34 @@ void sqlite3VtabBeginParse(
   Token *pName2,        /* Name of new table or NULL */
   Token *pModuleName    /* Name of the module for the virtual table */
 ){
+  int iDb;              /* The database the table is being created in */
   Table *pTable;        /* The new virtual table */
+  Token *pDummy;        /* Dummy arg for sqlite3TwoPartName() */
 
-  /* TODO: The 5th argument to sqlite3StartTable() - isView - is being 
-  ** passed a true value at present. This prevents sqlite3StartTable()
-  ** from coding OP_CreateTable, which is correct, but causes it
-  ** to invoke the authorization function as if a CREATE VIEW statement
-  ** were attempted, which is incorrect.
-  */
-  sqlite3StartTable(pParse, pName1, pName2, 0, 1, 0);
-
+  sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
   pTable = pParse->pNewTable;
-  if( pTable==0 ) return;
+  if( pTable==0 || pParse->nErr ) return;
+  assert( 0==pTable->pIndex );
+
   pTable->isVirtual = 1;
   pTable->nModuleArg = 0;
   addModuleArgument(pTable, sqlite3NameFromToken(pModuleName));
   pParse->sNameToken.n = pModuleName->z + pModuleName->n - pName1->z;
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+  /* Creating a virtual table invokes the authorization callback twice.
+  ** The first invocation, to obtain permission to INSERT a row into the
+  ** sqlite_master table, has already been made by sqlite3StartTable().
+  ** The second call, to obtain permission to create the table, is made now.
+  */
+  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pDummy);
+  assert( iDb>=0 );
+  if( sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, 
+          pTable->azModuleArg[0], pParse->db->aDb[iDb].zName) 
+  ){
+    return;
+  }
+#endif
 }
 
 /*
diff --git a/test/vtab3.test b/test/vtab3.test
new file mode 100644 (file)
index 0000000..49d12e3
--- /dev/null
@@ -0,0 +1,142 @@
+# 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 implements regression tests for SQLite library.  The
+# focus of this file is the authorisation callback and virtual tables.
+#
+# $Id: vtab3.test,v 1.1 2006/06/16 08:01:04 danielk1977 Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+ifcapable !vtab {
+  finish_test
+  return
+}
+
+set ::auth_fail 0
+set ::auth_log [list]
+set ::auth_filter [list SQLITE_READ SQLITE_UPDATE SQLITE_SELECT SQLITE_PRAGMA]
+
+proc auth {code arg1 arg2 arg3 arg4} {
+  if {[lsearch $::auth_filter $code]>-1} {
+    return SQLITE_OK
+  }
+  lappend ::auth_log $code $arg1 $arg2 $arg3 $arg4
+  incr ::auth_fail -1
+  if {$::auth_fail == 0} {
+    return SQLITE_DENY
+  }
+  return SQLITE_OK
+}
+
+do_test vtab3-1.1 {
+  execsql {
+    CREATE TABLE elephant(
+      name VARCHAR(32), 
+      color VARCHAR(16), 
+      age INTEGER, 
+      UNIQUE(name, color)
+    );
+  }
+} {}
+
+
+do_test vtab3-1.2 {
+  register_echo_module [sqlite3_connection_pointer db]
+  db authorizer ::auth
+  execsql {
+    CREATE VIRTUAL TABLE pachyderm USING echo(elephant);
+  }
+  set ::auth_log
+} [list \
+  SQLITE_INSERT        sqlite_master {}   main {} \
+  SQLITE_CREATE_VTABLE pachyderm     echo main {} \
+]
+
+do_test vtab3-1.3 {
+  set ::auth_log [list]
+  execsql {
+    DROP TABLE pachyderm;
+  }
+  set ::auth_log
+} [list \
+  SQLITE_DELETE        sqlite_master {}   main {} \
+  SQLITE_DROP_VTABLE   pachyderm     echo main {} \
+  SQLITE_DELETE        pachyderm     {}   main {} \
+  SQLITE_DELETE        sqlite_master {}   main {} \
+]
+
+do_test vtab3-1.4 {
+  set ::auth_fail 1
+  catchsql {
+    CREATE VIRTUAL TABLE pachyderm USING echo(elephant);
+  }
+} {1 {not authorized}}
+do_test vtab3-1.5 {
+  execsql {
+    SELECT name FROM sqlite_master WHERE type = 'table';
+  }
+} {elephant}
+
+do_test vtab3-1.5 {
+  set ::auth_fail 2
+  catchsql {
+    CREATE VIRTUAL TABLE pachyderm USING echo(elephant);
+  }
+} {1 {not authorized}}
+do_test vtab3-1.6 {
+  execsql {
+    SELECT name FROM sqlite_master WHERE type = 'table';
+  }
+} {elephant}
+
+do_test vtab3-1.5 {
+  set ::auth_fail 3
+  catchsql {
+    CREATE VIRTUAL TABLE pachyderm USING echo(elephant);
+  }
+} {0 {}}
+do_test vtab3-1.6 {
+  execsql {
+    SELECT name FROM sqlite_master WHERE type = 'table';
+  }
+} {elephant pachyderm}
+
+foreach i [list 1 2 3 4] {
+  set ::auth_fail $i
+  do_test vtab3-1.7.$i.1 {
+    set rc [catch {
+      execsql {DROP TABLE pachyderm;}
+    } msg]
+    if {$msg eq "authorization denied"} {set msg "not authorized"}
+    list $rc $msg
+  } {1 {not authorized}}
+  do_test vtab3-1.7.$i.2 {
+    execsql {
+      SELECT name FROM sqlite_master WHERE type = 'table';
+    }
+  } {elephant pachyderm}
+}
+do_test vtab3-1.8.1 {
+  set ::auth_fail 0
+  catchsql {
+    DROP TABLE pachyderm;
+  }
+} {0 {}}
+do_test vtab3-1.8.2 {
+  execsql {
+    SELECT name FROM sqlite_master WHERE type = 'table';
+  }
+} {elephant}
+
+finish_test
+
+