From: Date: March 2 2007 8:14pm Subject: Connector/NET commit: r626 - in branches/5.0: . Driver/Source Driver/Source/Types TestSuite List-Archive: http://lists.mysql.com/commits/21055 X-Bug: 25605 Message-Id: <200703021914.l22JEMqS008336@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: branches/5.0/CHANGES branches/5.0/Driver/Source/Field.cs branches/5.0/Driver/Source/MysqlDefs.cs branches/5.0/Driver/Source/NativeDriver.cs branches/5.0/Driver/Source/StoredProcedure.cs branches/5.0/Driver/Source/Types/MetaData.cs branches/5.0/Driver/Source/parameter.cs branches/5.0/TestSuite/DataTypeTests.cs branches/5.0/TestSuite/StoredProcedure.cs Log: Bug #25605 BINARY and VARBINARY is returned as a string Fixed this by adding new virtual types for BINARY and VARBINARY and then reworking how Field determines if a field is truly binary. This is a hack right now and just checks for functino names (just Char(xx) right now but will increase later). Modified: branches/5.0/CHANGES =================================================================== --- branches/5.0/CHANGES 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/CHANGES 2007-03-02 19:14:21 UTC (rev 626) @@ -1,3 +1,9 @@ +Version 5.0.5 + + Bugs fixed + ---------- + Bug #25605 BINARY and VARBINARY is returned as a string + Version 5.0.4 2-28-2007 Bugs fixed Modified: branches/5.0/Driver/Source/Field.cs =================================================================== --- branches/5.0/Driver/Source/Field.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/Driver/Source/Field.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -69,6 +69,7 @@ protected byte scale; protected MySqlDbType mySqlDbType; protected DBVersion connVersion; + protected bool binaryOk; #endregion @@ -76,11 +77,12 @@ { this.connVersion = connVersion; maxLength = 1; + binaryOk = true; } #region Properties - public int CharactetSetIndex + public int CharacterSetIndex { get { return charSetIndex; } set { charSetIndex = value; } @@ -146,7 +148,12 @@ public bool IsBinary { - get { return (colFlags & ColumnFlags.BINARY) > 0; } + get + { + if (connVersion.isAtLeast(4,1,0)) + return binaryOk && (CharacterSetIndex == 63); + return binaryOk && ((colFlags & ColumnFlags.BINARY) > 0); + } } public bool IsUnsigned @@ -172,29 +179,66 @@ { colFlags = flags; mySqlDbType = type; - if (!IsUnsigned) return; - switch (type) - { - case MySqlDbType.Byte: - mySqlDbType = MySqlDbType.UByte; break; - case MySqlDbType.Int16: - mySqlDbType = MySqlDbType.UInt16; break; - case MySqlDbType.Int24: - mySqlDbType = MySqlDbType.UInt24; break; - case MySqlDbType.Int32: - mySqlDbType = MySqlDbType.UInt32; break; - case MySqlDbType.Int64: - mySqlDbType = MySqlDbType.UInt64; break; - } + // if our type is an unsigned number, then we need + // to bump it up into our unsigned types + // we're trusting that the server is not going to set the UNSIGNED + // flag unless we are a number + if (IsUnsigned) + { + switch (type) + { + case MySqlDbType.Byte: + mySqlDbType = MySqlDbType.UByte; break; + case MySqlDbType.Int16: + mySqlDbType = MySqlDbType.UInt16; break; + case MySqlDbType.Int24: + mySqlDbType = MySqlDbType.UInt24; break; + case MySqlDbType.Int32: + mySqlDbType = MySqlDbType.UInt32; break; + case MySqlDbType.Int64: + mySqlDbType = MySqlDbType.UInt64; break; + } + } + + // now determine if we really should be binary + if (CharacterSetIndex == 63 && (colFlags & ColumnFlags.BINARY) != 0) + CheckForFunction(); + + if (IsBinary) + { + if (type == MySqlDbType.String) + mySqlDbType = MySqlDbType.Binary; + else if (type == MySqlDbType.VarChar || + type == MySqlDbType.VarString) + mySqlDbType = MySqlDbType.VarBinary; + } + else + { + if (type == MySqlDbType.TinyBlob) + mySqlDbType = MySqlDbType.TinyText; + else if (type == MySqlDbType.MediumBlob) + mySqlDbType = MySqlDbType.MediumText; + else if (type == MySqlDbType.Blob) + mySqlDbType = MySqlDbType.Text; + else if (type == MySqlDbType.LongBlob) + mySqlDbType = MySqlDbType.LongText; + } } + private void CheckForFunction() + { + string colName = OriginalColumnName.ToLower(CultureInfo.InvariantCulture); + if (colName.StartsWith("char(")) + binaryOk = false; + } + public IMySqlValue GetValueObject() { - return GetIMySqlValue(Type, IsBinary); + return GetIMySqlValue(Type); } - public static IMySqlValue GetIMySqlValue(MySqlDbType type, bool binary) + public static IMySqlValue GetIMySqlValue(MySqlDbType type) { switch (type) { @@ -238,13 +282,20 @@ case MySqlDbType.String: case MySqlDbType.VarString: case MySqlDbType.VarChar: + case MySqlDbType.Text: + case MySqlDbType.TinyText: + case MySqlDbType.MediumText: + case MySqlDbType.LongText: return new MySqlString(type, true); case MySqlDbType.Blob: case MySqlDbType.MediumBlob: case MySqlDbType.LongBlob: - default: - if (binary) return new MySqlBinary(type, true); - return new MySqlString(type, true); + case MySqlDbType.TinyBlob: + case MySqlDbType.Binary: + case MySqlDbType.VarBinary: + return new MySqlBinary(type, true); + default: + throw new MySqlException("Unknown data type"); } } } Modified: branches/5.0/Driver/Source/MysqlDefs.cs =================================================================== --- branches/5.0/Driver/Source/MysqlDefs.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/Driver/Source/MysqlDefs.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -200,27 +200,25 @@ /// Set = 248, /// - /// A BLOB or TEXT column with a maximum length of 255 (2^8 - 1) + /// A binary column with a maximum length of 255 (2^8 - 1) /// characters /// TinyBlob = 249, /// - /// A BLOB or TEXT column with a maximum length of 16777215 (2^24 - 1) - /// characters + /// A binary column with a maximum length of 16777215 (2^24 - 1) bytes. /// MediumBlob = 250, /// - /// A BLOB or TEXT column with a maximum length of 4294967295 or - /// 4G (2^32 - 1) characters. + /// A binary column with a maximum length of 4294967295 or + /// 4G (2^32 - 1) bytes. /// LongBlob = 251, /// - /// A BLOB or TEXT column with a maximum length of 65535 (2^16 - 1) - /// characters. + /// A binary column with a maximum length of 65535 (2^16 - 1) bytes. /// Blob = 252, /// - /// A variable-length string containing 0 to 255 characters. + /// A variable-length string containing 0 to 255 bytes. /// VarChar = 253, /// @@ -234,23 +232,48 @@ /// /// Unsigned 8-bit value. /// - UByte = 1024, + UByte = 501, /// /// Unsigned 16-bit value. /// - UInt16 = 1025, + UInt16 = 502, /// /// Unsigned 24-bit value. /// - UInt24 = 1026, + UInt24 = 509, /// /// Unsigned 32-bit value. /// - UInt32 = 1027, + UInt32 = 503, /// /// Unsigned 64-bit value. /// - UInt64 = 1028 + UInt64 = 508, + /// + /// Fixed length binary string. + /// + Binary = 600, + /// + /// Variable length binary string. + /// + VarBinary = 601, + /// + /// A text column with a maximum length of 255 (2^8 - 1) characters. + /// + TinyText = 749, + /// + /// A text column with a maximum length of 16777215 (2^24 - 1) characters. + /// + MediumText = 750, + /// + /// A text column with a maximum length of 4294967295 or + /// 4G (2^32 - 1) characters. + /// + LongText = 751, + /// + /// A text column with a maximum length of 65535 (2^16 - 1) characters. + /// + Text = 752 }; Modified: branches/5.0/Driver/Source/NativeDriver.cs =================================================================== --- branches/5.0/Driver/Source/NativeDriver.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/Driver/Source/NativeDriver.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -691,10 +691,10 @@ field.RealTableName = stream.ReadLenString(); field.ColumnName = stream.ReadLenString(); field.OriginalColumnName = stream.ReadLenString(); - stream.ReadByte(); - field.CharactetSetIndex = stream.ReadInteger(2); + byte b = (byte)stream.ReadByte(); + field.CharacterSetIndex = stream.ReadInteger(2); field.ColumnLength = stream.ReadInteger(4); - MySqlDbType type = (MySqlDbType)stream.ReadByte(); + MySqlDbType type = (MySqlDbType)stream.ReadByte(); ColumnFlags colFlags; if ((Flags & ClientFlags.LONG_FLAG) != 0) colFlags = (ColumnFlags)stream.ReadInteger(2); @@ -704,14 +704,16 @@ field.Scale = (byte)stream.ReadByte(); - if (stream.HasMoreData) - stream.ReadInteger(2); // reserved + if (stream.HasMoreData) + { + int reserved = stream.ReadInteger(2); // reserved + } if (charSets != null) { - CharacterSet cs = CharSetMap.GetChararcterSet(this.Version, (string)charSets[field.CharactetSetIndex]); + CharacterSet cs = CharSetMap.GetChararcterSet(this.Version, (string)charSets[field.CharacterSetIndex]); field.MaxLength = cs.byteCount; - field.Encoding = CharSetMap.GetEncoding(this.version, (string)charSets[field.CharactetSetIndex]); + field.Encoding = CharSetMap.GetEncoding(this.version, (string)charSets[field.CharacterSetIndex]); } return field; Modified: branches/5.0/Driver/Source/StoredProcedure.cs =================================================================== --- branches/5.0/Driver/Source/StoredProcedure.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/Driver/Source/StoredProcedure.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -206,7 +206,7 @@ { string fieldName = reader.GetName(i); fieldName = marker + fieldName.Remove(0, hash.Length + 1); - reader.values[i] = MySqlField.GetIMySqlValue(Parameters[fieldName].MySqlDbType, true); + reader.values[i] = MySqlField.GetIMySqlValue(Parameters[fieldName].MySqlDbType); } reader.Read(); Modified: branches/5.0/Driver/Source/Types/MetaData.cs =================================================================== --- branches/5.0/Driver/Source/Types/MetaData.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/Driver/Source/Types/MetaData.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -72,18 +72,26 @@ case "double": return MySqlDbType.Double; case "real": return realAsFloat ? MySqlDbType.Float : MySqlDbType.Double; - case "blob": - case "text": + case "text": + return MySqlDbType.Text; + case "blob": return MySqlDbType.Blob; case "longblob": - case "longtext": - return MySqlDbType.LongBlob; + return MySqlDbType.LongBlob; + case "longtext": + return MySqlDbType.LongText; case "mediumblob": - case "mediumtext": - return MySqlDbType.MediumBlob; + return MySqlDbType.MediumBlob; + case "mediumtext": + return MySqlDbType.MediumText; case "tinyblob": + return MySqlDbType.TinyBlob; case "tinytext": - return MySqlDbType.TinyBlob; + return MySqlDbType.TinyText; + case "binary": + return MySqlDbType.Binary; + case "varbinary": + return MySqlDbType.VarBinary; } throw new MySqlException("Unhandled type encountered"); } Modified: branches/5.0/Driver/Source/parameter.cs =================================================================== --- branches/5.0/Driver/Source/parameter.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/Driver/Source/parameter.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -358,7 +358,7 @@ internal void Serialize(MySqlStream stream, bool binary) { - IMySqlValue v = MySqlField.GetIMySqlValue(mySqlDbType, true); + IMySqlValue v = MySqlField.GetIMySqlValue(mySqlDbType); if (!binary && (paramValue == null || paramValue == DBNull.Value)) stream.WriteStringNoNull("NULL"); Modified: branches/5.0/TestSuite/DataTypeTests.cs =================================================================== --- branches/5.0/TestSuite/DataTypeTests.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/TestSuite/DataTypeTests.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -737,7 +737,6 @@ /// /// Bug #25605 BINARY and VARBINARY is returned as a string /// - [Category("NotWorking")] [Test] public void BinaryAndVarBinary() { Modified: branches/5.0/TestSuite/StoredProcedure.cs =================================================================== --- branches/5.0/TestSuite/StoredProcedure.cs 2007-03-02 19:10:40 UTC (rev 625) +++ branches/5.0/TestSuite/StoredProcedure.cs 2007-03-02 19:14:21 UTC (rev 626) @@ -1158,5 +1158,40 @@ } } } + + [Test] + public void BinaryAndVarBinaryParameters() + { + execSQL("DROP PROCEDURE IF EXISTS spTest"); + execSQL("CREATE PROCEDURE spTest(OUT out1 BINARY(20), OUT out2 VARBINARY(20)) " + + "BEGIN SET out1 = 'out1'; SET out2='out2'; END"); + + try + { + MySqlCommand cmd = new MySqlCommand("spTest", conn); + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.Add("out1", MySqlDbType.Binary); + cmd.Parameters[0].Direction = ParameterDirection.Output; + cmd.Parameters.Add("out2", MySqlDbType.VarBinary); + cmd.Parameters[1].Direction = ParameterDirection.Output; + cmd.ExecuteNonQuery(); + + byte[] out1 = (byte[])cmd.Parameters[0].Value; + Assert.AreEqual('o', out1[0]); + Assert.AreEqual('u', out1[1]); + Assert.AreEqual('t', out1[2]); + Assert.AreEqual('1', out1[3]); + + out1 = (byte[])cmd.Parameters[1].Value; + Assert.AreEqual('o', out1[0]); + Assert.AreEqual('u', out1[1]); + Assert.AreEqual('t', out1[2]); + Assert.AreEqual('2', out1[3]); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } } }