aws / aws/amazon-redshift-odbc-driver
TEXT data type not mapped in SQLColumns metadata path — breaks Tableau field resolution
- Dominant language
- C
- Stars
- 25
- Forks
- 17
- PR merge metrics
- No merged PRs in 30d
Description
## Bug: Redshift TEXT data type not mapped in SQLColumns metadata path — breaks Tableau field resolution
### Driver version
2.1.16.0 (also affects 2.1.2 through 2.1.17 for the `typeInfoMap` issue)
### Platform
macOS arm64 (Apple Silicon), Tableau Desktop 2025.3
### Description
Columns defined with the Redshift `TEXT` data type are not recognized by ODBC applications that use `SQLColumns` for metadata discovery. The driver's `SHOW COLUMNS` metadata path returns `data_type = "text"` from the server, but the `typeInfoMap` in `rsMetadataAPIHelper.cpp` has no entry for `"text"`, causing the type lookup to fail. The column is reported with an unknown SQL type, which causes applications like Tableau to silently drop the field.
This produces the Tableau error:
```
The field xxx does not exist in the database.
```
### Root cause
There are two gaps in the driver code:
**1. Missing `"text"` entry in `typeInfoMap` (`rsMetadataAPIHelper.cpp:572-623`)** https://github.com/aws/amazon-redshift-odbc-driver/blob/main/src/odbc/rsodbc/rsMetadataAPIHelper.cpp#L572-L580
The map includes `"character varying"`, `"varchar"`, `"bpchar"`, `"string"`, etc. — but not `"text"`. When `processDataTypeInfo()` looks up `"text"`, it gets `TypeInfoResult::notFound()`.
Note that `"text"` is already listed in `VALID_TYPES` (line 710), confirming the omission from `typeInfoMap` is an oversight. https://github.com/aws/amazon-redshift-odbc-driver/blob/main/src/odbc/rsodbc/rsMetadataAPIHelper.cpp#L710
The wire-protocol path was fixed in commit `dcff10f` (v2.1.2, "Added missing OID mapping for Redshift Text data type"), which added `case TEXTOID:` to `mapPgTypeToSqlType()` in `rslibpq.c`. However, the newer `SHOW COLUMNS` metadata proxy path introduced for `showDiscoveryVersion >= V4` uses `typeInfoMap` for type resolution and was never updated to include `"text"`.
**2. Missing `TEXTOID` size assignment in `getResultDescription()` (`rslibpq.c:2119-2152`)**
When `pgMod = -1` (always the case for `text`), there is no `TEXTOID` case in the if-else chain, so `iSize` falls through to `0`. Redshift TEXT is equivalent to VARCHAR(256), so the size should be 256. With `iSize = 0`, downstream logic (including `applyVarcharPromotion` from v2.1.16) may behave unexpectedly.
### Proposed fix
**Change 1** — Add to `typeInfoMap` in `rsMetadataAPIHelper.cpp` after the `"varchar"` entry:
```cpp
{"text", {SQL_VARCHAR, SQL_VARCHAR, kNotApplicable, "varchar"}},
```
**Change 2** — Add `TEXTOID` case in `getResultDescription()` in `rslibpq.c` inside the `if(pgMod < 0)` branch:
```c
if(pgType == TEXTOID)
pDescRec->iSize = 256;
else
if(pgType == NAMEOID)
pDescRec->iSize = MAX_NAMEOID_SIZE;
```
Both are one-line additions.
### Steps to reproduce
1. Create a Redshift table with a `TEXT` column:
```sql
CREATE TABLE test_text_type (
id INT IDENTITY(1,1),
name VARCHAR(256),
label TEXT
);
INSERT INTO test_text_type (name, label) VALUES ('test', 'hello');
```
2. Connect using ODBC 2.x driver (v2.1.16.0) and call `SQLColumns` for the table.
3. Observe that `name` (VARCHAR) is correctly reported as `SQL_VARCHAR`, but `label` (TEXT) is reported with an unknown/incorrect type.
4. In Tableau: connect to the table and try to use the `label` field — Tableau reports "The field label does not exist in the database."
### Verification
Confirm the column exists and is typed as `text`:
```sql
SELECT column_name, data_type, udt_name, character_maximum_length
FROM information_schema.columns
WHERE table_name = 'test_text_type';
```
| column_name | data_type | udt_name | character_maximum_length |
|-------------|-----------|----------|--------------------------|
| id | integer | int4 | NULL |
| name | character varying | varchar | 256 |
| label | text | text | NULL |
### Workaround
Setting `MaxVarcharSize=0` in the connection string partially mitigates the issue by disabling varchar-to-longvarchar promotion. However, this does not fix the missing `typeInfoMap` entry — the `SHOW COLUMNS` metadata path will still fail to map `"text"` to `SQL_VARCHAR`. This probably will not work in tableau
Contributor guide
Research direction
Inspect src/odbc/rsodbc/rsMetadataAPIHelper.cpp around typeInfoMap and rslibpq.c around getResultDescription(), then trace the SQLColumns SHOW COLUMNS path and the existing TEXTOID handling. Done means TEXT resolves to SQL_VARCHAR through metadata discovery and its result description reports size 256; verify with the provided test_text_type SQL and SQLColumns reproduction steps.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100