abouffard/csharp-sqlite

Zero-length byte arrays returned as NULL

Opened this issue · 1 comments

What steps will reproduce the problem?

Executing this code will fail with 'res == null':

 using (var c = new SqliteConnection("Data Source=TestZeroArray.db"))
 {
   using (var cmd = cnn.CreateCommand())
   {
     cmd.CommandText = "CREATE TABLE TestZeroArrayTable (TheField BLOB)";
     cmd.ExecuteNonQuery();

     cmd.CommandText = "INSERT INTO TestZeroArrayTable VALUES(?)";
     var field6 = cmd.CreateParameter();
     cmd.Parameters.Add(field6);

     var data = new byte[] {};

     field6.Value = data;
     cmd.ExecuteNonQuery();

     cmd.CommandText = "SELECT TheField FROM TestZeroArrayTable";
     var res = (byte[])cmd.ExecuteScalar();

     if (res == null) throw new ArgumentException("res == null");
     if (!data.Equals(res)) throw new ArgumentException("!data.Equals(res)");
     if (res.Length != 0) throw new ArgumentException("res.Length != 0");
   }
 }

What is the expected output? What do you see instead?
The expected output is no exceptions thrown:
  res is byte[0]{} - empty byte array
  res is not null
  res.Length = 0

The current result is that res is null.

What version of the product are you using? On what operating system?
I am using the latest source code : b3329cf52e93
On windows 7 Pro running in the WP emulator

Please provide any additional information below.
The value is being saved correctly as I can check, after getting the db, using 
the Mono.Data.Sqlite classes.

The problem seems to lie here:
  Function : public static byte[] sqlite3_value_blob(sqlite3_value pVal)
  Namespace : Sqite3
  File : vdbeapi_c.cs
  Line # : 208
  Line : return p.n > 0 ? p.zBLOB : null;

In the official C code this seems to be the same, but the functionality of the 
previous check may be different.

I don't profess to be a C boff, let me know what you think

Original issue reported on code.google.com by mattleib...@gmail.com on 30 Mar 2012 at 10:43

I've committed up a fix for this issue, in my clone, at 
http://code.google.com/r/zacharygramana-csharp-sqlite/source/detail?r=1713cba846
5656dafc28fb8d21ed066f3b53d74c#.

This commit adds a new symbol, EMPTY_BYTE_ARRAYS, which enables the behavior 
requested in this issue. Considering this change would impact code that expects 
empty results to equal null, this was wrapped in a pragma to allow "opting in." 
In my case, I only enabled the behavior on the WinRT project in order to 
successfully integrate with sqlite-net.

Cheers!

Original comment by zachary....@xamarin.com on 10 Jun 2013 at 3:10