]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Increase the maximum number of arguments on an SQL function to 1000 with the
authordrh <>
Thu, 12 Dec 2024 20:39:56 +0000 (20:39 +0000)
committerdrh <>
Thu, 12 Dec 2024 20:39:56 +0000 (20:39 +0000)
capability to increase it further up to 32767 using a compile-time option.

FossilOrigin-Name: 3c25c69c93e55738cdbfdd87fa3c879b878674973955490770f5e274da1ca9a4

13 files changed:
manifest
manifest.uuid
src/expr.c
src/main.c
src/pragma.c
src/select.c
src/sqliteInt.h
src/sqliteLimit.h
src/test_func.c
src/trigger.c
src/vdbeInt.h
src/window.c
test/func.test

index 77658fa96851c863c9f84623ba359763d6379ba7..0ddc7c19cfa3f438ae8be35703d94054abb44550 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sextra\slogging\sfor\salternative\sstat4\scode.
-D 2024-12-12T19:20:40.157
+C Increase\sthe\smaximum\snumber\sof\sarguments\son\san\sSQL\sfunction\sto\s1000\swith\sthe\ncapability\sto\sincrease\sit\sfurther\sup\sto\s32767\susing\sa\scompile-time\soption.
+D 2024-12-12T20:39:56.185
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -724,7 +724,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
 F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
 F src/delete.c 444c4d1eaac40103461e3b6f0881846dd3aafc1cec1dd169d3482fa331667da7
-F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
+F src/expr.c f126029aed954608925395cfde214564f2f781f40ea5951ca8e987f07b73b0e4
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
 F src/func.c ce9dc15867388c76894fa67b3500f5726579b766b00ba617a2ad46c16ca76c1e
@@ -737,7 +737,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
 F src/legacy.c 5fff8efbb4f20396136beb913fff323686cff8f6f5d7d728189f68e98f7310bb
 F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
-F src/main.c def50c462ce61f722196f7615d79374e2e5b9e856cce2991192faea3b9dbd33c
+F src/main.c 2aa8cea363b16f4093fc317f8bab38922c8e7b8d2c78b99cb64b6ab782a7c8e8
 F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -767,20 +767,20 @@ F src/parse.y 8388b36e6cd15ebc5c1796cb72dd0a67a04abc446f52838ab3a2e8591487b2f1
 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
 F src/pcache1.c 437282ad81350c98a8592425b19e1b4e132196f7a81aef49b2ca39c50937b827
-F src/pragma.c 08472536cf1ecc38947d56f6cb2c8d8b3f6a26722451a38614c41a5b0cbcfc52
+F src/pragma.c 464813bf39538eaa2c2cfe349de97888cc4d82645c0574d9c522190d46898149
 F src/pragma.h 6ebbdee90ed56a892d2c728e27fd9c1ce48c8a28841888d0c6c147946b38cb25
 F src/prepare.c 3476a2d3353d3a881822f888fcd04bfdf5bf62a2a0566ffca83dc42190fdae19
 F src/printf.c 9480e90343dfde2406eeb25ff072774a77453d0f57fcd6495102f915dcc26a82
 F src/random.c 9bd018738ec450bf35d28050b4b33fa9a6eebf3aaefb1a1cff42dc14a7725673
 F src/resolve.c 2c127880c0634962837f16f2f48a295e514357af959330cc038de73015d5b5e8
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 108baa344f34a17a0723067d28b5b4b7da937d02ddc2d7c1a39a4a4815628ca4
+F src/select.c d07d1872161db7c922194c5279d67686e8355c6d304ed0e0646fbaa59b59f561
 F src/shell.c.in 40de636c1d90fb8a9ca7f49dc8f50d930f1b60736e73aca5eb37c4c7d0e47f9d
 F src/sqlite.h.in b7ff496637807ae88b2557039fc940518db328bf5d5621e2f7c048dfba32a52b
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
-F src/sqliteInt.h 727bcaaced1e9f715cfdfca6d1e9766a42543ce471355fa276b5508c094d6c72
-F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
+F src/sqliteInt.h 4e8896f6baa07faeda8182ef5caca178eaa1c10e1e5eb4a1983e5ac55fb84256
+F src/sqliteLimit.h da2cffdffa7d71b035f9e59668fbaad74b5939300dbfa9915304e6d8f72b0761
 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c c6888598f08dee3d9112a38ef42c8f5c89ca7f3190f4694744d0b84250f4bf8c
