Re: tab-completion debug print - Mailing list pgsql-hackers
From | Kyotaro HORIGUCHI |
---|---|
Subject | Re: tab-completion debug print |
Date | |
Msg-id | 20181213.200739.07969126.horiguchi.kyotaro@lab.ntt.co.jp Whole thread Raw |
In response to | Re: tab-completion debug print (Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>) |
Responses |
Re: tab-completion debug print
|
List | pgsql-hackers |
Hello. At Wed, 28 Nov 2018 17:28:39 +0900 (Tokyo Standard Time), Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> wrote in <20181128.172839.242071562.horiguchi.kyotaro@lab.ntt.co.jp> > I'm not sure how much it is wanted but it's easy to do. Using > psql variable doesn't seem to make sense since the debug print > (currently) requires session log file, which can be turned on > only at the startup time. '-g' option is available by 0003. > > $ psql -gL ~/psql.log postgres > > > Can we conceive of a circumstance where the check for -L/\L would be > > significant? I've seen people type pretty quickly, but not thus far > > fast enough to notice a cache miss. > > We could switch completion_matches body as necessity using > function poniter, but we aren't so eager for speed here. It is at > most called every time entering tab. So, the new version v6 patch consists of the following two files: - v6-0001-Tab-copletion-debug-log.patch Full-context version. Activated by -DTABCOMPLETION_DEBUG at compile time and always emit logs into session log file specified -L. The format of a line looks like below. > tab-complete.c:1870: (...table t1 alter [CO]) -> ("CO", "COLUMN", "CONSTRAINT") - v6-0002-Add-psql-g-option-to-control-debug-print.patch Applies on top of 0001. Code is always active, -g addition to -L activates debug print into the log file. If only -g is specified it is forcibly turned off. > $ psql postgres -g > psql: no session log file, turn off debug print > psql (12devel) > Type "help" for help. -g option shows in help message. (perhaps arguable.) I'll register this to the next CF. regards. -- Kyotaro Horiguchi NTT Open Source Software Center From ab5f2b27a13ee6fd19e0c496748d1b0d299e86d6 Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp> Date: Tue, 27 Nov 2018 14:57:46 +0900 Subject: [PATCH 1/2] Tab-copletion debug log With this patch, psql built with TABCOMPLETION_DEBUG defined emits tab-completion debug log into the file specified -L option. --- src/bin/psql/tab-complete.c | 82 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 7 deletions(-) diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index fa44b2820b..8addca60a6 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -60,6 +60,67 @@ extern char *filename_completion_function(); #define completion_matches rl_completion_matches #endif +/* + * By enabling TABCOMPLETION_DEBUG, every completion attempt is logged in + * session log file if any. + */ +#ifdef TABCOMPLETION_DEBUG + +#undef completion_matches +#define completion_matches(text, func) \ + completion_debug(__LINE__, (text), (func), \ + previous_words, previous_words_count) + +#define DEBUG_NCONTEXT 3 + +static char ** +completion_debug(int line, const char *text, rl_compentry_func_t *func, + char **previous_words, int previous_words_count) +{ +#ifdef HAVE_RL_COMPLETION_MATCHES + char **list = rl_completion_matches(text, func); +#else + char **list = completion_matches(text, func); +#endif + + if (pset.logfile) + { + /* Emit completion log */ + + /* Enclose empty list with brackets since it is an intermediate state + * which is immediately followed by a non-empty list. + */ + fprintf(pset.logfile, "%s:%d: %s(", __FILE__, line, list ? "" : "["); + + /* input context */ + if (previous_words_count > 0) + { + int nwords = DEBUG_NCONTEXT; + + /* ellipse more than DEBUG_NCONTEXT words back */ + if (previous_words_count > nwords) + fprintf(pset.logfile, "..."); + else + nwords = previous_words_count; + + for (int i = 0 ; i < nwords ; ++i) + fprintf(pset.logfile, "%s ", previous_words[nwords - i - 1]); + } + + fprintf(pset.logfile, "[%s]) -> (", text); + + /* completion result */ + for (int i = 0; list && list[i]; ++i) + fprintf(pset.logfile, "%s\"%s\"", i ? ", " : "", list[i]); + fprintf(pset.logfile, ")%s\n", list ? "": "]"); + + fflush(pset.logfile); + } + + return list; +} +#endif /* TABCOMPLETION_DEBUG */ + /* word break characters */ #define WORD_BREAKS "\t\n@$><=;|&{() " @@ -1012,7 +1073,8 @@ static void append_variable_names(char ***varnames, int *nvars, int *maxvars, const char *varname, const char *prefix, const char *suffix); static char **complete_from_variables(const char *text, - const char *prefix, const char *suffix, bool need_value); + const char *prefix, const char *suffix, bool need_value, + char ** previous_words, int previous_words_count); static char *complete_from_files(const char *text, int state); static char *pg_strdup_keyword_case(const char *s, const char *ref); @@ -1385,11 +1447,14 @@ psql_completion(const char *text, int start, int end) else if (text[0] == ':' && text[1] != ':') { if (text[1] == '\'') - matches = complete_from_variables(text, ":'", "'", true); + matches = complete_from_variables(text, ":'", "'", true, + previous_words, previous_words_count); else if (text[1] == '"') - matches = complete_from_variables(text, ":\"", "\"", true); + matches = complete_from_variables(text, ":\"", "\"", true, + previous_words, previous_words_count); else - matches = complete_from_variables(text, ":", "", true); + matches = complete_from_variables(text, ":", "", true, + previous_words, previous_words_count); } /* If no previous word, suggest one of the basic sql commands */ @@ -3548,9 +3613,11 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_CS("single", "double"); } else if (TailMatchesCS("\\unset")) - matches = complete_from_variables(text, "", "", true); + matches = complete_from_variables(text, "", "", true, + previous_words, previous_words_count); else if (TailMatchesCS("\\set")) - matches = complete_from_variables(text, "", "", false); + matches = complete_from_variables(text, "", "", false, + previous_words, previous_words_count); else if (TailMatchesCS("\\set", MatchAny)) { if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|" @@ -4102,7 +4169,8 @@ append_variable_names(char ***varnames, int *nvars, */ static char ** complete_from_variables(const char *text, const char *prefix, const char *suffix, - bool need_value) + bool need_value, + char ** previous_words, int previous_words_count) { char **matches; char **varnames; -- 2.16.3 From 5a7dbb38167c226dcc093e5190b0ab4437c138df Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp> Date: Wed, 28 Nov 2018 11:24:53 +0900 Subject: [PATCH 2/2] Add psql -g option to control debug print Added -g option and related help messages. TABCOMPLETION_DEBUG was removed and the previously ifdef'ed code became always active. --- src/bin/psql/help.c | 2 +- src/bin/psql/settings.h | 1 + src/bin/psql/startup.c | 12 +++++++++++- src/bin/psql/tab-complete.c | 14 +------------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 2e9fe760eb..43f224f3e8 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -123,7 +123,7 @@ usage(unsigned short int pager) " set field separator for unaligned output to zero byte\n")); fprintf(output, _(" -0, --record-separator-zero\n" " set record separator for unaligned output to zero byte\n")); - + fprintf(output, _(" -g, --debug turn on debug print to session log file\n")); fprintf(output, _("\nConnection options:\n")); /* Display default host */ env = getenv("PGHOST"); diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index 176c85afd0..c0bc96bf20 100644 --- a/src/bin/psql/settings.h +++ b/src/bin/psql/settings.h @@ -140,6 +140,7 @@ typedef struct _psqlSettings const char *prompt3; PGVerbosity verbosity; /* current error verbosity level */ PGContextVisibility show_context; /* current context display level */ + bool debug; } PsqlSettings; extern PsqlSettings pset; diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index e7536a8a06..25f78bcc2c 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -310,6 +310,12 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } } + else if (pset.debug) + { + fprintf(stderr, _("%s: no session log file, turn off debug print\n"), + pset.progname); + pset.debug = false; + } if (!options.no_psqlrc) process_psqlrc(argv[0]); @@ -440,6 +446,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) {"no-align", no_argument, NULL, 'A'}, {"command", required_argument, NULL, 'c'}, {"dbname", required_argument, NULL, 'd'}, + {"debug", no_argument, NULL, 'g'}, {"echo-queries", no_argument, NULL, 'e'}, {"echo-errors", no_argument, NULL, 'b'}, {"echo-hidden", no_argument, NULL, 'E'}, @@ -480,7 +487,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) memset(options, 0, sizeof *options); - while ((c = getopt_long(argc, argv, "aAbc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01", + while ((c = getopt_long(argc, argv, "aAbc:d:eEf:F:gh:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01", long_options, &optindex)) != -1) { switch (c) @@ -518,6 +525,9 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) ACT_FILE, optarg); break; + case 'g': + pset.debug = true; + break; case 'F': pset.popt.topt.fieldSep.separator = pg_strdup(optarg); pset.popt.topt.fieldSep.separator_zero = false; diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 8addca60a6..e034ff6da2 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -56,17 +56,6 @@ extern char *filename_completion_function(); #endif -#ifdef HAVE_RL_COMPLETION_MATCHES -#define completion_matches rl_completion_matches -#endif - -/* - * By enabling TABCOMPLETION_DEBUG, every completion attempt is logged in - * session log file if any. - */ -#ifdef TABCOMPLETION_DEBUG - -#undef completion_matches #define completion_matches(text, func) \ completion_debug(__LINE__, (text), (func), \ previous_words, previous_words_count) @@ -83,7 +72,7 @@ completion_debug(int line, const char *text, rl_compentry_func_t *func, char **list = completion_matches(text, func); #endif - if (pset.logfile) + if (pset.debug && pset.logfile) { /* Emit completion log */ @@ -119,7 +108,6 @@ completion_debug(int line, const char *text, rl_compentry_func_t *func, return list; } -#endif /* TABCOMPLETION_DEBUG */ /* word break characters */ #define WORD_BREAKS "\t\n@$><=;|&{() " -- 2.16.3
pgsql-hackers by date: