{
  "id": "supported-types",
  "title": "Supported data types by source",
  "url": "https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/supported-types/",
  "summary": "Learn about supported data types for each source database.",
  "tags": [
    "docs",
    "integrate",
    "rs",
    "rdi"
  ],
  "last_updated": "2026-07-02T11:31:07-05:00",
  "page_type": "content",
  "content_hash": "2d367e71a2dd83d3a4fc4d2650e89a5232d2c0e9d5c4a1b3900b1495bb9d5f2e",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "This page describes the source data types that RDI captures for the\n[Oracle](#oracle), [MySQL/MariaDB](#mysql-and-mariadb),\n[PostgreSQL](#postgresql-supabase-and-alloydb), [SQL Server](#sql-server),\n[MongoDB](#mongodb), and [Spanner](#spanner) source databases, and how they are\nrepresented in Redis. There are also some\n[cross-cutting considerations](#cross-cutting-considerations) that apply to all\nsource databases."
    },
    {
      "id": "how-rdi-captures-and-represents-data",
      "title": "How RDI captures and represents data",
      "role": "content",
      "text": "For most source databases, RDI uses an embedded\n[Debezium](https://debezium.io/) connector as its change data capture (CDC)\n*collector*. RDI ships a Debezium 3.x–based collector, so the collector-level\nmappings on this page follow the\n[Debezium connector reference](https://debezium.io/documentation/reference/).\n[Google Cloud Spanner](#spanner) is the exception: it uses a Flink-based collector\nthat reads Spanner change streams rather than Debezium (see the\n[Spanner section](#spanner) for details).\n\n**RDI does not always pass the collector value through unchanged.** RDI's\nprocessors normalize several Debezium logical types before they reach your jobs and\nRedis, and drop a few that they cannot represent. The collector-level representations\nin the tables below are therefore the *input* to RDI's processing, not always the\nfinal Redis value — the per-type notes and [cross-cutting considerations](#cross-cutting-considerations)\ncall out where RDI transforms or drops a value.\n\nIt helps to think of the data flow in two layers:\n\n1. **What the collector emits.** Debezium converts each source column to a\n   Kafka Connect value with a *literal type* (for example, `STRING`, `INT64`,\n   `BYTES`, `STRUCT`) and an optional *semantic type* (for example,\n   `io.debezium.time.MicroTimestamp`). Several of these conversions are controlled\n   by connector properties such as\n   [`decimal.handling.mode`](#decimal-and-numeric-values),\n   [`binary.handling.mode`](#binary-values), and\n   [`time.precision.mode`](#temporal-values). The tables below show the\n   representation that each connector produces with its **default** settings.\n2. **How RDI writes it to Redis.** RDI's processors take the collector value,\n   normalize some logical types (and drop a few unsupported ones), then write each\n   record to a Redis [Hash](https://redis.io/docs/latest/develop/data-types/hashes) (the default)\n   or, if you set `target_data_type: json`, to a\n   [JSON](https://redis.io/docs/latest/develop/data-types/json) document. For Hash targets,\n   every field value is stored as a string; for JSON targets, numbers and booleans\n   are stored as native JSON values.\n\nWhen you need to reformat a value in a job, see\n[Formatting date and time values](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/transform-examples/formatting-date-and-time-values)\nfor worked examples."
    },
    {
      "id": "setting-collector-properties",
      "title": "Setting collector properties",
      "role": "configuration",
      "text": "Where the sections below recommend a Debezium property (for example,\n`decimal.handling.mode` or `lob.enabled`), set it in the `advanced.source` block of\nthe source in your pipeline `config.yaml` file. These properties are passed\nthrough to the underlying Debezium connector. For example:\n\n[code example]\n\nSee [Pipeline configuration](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/pipeline-config)\nfor more about the `advanced` section."
    },
    {
      "id": "quick-configuration-summary",
      "title": "Quick configuration summary",
      "role": "content",
      "text": "The lists below summarize the extra configuration you may need for each source\ndatabase. Each database has its own section with full detail.\n\n[**Oracle**](#oracle)\n\n- Enable [supplemental logging](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/oracle) on the tables/schemas you capture.\n- Set `lob.enabled: true` if you need `CLOB`, `NCLOB`, `BLOB`, or `XMLTYPE`.\n- Choose `binary.handling.mode` for `RAW`/`BLOB` (default is `bytes`).\n- `decimal.handling.mode` defaults to `string` in RDI; set `double` for numeric `NUMBER`/`DECIMAL` values.\n- Avoid unsupported types (`LONG`, `LONG RAW`, `BFILE`, `UROWID`, `VECTOR`, UDTs, spatial) or cast them upstream.\n\n[**MySQL/MariaDB**](#mysql-and-mariadb)\n\n- Enable the binary log in **ROW** mode.\n- Choose `decimal.handling.mode` to balance precision against convenience.\n- For `BOOLEAN`/`TINYINT(1)` fidelity, consider the `TinyIntOneToBooleanConverter`.\n- Be aware that spatial and `VECTOR` types arrive as structured values, not scalars.\n\n[**PostgreSQL/Supabase/AlloyDB**](#postgresql-supabase-and-alloydb)\n\n- Ensure WAL/logical replication settings match the connector's needs.\n- `decimal.handling.mode` defaults to `string` in RDI; set `double` for numeric values.\n- Use a RedisJSON target to get the most value from `JSON`/`JSONB`.\n\n[**SQL Server**](#sql-server)\n\n- Enable CDC at both the database and table level.\n- Choose `decimal.handling.mode` for `MONEY`/`DECIMAL` precision.\n- Choose `time.precision.mode` if you need predictable temporal precision.\n\n[**MongoDB**](#mongodb)\n\n- Ensure a replica set and change streams are configured.\n- Use a RedisJSON target to preserve document structure.\n- Choose `capture.mode` to control whether updates include the full document.\n\n[**Spanner**](#spanner)\n\n- Spanner uses the Flink-based collector (not Debezium) and is supported only on Kubernetes/Helm."
    },
    {
      "id": "cross-cutting-considerations",
      "title": "Cross-cutting considerations",
      "role": "content",
      "text": "The settings below apply to all of the Debezium-based source connectors. They are\nthe most common cause of \"the value in Redis doesn't look like the value in my\ndatabase\", so review them before reading the per-database sections."
    },
    {
      "id": "decimal-and-numeric-values",
      "title": "Decimal and numeric values",
      "role": "content",
      "text": "`DECIMAL`, `NUMERIC`, `MONEY`, and similar types are controlled by\n`decimal.handling.mode`. **RDI's effective default is `string`** — the RDI collector\ntemplates set `debezium.source.decimal.handling.mode=string` before your\n`advanced.source` overrides apply, so decimals reach Redis as readable strings rather\nthan Debezium's own `precise` binary default:\n\n| `decimal.handling.mode` | Representation                                                              |\n|-------------------------|----------------------------------------------------------------------------|\n| `string` (RDI default)  | The exact decimal as a `STRING`.                                            |\n| `double`                | A `FLOAT64` number (may lose precision for very large/precise values).      |\n| `precise`               | A Kafka Connect `Decimal` (`BYTES`) — a base64-encoded, scaled binary value. This is Debezium's default but not RDI's. |\n\nLeave the default (`string`) for exact decimal fidelity, or set\n`decimal.handling.mode: double` if you want numeric values and can accept double\nprecision."
    },
    {
      "id": "temporal-values",
      "title": "Temporal values",
      "role": "content",
      "text": "Temporal types are controlled by `time.precision.mode`. The default is `adaptive`\nfor Oracle, PostgreSQL, and SQL Server, and `adaptive_time_microseconds` for MySQL\nand MariaDB. In adaptive modes, the precision of the emitted value depends on the\ncolumn's declared precision:\n\n- `DATE` columns are emitted as **days since epoch** (an `INT32`), *not*\n  milliseconds at midnight.\n- `TIME`/`DATETIME`/`TIMESTAMP` columns are emitted as milliseconds, **microseconds**,\n  or **nanoseconds** since epoch (or since midnight for time-of-day types) depending\n  on their precision. For example, an Oracle `TIMESTAMP(6)` or a PostgreSQL\n  `timestamp` is emitted as microseconds.\n\nRDI's processors may normalize these Debezium temporal types before they reach your\njobs and Redis (for example, converting a `Date` to epoch milliseconds). See\n[Formatting date and time values](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/transform-examples/formatting-date-and-time-values)\nfor worked examples of converting temporal values in an RDI job."
    },
    {
      "id": "time-zones",
      "title": "Time zones",
      "role": "content",
      "text": "Time zone–aware types (for example, Oracle `TIMESTAMP WITH TIME ZONE`, PostgreSQL\n`timestamptz`, SQL Server `datetimeoffset`, and MySQL `TIMESTAMP`) are **not**\nconverted to epoch milliseconds. They are emitted as **ISO 8601 strings**\n(semantic type `io.debezium.time.ZonedTimestamp`), normalized to UTC/GMT — for\nexample, `2025-06-07T10:15:00.000000Z`."
    },
    {
      "id": "binary-values",
      "title": "Binary values",
      "role": "content",
      "text": "Binary columns are controlled by `binary.handling.mode`. The default is **`bytes`**\n(raw bytes), *not* base64. The options are:\n\n- `bytes` (default) — raw byte array.\n- `base64` — base64-encoded string.\n- `base64-url-safe` — URL-safe base64 string.\n- `hex` — hex string.\n\nSet `binary.handling.mode: base64` (or `hex`) if your consumers expect an encoded\nstring rather than raw bytes. Make sure your consumer understands the encoding you\nchoose."
    },
    {
      "id": "large-objects-lobs-and-unavailable-values",
      "title": "Large objects (LOBs) and unavailable values",
      "role": "content",
      "text": "When a connector captures large objects (for example, Oracle `CLOB`/`BLOB`), an\nupdate event never contains the value of an *unchanged* LOB column. Instead, the\ncolumn carries a placeholder. The default placeholder is `__debezium_unavailable_value`,\nwhich you can change with `advanced.source.unavailable.value.placeholder` on the\nsource (the Helm chart exposes this as `processor.lob.placeholder`). RDI skips these\nplaceholder values rather than writing them to Redis as user data."
    },
    {
      "id": "nullability",
      "title": "Nullability",
      "role": "content",
      "text": "- **Redis Hashes**: null values are not stored (the field is absent).\n- **RedisJSON**: null values become JSON `null`. Note that if you use the native\n  `JSON.MERGE` command (the default from RDI 1.15.0, controlled by\n  `use_native_json_merge`), merging a `null` value *removes* the field rather than\n  storing it, following [RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396).\n  See [Pipeline configuration](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/pipeline-config)."
    },
    {
      "id": "structured-values-structs-arrays-and-maps",
      "title": "Structured values (structs, arrays, and maps)",
      "role": "content",
      "text": "Some source types are emitted as Kafka Connect `STRUCT`, `ARRAY`, or `MAP` values\nrather than scalars — for example, spatial types (a struct of `srid` + `wkb`) and\nvector types (an array of floats).\n\n**RDI does not support every complex logical type.** In particular, RDI treats\n`io.debezium.data.Bits` (from `BIT(>1)`/`BIT VARYING`) and the interval logical types\nas **unsupported**: the classic processor maps them to `None` and the Flink processor\nremoves the field (via `RemovalConverter`), so they do not reach Redis. Other\nstructured values (spatial `Geometry`, pgvector) pass through to RDI's processors,\nbut how they are rendered into a Redis Hash or JSON document is noted per type below."
    },
    {
      "id": "oracle",
      "title": "Oracle",
      "role": "content",
      "text": "RDI captures Oracle changes via the\n[Debezium Oracle connector](https://debezium.io/documentation/reference/3.0/connectors/oracle.html).\nSee [Prepare Oracle for RDI](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/oracle)\nfor the required supplemental-logging setup."
    },
    {
      "id": "supported-types",
      "title": "Supported types",
      "role": "compatibility",
      "text": "| Oracle type | Collector representation (default settings) | Notes |\n|-------------|---------------------------------------------|-------|\n| `NUMBER`, `DECIMAL`, `NUMERIC`, `INT`, `INTEGER`, `SMALLINT` | Kafka Connect `Decimal` (`BYTES`) | Controlled by `decimal.handling.mode`. See [Decimal and numeric values](#decimal-and-numeric-values). |\n| `NUMBER(p,*)`, `FLOAT`, `REAL`, `DOUBLE PRECISION` | `VariableScaleDecimal` (`STRUCT`) | Variable-scale decimal. |\n| `BINARY_FLOAT` | `FLOAT32` | |\n| `BINARY_DOUBLE` | `FLOAT64` | |\n| `CHAR`, `VARCHAR`, `VARCHAR2`, `NCHAR`, `NVARCHAR2` | `STRING` | UTF-8 preserved. |\n| `DATE` | `Timestamp` (`INT64`, ms since epoch) | |\n| `TIMESTAMP(0-3)` | `Timestamp` (ms) | Precision depends on the column; see [Temporal values](#temporal-values). |\n| `TIMESTAMP(4-6)` | `MicroTimestamp` (µs) | A bare `TIMESTAMP` defaults to precision 6 (microseconds). |\n| `TIMESTAMP(7-9)` | `NanoTimestamp` (ns) | |\n| `TIMESTAMP WITH TIME ZONE` | `ZonedTimestamp` (`STRING`, ISO 8601) | See [Time zones](#time-zones). |\n| `TIMESTAMP WITH LOCAL TIME ZONE` | `ZonedTimestamp` (`STRING`, UTC) | |\n| `INTERVAL YEAR TO MONTH`, `INTERVAL DAY TO SECOND` | `MicroDuration` (`INT64`) | **Not supported by RDI** — interval types are dropped before reaching Redis. See [Structured values](#structured-values-structs-arrays-and-maps). |\n| `CLOB`, `NCLOB` | `STRING` | Requires `lob.enabled: true`. |\n| `BLOB` | `BYTES` | Requires `lob.enabled: true`; encoded per `binary.handling.mode`. |\n| `RAW` | `BYTES` | Encoded per `binary.handling.mode`. |\n| `XMLTYPE` | `Xml` (`STRING`) | **Incubating** in Debezium. Requires `lob.enabled: true` and a non-hybrid mining strategy. |\n| `ROWID` | `STRING` | Supported in LogMiner mode only; not exposed when using XStream. |"
    },
    {
      "id": "configuration-notes",
      "title": "Configuration notes",
      "role": "configuration",
      "text": "- **LOBs**: set `lob.enabled: true` (default `false`) to capture `CLOB`, `NCLOB`,\n  `BLOB`, and `XMLTYPE`. You cannot use the *hybrid* mining strategy with\n  `lob.enabled: true` — use `online_catalog` or `redo_log_catalog` instead.\n- **Extended strings**: if the database parameter `max_string_size` is `EXTENDED`,\n  set `lob.enabled: true` to capture `VARCHAR2`/`NVARCHAR2` values over 4000 bytes\n  and `RAW` values over 2000 bytes.\n- **XMLTYPE**: requires `lob.enabled: true` and a non-hybrid mining strategy\n  (`online_catalog` or `redo_log_catalog`). The connector emits the XML as text\n  (`STRING`). XMLTYPE support also requires the Oracle **XDB library** and the\n  **`xmlparserv2`** dependency in addition to the standard `ojdbc11.jar` driver. If\n  the runtime selects Oracle's `xmlparserv2` SAX parser, you may need to set the JVM\n  option `-Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl`."
    },
    {
      "id": "not-captured",
      "title": "Not captured",
      "role": "content",
      "text": "The Debezium Oracle connector does not support `LONG`, `LONG RAW`, `BFILE`,\n`UROWID`, `VECTOR`, the native Oracle 23 `BOOLEAN` column type, user-defined/object\ntypes (objects, `REF`, `VARRAY`, nested tables), or Oracle spatial types. Cast these\nto a supported type upstream if you need them. A `NumberOneToBooleanConverter` is\navailable to map `NUMBER(1)` columns to booleans."
    },
    {
      "id": "mysql-and-mariadb",
      "title": "MySQL and MariaDB",
      "role": "content",
      "text": "RDI captures both `mysql` and `mariadb` sources with the\n[Debezium MySQL connector](https://debezium.io/documentation/reference/stable/connectors/mysql.html)\n(`io.debezium.connector.mysql.MySqlConnector`) — it does not use Debezium's separate\nMariaDB connector. The mappings below therefore apply to both source types. See\n[Prepare MySQL/MariaDB for RDI](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/my-sql-mariadb)\nfor setup. Enable the binary log in **ROW** mode."
    },
    {
      "id": "supported-types",
      "title": "Supported types",
      "role": "compatibility",
      "text": "| MySQL/MariaDB type | Collector representation (default settings) | Notes |\n|--------------------|---------------------------------------------|-------|\n| `TINYINT`, `SMALLINT`, `MEDIUMINT`, `INT`, `BIGINT` | `INT8`/`INT16`/`INT32`/`INT64` | |\n| `BIT(1)` | `BOOLEAN` | A single bit is mapped to a boolean. |\n| `BIT(>1)` | `Bits` (`BYTES`) | **Not supported by RDI** — dropped before reaching Redis. See [Structured values](#structured-values-structs-arrays-and-maps). |\n| `DECIMAL`, `NUMERIC` | Kafka Connect `Decimal` (`BYTES`) | Controlled by `decimal.handling.mode`. See [Decimal and numeric values](#decimal-and-numeric-values). |\n| `FLOAT(0-23)`, `REAL` | `FLOAT32` | |\n| `FLOAT(24-53)`, `DOUBLE` | `FLOAT64` | |\n| `CHAR`, `VARCHAR`, `TINYTEXT`, `TEXT`, `MEDIUMTEXT`, `LONGTEXT` | `STRING` | |\n| `BINARY`, `VARBINARY`, `TINYBLOB`, `BLOB`, `MEDIUMBLOB`, `LONGBLOB` | `BYTES` | Encoded per `binary.handling.mode`. Up to 2 GB; use the claim-check pattern for large values. |\n| `DATE` | `Date` (days since epoch) | See [Temporal values](#temporal-values). |\n| `TIME` | `MicroTime` (µs since midnight) | Default `time.precision.mode` is `adaptive_time_microseconds`. |\n| `DATETIME` | `Timestamp`/`MicroTimestamp` by precision | |\n| `TIMESTAMP` | `ZonedTimestamp` (`STRING`, ISO 8601, UTC) | Not epoch ms. See [Time zones](#time-zones). |\n| `YEAR` | `io.debezium.time.Year` (`INT32`) | |\n| `BOOLEAN`, `BOOL` | `BOOLEAN` | During snapshots the connector sees `TINYINT(1)`; use `TinyIntOneToBooleanConverter` for consistent boolean fidelity. |\n| `ENUM` | `io.debezium.data.Enum` (`STRING`) | The `allowed` schema parameter lists the permitted values. |\n| `SET` | `io.debezium.data.EnumSet` (`STRING`) | Comma-separated selected values. |\n| `JSON` | `io.debezium.data.Json` (`STRING`) | Parsed into a nested structure on a RedisJSON target. |\n| `VECTOR` | `ARRAY (FLOAT32)`, `io.debezium.data.FloatVector` | See [Structured values](#structured-values-structs-arrays-and-maps). |\n| Spatial: `GEOMETRY`, `POINT`, `LINESTRING`, `POLYGON`, `MULTIPOINT`, `MULTILINESTRING`, `MULTIPOLYGON`, `GEOMETRYCOLLECTION` | `io.debezium.data.geometry.Geometry` (`STRUCT`) | A struct with `srid` (`INT32`) and `wkb` (`BYTES`, Well-Known Binary). |"
    },
    {
      "id": "booleans",
      "title": "Booleans",
      "role": "content",
      "text": "MySQL and MariaDB both represent `BOOLEAN`/`BOOL` as `TINYINT(1)`. Because RDI uses\nthe MySQL connector for both, the connector may report these columns as `TINYINT(1)`\nrather than `BOOLEAN` (especially during snapshots). Use the\n`TinyIntOneToBooleanConverter` for consistent boolean fidelity."
    },
    {
      "id": "postgresql-supabase-and-alloydb",
      "title": "PostgreSQL, Supabase, and AlloyDB",
      "role": "content",
      "text": "RDI captures PostgreSQL changes via the\n[Debezium PostgreSQL connector](https://debezium.io/documentation/reference/3.0/connectors/postgresql.html)\nusing logical replication. **Supabase** and **AlloyDB** are PostgreSQL-compatible\nand use the same connector, so the mappings below apply to all three. See\n[Prepare PostgreSQL for RDI](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/postgresql)."
    },
    {
      "id": "supported-types",
      "title": "Supported types",
      "role": "compatibility",
      "text": "| PostgreSQL type | Collector representation (default settings) | Notes |\n|-----------------|---------------------------------------------|-------|\n| `SMALLINT`, `INTEGER`, `BIGINT` | `INT16`/`INT32`/`INT64` | `SMALLSERIAL`/`SERIAL`/`BIGSERIAL` map the same as their integer base. |\n| `OID` | `INT64` | |\n| `NUMERIC`, `DECIMAL` | Kafka Connect `Decimal` (`BYTES`), or `VariableScaleDecimal` when unscaled | Controlled by `decimal.handling.mode`. See [Decimal and numeric values](#decimal-and-numeric-values). |\n| `MONEY` | Kafka Connect `Decimal` (`BYTES`) | Scale set by `money.fraction.digits`. |\n| `REAL` | `FLOAT32` | |\n| `DOUBLE PRECISION` | `FLOAT64` | |\n| `BOOLEAN` | `BOOLEAN` | |\n| `BIT(1)` | `BOOLEAN` | |\n| `BIT(>1)`, `BIT VARYING` | `Bits` (`BYTES`) | **Not supported by RDI** — dropped before reaching Redis. See [Structured values](#structured-values-structs-arrays-and-maps). |\n| `CHAR`, `VARCHAR`, `TEXT`, `CITEXT` | `STRING` | |\n| `BYTEA` | `BYTES` | Encoded per `binary.handling.mode`. Requires `bytea_output = hex` in PostgreSQL. |\n| `DATE` | `Date` (days since epoch) | See [Temporal values](#temporal-values). |\n| `TIME` | `MicroTime` (µs since midnight) | |\n| `TIME WITH TIME ZONE` (`TIMETZ`) | `ZonedTime` (`STRING`, GMT) | For example, `07:15:00Z`. |\n| `TIMESTAMP` | `MicroTimestamp` (µs since epoch) | See [Temporal values](#temporal-values). |\n| `TIMESTAMP WITH TIME ZONE` (`TIMESTAMPTZ`) | `ZonedTimestamp` (`STRING`, GMT) | See [Time zones](#time-zones). |\n| `INTERVAL` | `MicroDuration` (`INT64`) | **Not supported by RDI** — interval types are dropped before reaching Redis. See [Structured values](#structured-values-structs-arrays-and-maps). |\n| `UUID` | `io.debezium.data.Uuid` (`STRING`) | |\n| `INET`, `CIDR`, `MACADDR`, `MACADDR8` | `STRING` | |\n| `JSON`, `JSONB` | `io.debezium.data.Json` (`STRING`) | Parsed into a nested structure on a RedisJSON target. |\n| `HSTORE` | `io.debezium.data.Json` (`STRING`) | Default `hstore.handling.mode` is `json` (for example, `{\"key\":\"val\"}`); set `map` for a `MAP` value. |\n| `XML` | `io.debezium.data.Xml` (`STRING`) | |\n| `LTREE` | `io.debezium.data.Ltree` (`STRING`) | |\n| `TSVECTOR` | `io.debezium.data.Tsvector` (`STRING`) | |\n| Range types (`INT4RANGE`, `INT8RANGE`, `NUMRANGE`, `TSRANGE`, `TSTZRANGE`, `DATERANGE`) | `STRING` | |\n| `ENUM` | `io.debezium.data.Enum` (`STRING`) | |\n| pgvector `VECTOR` | `ARRAY (FLOAT64)`, `io.debezium.data.DoubleVector` | Supabase and AlloyDB commonly enable pgvector. |\n| pgvector `HALFVEC` | `ARRAY (FLOAT32)`, `io.debezium.data.FloatVector` | |\n| pgvector `SPARSEVEC` | `STRUCT`, `io.debezium.data.SparseVector` | `dimensions` (`INT16`) + `vector` (`MAP(INT16, FLOAT64)`). |\n| PostGIS `GEOMETRY` | `io.debezium.data.geometry.Geometry` (`STRUCT`) | `srid` (`INT32`) + `wkb` (`BYTES`). |\n| PostGIS `GEOGRAPHY` | `io.debezium.data.geometry.Geography` (`STRUCT`) | |\n| Native `POINT` | `io.debezium.data.geometry.Point` (`STRUCT`) | Two `FLOAT64` fields (`x`, `y`). |\n\nDomain types (user-defined types based on an underlying type) are captured using\ntheir base type's representation.\n\nThe Debezium 3.0 PostgreSQL reference does not explicitly document how native array\ncolumns (for example, `int[]` or `text[]`) are captured — the Kafka Connect `ARRAY`\nliteral type is used in the reference only for the pgvector types above. In practice,\nthe connector represents arrays of supported primitive types as `ARRAY` values, but\nthis is not stated in the reference."
    },
    {
      "id": "not-captured",
      "title": "Not captured",
      "role": "content",
      "text": "The connector does not capture the native geometric types `LINE`, `LSEG`, `BOX`,\n`PATH`, `POLYGON`, and `CIRCLE`, or true composite/row types. Cast these upstream if\nyou need them."
    },
    {
      "id": "sql-server",
      "title": "SQL Server",
      "role": "content",
      "text": "RDI captures SQL Server changes via the\n[Debezium SQL Server connector](https://debezium.io/documentation/reference/3.0/connectors/sqlserver.html).\nCDC must be enabled at both the database and table level. See\n[Prepare SQL Server for RDI](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/sql-server)."
    },
    {
      "id": "supported-types",
      "title": "Supported types",
      "role": "compatibility",
      "text": "| SQL Server type | Collector representation (default settings) | Notes |\n|-----------------|---------------------------------------------|-------|\n| `TINYINT`, `SMALLINT`, `INT`, `BIGINT` | `INT16`/`INT16`/`INT32`/`INT64` | |\n| `BIT` | `BOOLEAN` | |\n| `DECIMAL`, `NUMERIC` | Kafka Connect `Decimal` (`BYTES`) | Controlled by `decimal.handling.mode`. See [Decimal and numeric values](#decimal-and-numeric-values). |\n| `MONEY`, `SMALLMONEY` | Kafka Connect `Decimal` (`BYTES`) | |\n| `REAL` | `FLOAT32` | |\n| `FLOAT[(N)]` | `FLOAT64` | |\n| `CHAR`, `VARCHAR`, `NCHAR`, `NVARCHAR`, `TEXT`, `NTEXT` | `STRING` | |\n| `XML` | `io.debezium.data.Xml` (`STRING`) | |\n| `DATE` | `Date` (days since epoch) | Not \"ms at midnight\". See [Temporal values](#temporal-values). |\n| `TIME(0-3)` | `Time` (ms since midnight) | |\n| `TIME(4-6)` | `MicroTime` (µs since midnight) | |\n| `TIME(7)` | `NanoTime` (ns since midnight) | |\n| `DATETIME`, `SMALLDATETIME` | `Timestamp` (ms since epoch) | |\n| `DATETIME2(0-3)` | `Timestamp` (ms) | |\n| `DATETIME2(4-6)` | `MicroTimestamp` (µs) | |\n| `DATETIME2(7)` | `NanoTimestamp` (ns) | |\n| `DATETIMEOFFSET` | `ZonedTimestamp` (`STRING`, GMT) | See [Time zones](#time-zones). |\n| `BINARY`, `VARBINARY` | `BYTES` | Encoded per `binary.handling.mode` (default `bytes`). Not in the reference's mapping tables, but handled via the `binary.handling.mode` property. |"
    },
    {
      "id": "types-requiring-confirmation",
      "title": "Types requiring confirmation",
      "role": "content",
      "text": "The previous version of this page documented `UNIQUEIDENTIFIER`,\n`ROWVERSION`/`TIMESTAMP` (the row-version column type), `sql_variant`, `hierarchyid`,\n`IMAGE`, and the spatial types (`geometry`, `geography`) for SQL Server. None of these\nappear in the Debezium 3.0 SQL Server connector reference's data type mapping tables.\n\nNote that *absence from the reference's tables does not necessarily mean a type is\nunsupported* — `BINARY` and `VARBINARY`, for example, are handled via the\n`binary.handling.mode` property even though they have no mapping-table row. So these\ntypes should be confirmed empirically rather than assumed unsupported."
    },
    {
      "id": "mongodb",
      "title": "MongoDB",
      "role": "content",
      "text": "RDI captures MongoDB changes via the\n[Debezium MongoDB connector](https://debezium.io/documentation/reference/3.0/connectors/mongodb.html),\nwhich works differently from the relational connectors. See\n[Prepare MongoDB for RDI](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/mongodb)."
    },
    {
      "id": "what-the-collector-emits",
      "title": "What the collector emits",
      "role": "content",
      "text": "The MongoDB connector does **not** map each BSON field to a separate typed value.\nInstead, it emits the whole document as a **single JSON string** using MongoDB\n[extended JSON, strict mode](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/).\nBSON values appear inside that string using extended-JSON wrappers, for example:\n\n| BSON type | Extended-JSON representation |\n|-----------|------------------------------|\n| `ObjectId` | `{\"$oid\": \"596e275826f08b2730779e1f\"}` |\n| `Int32` / `Int64` | `1234` / `{\"$numberLong\": \"1234\"}` |\n| `Double` | a JSON number |\n| `Decimal128` | `{\"$numberDecimal\": \"...\"}` |\n| `Date` | `{\"$date\": ...}` |\n| `Timestamp` (BSON) | `{\"$timestamp\": {\"t\": ..., \"i\": ...}}` |\n| `Binary` | `{\"$binary\": \"...\", \"$type\": \"00\"}` |\n| `Boolean` | `true` / `false` |\n| `Null` | `null` |\n| Regular expression | `{\"$regularExpression\": {\"pattern\": \"...\", \"options\": \"...\"}}` |\n| JavaScript | `{\"$code\": \"...\"}` |\n| `MinKey` / `MaxKey` | `{\"$minKey\": 1}` / `{\"$maxKey\": 1}` |\n\nThe document's `_id` is placed in the change event **key** (as an extended-JSON\nstring). It can be any BSON type — it is only a 24-character hex value when it is an\n`ObjectId`.\n\nWhat is available for updates depends on `capture.mode`:\n\n- A *create* event always includes the full document.\n- An *update* event includes the full document only when `capture.mode` is\n  `change_streams_update_full`; otherwise it carries only the changed fields\n  (`updatedFields`/`removedFields`). A `*_with_pre_image` mode is required to include\n  the prior document state.\n\nDocuments larger than the 16 MB BSON limit require `oversize.handling.mode` (and\nMongoDB 6.0.9+)."
    },
    {
      "id": "how-rdi-maps-it-to-redis",
      "title": "How RDI maps it to Redis",
      "role": "content",
      "text": "RDI parses the collector's JSON string and writes the result to your Redis target:\n\n- With a RedisJSON target, the document structure (nested objects and arrays) is\n  preserved.\n- With a Hash target, nested objects and arrays are stored as stringified JSON.\n- RDI typically derives the Redis key (in whole or in part) from the document's\n  `_id`."
    },
    {
      "id": "spanner",
      "title": "Spanner",
      "role": "content",
      "text": "RDI supports [Google Cloud Spanner](https://cloud.google.com/spanner) as a source,\nbut **Spanner does not use Debezium**. During the snapshot phase RDI reads Spanner\ndirectly over JDBC, and during streaming it consumes\n[Spanner change streams](https://cloud.google.com/spanner/docs/change-streams) via a\nFlink-based collector (`type: flink`). Spanner is supported only when RDI is deployed\non Kubernetes/Helm. See\n[Prepare Spanner for RDI](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/spanner)\nfor setup.\n\nBecause Spanner uses a different collector, its data type handling is not governed by\nthe Debezium settings described elsewhere on this page. There is no Debezium or Flink\ntype-mapping reference to consult: Flink is only the stream-processing runtime, and\nneither Flink core nor Flink CDC provides a Spanner connector. The representation of\neach value comes from Spanner itself."
    },
    {
      "id": "supported-types",
      "title": "Supported types",
      "role": "compatibility",
      "text": "During the streaming phase, values arrive in Spanner's\n[change stream record format](https://cloud.google.com/spanner/docs/change-streams/details),\nin which each value is JSON-encoded according to the Spanner\n[`TypeCode`](https://cloud.google.com/spanner/docs/reference/rest/v1/Type) reference\n(the same encoding that the record's `column_types` metadata points to). The table\nbelow uses GoogleSQL type names; the PostgreSQL dialect uses different type names\n(for example, `bigint`, `bytea`, `timestamptz`, `jsonb`) but the same value encoding.\n\n| Spanner type (GoogleSQL) | Change-stream representation |\n|--------------------------|------------------------------|\n| `BOOL` | JSON `true`/`false`. |\n| `INT64` | A `STRING` in decimal format (not a JSON number). |\n| `FLOAT32`, `FLOAT64` | A JSON number, or the strings `\"NaN\"`, `\"Infinity\"`, `\"-Infinity\"`. |\n| `NUMERIC` | A `STRING` in decimal or scientific notation. |\n| `STRING` | A `STRING`. |\n| `BYTES` | A base64-encoded `STRING` (RFC 4648). |\n| `JSON` | A JSON-formatted `STRING` (RFC 7159). |\n| `TIMESTAMP` | A `STRING` in RFC 3339 format, time zone `Z` (UTC). |\n| `DATE` | A `STRING` in RFC 3339 date format. |\n| `UUID` | A lower-case hexadecimal `STRING` (RFC 9562). |\n| `ENUM` | A `STRING` in decimal format. |\n| `ARRAY` | A JSON list of elements encoded per the element type. |\n| `STRUCT` | A JSON list of field values encoded per the field types. |\n\nThis table shows the **raw change-stream representation** only. RDI's Spanner\ncollector parses some of these values before they become change events — for\nexample, the string-encoded `INT64` values are parsed to numbers — and the snapshot\nphase reads through the Spanner JDBC path, which may not match the change-stream\nencoding. The RDI job/target representation is therefore not always identical to the\nraw encoding above."
    }
  ],
  "examples": [
    {
      "id": "setting-collector-properties-ex0",
      "language": "yaml",
      "code": "sources:\n  my-source:\n    # ...connection details...\n    advanced:\n      source:\n        decimal.handling.mode: double\n        binary.handling.mode: base64",
      "section_id": "setting-collector-properties"
    }
  ]
}
