diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c index 6b0a3067e6..e679169019 100644 --- a/src/interfaces/ecpg/ecpglib/connect.c +++ b/src/interfaces/ecpg/ecpglib/connect.c @@ -374,7 +374,8 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p } tmp = last_dir_separator(dbname + offset); - if (tmp != NULL) /* database name given */ + if (tmp != NULL + && strchr(tmp + 1, ':') == NULL) /* database name given */ { if (tmp[1] != '\0') /* non-empty database name */ { @@ -384,13 +385,13 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p *tmp = '\0'; } - tmp = strrchr(dbname + offset, ':'); + tmp = strchr(dbname + offset, ':'); if (tmp != NULL) /* port number or Unix socket path given */ { char *tmp2; *tmp = '\0'; - if ((tmp2 = strchr(tmp + 1, ':')) != NULL) + if ((tmp2 = strrchr(tmp + 1, ':')) != NULL) { *tmp2 = '\0'; host = ecpg_strdup(tmp + 1, lineno); diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 0e4a041393..1368c31097 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -83,9 +83,9 @@ connection_target: opt_database_name opt_server opt_port else $$ = make3_str(mm_strdup("\""), make3_str($1, $2, $3), mm_strdup("\"")); } - | db_prefix ':' server opt_port '/' opt_database_name opt_options + | db_prefix ':' server opt_port_or_unix_socket '/' opt_database_name opt_options { - /* new style: :postgresql://server[:port][/dbname] */ + /* new style: :postgresql://server[:port|:/unixsocket/path:][/dbname] */ if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0) mmerror(PARSE_ERROR, ET_ERROR, "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported"); @@ -148,10 +148,21 @@ server_name: ColId { $$ = $1; } | IP { $$ = make_name(); } ; +opt_port_or_unix_socket: opt_port { $$ = $1; } + | opt_unix_socket { $$ = $1; } + ; + opt_port: ':' Iconst { $$ = make2_str(mm_strdup(":"), $2); } | /*EMPTY*/ { $$ = EMPTY; } ; +opt_unix_socket: ':' dir_name ':' { $$ = make3_str(mm_strdup(":"), $2, mm_strdup(":")); } + ; + +dir_name: '/' dir_name { $$ = make2_str(mm_strdup("/"), $2); } + | ecpg_ident { $$ = $1; } + ; + opt_connection_name: AS connection_object { $$ = $2; } | /*EMPTY*/ { $$ = mm_strdup("NULL"); } ; diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type index eca298bdb8..5f4f9fb12d 100644 --- a/src/interfaces/ecpg/preproc/ecpg.type +++ b/src/interfaces/ecpg/preproc/ecpg.type @@ -85,7 +85,10 @@ %type opt_options %type opt_output %type opt_pointer +%type opt_port_or_unix_socket %type opt_port +%type opt_unix_socket +%type dir_name %type opt_reference %type opt_scale %type opt_server