@@ -804,7 +804,7 @@ F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf
 F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
 F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5
-F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851
+F src/test_func.c 858d4dddb7acf88222ebcba7cffb585f6dde83e4a15b838c0d05ccdf8d5219b9
 F src/test_hexio.c 35704e7db83fe1a0e1a014bacb17de97d7d1e89af3356a9da04e37cdaa087c09
 F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e
 F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5
@@ -839,7 +839,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68
 F src/treeview.c 88aa39b754f5ef7214385c1bbbdd2f3dc20efafeed0cf590e8d1199b9c6e44aa
-F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461
+F src/trigger.c 247e2d712d5edc6021d52a169f6ac9a9c10d7144bc4ac7ea06c1ed2aa414659f
 F src/update.c 2dd1b745acc9253df1b210ac69137c7a6b290e561d3f42da24418c4e807e889b
 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
 F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
@@ -847,7 +847,7 @@ F src/util.c 5d1a0134cf4240648d1c6bb5cc8efaca0ea2b5d5c840985aec7e947271f04375
 F src/vacuum.c 25e407a6dc8b288fa4295b3d92fa9ce9318503e84df53cdf403a50fccbc1ba31
 F src/vdbe.c fa31aa6525e34b51763702d246a69c3877436f0bbf6be5f6351cdcb770b9b7ab
 F src/vdbe.h b74bfd9cb1fa895e545a5286ee1cac6d75f706d325f89be0e3bf3c5107eb8a78
-F src/vdbeInt.h 92b7eabbaadbe8127741cd96e7e39c4834c2bb0b75987d5f6251975f47233690
+F src/vdbeInt.h 75373833a8178a78126625dda269bcd41db40547092114d1edff12e7bcbb1606
 F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
 F src/vdbeaux.c ad80e779f4bf685742fc2d98cb9b802a79d427a4b20f961583f0bcdf8ebcf1fe
 F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797
@@ -864,7 +864,7 @@ F src/where.c c046dd58c3410f7b7528e1e6317cb876398557bad346d568ed8562321a7d002d
 F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192
 F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf
 F src/whereexpr.c 44f41ae554c7572e1de1485b3169b233ee04d464b2ee5881687ede3bf07cacfa
-F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975
+F src/window.c e1ba6ecb65aed5ffc9bc4ef8798db414412bb7568662efebb282a5343fbae5ec
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
 F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
@@ -1272,7 +1272,7 @@ F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f75
 F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9
 F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d
 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
-F test/func.test b56905748ce0567c01d60005f3e6ad1af19453d224ba4730ee687d048fd09ef9
+F test/func.test 0caa32dda62786c45bf831385384cb025851d5d4ba616b1ad4d9009fc2db0354
 F test/func2.test 69f6ae3751b4ec765bdc3b803c0a255aa0f693f28f44805bef03e6b4a3fd242f
 F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a
 F test/func4.test a3f9062487dbd826776f54f4e0e9517fe8c3cf689af92735308965774d51fac5
@@ -2250,8 +2250,9 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P e0bcd30581b5b55abb0ba0f2855dbfa27f4e036b45423062402fe344db7bb070
-R 16bbc1b35bbe7111b823770bff0a9f1d
-U dan
-Z 153ef0568219aec43eab90757993b76a
+P 9dde0365cb1df8bded58791f6409db464c969a61bc3a1a5682b4c4438c36a598
+Q +e8d7d68ba0bb0bc2f948db5d9966990a5d23597fc3658b7cd0bc99d53c7353a9
+R 0f00340254ec757d7293a2fab781a175
+U drh
+Z b5be36f6e57315edb37046686085d1ab
 # Remove this line to create a well-formed Fossil manifest.
