Skip to content

Commit

Permalink
SQL-2193: Add support for wlongvarchar and wchar types with conversio…
Browse files Browse the repository at this point in the history
…ns to those types (#232)

* add types

* Fix direct query with large string datasets

* Update tests

* Update tests

* Add longvarchar and wchar conversion support, add comments

* Add longvarchar and char to types

* Fix comment

* Update bson_type_info.rs

* Update bson_type_info.rs
  • Loading branch information
pmeredit authored Jul 6, 2024
1 parent 274f04e commit c8659a3
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 88 deletions.
92 changes: 7 additions & 85 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions constants/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,12 @@ pub const MONGO_CAST_SUPPORT: u32 = SQL_CVT_CHAR
| SQL_CVT_FLOAT
| SQL_CVT_REAL
| SQL_CVT_DOUBLE
| SQL_CVT_CHAR
| SQL_CVT_LONGVARCHAR
| SQL_CVT_VARCHAR
| SQL_CVT_WCHAR
| SQL_CVT_WLONGVARCHAR
| SQL_CVT_WVARCHAR
| SQL_CVT_BIT
| SQL_CVT_TIMESTAMP;

Expand Down
108 changes: 108 additions & 0 deletions core/src/bson_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ impl BsonTypeInfo {
column_size: make_default_attr_func!(Some(15)),
simple_type_info: None,
};
// This represents the literal mongodb string type. Other bson type
// info mapping to "string" are aliases for the benefits of bi tools.
pub const STRING: BsonTypeInfo = BsonTypeInfo {
type_name: "string",
sql_type: SqlDataType::SQL_WVARCHAR,
Expand All @@ -194,6 +196,59 @@ impl BsonTypeInfo {
};
// This is essentially here just to support Direct Query casting
// to text in Power BI because they look for a type that is specifically
// sqltype = CHAR.
pub const CHAR: BsonTypeInfo = BsonTypeInfo {
type_name: "string",
sql_type: SqlDataType::SQL_CHAR,
non_concise_type: None,
searchable: SQL_SEARCHABLE,
is_case_sensitive: true,
fixed_prec_scale: false,
scale: None,
length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
precision: None,
char_octet_length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
transfer_octet_length: None,
display_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
literal_prefix: Some("'"),
literal_suffix: Some("'"),
sql_code: None,
is_auto_unique_value: None,
is_unsigned: None,
num_prec_radix: None,
decimal_digit: None,
column_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
simple_type_info: None,
};
// This is essentially here just to support Direct Query casting
// to text in Power BI because they look for a type that is specifically
// sqltype = LONGVARCHAR. This comes up when scrolling through large string
// datasets with direct query enabled.
pub const LONGVARCHAR: BsonTypeInfo = BsonTypeInfo {
type_name: "string",
sql_type: SqlDataType::SQL_LONGVARCHAR,
non_concise_type: None,
searchable: SQL_SEARCHABLE,
is_case_sensitive: true,
fixed_prec_scale: false,
scale: None,
length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
precision: None,
char_octet_length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
transfer_octet_length: None,
display_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
literal_prefix: Some("'"),
literal_suffix: Some("'"),
sql_code: None,
is_auto_unique_value: None,
is_unsigned: None,
num_prec_radix: None,
decimal_digit: None,
column_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
simple_type_info: None,
};
// This is essentially here just to support Direct Query casting
// to text in Power BI because they look for a type that is specifically
// sqltype = VARCHAR
pub const VARCHAR: BsonTypeInfo = BsonTypeInfo {
type_name: "varchar",
Expand All @@ -218,6 +273,59 @@ impl BsonTypeInfo {
column_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
simple_type_info: None,
};
// This is essentially here just to support Direct Query casting
// to text in Power BI because they look for a type that is specifically
// sqltype = WLONGVARCHAR. This comes up when scrolling through large string
// datasets with direct query enabled.
pub const WLONGVARCHAR: BsonTypeInfo = BsonTypeInfo {
type_name: "string",
sql_type: SqlDataType::SQL_WLONGVARCHAR,
non_concise_type: None,
searchable: SQL_SEARCHABLE,
is_case_sensitive: true,
fixed_prec_scale: false,
scale: None,
length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
precision: None,
char_octet_length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
transfer_octet_length: None,
display_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
literal_prefix: Some("'"),
literal_suffix: Some("'"),
sql_code: None,
is_auto_unique_value: None,
is_unsigned: None,
num_prec_radix: None,
decimal_digit: None,
column_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
simple_type_info: None,
};
// This is essentially here just to support Direct Query casting
// to text in Power BI because they look for a type that is specifically
// sqltype = WCHAR
pub const WCHAR: BsonTypeInfo = BsonTypeInfo {
type_name: "string",
sql_type: SqlDataType::SQL_WCHAR,
non_concise_type: None,
searchable: SQL_SEARCHABLE,
is_case_sensitive: true,
fixed_prec_scale: false,
scale: None,
length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
precision: None,
char_octet_length: make_default_attr_func!(Some(MAX_STRING_SIZE)),
transfer_octet_length: None,
display_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
literal_prefix: Some("'"),
literal_suffix: Some("'"),
sql_code: None,
is_auto_unique_value: None,
is_unsigned: None,
num_prec_radix: None,
decimal_digit: None,
column_size: make_default_attr_func!(Some(MAX_STRING_SIZE)),
simple_type_info: None,
};
pub const OBJECT: BsonTypeInfo = BsonTypeInfo {
type_name: "object",
sql_type: SqlDataType::SQL_UNKNOWN_TYPE,
Expand Down
2 changes: 1 addition & 1 deletion core/src/err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub enum Error {
QueryCursorUpdate(mongodb::error::Error),
#[error("Getting metadata for query failed with error: {0}")]
QueryDeserialization(mongodb::bson::de::Error),
#[error("Trying to execute query failed with error: {0}")]
#[error("Trying to execute query failed with error: {0:?}")]
QueryExecutionFailed(mongodb::error::Error),
#[error("Unknown column '{0}' in result set schema")]
UnknownColumn(String),
Expand Down
6 changes: 5 additions & 1 deletion core/src/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,14 @@ const LEGACY_DATE: BsonTypeInfo = BsonTypeInfo {

// order of array is by SqlDataType, since that is the ordering of the
// SQLGetTypeInfo result set according to the spec
const DATA_TYPES: [BsonTypeInfo; 23] = [
const DATA_TYPES: [BsonTypeInfo; 27] = [
BsonTypeInfo::WLONGVARCHAR, // SqlDataType(-10)
BsonTypeInfo::STRING, // SqlDataType(-9)
BsonTypeInfo::WCHAR, // SqlDataType(-8)
BsonTypeInfo::BOOL, // SqlDataType(-7)
BsonTypeInfo::LONG, // SqlDataType(-5)
BsonTypeInfo::BINDATA, // SqlDataType(-2)
BsonTypeInfo::LONGVARCHAR, // SqlDataType(-1)
BsonTypeInfo::ARRAY, // SqlDataType(0)
BsonTypeInfo::BSON, // SqlDataType(0)
BsonTypeInfo::DBPOINTER, // SqlDataType(0)
Expand All @@ -55,6 +58,7 @@ const DATA_TYPES: [BsonTypeInfo; 23] = [
BsonTypeInfo::SYMBOL, // SqlDataType(0)
BsonTypeInfo::TIMESTAMP, // SqlDataType(0)
BsonTypeInfo::UNDEFINED, // SqlDataType(0)
BsonTypeInfo::CHAR, // SqlDataType(1)
BsonTypeInfo::INT, // SqlDataType(4)
BsonTypeInfo::DOUBLE, // SqlDataType(8)
LEGACY_DATE, // SqlDataType(11)
Expand Down
6 changes: 5 additions & 1 deletion integration_test/tests/odbc_2_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,14 @@ mod integration {
let _ = unsafe { Box::from_raw(env_handle) };
}

const EXPECTED_DATATYPES: [SqlDataType; 23] = [
const EXPECTED_DATATYPES: [SqlDataType; 27] = [
SqlDataType::SQL_WLONGVARCHAR,
SqlDataType::SQL_WVARCHAR,
SqlDataType::SQL_WCHAR,
SqlDataType::SQL_BIT,
SqlDataType::SQL_BIGINT,
SqlDataType::SQL_BINARY,
SqlDataType::SQL_LONGVARCHAR,
SqlDataType::SQL_UNKNOWN_TYPE,
SqlDataType::SQL_UNKNOWN_TYPE,
SqlDataType::SQL_UNKNOWN_TYPE,
Expand All @@ -85,6 +88,7 @@ mod integration {
SqlDataType::SQL_UNKNOWN_TYPE,
SqlDataType::SQL_UNKNOWN_TYPE,
SqlDataType::SQL_UNKNOWN_TYPE,
SqlDataType::SQL_CHAR,
SqlDataType::SQL_INTEGER,
SqlDataType::SQL_DOUBLE,
SqlDataType::SQL_TIMESTAMP,
Expand Down
8 changes: 8 additions & 0 deletions resources/integration_test/tests/functions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@ tests:
db: integration_test
is_standard_type: true
expected_result:
- [ "string", -10, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -10, null, null, null ]
- [ "string", -9, null, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -9, null, null, null ]
- [ "string", -8, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -8, null, null, null ]
- [ "bool", -7, 1, null, null, null, 1, 0, 2, null, 0, null, "bool", 0, 0, -7, null, null, null ]
- [ "long", -5, 20, null, null, null, 1, 0, 2, 0, 1, 0, "long", 0, 0, -5, null, 10, null ]
- [ "binData", -2, null, null, null, null, 1, 0, 0, null, 0, null, "binData", null, null, -2, null, null, null ]
- [ "string", -1, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -1, null, null, null ]
- [ "array", 0, null, null, null, null, 1, 0, 0, null, 0, null, "array", null, null, 0, null, null, null ]
- [ "bson", 0, null, null, null, null, 1, 0, 0, null, 0, null, "bson", null, null, 0, null, null, null ]
- [ "dbPointer", 0, null, null, null, null, 1, 0, 2, null, 0, null, "dbPointer", null, null, 0, null, null, null ]
Expand All @@ -74,6 +77,7 @@ tests:
- [ "symbol", 0, null, null, null, null, 1, 0, 2, null, 0, null, "symbol", null, null, 0, null, null, null ]
- [ "timestamp", 0, null, null, null, null, 1, 0, 2, null, 0, null, "timestamp", null, null, 0, null, null, null ]
- [ "undefined", 0, null, null, null, null, 1, 0, 0, null, 0, null, "undefined", null, null, 0, null, null, null ]
- [ "string", 1, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, 1, null, null, null ]
- [ "int", 4, 10, null, null, null, 1, 0, 2, 0, 1, 0, "int", 0, 0, 4, null, 10, null ]
- [ "double", 8, 15, null, null, null, 1, 0, 2, 0, 0, 0, "double", 0, 0, 8, null, 2, null ]
- [ "date", 11, 23, "'", "'", null, 1, 0, 2, null, 1, null, "date", 3, 3, 11, 3, null, null ]
Expand All @@ -83,10 +87,13 @@ tests:
test_definition: [ "sqlgettypeinfo", 0 ]
db: integration_test
expected_result:
- [ "string", -10, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -10, null, null, null ]
- [ "string", -9, null, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -9, null, null, null ]
- [ "string", -8, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -8, null, null, null ]
- [ "bool", -7, 1, null, null, null, 1, 0, 2, null, 0, null, "bool", 0, 0, -7, null, null, null ]
- [ "long", -5, 20, null, null, null, 1, 0, 2, 0, 1, 0, "long", 0, 0, -5, null, 10, null ]
- [ "binData", -9, null, null, null, null, 1, 0, 0, null, 0, null, "binData", null, null, -9, null, null, null ]
- [ "string", -1, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, -1, null, null, null ]
- [ "array", -9, null, null, null, null, 1, 0, 0, null, 0, null, "array", null, null, -9, null, null, null ]
- [ "bson", -9, null, null, null, null, 1, 0, 0, null, 0, null, "bson", null, null, -9, null, null, null ]
- [ "dbPointer", -9, null, null, null, null, 1, 0, 2, null, 0, null, "dbPointer", null, null, -9, null, null, null ]
Expand All @@ -101,6 +108,7 @@ tests:
- [ "symbol", -9, null, null, null, null, 1, 0, 2, null, 0, null, "symbol", null, null, -9, null, null, null ]
- [ "timestamp", -9, 68, null, null, null, 1, 0, 2, null, 0, null, "timestamp", null, null, -9, null, null, null ]
- [ "undefined", -9, 20, null, null, null, 1, 0, 0, null, 0, null, "undefined", null, null, -9, null, null, null ]
- [ "string", 1, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "string", null, null, 1, null, null, null ]
- [ "int", 4, 10, null, null, null, 1, 0, 2, 0, 1, 0, "int", 0, 0, 4, null, 10, null ]
- [ "double", 8, 15, null, null, null, 1, 0, 2, 0, 0, 0, "double", 0, 0, 8, null, 2, null ]
- [ "date", 11, 23, "'", "'", null, 1, 0, 2, null, 1, null, "date", 3, 3, 11, 3, null, null ]
Expand Down

0 comments on commit c8659a3

Please sign in to comment.