@@ -29,9 +29,11 @@ const DatabaseModal = ({ open, onOpenChange }: DatabaseModalProps) => {
2929 const [ database , setDatabase ] = useState ( "" ) ;
3030 const [ username , setUsername ] = useState ( "" ) ;
3131 const [ password , setPassword ] = useState ( "" ) ;
32+ const [ schema , setSchema ] = useState ( "" ) ;
33+ const [ schemaError , setSchemaError ] = useState ( "" ) ;
3234 // Snowflake-specific fields
3335 const [ account , setAccount ] = useState ( "" ) ;
34- const [ schema , setSchema ] = useState ( "PUBLIC" ) ;
36+ const [ snowflakeSchema , setSnowflakeSchema ] = useState ( "PUBLIC" ) ;
3537 const [ warehouse , setWarehouse ] = useState ( "COMPUTE_WH" ) ;
3638 const [ authMode , setAuthMode ] = useState < 'password' | 'keypair' > ( 'password' ) ;
3739 const [ privateKey , setPrivateKey ] = useState ( "" ) ;
@@ -118,7 +120,7 @@ const DatabaseModal = ({ open, onOpenChange }: DatabaseModalProps) => {
118120 if ( connectionMode === 'manual' ) {
119121 if ( selectedDatabase === 'snowflake' ) {
120122 // Build Snowflake URL: snowflake://user@account /database/schema?warehouse=WH
121- const builtUrl = new URL ( `snowflake://${ account } /${ database } /${ schema } ` ) ;
123+ const builtUrl = new URL ( `snowflake://${ account } /${ database } /${ snowflakeSchema } ` ) ;
122124 builtUrl . username = username ;
123125 if ( authMode === 'keypair' && privateKey ) {
124126 // Base64-encode the PEM key for safe URL transport
@@ -136,6 +138,15 @@ const DatabaseModal = ({ open, onOpenChange }: DatabaseModalProps) => {
136138 const builtUrl = new URL ( `${ protocol } ://${ host } :${ port } /${ database } ` ) ;
137139 builtUrl . username = username ;
138140 builtUrl . password = password ;
141+
142+ // Append schema option for PostgreSQL if provided
143+ if ( selectedDatabase === 'postgresql' && schema . trim ( ) ) {
144+ if ( / [ ^ a - z A - Z 0 - 9 _ ] / . test ( schema . trim ( ) ) ) {
145+ throw new Error ( 'Schema name can only contain letters, digits, and underscores' ) ;
146+ }
147+ builtUrl . searchParams . set ( 'options' , `-csearch_path=${ schema . trim ( ) } ` ) ;
148+ }
149+
139150 dbUrl = builtUrl . toString ( ) ;
140151 }
141152 }
@@ -220,8 +231,10 @@ const DatabaseModal = ({ open, onOpenChange }: DatabaseModalProps) => {
220231 setDatabase ( "" ) ;
221232 setUsername ( "" ) ;
222233 setPassword ( "" ) ;
234+ setSchema ( "" ) ;
235+ setSchemaError ( "" ) ;
223236 setAccount ( "" ) ;
224- setSchema ( "PUBLIC" ) ;
237+ setSnowflakeSchema ( "PUBLIC" ) ;
225238 setWarehouse ( "COMPUTE_WH" ) ;
226239 setAuthMode ( 'password' ) ;
227240 setPrivateKey ( "" ) ;
@@ -416,12 +429,12 @@ const DatabaseModal = ({ open, onOpenChange }: DatabaseModalProps) => {
416429 </ div >
417430
418431 < div className = "space-y-2" >
419- < Label htmlFor = "schema" className = "text-sm font-medium" > Schema</ Label >
432+ < Label htmlFor = "snowflake- schema" className = "text-sm font-medium" > Schema</ Label >
420433 < Input
421- id = "schema"
434+ id = "snowflake- schema"
422435 placeholder = "PUBLIC"
423- value = { schema }
424- onChange = { ( e ) => setSchema ( e . target . value ) }
436+ value = { snowflakeSchema }
437+ onChange = { ( e ) => setSnowflakeSchema ( e . target . value ) }
425438 className = "bg-muted border-border focus-visible:ring-purple-500"
426439 />
427440 < p className = "text-xs text-muted-foreground" >
@@ -578,6 +591,38 @@ const DatabaseModal = ({ open, onOpenChange }: DatabaseModalProps) => {
578591 className = "bg-muted border-border focus-visible:ring-purple-500"
579592 />
580593 </ div >
594+
595+ { /* Schema field - PostgreSQL only */ }
596+ { selectedDatabase === 'postgresql' && (
597+ < div className = "space-y-2" >
598+ < Label htmlFor = "schema" className = "text-sm font-medium" >
599+ Schema < span className = "text-muted-foreground font-normal" > (optional)</ span >
600+ </ Label >
601+ < Input
602+ id = "schema"
603+ data-testid = "schema-input"
604+ placeholder = "public"
605+ value = { schema }
606+ onChange = { ( e ) => {
607+ const val = e . target . value ;
608+ setSchema ( val ) ;
609+ if ( val && / [ ^ a - z A - Z 0 - 9 _ ] / . test ( val ) ) {
610+ setSchemaError ( 'Schema name can only contain letters, digits, and underscores' ) ;
611+ } else {
612+ setSchemaError ( '' ) ;
613+ }
614+ } }
615+ className = { `bg-muted border-border ${ schemaError ? 'border-red-500' : '' } ` }
616+ />
617+ { schemaError ? (
618+ < p className = "text-xs text-red-500" > { schemaError } </ p >
619+ ) : (
620+ < p className = "text-xs text-muted-foreground" >
621+ Leave empty to use the default 'public' schema
622+ </ p >
623+ ) }
624+ </ div >
625+ ) }
581626 </ >
582627 ) }
583628 </ >
0 commit comments