From: Tom Lane <tgl@sss.pgh.pa.us>
To: David G. Johnston <david.g.johnston@gmail.com>
Cc: Erki Eessaar <erki.eessaar@taltech.ee>
Cc: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
Cc: pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
Subject: Re: INFORMATION_SCHEMA.routines column routine_definition does not show the source
Date: Thu, 01 Dec 2022 21:41:30 -0500
Message-ID: <1852623.1669948890@sss.pgh.pa.us> (raw)
In-Reply-To: <1744742.1669944519@sss.pgh.pa.us>
References: <AM9PR01MB8268D5CDABDF044EE9F42173FE8C9@AM9PR01MB8268.eurprd01.prod.exchangelabs.com>
<CAKFQuwZaihWCaR4T=4Ov9ufk7jipRbBBtEDon61XMYOU6qkhxQ@mail.gmail.com>
<134216.1635957998@sss.pgh.pa.us>
<CAKFQuwYT+HudtXnYTp_EvPvjd_a0516_PmmzJWX2SLQ+PLhqfg@mail.gmail.com>
<1744742.1669944519@sss.pgh.pa.us>
I wrote:
> We could partially fix that by teaching psql to also recognize
> "BEGIN" as the start of the function body.
Looks like we need "RETURN " too, so more or less as attached.
(I didn't bother with a test case yet. \sf wouldn't be too
hard to exercise, but I wonder how we could test \ef portably.)
regards, tom lane
Attachments:fix-psql-sf-ef-for-new-style-functions.patch (text/x-diff, 4.4K) downloaddiff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.cindex a20a1b069b..641df1cabe 100644--- a/src/backend/utils/adt/ruleutils.c+++ b/src/backend/utils/adt/ruleutils.c@@ -2867,8 +2867,8 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
*
* Note: if you change the output format of this function, be careful not
* to break psql's rules (in \ef and \sf) for identifying the start of the
- * function body. To wit: the function body starts on a line that begins- * with "AS ", and no preceding line will look like that.+ * function body. To wit: the function body starts on a line that begins with+ * "AS ", "BEGIN ", or "RETURN ", and no preceding line will look like that.
*/
Datum
pg_get_functiondef(PG_FUNCTION_ARGS)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.cindex 7672ed9e9d..de6a3a71f8 100644--- a/src/bin/psql/command.c+++ b/src/bin/psql/command.c@@ -168,8 +168,7 @@ static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid,
PQExpBuffer buf);
static int strip_lineno_from_objdesc(char *obj);
static int count_lines_in_buf(PQExpBuffer buf);
-static void print_with_linenumbers(FILE *output, char *lines,- const char *header_keyword);+static void print_with_linenumbers(FILE *output, char *lines, bool is_func);
static void minimal_error_message(PGresult *res);
static void printSSLInfo(void);
@@ -1201,17 +1200,19 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
/*
* lineno "1" should correspond to the first line of the
* function body. We expect that pg_get_functiondef() will
- * emit that on a line beginning with "AS ", and that there- * can be no such line before the real start of the function- * body. Increment lineno by the number of lines before that- * line, so that it becomes relative to the first line of the- * function definition.+ * emit that on a line beginning with "AS ", "BEGIN ", or+ * "RETURN ", and that there can be no such line before the+ * real start of the function body. Increment lineno by the+ * number of lines before that line, so that it becomes+ * relative to the first line of the function definition.
*/
const char *lines = query_buf->data;
while (*lines != '\0')
{
- if (strncmp(lines, "AS ", 3) == 0)+ if (strncmp(lines, "AS ", 3) == 0 ||+ strncmp(lines, "BEGIN ", 6) == 0 ||+ strncmp(lines, "RETURN ", 7) == 0)
break;
lineno++;
/* find start of next line */
@@ -2528,15 +2529,8 @@ exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
if (show_linenumbers)
{
- /*- * For functions, lineno "1" should correspond to the first- * line of the function body. We expect that- * pg_get_functiondef() will emit that on a line beginning- * with "AS ", and that there can be no such line before the- * real start of the function body.- */- print_with_linenumbers(output, buf->data,- is_func ? "AS " : NULL);+ /* add line numbers */+ print_with_linenumbers(output, buf->data, is_func);
}
else
{
@@ -5611,24 +5605,28 @@ count_lines_in_buf(PQExpBuffer buf)
/*
* Write text at *lines to output with line numbers.
*
- * If header_keyword isn't NULL, then line 1 should be the first line beginning- * with header_keyword; lines before that are unnumbered.+ * For functions, lineno "1" should correspond to the first line of the+ * function body; lines before that are unnumbered. We expect that+ * pg_get_functiondef() will emit that on a line beginning with "AS ",+ * "BEGIN ", or "RETURN ", and that there can be no such line before+ * the real start of the function body.
*
* Caution: this scribbles on *lines.
*/
static void
-print_with_linenumbers(FILE *output, char *lines,- const char *header_keyword)+print_with_linenumbers(FILE *output, char *lines, bool is_func)
{
- bool in_header = (header_keyword != NULL);- size_t header_sz = in_header ? strlen(header_keyword) : 0;+ bool in_header = is_func;
int lineno = 0;
while (*lines != '\0')
{
char *eol;
- if (in_header && strncmp(lines, header_keyword, header_sz) == 0)+ if (in_header &&+ (strncmp(lines, "AS ", 3) == 0 ||+ strncmp(lines, "BEGIN ", 6) == 0 ||+ strncmp(lines, "RETURN ", 7) == 0))
in_header = false;
/* increment lineno only for body's lines */
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: tgl@sss.pgh.pa.us, david.g.johnston@gmail.com, erki.eessaar@taltech.ee, peter.eisentraut@2ndquadrant.com, pgsql-bugs@lists.postgresql.org
Subject: Re: INFORMATION_SCHEMA.routines column routine_definition does not show the source
In-Reply-To: <1852623.1669948890@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox