function TZInterbase6DatabaseMetadata.UncachedGetColumns (from unit ZDbcInterbase6Metadata) recognize numeric/decimal columns only if the field is 8 bytes long. In other cases the column is reported as smallint or integer.
TEST:
Code: Select all
procedure TForm1.GetMeta;
var
rs: IZResultSet;
begin
rs := ZConnection1.DbcConnection.GetMetadata.GetColumns('', '', 'NUMTEST', '');
while rs.Next do
Memo1.Lines.Add( Format('%s : %s (%s, %s)', [
rs.GetString(ColumnNameIndex),
rs.GetString(TableColColumnTypeNameIndex),
rs.GetString(TableColColumnSizeIndex),
rs.GetString(TableColColumnDecimalDigitsIndex)
]));
end;
N51 : INTEGER (0, 1) // col : type (precision, scale)
N41 : SMALLINT (0, 1)
D51 : INTEGER (0, 1)
after fix:
N51 : NUMERIC (5, 1)
N41 : NUMERIC (4, 1)
D51 : DECIMAL (5, 1)
FIX:
Code: Select all
function TZMsSqlDatabaseMetadata.UncachedGetColumns
...
(* bug fix start, line 1794 in the original code *)
// TYPE_NAME
case TypeName of
7 : Result.UpdateString(TableColColumnTypeNameIndex, 'SMALLINT');
8 : Result.UpdateString(TableColColumnTypeNameIndex, 'INTEGER' );
37 : Result.UpdateString(TableColColumnTypeNameIndex, 'VARCHAR'); // Instead of VARYING
else
Result.UpdateString(TableColColumnTypeNameIndex, GetString(ColumnIndexes[8]));
end;
if (TypeName in [7, 8, 16]) then
if (SubTypeName = 1) then
Result.UpdateString(TableColColumnTypeNameIndex, 'NUMERIC')
else if (SubTypeName = 2) then
Result.UpdateString(TableColColumnTypeNameIndex, 'DECIMAL');
// COLUMN_SIZE.
case TypeName of
7, 8, 16: Result.UpdateInt(TableColColumnSizeIndex, GetInt(ColumnIndexes[9]));
37, 38: Result.UpdateNull(TableColColumnSizeIndex); //the defaults of the resultsets will be used if null
else
Result.UpdateInt(TableColColumnSizeIndex, GetInt(ColumnIndexes[10]));
end;
(* bug fix end *)
(* old code, replaced by the bug fix
// TYPE_NAME
case TypeName of
7 : Result.UpdateString(TableColColumnTypeNameIndex, 'SMALLINT');
8 : Result.UpdateString(TableColColumnTypeNameIndex, 'INTEGER' );
16 :
begin
if (SubTypeName = 0) then
Result.UpdateString(TableColColumnTypeNameIndex, GetString(ColumnIndexes[8]));
if (SubTypeName = 1) then
Result.UpdateString(TableColColumnTypeNameIndex, 'NUMERIC');
if (SubTypeName = 2) then
Result.UpdateString(TableColColumnTypeNameIndex, 'DECIMAL');
end;
37 : Result.UpdateString(TableColColumnTypeNameIndex, 'VARCHAR'); // Instead of VARYING
else
Result.UpdateString(TableColColumnTypeNameIndex, GetString(ColumnIndexes[8]));
end;
// COLUMN_SIZE.
case TypeName of
7, 8 : Result.UpdateInt(TableColColumnSizeIndex, 0);
16 : Result.UpdateInt(TableColColumnSizeIndex, GetInt(ColumnIndexes[9]));
37, 38: Result.UpdateNull(TableColColumnSizeIndex); //the defaults of the resultsets will be used if null
{if ( ConSettings.ClientCodePage.ID = 0 ) then //CharcterSet 'NONE'
Result.UpdateInt(TableColColumnSizeIndex, GetFieldSize(SQLType, ConSettings,
GetInt(ColumnIndexes[10]), GetConnection.GetIZPlainDriver.ValidateCharEncoding(SubTypeName).CharWidth, nil, True)) //FireBird return Char*Bytes for Varchar
else
Result.UpdateInt(TableColColumnSizeIndex, GetFieldSize(SQLType, ConSettings,
GetInt(ColumnIndexes[10]), ConSettings.ClientCodePage.CharWidth, nil, True)); //FireBird return Char*Bytes for Varchar}
else
Result.UpdateInt(TableColColumnSizeIndex, GetInt(ColumnIndexes[10]));
end;
*)