aws / aws/amazon-redshift-odbc-driver

TEXT data type not mapped in SQLColumns metadata path — breaks Tableau field resolution

Open Beginner friendly
#43 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.