Closed datiscum closed 2 years ago
What reason is there to take any original type of Firebird +1 ?
Because we perform some "Bitwise AND" operations with the sqltype. So this sql_type_and_subtype
doesn't reflects the exactly firebird type.
I think the blob subtypes are also swapped.
Not exactly. We use the sub_type 0
for raw binary here.
But when we have a text until 32.769 chars, we can send it as a normal varchar(ibase::SQL_TEXT + 1
), after that size we send it as a blob sub_type 0
(ibase::SQL_BLOB + 1
).
For matching the Firebird types, you can use the SqlType enum values:
let abd = row.cols[0];
if abd == SqlType::Integer {
println!("Int64 " );
}
For matching the Firebird types, you can use the SqlType enum values:
let abd = row.cols[0]; if abd == SqlType::Integer { println!("Int64 " ); }
Unfortunately, it doesn't work like that and my attempts to change it myself haven't worked yet either. But when I am a bit more familiar with RUST, it should be feasible. That was the reason why I came up with the idea of "if abd.0 == SQL_INT64" in the first place. Thank you
I haven't tested the code in my answer, maybe a .value
is missing:
let abd = row.cols[0].value;
If you need more help, you can share a gist with your full code.
Didn't work either! I have tested this and other variants, but only got from one error to the next.
The last bit of the sqltype number is 0 if the column is not nullable, and 1 if the column is nullable.
If you just want to compare with the type, you can use sqltype & (!1) == ibase::SQL_TEXT
to set the last bit to 0.
I've only been looking at Rust for two days, but I've been dealing with Firebird/Interbase for 20 years. When trying with the sample sources, I wanted to test the SQLType of the field:
let abd: (u32, u32) = row.cols[0].value.sql_type_and_subtype(); if abd.0 == SQL_INT64 { println!("Int64 " ); }
This did not work because " abd.0 == SQL_INT64 + 1 " is
Extract from params.rs impl SqlType { /// Convert the sql value to interbase format pub fn sql_type_and_subtype(&self) -> (u32, u32) { match self { Text(s) => { if s.len() > MAX_TEXT_LENGTH { (ibase::SQL_BLOB + 1, 1) } else { (ibase::SQLTEXT + 1, 0) } } Integer() => (ibase::SQLINT64 + 1, 0), Floating() => (ibase::SQLDOUBLE + 1, 0), Timestamp() => (ibase::SQL_TIMESTAMP + 1, 0), Null => (ibase::SQLTEXT + 1, 0), Binary() => (ibase::SQLBLOB + 1, 0), Boolean() => (ibase::SQL_BOOLEAN + 1, 0), } } } What reason is there to take any original type of Firebird +1 ?
I think the blob subtypes are also swapped. Excerpt from : https://firebirdsql.org/file/documentation/chunk/en/refdocs/fblangref30/fblangref30-datatypes-bnrytypes.html
3.7.1 BLOB subtypes
The optional SUB_TYPE parameter specifies the nature of data written to the column. Firebird provides two pre-defined subtypes for storing user data:
Subtype 0: BINARY (ibase::SQL_BLOB + 1, ->1<-) If a subtype is not specified, the specification is assumed to be for untyped data and the default SUB_TYPE 0 is applied. The alias for subtype zero is BINARY. This is the subtype to specify when the data are any form of binary file or stream: images, audio, word-processor files, PDFs and so on. Subtype 1: TEXT (ibase::SQL_TEXT + 1, ->0<- ) Subtype 1 has an alias, TEXT, which can be used in declarations and definitions. For instance, BLOB SUB_TYPE TEXT. It is a specialised subtype used to store plain text data that is too large to fit into a string type.