]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the sqlite3_table_column_metadata() routine so that it gives the correct
authordrh <drh@noemail.net>
Tue, 9 Dec 2014 22:24:42 +0000 (22:24 +0000)
committerdrh <drh@noemail.net>
Tue, 9 Dec 2014 22:24:42 +0000 (22:24 +0000)
answer for the "rowid" column in a WITHOUT ROWID table.  Enhance it so that
it can be used to check for the existence of a table by setting the column
name parameter to NULL.  The routine is now included in the build by
default, even without the SQLITE_ENABLE_COLUMN_METADATA compile-time option.

FossilOrigin-Name: cf9be419a16156a9814e1378bb49b780de977343

manifest
manifest.uuid
src/main.c
src/sqlite.h.in
src/test1.c
test/colmeta.test

index 0baa94d673dffbf52218884e673c6292e19783e3..e4a81bbd8dffcfa97aecdcd69a0394ba4cb3f719 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sextra\stests\sto\se_walckpt.test.
-D 2014-12-09T20:13:40.856
+C Fix\sthe\ssqlite3_table_column_metadata()\sroutine\sso\sthat\sit\sgives\sthe\scorrect\nanswer\sfor\sthe\s"rowid"\scolumn\sin\sa\sWITHOUT\sROWID\stable.\s\sEnhance\sit\sso\sthat\nit\scan\sbe\sused\sto\scheck\sfor\sthe\sexistence\sof\sa\stable\sby\ssetting\sthe\scolumn\nname\sparameter\sto\sNULL.\s\sThe\sroutine\sis\snow\sincluded\sin\sthe\sbuild\sby\ndefault,\seven\swithout\sthe\sSQLITE_ENABLE_COLUMN_METADATA\scompile-time\soption.
+D 2014-12-09T22:24:42.981
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 6c4f961fa91d0b4fa121946a19f9e5eac2f2f809
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
 F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
 F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660
-F src/main.c ad4c0ed3b4731274aabb91b9158405a48dfaabad
+F src/main.c 4bfb07de96118350a63103380819ff8cbbefc5cd
 F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
@@ -230,7 +230,7 @@ F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
 F src/select.c f377fb8a5c73c10678ea74f3400f7913943e3d75
 F src/shell.c 45d9c9bd7cde07845af957f2d849933b990773cf
-F src/sqlite.h.in a68ac3ba964e17c446457944b41ad50313a11b21
+F src/sqlite.h.in cc237b8aa62348685b36d06f1b6beb10dfea39ae
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
 F src/sqliteInt.h 28049b803b74a7f73242a8226915ea00ebb1309f
@@ -238,7 +238,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 81712116e826b0089bb221b018929536b2b5406f
 F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc
 F src/tclsqlite.c 0a874655dd39a9875e39c5d3c464db662171d228
-F src/test1.c f60b9e973cf813fdabb2b67ccbb4a08e9f1d81be
+F src/test1.c 7e806af12d7915445e46407d32b275d8ca9db4e7
 F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
 F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -404,7 +404,7 @@ F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
 F test/collate8.test df26649cfcbddf109c04122b340301616d3a88f6
 F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
 F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
-F test/colmeta.test 63f92e28d87de59430b1a1a9bb43ad7f8d19335e
+F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
 F test/conflict.test 841bcf7cabbfca39c577eb8411ea8601843b46a8
 F test/conflict2.test 0d3af4fb534fa1bd020c79960bb56e4d52655f09
@@ -1226,7 +1226,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 1ba8911c18f2fe34c20dc42f25a8f3c1c798fa7a
-R 3c53b0c88f36488767cc876fe1e6e0b0
-U dan
-Z bbcee16517facfe70298aa47dfb20c31
+P 84f9581019961efa31297f8be48427b17bcca857
+R 0b640911f896cbfee28a6d7f7893118c
+U drh
+Z 0a34c44c2738c668de181b5c6607c9d7
index 587f7e93dcfe0a80d5c71e5f76f51e025f571534..fbd6f6fb7bb5408778ae7da54fb68b66363d8a66 100644 (file)
@@ -1 +1 @@
-84f9581019961efa31297f8be48427b17bcca857
\ No newline at end of file
+cf9be419a16156a9814e1378bb49b780de977343
\ No newline at end of file
index 6d10c1538919985881d028e9ce2350de3c8395db..0727c0d75a4a55654608cc9ef70dee57c4831429 100644 (file)
@@ -3188,11 +3188,8 @@ int sqlite3_table_column_metadata(
   }
 
   /* Find the column for which info is requested */
-  if( sqlite3IsRowid(zColumnName) ){
-    iCol = pTab->iPKey;
-    if( iCol>=0 ){
-      pCol = &pTab->aCol[iCol];
-    }
+  if( zColumnName==0 ){
+    /* Query for existance of table only */
   }else{
     for(iCol=0; iCol<pTab->nCol; iCol++){
       pCol = &pTab->aCol[iCol];
@@ -3201,8 +3198,13 @@ int sqlite3_table_column_metadata(
       }
     }
     if( iCol==pTab->nCol ){
-      pTab = 0;
-      goto error_out;
+      if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
+        iCol = pTab->iPKey;
+        pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
+      }else{
+        pTab = 0;
+        goto error_out;
+      }
     }
   }
 
index 66a917e0cdfc713248c161678c0ab56cea783a4c..b3ff06115129a81c4e96dc9dfe8ef7d3c64eda61 100644 (file)
@@ -5152,9 +5152,17 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 /*
 ** CAPI3REF: Extract Metadata About A Column Of A Table
 **
-** ^This routine returns metadata about a specific column of a specific
-** database table accessible using the [database connection] handle
-** passed as the first function argument.
+** ^The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
+** information about column C of table T in database D
+** on [database connection] X.  ^The sqlite3_table_column_metadata()
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
+** the final five arguments with appropriate vaules if the specified
+** column exists.  ^The sqlite3_table_column_metadata() interface returns
+** SQLITE_ERROR and if the specified column does not exist.
+** If the column-name parameter to sqlite3_table_column_metadata() is a
+** NULL pointer, then the routine simply checks for the existance of the
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+** does not.
 **
 ** ^The column is identified by the second, third and fourth parameters to
 ** this function. ^The second parameter is either the name of the database
@@ -5164,8 +5172,7 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 ** resolve unqualified table references.
 **
 ** ^The third and fourth parameters to this function are the table and column
-** name of the desired column, respectively. Neither of these parameters
-** may be NULL.
+** name of the desired column, respectively.
 **
 ** ^Metadata is returned by writing to the memory locations passed as the 5th
 ** and subsequent parameters to this function. ^Any of these arguments may be
@@ -5184,16 +5191,17 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 ** </blockquote>)^
 **
 ** ^The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
+** declaration type and collation sequence is valid until the next
 ** call to any SQLite API function.
 **
 ** ^If the specified table is actually a view, an [error code] is returned.
 **
-** ^If the specified column is "rowid", "oid" or "_rowid_" and an
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table 
+** is not a [WITHOUT ROWID] table and an
 ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
 ** parameters are set for the explicitly declared column. ^(If there is no
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
-** parameters are set as follows:
+** [INTEGER PRIMARY KEY] column, then the outputs
+** for the [rowid] are set as follows:
 **
 ** <pre>
 **     data type: "INTEGER"
@@ -5203,10 +5211,9 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 **     auto increment: 0
 ** </pre>)^
 **
-** ^(This function may load one or more schemas from database files. If an
-** error occurs during this process, or if the requested table or column
-** cannot be found, an [error code] is returned and an error message left
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
+** ^This function causes all database schemas to be read from disk and
+** parsed, if that has not already been done, and returns an error if
+** any errors are encountered while loading the schema.
 */
 int sqlite3_table_column_metadata(
   sqlite3 *db,                /* Connection handle */
index 009b88a5432e0a35a4af5dd963bf85ae1dba5dad..851249461cd24668956a8688c3bbe46e742618e7 100644 (file)
@@ -1588,14 +1588,14 @@ static int test_table_column_metadata(
   int primarykey;
   int autoincrement;
 
-  if( objc!=5 ){
+  if( objc!=5 && objc!=4 ){
     Tcl_WrongNumArgs(interp, 1, objv, "DB dbname tblname colname");
     return TCL_ERROR;
   }
   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
   zDb = Tcl_GetString(objv[2]);
   zTbl = Tcl_GetString(objv[3]);
-  zCol = Tcl_GetString(objv[4]);
+  zCol = objc==5 ? Tcl_GetString(objv[4]) : 0;
 
   if( strlen(zDb)==0 ) zDb = 0;
 
index ec5891f058e2ac46f47cdb0caaab7a6230d61012..21b0e0f38a59ef6de9f3f8f3f184dbd17652c647 100644 (file)
@@ -23,6 +23,8 @@ do_test colmeta-0 {
     CREATE TABLE abc(a, b, c);
     CREATE TABLE abc2(a PRIMARY KEY COLLATE NOCASE, b VARCHAR(32), c);
     CREATE TABLE abc3(a NOT NULL, b INTEGER PRIMARY KEY, c);
+    CREATE TABLE abc5(w,x,y,z,PRIMARY KEY(x,z)) WITHOUT ROWID;
+    CREATE TABLE abc6(rowid TEXT COLLATE rtrim, oid REAL, _rowid_ BLOB);
   }
   ifcapable autoinc {
     execsql {
@@ -52,19 +54,27 @@ set tests {
   13 {main abc rowid}            {0 {INTEGER BINARY 0 1 0}}
   14 {main abc3 rowid}           {0 {INTEGER BINARY 0 1 0}}
   16 {main abc d}                {1 {no such table column: abc.d}}
+  20 {main abc5 w}               {0 {{} BINARY 0 0 0}}
+  21 {main abc5 x}               {0 {{} BINARY 1 1 0}}
+  22 {main abc5 y}               {0 {{} BINARY 0 0 0}}
+  23 {main abc5 z}               {0 {{} BINARY 1 1 0}}
+  24 {main abc5 rowid}           {1 {no such table column: abc5.rowid}}
+  30 {main abc6 rowid}           {0 {TEXT rtrim 0 0 0}}
+  31 {main abc6 oid}             {0 {REAL BINARY 0 0 0}}
+  32 {main abc6 _rowid_}         {0 {BLOB BINARY 0 0 0}}
 }
-ifcapable view {
+ifcapable autoinc {
   set tests [concat $tests {
-    8  {{} abc4 b}                 {0 {INTEGER BINARY 0 1 1}}
-    15 {main abc4 rowid}           {0 {INTEGER BINARY 0 1 1}}
+    100 {{} abc4 b}              {0 {INTEGER BINARY 0 1 1}}
+    101 {main abc4 rowid}        {0 {INTEGER BINARY 0 1 1}}
   }]
 }
 ifcapable view {
   set tests [concat $tests {
-    9  {{} v1 a}                   {1 {no such table column: v1.a}}
-    10 {main v1 b}                 {1 {no such table column: v1.b}}
-    11 {main v1 badname}           {1 {no such table column: v1.badname}}
-    12 {main v1 rowid}             {1 {no such table column: v1.rowid}}
+    200 {{} v1 a}                {1 {no such table column: v1.a}}
+    201 {main v1 b}              {1 {no such table column: v1.b}}
+    202 {main v1 badname}        {1 {no such table column: v1.badname}}
+    203 {main v1 rowid}          {1 {no such table column: v1.rowid}}
   }]
 }
 
@@ -86,4 +96,15 @@ foreach {tn params results} $tests {
   } $results
 }
 
+# Calling sqlite3_table_column_metadata with a NULL column name merely
+# checks for the existance of the table.
+#
+do_test colmeta-300 {
+  catch {sqlite3_table_column_metadata $::DB main xyzzy} res
+} {1}
+do_test colmeta-301 {
+  catch {sqlite3_table_column_metadata $::DB main abc} res
+} {0}
+
+
 finish_test