]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
wasm: corrected the propagation of text/blob values via UDFs. DB.exec()'s sql may...
authorstephan <stephan@noemail.net>
Sat, 25 Jun 2022 03:53:43 +0000 (03:53 +0000)
committerstephan <stephan@noemail.net>
Sat, 25 Jun 2022 03:53:43 +0000 (03:53 +0000)
FossilOrigin-Name: 37a8fecb56793fbd3763a2240a0bd62b639c811934d3af2ef0e5ff579073d632

ext/fiddle/sqlite3-api.js
ext/fiddle/testing1.js
manifest
manifest.uuid

index 74f3e35480a57dac00fb9d2e2c13f1254ba7baba..f4d0b68d00edf88d968780ee3ba13a6c65894490 100644 (file)
@@ -186,7 +186,12 @@ Module.postRun.push(function(namespace/*the module object, the target for
                module-init-internal state which isn't normally visible to
                us.
             */
-            allocate: (slab, allocator=SQM.ALLOC_NORMAL)=>SQM.allocate(slab, allocator)
+            allocate: (slab, allocator=SQM.ALLOC_NORMAL)=>SQM.allocate(slab, allocator),
+            /**
+               The buffer which holds the heap memory managed by the
+               emscripten-installed allocator.
+            */
+            HEAP8: SQM.HEAP8
         }
     };
     [/* C-side functions to bind. Each entry is an array with 3 or 4
@@ -485,7 +490,7 @@ Module.postRun.push(function(namespace/*the module object, the target for
     /** Returns true if n is a 32-bit (signed) integer,
         else false. */
     const isInt32 = function(n){
-        return (n===n|0 && n<0xFFFFFFFF) ? true : undefined;
+        return (n===(n|0) && n<0xFFFFFFFF) ? true : undefined;
     };
 
     /**
@@ -521,6 +526,8 @@ Module.postRun.push(function(namespace/*the module object, the target for
         };
         if(out.sql instanceof Uint8Array){
             out.sql = uint8ToString(out.sql);
+        }else if(Array.isArray(out.sql)){
+            out.sql = out.sql.join('');
         }else if('string'!==typeof out.sql){
             toss("Missing SQL argument.");
         }
@@ -713,7 +720,10 @@ Module.postRun.push(function(namespace/*the module object, the target for
            properties:
 
            - .sql = the SQL to run (unless it's provided as the first
-             argument). This must be of type string or Uint8Array.
+             argument). This must be of type string, Uint8Array, or an
+             array of strings (in which case they're concatenated
+             together as-is, with no separator between elements,
+             before evaluation).
 
            - .bind = a single value valid as an argument for
              Stmt.bind(). This is ONLY applied to the FIRST non-empty
@@ -721,12 +731,13 @@ Module.postRun.push(function(namespace/*the module object, the target for
              parameters. (Empty statements are skipped entirely.)
 
            - .callback = a function which gets called for each row of
-             the FIRST statement in the SQL (if it has any result
-             rows). The second argument passed to the callback is
-             always the current Stmt object (so that the caller
-             may collect column names, or similar). The first
-             argument passed to the callback defaults to the current
-             Stmt object but may be changed with ...
+             the FIRST statement in the SQL which has result
+             _columns_, but only if that statement has any result
+             _rows_. The second argument passed to the callback is
+             always the current Stmt object (so that the caller may
+             collect column names, or similar). The first argument
+             passed to the callback defaults to the current Stmt
+             object but may be changed with ...
 
            - .rowMode = a string describing what type of argument
              should be passed as the first argument to the callback. A
@@ -796,7 +807,7 @@ Module.postRun.push(function(namespace/*the module object, the target for
                         stmt.bind(bind);
                         bind = null;
                     }
-                    if(opt.callback && null!==rowMode){
+                    if(opt.callback && null!==rowMode && stmt.columnCount){
                         while(stmt.step()){
                             stmt._isLocked = true;
                             callback(arg.cbArg(stmt), stmt);
@@ -907,15 +918,15 @@ Module.postRun.push(function(namespace/*the module object, the target for
                             case api.SQLITE_FLOAT:
                                 arg = api.sqlite3_value_double(pVal);
                                 break;
-                            case SQLITE_TEXT:
+                            case api.SQLITE_TEXT:
                                 arg = api.sqlite3_value_text(pVal);
                                 break;
-                            case SQLITE_BLOB:{
-                                const n = api.sqlite3_value_bytes(ptr);
-                                const pBlob = api.sqlite3_value_blob(ptr);
+                            case api.SQLITE_BLOB:{
+                                const n = api.sqlite3_value_bytes(pVal);
+                                const pBlob = api.sqlite3_value_blob(pVal);
                                 arg = new Uint8Array(n);
                                 let i;
-                                for(i = 0; i < n; ++i) arg[i] = HEAP8[pBlob+i];
+                                for(i = 0; i < n; ++i) arg[i] = api.wasm.HEAP8[pBlob+i];
                                 break;
                             }
                             default:
@@ -948,7 +959,7 @@ Module.postRun.push(function(namespace/*the module object, the target for
                                       api.wasm.allocate(val);
                                 api.sqlite3_result_blob(pCx, pBlob, val.length,
                                                         api.SQLITE_TRANSIENT);
-                                api.wasm._free(blobptr);
+                                api.wasm._free(pBlob);
                                 break;
                             }
                             // else fall through
@@ -1082,7 +1093,7 @@ Module.postRun.push(function(namespace/*the module object, the target for
     const affirmParamIndex = function(stmt,key){
         const n = ('number'===typeof key)
               ? key : api.sqlite3_bind_parameter_index(stmt._pStmt, key);
-        if(0===n || (n===key && (n!==(n|0)/*floating point*/))){
+        if(0===n || !isInt32(n)){
             toss("Invalid bind() parameter name: "+key);
         }
         else if(n<1 || n>stmt.parameterCount) toss("Bind index",key,"is out of range.");
@@ -1456,7 +1467,7 @@ Module.postRun.push(function(namespace/*the module object, the target for
                     const n = api.sqlite3_column_bytes(this._pStmt, ndx);
                     const ptr = api.sqlite3_column_blob(this._pStmt, ndx);
                     const rc = new Uint8Array(n);
-                    for(let i = 0; i < n; ++i) rc[i] = HEAP8[ptr + i];
+                    for(let i = 0; i < n; ++i) rc[i] = api.wasm.HEAP8[ptr + i];
                     if(n && this.db._blobXfer instanceof Array){
                         /* This is an optimization soley for the
                            Worker-based API. These values will be
index ceea0e62000a7c2a13a8a1ccd48769272fe798e5..0b178d8d9e50e0823aa1f28fb687df7033c78120 100644 (file)
 
         let list = [];
         db.exec({
-            sql:`CREATE TABLE t(a,b);
-INSERT INTO t(a,b) VALUES(1,2),(3,4),(?,?);`,
+            sql:['CREATE TABLE t(a,b);',
+                 "INSERT INTO t(a,b) VALUES(1,2),(3,4),",
+                 "(?,?),('blob',X'6869');"
+                ],
             multi: true,
             saveSql: list,
             bind: [5,6]
+            /* Achtung: ^^^ bind support might be removed from multi-mode exec. */
         });
         T.assert(2 === list.length);
         //log("Exec'd SQL:", list);
@@ -82,23 +85,24 @@ INSERT INTO t(a,b) VALUES(1,2),(3,4),(?,?);`,
             columnNames: colNames,
             callback: function(row,stmt){
                 ++counter;
-                T.assert(row.a%2 && row.a<6);
+                T.assert((row.a%2 && row.a<6) || 'blob'===row.a);
             }
         });
         T.assert(2 === colNames.length)
             .assert('a' === colNames[0])
-            .assert(3 === counter)
-            .assert(3 === list.length);
+            .assert(4 === counter)
+            .assert(4 === list.length);
         list.length = 0;
         db.exec("SELECT a a, b b FROM t",{
             rowMode: 'array',
             callback: function(row,stmt){
                 ++counter;
                 T.assert(Array.isArray(row))
-                    .assert(0===row[1]%2 && row[1]<7);
+                    .assert((0===row[1]%2 && row[1]<7)
+                            || (row[1] instanceof Uint8Array));
             }
         });
-        T.assert(6 === counter);
+        T.assert(8 === counter);
     };
 
     const testUDF = function(db){
@@ -106,7 +110,7 @@ INSERT INTO t(a,b) VALUES(1,2),(3,4),(?,?);`,
         db.createFunction("foo",function(a,b){return a+b});
         T.assert(7===db.selectValue("select foo(3,4)")).
             assert(5===db.selectValue("select foo(3,?)",2)).
-            assert(5===db.selectValue("select foo(?,?)",[1,4])).
+            assert(5===db.selectValue("select foo(?,?2)",[1,4])).
             assert(5===db.selectValue("select foo($a,$b)",{$a:0,$b:5}));
         db.createFunction("bar", {
             arity: -1,
@@ -115,15 +119,26 @@ INSERT INTO t(a,b) VALUES(1,2),(3,4),(?,?);`,
                 for(let i = 0; i < arguments.length; ++i) rc += arguments[i];
                 return rc;
             }
+        }).createFunction({
+            name: "asis",
+            callback: function(arg){
+                return arg;
+            }
         });
 
         log("Testing DB::selectValue() w/ UDF...");
         T.assert(0===db.selectValue("select bar()")).
             assert(1===db.selectValue("select bar(1)")).
             assert(3===db.selectValue("select bar(1,2)")).
-            assert(-1===db.selectValue("select bar(1,2,-4)"));
+            assert(-1===db.selectValue("select bar(1,2,-4)")).
+            assert('hi'===db.selectValue("select asis('hi')"));
+        let blob = db.selectValue("select asis(X'6869')");
+        T.assert(blob instanceof Uint8Array).
+            assert(2 === blob.length).
+            assert(0x68==blob[0] && 0x69==blob[1]);
 
         const eqApprox = function(v1,v2,factor=0.05){
+            //log('eqApprox',v1, v2);
             return v1>=(v2-factor) && v1<=(v2+factor);
         };
         
@@ -132,7 +147,8 @@ INSERT INTO t(a,b) VALUES(1,2),(3,4),(?,?);`,
             assert(null === db.selectValue("select ?",null)).
             assert(null === db.selectValue("select ?",[null])).
             assert(null === db.selectValue("select $a",{$a:null})).
-            assert(eqApprox(3.1,db.selectValue("select 3.0 + 0.1")))
+            assert(eqApprox(3.1,db.selectValue("select 3.0 + 0.1"))).
+            assert(eqApprox(1.3,db.selectValue("select asis(1 + 0.3)")))
         ;
     };
 
index 6a4922ca361f17dbdfb1945bcd0001f7390493d9..ab24710ad4d56b2512951d627625dcf52b3d57e1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\swasm\sdoc\stweaks.
-D 2022-06-25T02:54:20.783
+C wasm:\scorrected\sthe\spropagation\sof\stext/blob\svalues\svia\sUDFs.\sDB.exec()'s\ssql\smay\snow\sbe\san\sarray\sof\sstrings\swhich\sget\sconcatenated\stogether\sbefore\spassing\sit\son\sto\ssqlite3_prepare_v2().\sDB.exec()'s\scallback\snow\sapplies\sto\sthe\sfirst\sstatement\swhich\shas\sresult\scolumns\sinstead\sof\sonly\sthe\sfirst\sstatement.\sFixed\sa\sprecedence\sbut\swhich\scaused\sisInt32()\sto\sreport\sfalse\spositives.
+D 2022-06-25T03:53:43.503
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -65,11 +65,11 @@ F ext/fiddle/fiddle-worker.js 88bc2193a6cb6a3f04d8911bed50a4401fe6f277de7a71ba83
 F ext/fiddle/fiddle.html 550c5aafce40bd218de9bf26192749f69f9b10bc379423ecd2e162bcef885c08
 F ext/fiddle/fiddle.js 812f9954cc7c4b191884ad171f36fcf2d0112d0a7ecfdf6087896833a0c079a8
 F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf
-F ext/fiddle/sqlite3-api.js c54f0ee6a65a59284e6b0184f556376b35f5996b6b82607d7275a95f759a380a
+F ext/fiddle/sqlite3-api.js b706be1f777a4508f9e3e237301e11c108933ae651b3fa599bf047cac34b5bdb
 F ext/fiddle/sqlite3-worker.js a9c2b614beca187dbdd8c053ec2770cc61ec1ac9c0ec6398ceb49a79f705a421
 F ext/fiddle/testing.css 750572dded671d2cf142bbcb27af5542522ac08db128245d0b9fe410aa1d7f2a
 F ext/fiddle/testing1.html ea1f3be727f78e420007f823912c1a03b337ecbb8e79449abc2244ad4fe15d9a
-F ext/fiddle/testing1.js 2ba8d14b335cdfc694757c25a3ffcfa76f4696bb21187db5c12ea6e505c44af0
+F ext/fiddle/testing1.js 3e5f1fb22764ec735396db518b85ea6b3070f6c2da479cba69c8d8e89f8299f8
 F ext/fiddle/testing2.html 9063b2430ade2fe9da4e711addd1b51a2741cf0c7ebf6926472a5e5dd63c0bc4
 F ext/fiddle/testing2.js 7b45b4e7fddbd51dbaf89b6722c02758051b34bac5a98c11b569a7e7572f88ee
 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
@@ -1978,8 +1978,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 ab3e50dab4d71557ab5d179bbd6caf7fb61ab7c51dffc8e4714441c189ce3e5c
-R bbdb5fff926c789b277af363fc1aa00d
+P 42dc500819bfc1308a9542aa2cae4f6dfd98a29237c59cec82e0e6f9e0bf3779
+R a152bf70e7d16ac14f437dceeb13aaae
 U stephan
-Z 54385a773b385e5557f29a3390198b0f
+Z 385f37f8ee9972f16da6e6bace96df52
 # Remove this line to create a well-formed Fossil manifest.
index 66b772061087ed24f620e6aabebfa640af71a483..cd66bdca9e21dcbcc585437849e7eda2d86f37eb 100644 (file)
@@ -1 +1 @@
-42dc500819bfc1308a9542aa2cae4f6dfd98a29237c59cec82e0e6f9e0bf3779
\ No newline at end of file
+37a8fecb56793fbd3763a2240a0bd62b639c811934d3af2ef0e5ff579073d632
\ No newline at end of file