mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Fix psql's \sf and \ef for new-style SQL functions.
Some options of these commands need to be able to identify the start of the function body within the output of pg_get_functiondef(). It used to be that that always began with "AS", but since the introduction of new-style SQL functions, it might also start with "BEGIN" or "RETURN". Fix that on the psql side, and add some regression tests. Noted by me awhile ago, but I didn't do anything about it. Thanks to David Johnston for a nag. Discussion: https://postgr.es/m/AM9PR01MB8268D5CDABDF044EE9F42173FE8C9@AM9PR01MB8268.eurprd01.prod.exchangelabs.com
This commit is contained in:
@ -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 */
|
||||
|
Reference in New Issue
Block a user