[Mono-bugs] [Bug 74758][Wis] New - Odbc.DataReader.GetValue returns wrong data on CHAR columns

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Thu, 28 Apr 2005 06:22:13 -0400 (EDT)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by dfreund@runlevel-5.org.

http://bugzilla.ximian.com/show_bug.cgi?id=74758

--- shadow/74758	2005-04-28 06:22:13.000000000 -0400
+++ shadow/74758.tmp.29828	2005-04-28 06:22:13.000000000 -0400
@@ -0,0 +1,160 @@
+Bug#: 74758
+Product: Mono: Class Libraries
+Version: 1.1
+OS: All
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Wishlist
+Component: Sys.Data
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: dfreund@runlevel-5.org               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Odbc.DataReader.GetValue returns wrong data on CHAR columns
+
+GetValue() always returns the length 255 for CHAR fields when using ODBC. 
+This is because a NULL-character is returned at the end of the string
+(which in my opinion is the actual bug). This leads to the wrong string
+size and to a complete mess when I try to display a database result in a
+ASP.NET DataGrid.
+
+If I remove the NULL manually, everything is OK.
+I tested this with Mono 1.1.6 (on Windows and SLES9/unixODBC); MS .NET
+behaves OK - no NULL characters and string length is correct.
+
+This is no Informix specific behaviour. It appears everytime on every CHAR
+column. VARCHARS work OK.
+See the test case below for details:
+
+1. Install Firebird ODBC-Driver 1.2.0 from www.ibphoenix.com
+2. Create Firebird Database and a table t_odbc_test. This table basically
+   has a VARCHAR and a CHAR field
+   
+   CREATE TABLE T_ODBC_TEST (
+      ID          SMALLINT NOT NULL,
+      LAST_NAME   VARCHAR(20),
+      FIRST_NAME  CHAR(20)
+   );
+
+   ALTER TABLE T_ODBC_TEST ADD CONSTRAINT PK_T_ODBC_TEST PRIMARY KEY (ID);
+
+3. Add some Data:
+   INSERT INTO T_ODBC_TEST 
+      (ID, LAST_NAME, FIRST_NAME) VALUES (1, 'Arthur', 'Dent');
+   INSERT INTO T_ODBC_TEST (ID, LAST_NAME, FIRST_NAME) VALUES 
+      (2, 'Zaphod', 'Beeblebrox');
+   INSERT INTO T_ODBC_TEST (ID, LAST_NAME, FIRST_NAME) VALUES 
+      (3, 'Ford', 'Prefect');
+   INSERT INTO T_ODBC_TEST (ID, LAST_NAME, FIRST_NAME) VALUES 
+      (4, 'Prostetnic', 'Vogon Jeltz');
+
+4. Compile the following test case: mcs -r:System.Data OdbcTest.cs
+
+using System;
+using System.Data;
+using System.Data.Odbc;
+using System.Text;
+
+class MainClass
+{
+   const string DB_CONN   =
+      "Driver=Firebird/InterBase(r)
+driver;UID=sysdba;PWD=masterkey;Dbname=127.0.0.1:D:/user/freund/db/BMDWEB.FDB";
+   const string SELECT_SQL =
+      "SELECT * FROM t_odbc_test order by id";
+   
+   public static void Main(string[] args)
+   {
+      string fieldName = (args.Length == 1) ? args[0].ToUpper() : "LAST_NAME";
+      Console.WriteLine("Column: " + fieldName);
+         
+      try
+      {
+         using (OdbcConnection conn = new OdbcConnection(DB_CONN))
+         {
+            conn.Open();
+            
+            Console.WriteLine("------------------------------------------");
+            
+            OdbcCommand    cmd    = new OdbcCommand(SELECT_SQL, conn);
+            OdbcDataReader reader = cmd.ExecuteReader();
+            
+            Console.WriteLine("Length | Pos of NUL | Len NUL rem. | Len
+trim |");
+            while (reader.Read())
+            {
+               string test  = (string)reader[fieldName];
+
+               string test2 = 
+                  test.IndexOf('\0') > -1 ? test.Substring(0,
+test.IndexOf('\0')) : test;
+                  
+               string test3 = test2.Trim();
+
+               Console.WriteLine("{0,6} | {1,10} | {2,12} | {3,8} | {4}", 
+                  test.Length, test.IndexOf('\0'), test2.Length,
+test3.Length, test3);
+            }
+            reader.Close();
+            Console.WriteLine("------------------------------------------");
+         }
+      }
+      catch (Exception ex)
+      {
+         Console.WriteLine(ex.Message);
+         Console.WriteLine(ex.StackTrace);
+      }
+   }
+}
+
+5. Run it once with 
+   mono OdbcTest.exe last_name
+You will get something like this:
+
+U:\work\tt>mono OdbcTest.exe last_name
+Column: LAST_NAME
+------------------------------------------
+Length | Pos of NUL | Len NUL rem. | Len trim |
+     6 |         -1 |            6 |        6 | Arthur
+     6 |         -1 |            6 |        6 | Zaphod
+     4 |         -1 |            4 |        4 | Ford
+    10 |         -1 |           10 |       10 | Prostetnic
+------------------------------------------
+
+The LAST_NAME is a VARCHAR and everything is correct. Column 1
+shows the correct length. Col. 2 says that there are no NULL
+characters
+
+Now run
+   mono OdbcTest.exe first_name
+Now you will get something like this:
+
+U:\work\tt>mono OdbcTest.exe first_name
+Column: FIRST_NAME
+------------------------------------------
+Length | Pos of NUL | Len NUL rem. | Len trim |
+   255 |         20 |           20 |        4 | Dent
+   255 |         20 |           20 |       10 | Beeblebrox
+   255 |         20 |           20 |        7 | Prefect
+   255 |         20 |           20 |       11 | Vogon Jeltz
+------------------------------------------
+
+FIRST_NAME is a CHAR column. The expected result would look similar to the
+example above using the LAST_NAME VARCHAR column. 
+Here the length of the string is 255 (col. 1) and the string has a NULL at
+pos 20 (col. 2) -> wrong length, wrong NULL charactar at pos 20 
+
+If I remove the NULL, the length is 20 (col 3) which
+is correct for a CHAR column because it is filled with spaces up to
+the database fields length (which actually is 20). After trimming the
+string I finally get the length of the string
+
+Let me know if I should attach the whole Firebrid database.
+
+Thanx,
+
+/daniel