@@ -274,6 +274,47 @@ $$`;
274274 expect ( deparsedBody ) . not . toContain ( 'old-schema' ) ;
275275 } ) ;
276276
277+ it ( 'should preserve array bounds when dehydrating modified type-name nodes' , ( ) => {
278+ const sql = `CREATE FUNCTION test_func() RETURNS void
279+ LANGUAGE plpgsql
280+ AS $$
281+ DECLARE
282+ v_items "old-schema".mytype[];
283+ v_item "old-schema".mytype;
284+ BEGIN
285+ NULL;
286+ END;
287+ $$` ;
288+
289+ const parsed = parsePlPgSQLSync ( sql ) as unknown as PLpgSQLParseResult ;
290+ const { ast : hydratedAst } = hydratePlpgsqlAst ( parsed ) ;
291+
292+ // Rename schema inside the hydrated TypeName AST nodes
293+ const renameTypeNames = ( obj : any ) : void => {
294+ if ( obj === null || typeof obj !== 'object' ) return ;
295+ if ( 'PLpgSQL_type' in obj ) {
296+ const typname = obj . PLpgSQL_type . typname ;
297+ if ( typname && typeof typname === 'object' && typname . kind === 'type-name' ) {
298+ for ( const name of typname . typeNameNode ?. names ?? [ ] ) {
299+ if ( name ?. String ?. sval === 'old-schema' ) {
300+ name . String . sval = 'new_schema' ;
301+ }
302+ }
303+ }
304+ }
305+ for ( const value of Object . values ( obj ) ) renameTypeNames ( value ) ;
306+ } ;
307+ renameTypeNames ( hydratedAst ) ;
308+
309+ const dehydratedAst = dehydratePlpgsqlAst ( hydratedAst ) ;
310+ const deparsedBody = deparseSync ( dehydratedAst ) ;
311+
312+ // The renamed array type must keep its [] bounds
313+ expect ( deparsedBody ) . toContain ( 'new_schema.mytype[]' ) ;
314+ expect ( deparsedBody ) . toContain ( 'v_item new_schema.mytype;' ) ;
315+ expect ( deparsedBody ) . not . toContain ( 'old-schema' ) ;
316+ } ) ;
317+
277318 it ( 'should deparse modified assign AST nodes (schema renaming in assignments)' , ( ) => {
278319 const sql = `CREATE FUNCTION test_func() RETURNS void
279320LANGUAGE plpgsql
0 commit comments