]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add further tests for the intck module.
authordan <Dan Kennedy>
Sat, 24 Feb 2024 16:26:15 +0000 (16:26 +0000)
committerdan <Dan Kennedy>
Sat, 24 Feb 2024 16:26:15 +0000 (16:26 +0000)
FossilOrigin-Name: c253e276b29de28a18270d01b60d95157ce3fc4b37e246d991f9119d26e718d7

ext/intck/intck1.test
ext/intck/intckbusy.test [new file with mode: 0644]
ext/intck/sqlite3intck.c
ext/intck/test_intck.c
manifest
manifest.uuid

index 4e86e4f2fc441adaf6d0db28607722378498ef3b..e05ae061662a1b7e6f684a4857171453966dea24 100644 (file)
@@ -200,9 +200,132 @@ reset_db
 do_execsql_test 5.0 {
   CREATE TABLE t1(a, b);             
   CREATE INDEX i1 ON t1(a COLLATE NOCASE);
+  INSERT INTO t1 VALUES(1, 1);
+  INSERT INTO t1 VALUES(2, 2);
 }
 
-#puts [intck_sql db i1]
+do_test 5.1 {
+  set ic [sqlite3_intck db nosuchdb]
+  $ic step
+} {SQLITE_ERROR}
+
+do_test 5.2 {
+  $ic close
+  set ic [sqlite3_intck db {}]
+  while {[$ic step]=="SQLITE_OK"} {}
+  set res [$ic error]
+  $ic close
+  set res
+} {SQLITE_OK {}}
+
+do_test 5.3 { test_do_intck db "main" } {}
+
+do_test 5.4 {
+  set ret {}
+  set ic [sqlite3_intck db main]
+  db eval [$ic test_sql t1] {
+    if {$error_message!=""} { lappend ret $error_message }
+  }
+  $ic close
+  set ret
+} {}
+
+do_test 5.5 {
+  set ret {}
+  set ic [sqlite3_intck db main]
+  db eval [$ic test_sql {}] {
+    if {$error_message!=""} { lappend ret $error_message }
+  }
+  $ic close
+  set ret
+} {}
+
+db cache flush
+
+do_test 5.6 {
+  set ret {}
+  set ic [sqlite3_intck db main]
+  $ic step
+  db eval [$ic test_sql {}] {
+    if {$error_message!=""} { lappend ret $error_message }
+  }
+  $ic close
+  set ret
+} {}
+
+#-------------------------------------------------------------------------
+reset_db
+
+do_execsql_test 6.0 {
+  CREATE TABLE t1(x, y, PRIMARY KEY(x)) WITHOUT ROWID;
+  CREATE INDEX i1 ON t1(y, x);
+  INSERT INTO t1 VALUES(X'0000', X'1111');
+}
+
+do_intck_test 6.1 {}
+
+do_execsql_test 6.2.1 {
+  PRAGMA writable_schema = 1;
+  UPDATE sqlite_schema SET sql = 'CREATE INDEX i1' WHERE name='i1';
+} {}
+do_intck_test 6.2.2 {}
+
+do_execsql_test 6.3.1 {
+  UPDATE sqlite_schema SET sql = 'CREATE INDEX i1(y' WHERE name='i1';
+} {}
+do_intck_test 6.3.2 {}
+
+do_execsql_test 6.4.1 {
+  UPDATE sqlite_schema 
+  SET sql = 'CREATE INDEX i1(y) hello world' 
+  WHERE name='i1';
+} {}
+do_intck_test 6.4.2 {}
+
+do_execsql_test 6.5.1 {
+  UPDATE sqlite_schema 
+  SET sql = 'CREATE INDEX i1(y, x) WHERE 1     ' 
+  WHERE name='i1';
+} {}
+do_intck_test 6.5.2 {}
+
+do_execsql_test 6.6.1 {
+  UPDATE sqlite_schema 
+  SET sql = 'CREATE INDEX i1(  ,  ) WHERE 1     ' 
+  WHERE name='i1';
+} {}
+
+do_test 6.7.2 {
+  set ic [sqlite3_intck db main]
+  $ic step
+} {SQLITE_ERROR}
+do_test 6.5.3 {
+  $ic error
+} {SQLITE_ERROR {near "AS": syntax error}}
+$ic close
+
+do_execsql_test 6.6.1 {
+  UPDATE sqlite_schema 
+  SET sql = 'CREATE INDEX i1([y'
+  WHERE name='i1';
+} {}
+do_intck_test 6.6.2 {}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 7.0 {
+  CREATE TABLE x1("1", "22", "3333", four);
+  CREATE INDEX i1 ON x1(  "1"  , "22", NULL);
+  INSERT INTO x1 VALUES(1, 22, 3333, NULL);
+  INSERT INTO x1 VALUES(1, 22, 3333, NULL);
+}
+do_execsql_test 7.1 " CREATE INDEX i2 ON x1(  \"1\"\r\n\t ) "
+do_execsql_test 7.2 { CREATE INDEX i3 ON x1( "22" || 'abc''def' || `1` ) }
+do_execsql_test 7.3 { CREATE INDEX i4 ON x1( [22] + [1] ) }
+do_execsql_test 7.4 { CREATE INDEX i5 ON x1( four||'hello' ) }
+
+do_intck_test 7.5 {}
+
 
 finish_test
 
