commit 8783a78011e3aaa84c2fd32152cc42490eed316b Author: kuroda.hayato%40jp.fujitsu.com Date: Thu Aug 26 05:11:37 2021 +0000 add application_name to postgres_fdw diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index a3e1c59a82..ee5a8ede06 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -82,7 +82,7 @@ #include "utils/guc.h" #include "utils/memutils.h" #include "utils/ps_status.h" - +#include "common/string.h" /* In this module, access gettext() via err_gettext() */ #undef _ @@ -177,7 +177,6 @@ static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *st static void write_console(const char *line, int len); static void setup_formatted_log_time(void); static void setup_formatted_start_time(void); -static const char *process_log_prefix_padding(const char *p, int *padding); static void log_line_prefix(StringInfo buf, ErrorData *edata); static void write_csvlog(ErrorData *edata); static void send_message_to_server_log(ErrorData *edata); @@ -2338,41 +2337,6 @@ setup_formatted_start_time(void) pg_localtime(&stamp_time, log_timezone)); } -/* - * process_log_prefix_padding --- helper function for processing the format - * string in log_line_prefix - * - * Note: This function returns NULL if it finds something which - * it deems invalid in the format string. - */ -static const char * -process_log_prefix_padding(const char *p, int *ppadding) -{ - int paddingsign = 1; - int padding = 0; - - if (*p == '-') - { - p++; - - if (*p == '\0') /* Did the buf end in %- ? */ - return NULL; - paddingsign = -1; - } - - /* generate an int version of the numerical string */ - while (*p >= '0' && *p <= '9') - padding = padding * 10 + (*p++ - '0'); - - /* format is invalid if it ends with the padding number */ - if (*p == '\0') - return NULL; - - padding *= paddingsign; - *ppadding = padding; - return p; -} - /* * Format tag info for log lines; append to the provided buffer. */ @@ -2427,7 +2391,7 @@ log_line_prefix(StringInfo buf, ErrorData *edata) /* * Process any formatting which may exist after the '%'. Note that - * process_log_prefix_padding moves p past the padding number if it + * process_padding moves p past the padding number if it * exists. * * Note: Since only '-', '0' to '9' are valid formatting characters we @@ -2441,7 +2405,7 @@ log_line_prefix(StringInfo buf, ErrorData *edata) */ if (*p > '9') padding = 0; - else if ((p = process_log_prefix_padding(p, &padding)) == NULL) + else if ((p = process_padding(p, &padding)) == NULL) break; /* process the option */ diff --git a/src/common/string.c b/src/common/string.c index 3aa378c051..9f8b5c3468 100644 --- a/src/common/string.c +++ b/src/common/string.c @@ -128,3 +128,38 @@ pg_strip_crlf(char *str) return len; } + +/* + * process_padding --- helper function for processing the format + * string + * + * Note: This function returns NULL if it finds something which + * it deems invalid in the format string. + */ +const char * +process_padding(const char *p, int *ppadding) +{ + int paddingsign = 1; + int padding = 0; + + if (*p == '-') + { + p++; + + if (*p == '\0') /* Did the buf end in %- ? */ + return NULL; + paddingsign = -1; + } + + /* generate an int version of the numerical string */ + while (*p >= '0' && *p <= '9') + padding = padding * 10 + (*p++ - '0'); + + /* format is invalid if it ends with the padding number */ + if (*p == '\0') + return NULL; + + padding *= paddingsign; + *ppadding = padding; + return p; +} diff --git a/src/include/common/string.h b/src/include/common/string.h index 686c158efe..1f14e3124f 100644 --- a/src/include/common/string.h +++ b/src/include/common/string.h @@ -19,6 +19,7 @@ extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, extern void pg_clean_ascii(char *str); extern int pg_strip_crlf(char *str); extern bool pg_is_ascii(const char *str); +extern const char* process_padding(const char *p, int *ppadding); /* functions in src/common/pg_get_line.c */ extern char *pg_get_line(FILE *stream); diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 49eec3e835..55fbad3087 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -427,6 +427,8 @@ static void default_threadlock(int acquire); static bool sslVerifyProtocolVersion(const char *version); static bool sslVerifyProtocolRange(const char *min, const char *max); +static void parse_and_rewrite_appnames(PGconn *conn); +static void parse_and_rewrite_appname_internal(PGconn *conn, char **name); /* global variable because fe-auth.c needs to access it */ pgthreadlock_t pg_g_threadlock = default_threadlock; @@ -1436,6 +1438,13 @@ connectOptions2(PGconn *conn) goto oom_error; } + /* + * if we have application_name or fallback_application_name, + * parse it and rewrite escape characters + */ + if (conn->appname || conn->fbappname) + parse_and_rewrite_appnames(conn); + /* * Only if we get this far is it appropriate to try to connect. (We need a * state flag, rather than just the boolean result of this function, in @@ -3834,6 +3843,76 @@ error_return: return PGRES_POLLING_FAILED; } +static void +parse_and_rewrite_appnames(PGconn *conn) +{ + if (conn->appname && conn->appname[0] != '\0') + parse_and_rewrite_appname_internal(conn, &conn->appname); + else if (conn->fbappname && conn->fbappname[0] != '\0') + parse_and_rewrite_appname_internal(conn, &conn->fbappname); +} + +/* + * Almost same as log_line_prefix + */ +static void +parse_and_rewrite_appname_internal(PGconn *conn, char **name) +{ + PQExpBuffer buf = createPQExpBuffer(); + const char *p; + int padding; + + for (p = *name; *p != '\0'; p++) + { + if (*p != '%') + { + /* literal char, just copy */ + appendPQExpBufferChar(buf, *p); + continue; + } + + /* must be a '%', so skip to the next char */ + p++; + if (*p == '\0') + break; /* format error - ignore it */ + else if (*p == '%') + { + /* string contains %% */ + appendPQExpBufferChar(buf, '%'); + continue; + } + + /* calculate padding, same as log_line_prefix */ + if (*p > '9') + padding = 0; + else if ((p = process_padding(p, &padding)) == NULL) + break; + + /* process the option */ + switch (*p) + { + case 'p': + { + int pid = (int) getpid(); + + if (padding != 0) + appendPQExpBuffer(buf, "%*d", padding, pid); + else + appendPQExpBuffer(buf, "%d", pid); + } + break; + default: + /* format error - ignore it */ + break; + } + } + + /* Finnaly replace the string */ + free(*name); + *name = strdup(buf->data); + + destroyPQExpBuffer(buf); +} /* * internal_ping