Skip to content

[BUG]:[1.0.0-rc.1] customType auto-resolves "geometry" codec from dataType, breaks for non-Point PostGIS columns #5711

@fireayehu

Description

@fireayehu

Report hasn't been filed before.

  • I have verified that the bug I'm about to report hasn't been filed before.

What version of drizzle-orm are you using?

1.0.0-rc.1

What version of drizzle-kit are you using?

1.0.0-rc.1

Other packages

No response

Describe the Bug

Summary

customType resolves a codec by slicing the dataType() string at the first (. For a PostGIS polygon defined as geometry(Polygon, 4326), this slices to "geometry", which maps to the
point-only codec and runs parseGeometryXY on polygon EWKB. The codec then throws Error: Unsupported geometry type on every read.

Versions

  • drizzle-orm@1.0.0-rc.1
  • Postgres + PostGIS

Repro

import { customType } from "drizzle-orm/pg-core";
                                                                                                                                                                                                
export const polygon = customType<{ data: [number, number][][] }>({                                                                                                                           
  dataType() {                                                                                                                                                                                  
    return "geometry(Polygon, 4326)";
  },                                                                                                                                                                                            
  toDriver(value) { /* ST_GeomFromText(...) */ },                                                                                                                                             
  // no fromDriver, no codec                                                                                                                                                                    
});
                                                                                                                                                                                                
export const Geofence = pgTable("geofences", {                                                                                                                                                
  id: uuid().primaryKey(),                                                                                                                                                                      
  polygon: polygon("polygon").notNull(),
});                                                                                                                                                                                             
                                                                                                                                                                                              
await db.select().from(Geofence); // throws                                                                                                                                                     

Where it happens

pg-core/columns/custom.js:

this.codec = resolvePgType(
  config.customTypeParams.codec ??                                                                                                                                                              
  this.sqlName.slice(0, Math.min(...[                                                                                                                                                           
    this.sqlName.indexOf("("),                                                                                                                                                                  
    this.sqlName.indexOf("[")                                                                                                                                                                   
  ].filter((e) => e !== -1)))                                                                                                                                                                   
);                                                                                                                                                                                              

For "geometry(Polygon, 4326)" this becomes resolvePgType("geometry") → the geometry codec → parseGeometryXY, which only supports Points:

if ((geomType & 65535) === 1) { /* Point */ }                                                                                                                                                 
throw new Error("Unsupported geometry type");                                                                                                                                                   

Expected

The auto-inferred codec for a custom PostGIS type that isn't a Point should not crash — either:

  • skip codec inference when the param substring doesn't have a 1:1 codec match for the actual geometry kind, or
  • only auto-infer when the inferred codec key has a definition compatible with the column data, or
  • document that customType users must set codec explicitly when their dataType() starts with geometry(...).

Actual

    at Module.parseEWKB (drizzle-orm/pg-core/columns/postgis_extension/utils.ts:46)
    at parseGeometryXY (drizzle-orm/pg-core/codecs.ts:287)                         
    at Object.eval (drizzle:jit-relational-query-mapper:82)                                                                                                                                     

Workaround

Pass an explicit codec whose key has no entry in the codec map (so CodecsCollection.get returns undefined and no normalization runs):

export const polygon = customType<{ data: [number, number][][] }>({                                                                                                                             
  dataType() { return "geometry(Polygon, 4326)"; },                                                                                                                                           
  codec: "polygon", // <- disables auto-inference; codecs["polygon"] is undefined
  toDriver(value) { /* ... */ },                                                                                                                                                                
});                                                                                                                                                                                             

Worked fine on 1.0.0-beta.* because customType did not auto-resolve a codec.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions