@@ -197,17 +197,46 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
197197 let cert_path = server. options . get ( "ssl_cert" ) . cloned ( ) ;
198198 let key_path = server. options . get ( "ssl_key" ) . cloned ( ) ;
199199 let servername = server. options . get ( "ssl_servername" ) . cloned ( ) ;
200- let username = server. options . get ( "username" ) . cloned ( ) ;
201- let password = server. options . get ( "password" ) . cloned ( ) ;
202200
203201 // Parse timeouts with defaults
204202 let connect_timeout = parse_timeout ( & server. options , "connect_timeout" , config. connect_timeout ) ?;
205203 let request_timeout = parse_timeout ( & server. options , "request_timeout" , config. request_timeout ) ?;
206204
207205 // ssl_cert + ssl_key must be both present or both absent
208- // username + password must be both present or both absent
209206 require_pair ( cert_path. is_some ( ) , key_path. is_some ( ) , EtcdFdwError :: CertKeyMismatch ( ( ) ) ) ?;
210- require_pair ( username. is_some ( ) , password. is_some ( ) , EtcdFdwError :: UserPassMismatch ( ( ) ) ) ?;
207+
208+ let mut username = None ;
209+ let mut password = None ;
210+
211+ unsafe {
212+ let usermapping = pg_sys:: GetUserMapping ( pg_sys:: GetUserId ( ) , server. server_oid ) ;
213+ let options = ( * usermapping) . options ;
214+ pgrx:: memcx:: current_context ( |mcx| {
215+ let list = pgrx:: list:: List :: < * mut std:: ffi:: c_void > :: downcast_ptr_in_memcx ( options, mcx) . unwrap ( ) ;
216+ for option in list. iter ( ) {
217+ let option = * option as * mut pg_sys:: DefElem ;
218+ let name = std:: ffi:: CStr :: from_ptr ( ( * option) . defname ) ;
219+ let value = std:: ffi:: CStr :: from_ptr ( pg_sys:: defGetString ( option) ) ;
220+ let name = name. to_str ( ) . map_err ( |_| {
221+ OptionsError :: OptionNameIsInvalidUtf8 (
222+ String :: from_utf8_lossy ( name. to_bytes ( ) ) . to_string ( ) ,
223+ )
224+ } ) ;
225+ let value = value. to_str ( ) . map_err ( |_| {
226+ OptionsError :: OptionValueIsInvalidUtf8 (
227+ String :: from_utf8_lossy ( value. to_bytes ( ) ) . to_string ( ) ,
228+ )
229+ } ) ;
230+ if let ( Ok ( name) , Ok ( value) ) = ( name, value) {
231+ match name {
232+ "username" => username = Some ( value. to_string ( ) ) ,
233+ "password" => password = Some ( value. to_string ( ) ) ,
234+ _ => { }
235+ }
236+ }
237+ }
238+ } ) ;
239+ }
211240
212241 config = EtcdConfig {
213242 endpoints : vec ! [ connstr] ,
@@ -613,11 +642,8 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
613642
614643 let cacert_path_exists = check_options_contain ( & options, "ssl_ca" ) . is_ok ( ) ;
615644 let cert_path_exists = check_options_contain ( & options, "ssl_cert" ) . is_ok ( ) ;
616- let username_exists = check_options_contain ( & options, "username" ) . is_ok ( ) ;
617- let password_exists = check_options_contain ( & options, "password" ) . is_ok ( ) ;
618645
619646 require_pair ( cacert_path_exists, cert_path_exists, EtcdFdwError :: CertKeyMismatch ( ( ) ) ) ?;
620- require_pair ( username_exists, password_exists, EtcdFdwError :: UserPassMismatch ( ( ) ) ) ?;
621647 } else if oid == FOREIGN_TABLE_RELATION_ID {
622648 check_options_contain ( & options, "rowid_column" ) ?;
623649
@@ -632,6 +658,11 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
632658 if prefix_exists && key_exists {
633659 return Err ( EtcdFdwError :: ConflictingPrefixAndKey ) ;
634660 }
661+ } else if oid == pg_sys:: BuiltinOid :: UserMappingRelationId . value ( ) {
662+ let username_exists = check_options_contain ( & options, "username" ) . is_ok ( ) ;
663+ let password_exists = check_options_contain ( & options, "password" ) . is_ok ( ) ;
664+
665+ require_pair ( username_exists, password_exists, EtcdFdwError :: UserPassMismatch ( ( ) ) ) ?;
635666 }
636667 }
637668
0 commit comments