diff --git a/ext/intck/intckbusy.test b/ext/intck/intckbusy.test
new file mode 100644 (file)
index 0000000..edfedf5
--- /dev/null
@@ -0,0 +1,48 @@
+# 2024 February 24
+#
+# 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]] intck_common.tcl]
+set testprefix intckbusy
+
+
+
+do_execsql_test 1.0 {
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
+  INSERT INTO t1 VALUES(1, 2, 3);
+  INSERT INTO t1 VALUES(2, 'two', 'three');
+  INSERT INTO t1 VALUES(3, NULL, NULL);
+  CREATE INDEX i1 ON t1(b, c);
+}
+
+sqlite3 db2 test.db
+
+do_execsql_test -db db2 1.1 {
+  BEGIN EXCLUSIVE;
+    INSERT INTO t1 VALUES(4, 5, 6);
+}
+
+do_test 1.2 {
+  set ic [sqlite3_intck db main]
+  $ic step
+} {SQLITE_BUSY}
+do_test 1.3 {
+  $ic unlock
+} {SQLITE_BUSY}
+do_test 1.4 {
+  $ic error
+} {SQLITE_BUSY {database is locked}}
+do_test 1.4 {
+  $ic close
+} {}
+
+finish_test
+
index b61035f157d971b150323c0d646c9dba4045e1f0..12d205e4d91cf65221066e4dcebfd9955b59cbe7 100644 (file)
@@ -60,12 +60,9 @@ struct sqlite3_intck {
 ** and error code currently held by the database handle in p->rc and p->zErr.
 */
 static void intckSaveErrmsg(sqlite3_intck *p){
-  const char *zDberr = sqlite3_errmsg(p->db);
   p->rc = sqlite3_errcode(p->db);
-  if( zDberr ){
-    sqlite3_free(p->zErr);
-    p->zErr = sqlite3_mprintf("%s", zDberr);
-  }
+  sqlite3_free(p->zErr);
+  p->zErr = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
 }
 
 /*
@@ -125,6 +122,15 @@ static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){
   }
 }
 
+/*
+** If there is already an error in handle p, return it. Otherwise, call
+** sqlite3_step() on the statement handle and return that value.
+*/
+static int intckStep(sqlite3_intck *p, sqlite3_stmt *pStmt){
+  if( p->rc ) return p->rc;
+  return sqlite3_step(pStmt);
+}
+
 /*
 ** Execute SQL statement zSql. There is no way to obtain any results 
 ** returned by the statement. This function uses the sqlite3_intck error
@@ -133,42 +139,10 @@ static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){
 static void intckExec(sqlite3_intck *p, const char *zSql){
   sqlite3_stmt *pStmt = 0;
   pStmt = intckPrepare(p, zSql);
-  while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) );
+  intckStep(p, pStmt);
   intckFinalize(p, pStmt);
 }
 
-/*
-** Wrapper around sqlite3_malloc64() that uses the sqlite3_intck error
-** code convention.
-*/
-static void *intckMalloc(sqlite3_intck *p, sqlite3_int64 nByte){
-  void *pRet = 0;
-  assert( nByte>0 );
-  if( p->rc==SQLITE_OK ){
-    pRet = sqlite3_malloc64(nByte);
-    if( pRet==0 ){
-      p->rc = SQLITE_NOMEM;
-    }
-  }
-  return pRet;
-}
-
-/*
-** Like strdup(), but uses the sqlite3_intck error code convention. Any
-** returned buffer should eventually be freed using sqlite3_free().
-*/
-static char *intckStrdup(sqlite3_intck *p, const char *zIn){
-  char *zOut = 0;
-  if( zIn ){
-    int nIn = strlen(zIn);
-    zOut = (char*)intckMalloc(p, nIn+1);
-    if( zOut ){
-      memcpy(zOut, zIn, nIn+1);
-    }
-  }
-  return zOut;
-}
-
 /*
 ** A wrapper around sqlite3_mprintf() that uses the sqlite3_intck error
 ** code convention.
@@ -280,7 +254,7 @@ static void intckSaveKey(sqlite3_intck *p){
       sqlite3_bind_value(pStmt, ii+1, sqlite3_column_value(p->pCheck, ii+1));
     }
     if( SQLITE_ROW==sqlite3_step(pStmt) ){
-      p->zKey = intckStrdup(p, (const char*)sqlite3_column_text(pStmt, 0));
+      p->zKey = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0));
     }
     intckFinalize(p, pStmt);
   }
@@ -318,7 +292,7 @@ static void intckFindObject(sqlite3_intck *p){
   if( p->rc==SQLITE_OK ){
     sqlite3_bind_text(pStmt, 1, zPrev, -1, SQLITE_TRANSIENT);
     if( sqlite3_step(pStmt)==SQLITE_ROW ){
-      p->zObj = intckStrdup(p, (const char*)sqlite3_column_text(pStmt, 0));
+      p->zObj = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0));
     }
   }
   intckFinalize(p, pStmt);
@@ -347,7 +321,7 @@ static int intckGetToken(const char *z){
     while( 1 ){
       if( z[iRet]==c ){
         iRet++;
-        if( z[iRet+1]!=c ) break;
+        if( z[iRet]!=c ) break;
       }
       iRet++;
     }
@@ -496,7 +470,7 @@ static int intckGetAutoIndex(sqlite3_intck *p){
   int bRet = 0;
   sqlite3_stmt *pStmt = 0;
   pStmt = intckPrepare(p, "PRAGMA automatic_index");
-  if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+  if( SQLITE_ROW==intckStep(p, pStmt) ){
     bRet = sqlite3_column_int(pStmt, 0);
   }
   intckFinalize(p, pStmt);
@@ -789,7 +763,7 @@ static char *intckCheckObjectSql(
   }
 
   while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
-    zRet = intckStrdup(p, (const char*)sqlite3_column_text(pStmt, 0));
+    zRet = intckMprintf(p, "%s", (const char*)sqlite3_column_text(pStmt, 0));
     if( pnKeyVal ){
       *pnKeyVal = sqlite3_column_int(pStmt, 1);
     }
@@ -839,15 +813,15 @@ int sqlite3_intck_open(
 */
 void sqlite3_intck_close(sqlite3_intck *p){
   if( p ){
-    if( p->db ){
-      sqlite3_create_function(
-          p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
-      );
-    }
+    sqlite3_finalize(p->pCheck);
+    sqlite3_create_function(
+        p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
+    );
     sqlite3_free(p->zObj);
     sqlite3_free(p->zKey);
     sqlite3_free(p->zTestSql);
     sqlite3_free(p->zErr);
+    sqlite3_free(p->zMessage);
     sqlite3_free(p);
   }
 }
@@ -881,7 +855,7 @@ int sqlite3_intck_step(sqlite3_intck *p){
         }
       }else if( p->rc==SQLITE_CORRUPT ){
         p->rc = SQLITE_OK;
-        p->zMessage = intckStrdup(p, 
+        p->zMessage = intckMprintf(p, "%s",
             "corruption found while reading database schema"
         );
         p->bCorruptSchema = 1;
@@ -937,7 +911,7 @@ int sqlite3_intck_error(sqlite3_intck *p, const char **pzErr){
 ** on the database.
 */
 int sqlite3_intck_unlock(sqlite3_intck *p){
-  if( p->pCheck && p->rc==SQLITE_OK ){
+  if( p->rc==SQLITE_OK && p->pCheck ){
     assert( p->zKey==0 && p->nKeyVal>0 );
     intckSaveKey(p);
     intckFinalize(p, p->pCheck);
index 4c34e2fd262f158204a7bdead8d4a95cfb8da882..72f72d8c1391434aa3ee5a316c8fa2d3cfb7893d 100644 (file)
@@ -92,12 +92,12 @@ static int testIntckCmd(
 
     case 3: assert( 0==strcmp("error", aCmd[iIdx].zName) ); {
       const char *zErr = 0;
-      int rc = sqlite3_intck_error(p->intck, &zErr);
+      int rc = sqlite3_intck_error(p->intck, 0);
       Tcl_Obj *pRes = Tcl_NewObj();
-
       Tcl_ListObjAppendElement(
           interp, pRes, Tcl_NewStringObj(sqlite3ErrName(rc), -1)
       );
+      sqlite3_intck_error(p->intck, &zErr);
       Tcl_ListObjAppendElement(
           interp, pRes, Tcl_NewStringObj(zErr ? zErr : 0, -1)
       );
@@ -160,6 +160,7 @@ static int test_sqlite3_intck(
     return TCL_ERROR;
   }
   zDb = Tcl_GetString(objv[2]);
+  if( zDb[0]=='\0' ) zDb = 0;
 
   rc = sqlite3_intck_open(db, zDb, &p->intck);
   if( rc!=SQLITE_OK ){
@@ -169,7 +170,7 @@ static int test_sqlite3_intck(
   }
 
   do {
-    sprintf(zName, "intck%d", iName);
+    sprintf(zName, "intck%d", iName++);
   }while( Tcl_GetCommandInfo(interp, zName, &info)!=0 );
   Tcl_CreateObjCommand(interp, zName, testIntckCmd, (void*)p, testIntckFree);
   Tcl_SetObjResult(interp, Tcl_NewStringObj(zName, -1));
@@ -226,6 +227,7 @@ static int test_do_intck(
   }
   Tcl_DecrRefCount(pRet);
   sqlite3_intck_close(pCk);
+  sqlite3_intck_close(0);
   return rc ? TCL_ERROR : TCL_OK;
 }
 
index 068e592cd0ba541c3060f59afc86701d13ac9d63..732ad1f72cd07c1505f8cc1ffe6e5ef762591cf4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stests\sfor\sthe\snew\scode\son\sthis\sbranch.
-D 2024-02-23T20:51:06.837
+C Add\sfurther\stests\sfor\sthe\sintck\smodule.
+D 2024-02-24T16:26:15.674
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -248,14 +248,15 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
 F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
 F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
 F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
-F ext/intck/intck1.test e73c4f87b54176291b9a01b52dbc9dd88f42f3ec8aea48c8e0bd7f87a1440a40
+F ext/intck/intck1.test 866f0937911bf3a10491af6ce319b75bcd587c39dc8decf2444746b946aa4f3e
 F ext/intck/intck2.test 97daaf43b8a3c870ba7c2fd421dc1887053f5b30188896fa64677ce8174c206f
 F ext/intck/intck_common.tcl 9e51458126576783f11051ac0fd25bea3f6b17f570a55884223737f3200b214b
+F ext/intck/intckbusy.test 0732fe3efbb9e0a53ffdcc240073f6ff2777ea82c3e08812b16494f650763fe1
 F ext/intck/intckcorrupt.test 3211ef68ac53e83951b6c8f6a8d2396506d123fe5898f97f848a25837744ec56
 F ext/intck/intckfault.test ba0213c9c8dce08d519d5251268a3bab076a184b4d07acdea23b65e89c9ae03c
-F ext/intck/sqlite3intck.c 642f57a4604580513547df9d8489cdb49b8f5f3af1981c7ffb87bc37e5ce1439
+F ext/intck/sqlite3intck.c 52381a627637504a49e93400814b36e99afa0b972a9a24ef1732b8268bb27fa8
 F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
-F ext/intck/test_intck.c dec07fc82e2626a1450e58be474e351643627b04ee08ce8fae6495a533b87e85
+F ext/intck/test_intck.c d63f1707432802f5db125ee40b794923af77d4686869bd8d3a7eb43332344267
 F ext/jni/GNUmakefile 59eb05f2a363bdfac8d15d66bed624bfe1ff289229184f3861b95f98a19cf4b2
 F ext/jni/README.md d899789a9082a07b99bf30b1bbb6204ae57c060efcaa634536fa669323918f42
 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
@@ -2170,8 +2171,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P cfd051836b72f7d4e38cc9614f6ae5c003de4ce377359fd391adf06fe1ddf6b9
-R aa9167c841a6524a2987fc0088c3a9be
+P 351d46b2373f08bc8033d0902d9f67cd6c8bcc16c0d9f787e4fb279c0a76da87
+R 38b420c887519ac9a48b5a886e5c9758
 U dan
-Z 2a1b98d11090580141aae0cbd3e3021e
+Z 449a9c9353165606d5987b5f74af35a1
 # Remove this line to create a well-formed Fossil manifest.
index c04383065796de862172a68ad0d8d7e20f2926c8..af08de7704aab2aace7baabf9db2f3e0b1060845 100644 (file)
@@ -1 +1 @@
-351d46b2373f08bc8033d0902d9f67cd6c8bcc16c0d9f787e4fb279c0a76da87
\ No newline at end of file
+c253e276b29de28a18270d01b60d95157ce3fc4b37e246d991f9119d26e718d7
\ No newline at end of file