@@ -158,6 +158,27 @@ function extractTypeNameFromCast(result: ParseResult): Node | undefined {
158158 * Handles special suffixes like %rowtype and %type by stripping them before
159159 * parsing and preserving them in the result.
160160 */
161+ /**
162+ * Quotes each dot-separated part of a type name that is not already quoted,
163+ * preserving array bounds (e.g. `my-schema.mytype[]` -> `"my-schema"."mytype"[]`).
164+ */
165+ function quoteTypnameParts ( typname : string ) : string {
166+ let bounds = '' ;
167+ let base = typname ;
168+ const boundsMatch = base . match ( / ( \[ [ ^ \] ] * \] ) + $ / ) ;
169+ if ( boundsMatch ) {
170+ bounds = boundsMatch [ 0 ] ;
171+ base = base . substring ( 0 , base . length - bounds . length ) ;
172+ }
173+ const parts = base . split ( '.' ) . map ( part => {
174+ if ( part . startsWith ( '"' ) && part . endsWith ( '"' ) ) {
175+ return part ;
176+ }
177+ return `"${ part . replace ( / " / g, '""' ) } "` ;
178+ } ) ;
179+ return parts . join ( '.' ) + bounds ;
180+ }
181+
161182function hydrateTypeName (
162183 typname : string ,
163184 path : string ,
@@ -194,10 +215,20 @@ function hydrateTypeName(
194215 try {
195216 // Parse the type name by wrapping it in a cast expression
196217 // Keep quotes intact for proper parsing of special identifiers
197- const sql = `SELECT NULL::${ parseTypname } ` ;
198- const parseResult = parseSync ( sql ) ;
199- const typeNameNode = extractTypeNameFromCast ( parseResult ) ;
200-
218+ let typeNameNode ;
219+ try {
220+ const sql = `SELECT NULL::${ parseTypname } ` ;
221+ const parseResult = parseSync ( sql ) ;
222+ typeNameNode = extractTypeNameFromCast ( parseResult ) ;
223+ } catch ( parseErr ) {
224+ // The parser reports typnames without quoting, so identifiers that
225+ // require quotes (e.g. schema names containing dashes) fail to parse
226+ // verbatim. Retry with each dot-separated part quoted.
227+ const quoted = quoteTypnameParts ( parseTypname ) ;
228+ const parseResult = parseSync ( `SELECT NULL::${ quoted } ` ) ;
229+ typeNameNode = extractTypeNameFromCast ( parseResult ) ;
230+ }
231+
201232 if ( typeNameNode ) {
202233 stats . typeNameExpressions ++ ;
203234 return {
0 commit comments