index 76903f63eab5ff56c759005104f4907f3699f0b7..4a47e3ed96b0f2f059c84265138b9be27935aec3 100644 (file)
@@ -1 +1 @@
-9dde0365cb1df8bded58791f6409db464c969a61bc3a1a5682b4c4438c36a598
+3c25c69c93e55738cdbfdd87fa3c879b878674973955490770f5e274da1ca9a4
index 1b18828dd6e3ef373492c706b227f666b2b058f9..eb8639937079961726793696bc703efcd0c31af5 100644 (file)
@@ -479,7 +479,7 @@ static int codeCompare(
   p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
   addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
                            (void*)p4, P4_COLLSEQ);
-  sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
+  sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5);
   return addr;
 }
 
index bd68fa74d7b3953e28a8c34b5f8997e604e06f2e..a5bdad98d6686e2e6e08afa0d0ec379e6206ecf0 100644 (file)
@@ -2894,8 +2894,8 @@ static const int aHardLimit[] = {
 #if SQLITE_MAX_VDBE_OP<40
 # error SQLITE_MAX_VDBE_OP must be at least 40
 #endif
-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
+#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767
+# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767
 #endif
 #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
 # error SQLITE_MAX_ATTACHED must be between 0 and 125
index 28a567ce9dcaa8c0140ad702df360e32f40d5234..a8d8ac0ce3e658acac58f4412c7d2ac2fd1334c8 100644 (file)
@@ -1773,7 +1773,7 @@ void sqlite3Pragma(
 
       /* Do the b-tree integrity checks */
       sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY);
-      sqlite3VdbeChangeP5(v, (u8)i);
+      sqlite3VdbeChangeP5(v, (u16)i);
       addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
       sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
          sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
index 761b51b544980ab75fb0b73182fa91635cb57461..00c33debdee9ea08bcb536a3eefec7218749eb28 100644 (file)
@@ -6825,7 +6825,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
       }
       sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
       sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
-      sqlite3VdbeChangeP5(v, (u8)nArg);
+      sqlite3VdbeChangeP5(v, (u16)nArg);
       sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v);
       sqlite3VdbeJumpHere(v, iTop);
       sqlite3ReleaseTempRange(pParse, regAgg, nArg);
@@ -6988,7 +6988,7 @@ static void updateAccumulator(
       }
       sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
       sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
-      sqlite3VdbeChangeP5(v, (u8)nArg);
+      sqlite3VdbeChangeP5(v, (u16)nArg);
       sqlite3ReleaseTempRange(pParse, regAgg, nArg);
     }
     if( addrNext ){
index 70d7832344970073d184f7744ac2f7dabd9120e2..7f7b48e7b4e5f40e8fbe43408a6495910bfa3ed9 100644 (file)
@@ -2054,7 +2054,7 @@ void sqlite3SchemaTimeLog(u64 *aSchemaTime, const char *zFile);
 ** field is used by per-connection app-def functions.
 */
 struct FuncDef {
-  i8 nArg;             /* Number of arguments.  -1 means unlimited */
+  i16 nArg;            /* Number of arguments.  -1 means unlimited */
   u32 funcFlags;       /* Some combination of SQLITE_FUNC_* */
   void *pUserData;     /* User data parameter */
   FuncDef *pNext;      /* Next function with same name */
index abf59e1b3a4887b4ea221aff0ec46c2de6ebaa6d..80d4b4aec5f65340d72d985a7756840ef33025f2 100644 (file)
 
 /*
 ** The maximum number of arguments to an SQL function.
+**
+** This value has a hard upper limit of 32767 due to storage
+** constraints (it needs to fit inside a i16).  We keep it
+** lower than that to prevent abuse.
 */
 #ifndef SQLITE_MAX_FUNCTION_ARG
-# define SQLITE_MAX_FUNCTION_ARG 127
+# define SQLITE_MAX_FUNCTION_ARG 1000
 #endif
 
 /*
index 8c06705ae442e67c48e92cfd1a9e7ae3b4c39626..82f7b3d9cadea8e6d2ee29656896fa181fa7e291 100644 (file)
@@ -773,7 +773,7 @@ static int SQLITE_TCLAPI abuse_create_function(
   rc = sqlite3_create_function(db, "tx", -2, SQLITE_UTF8, 0, tStep, 0, 0);
   if( rc!=SQLITE_MISUSE ) goto abuse_err;
 
-  rc = sqlite3_create_function(db, "tx", 128, SQLITE_UTF8, 0, tStep, 0, 0);
+  rc = sqlite3_create_function(db, "tx", 32768, SQLITE_UTF8, 0, tStep, 0, 0);
   if( rc!=SQLITE_MISUSE ) goto abuse_err;
 
   rc = sqlite3_create_function(db, "funcxx"
@@ -789,7 +789,7 @@ static int SQLITE_TCLAPI abuse_create_function(
   ** a no-op function (that always returns NULL) and which has the
   ** maximum-length function name and the maximum number of parameters.
   */
-  sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 10000);
+  sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 1000000);
   mxArg = sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, -1);
   rc = sqlite3_create_function(db, "nullx"
        "_123456789_123456789_123456789_123456789_123456789"
index ff2df82cbcbe3b4976c07c093b8c68a65fcf4cac..e306a2e66479f994b8a9fb05ac9e433c0cec7076 100644 (file)
@@ -1409,7 +1409,7 @@ void sqlite3CodeRowTriggerDirect(
     ** invocation is disallowed if (a) the sub-program is really a trigger,
     ** not a foreign key action, and (b) the flag to enable recursive triggers
     ** is clear.  */
-    sqlite3VdbeChangeP5(v, (u8)bRecursive);
+    sqlite3VdbeChangeP5(v, (u16)bRecursive);
   }
 }
 
index 09cbc75408fed681d3ae350aac92eda264967371..dafa40b104aee0988499e2bceb1b3c28fbd74195 100644 (file)
@@ -393,7 +393,7 @@ struct sqlite3_context {
   int isError;            /* Error code returned by the function. */
   u8 enc;                 /* Encoding to use for results */
   u8 skipFlag;            /* Skip accumulator loading if true */
-  u8 argc;                /* Number of arguments */
+  u16 argc;               /* Number of arguments */
   sqlite3_value *argv[1]; /* Argument set */
 };
 
index d4083beeb3edb495a605e97c1eebe419e84874ea..6fddb6951b246df9e7d525bc8d2c5159d7052211 100644 (file)
@@ -1750,7 +1750,7 @@ static void windowAggStep(
       sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
                         bInverse, regArg, pWin->regAccum);
       sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
-      sqlite3VdbeChangeP5(v, (u8)nArg);
+      sqlite3VdbeChangeP5(v, (u16)nArg);
       if( pWin->bExprArgs ){
         sqlite3ReleaseTempRange(pParse, regArg, nArg);
       }
index a3ecd4e30bbbd9f2b9e2b4a519e4a1c50787396c..6fa4bb6d9785f0e23e741acfe49176741768a789 100644 (file)
@@ -1186,7 +1186,9 @@ set midargs {}
 unset -nocomplain midres
 set midres {}
 unset -nocomplain result
-for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} {
+set limit [sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]
+if {$limit>400} {set limit 400}
+for {set i 1} {$i<$limit} {incr i} {
   append midargs ,'/$i'
   append midres /$i
   set result [md5 \
@@ -1264,7 +1266,8 @@ do_test func-26.1 {
 #
 do_test func-26.2 {
   set a {}
-  for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
+  set limit $::SQLITE_MAX_FUNCTION_ARG
+  for {set i 1} {$i<=$limit} {incr i} {
     lappend a $i
   }
   db eval "
@@ -1282,7 +1285,8 @@ do_test func-26.3 {
 } {1 {too many arguments on function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789}}
 do_test func-26.4 {
   set a {}
-  for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
+  set limit [expr {$::SQLITE_MAX_FUNCTION_ARG-1}]
+  for {set i 1} {$i<=$limit} {incr i} {
     lappend a $i
   }
   catchsql "