{"record":{"id":"832ab74c691c2180","repo":"apache/seatunnel","slug":"complex-type-mapped-to-string-consider-using-j","errorCode":null,"errorMessage":"Complex type {} mapped to STRING, consider using JSON serialization","messagePattern":"Complex type (.+?) mapped to STRING, consider using JSON serialization","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java","lineNumber":179,"sourceCode":"                builder.dataType(LocalTimeType.LOCAL_DATE_TYPE);\n                break;\n            case DUCKDB_TIME:\n                builder.dataType(LocalTimeType.LOCAL_TIME_TYPE);\n                break;\n            case DUCKDB_TIMESTAMP:\n                builder.dataType(LocalTimeType.LOCAL_DATE_TIME_TYPE);\n                break;\n            case DUCKDB_TIMESTAMP_WITH_TZ:\n                builder.dataType(LocalTimeType.OFFSET_DATE_TIME_TYPE);\n                break;\n            case DUCKDB_INTERVAL:\n                builder.dataType(BasicType.STRING_TYPE);\n                builder.columnLength(50L);\n                break;\n            case DUCKDB_ARRAY:\n            case DUCKDB_STRUCT:\n            case DUCKDB_MAP:\n                log.warn(\n                        \"Complex type {} mapped to STRING, consider using JSON serialization\",\n                        duckDBType);\n                builder.dataType(BasicType.STRING_TYPE);\n                builder.columnLength(lengthValue > 0 ? lengthValue : 65535);\n                break;\n            default:\n                log.warn(\"Unsupported DuckDB type: {}, falling back to STRING\", duckDBType);\n                builder.dataType(BasicType.STRING_TYPE);\n                builder.columnLength(lengthValue > 0 ? lengthValue : 255);\n        }\n        return builder.build();\n    }\n\n    private void handleDecimalType(\n            PhysicalColumn.PhysicalColumnBuilder builder, BasicTypeDefine typeDefine) {\n        long precision =\n                typeDefine.getPrecision() != null ? typeDefine.getPrecision() : DEFAULT_PRECISION;\n        int scale = typeDefine.getScale() != null ? typeDefine.getScale() : DEFAULT_SCALE;","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java#L161-L197","documentation":"This is a warning (not an exception) emitted by DuckDBTypeConverter.convert when a source column has a complex DuckDB type (ARRAY, STRUCT, or MAP). SeaTunnel's catalog Column model cannot represent these nested types in this dialect path, so the converter degrades the column to BasicType.STRING_TYPE with length 65535 (or the original length if positive). Data is read/written as a flat string, so nested semantics are lost unless the job handles serialization itself.","triggerScenarios":"Calling convert (or reconvert indirectly) on a BasicTypeDefine whose DuckDB type resolves to DUCKDB_ARRAY, DUCKDB_STRUCT, or DUCKDB_MAP — e.g. catalog/schema discovery of a table containing LIST, STRUCT, or MAP columns.","commonSituations":"Reading a DuckDB table that stores JSON-ish nested data in STRUCT/LIST columns; syncing a table with MAP columns into another sink that receives plain VARCHAR; schema auto-creation writing STRING columns downstream instead of nested types.","solutions":["If JSON text is acceptable, keep the mapping and parse the string downstream (e.g. with a JSON transform).","Pre-cast the column in your source SQL to a primitive type or VARCHAR/JSON before SeaTunnel reads the schema.","Use a sink/connector that supports nested types, or enable JSON serialization at the storage layer instead of relying on this fallback.","If the default 65535 length is wrong for your data, define the column explicitly in your sink schema."],"exampleFix":"// before (source SQL)\nSELECT info FROM users; -- info is STRUCT(name TEXT, age INT)\n// after\nSELECT json(info) AS info FROM users; -- explicit JSON string, parsed downstream","handlingStrategy":"validation","validationCode":"for (Column c : columns) {\n  if (c.getDataType() instanceof ArrayType || c.getDataType() instanceof MapType\n      || (c.getDataType() instanceof RowType)) {\n    // plan for string/JSON handling before submitting the job\n  }\n}","typeGuard":"boolean isComplex(Column c) {\n  return c.getDataType() instanceof ArrayType\n      || c.getDataType() instanceof MapType\n      || c.getDataType() instanceof RowType;\n}","tryCatchPattern":null,"preventionTips":["Inspect source schemas for LIST/STRUCT/MAP columns before running catalog-driven syncs.","Pre-cast complex columns to JSON/VARCHAR in the source SQL.","Parse STRING-mapped columns downstream with a JSON transform.","Pin explicit sink schemas instead of relying on auto type mapping."],"tags":["jdbc","duckdb","type-conversion","data-loss"],"backgroundTag":"unsupported-dtype","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}