Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #4489: SQL Anywhere incorrectly reports VARCHAR(n CHAR) as VARCHAR(n) #4499

Merged
merged 3 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {
SQL_FILTER_MATCH_ALL)
);
//
// IF MARIADB
// IF MARIADB OR SQL ANYWHERE
// Query to get actual data types and then map each column to its CachedRow
//
determineActualDataTypes(returnList, tableName);
Expand Down Expand Up @@ -431,7 +431,7 @@ public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {
escapeForLike(((AbstractJdbcDatabase) database).getJdbcSchemaName(catalogAndSchema), database),
SQL_FILTER_MATCH_ALL, SQL_FILTER_MATCH_ALL));
//
// IF MARIADB
// IF MARIADB OR SQL ANYWHERE
// Query to get actual data types and then map each column to its CachedRow
//
determineActualDataTypes(returnList, null);
Expand All @@ -449,11 +449,58 @@ public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {
// For MariaDB, query for the data type column so that we can correctly
// set the DATETIME(6) type if specified
//
// For SQL Anywhere, query for the scale column so we can correctly
// set the size unit
//
private void determineActualDataTypes(List<CachedRow> returnList, String tableName) {
//
// If not MariaDB then just return
// If not MariaDB / SQL Anywhere then just return
//
if (!(database instanceof MariaDBDatabase)) {
if (!(database instanceof MariaDBDatabase || database instanceof SybaseASADatabase)) {
return;
}

if (database instanceof SybaseASADatabase) {
//
// Query for actual data type for column. The actual SYSTABCOL.scale column value is
// not reported by the DatabaseMetadata.getColumns() query for CHAR-limited (in contrast
// to BYTE-limited) columns, and it is needed to capture the kind if limitation.
//
// See https://help.sap.com/docs/SAP_SQL_Anywhere/93079d4ba8e44920ae63ffb4def91f5b/3beaa3956c5f1014883cb0c3e3559cc9.html.
//
String selectStatement =
"SELECT table_name, column_name, scale FROM SYSTABCOL KEY JOIN SYSTAB KEY JOIN SYSUSER " +
"WHERE user_name = ? AND ? IS NULL OR table_name = ?";
Connection underlyingConnection = ((JdbcConnection) database.getConnection()).getUnderlyingConnection();
try (PreparedStatement stmt = underlyingConnection.prepareStatement(selectStatement)) {
stmt.setString(1, schemaName);
stmt.setString(2, tableName);
stmt.setString(3, tableName);
try (ResultSet columnSelectRS = stmt.executeQuery()) {
while (columnSelectRS.next()) {
String selectedTableName = columnSelectRS.getString("table_name");
String selectedColumnName = columnSelectRS.getString("column_name");
int selectedScale = columnSelectRS.getInt("scale");
for (CachedRow row : returnList) {
String rowTableName = row.getString("TABLE_NAME");
String rowColumnName = row.getString("COLUMN_NAME");
if (rowTableName.equalsIgnoreCase(selectedTableName) &&
rowColumnName.equalsIgnoreCase(selectedColumnName)) {
int rowDataType = row.getInt("DATA_TYPE");
if (rowDataType == Types.VARCHAR || rowDataType == Types.CHAR) {
row.set("scale", selectedScale);
}
break;
}
}
}
}
} catch (SQLException sqle) {
throw new RuntimeException(sqle);
//
// Do not stop
//
}
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,12 @@ protected DataType readDataType(CachedRow columnMetadataResultSet, Column column

DataType.ColumnSizeUnit columnSizeUnit = DataType.ColumnSizeUnit.BYTE;

if (database instanceof SybaseASADatabase &&
(columnMetadataResultSet.getInt("DATA_TYPE") == Types.VARCHAR || columnMetadataResultSet.getInt("DATA_TYPE") == Types.CHAR) &&
columnMetadataResultSet.getInt("scale") == 1) {
columnSizeUnit = DataType.ColumnSizeUnit.CHAR;
}

int dataType = columnMetadataResultSet.getInt("DATA_TYPE");
Integer columnSize = null;
Integer decimalDigits = null;
Expand Down