Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcabfb82

Browse files
committed
Fix psql's \sf and \ef for new-style SQL functions.
Some options of these commands need to be able to identify the startof the function body within the output of pg_get_functiondef().It used to be that that always began with "AS", but since theintroduction of new-style SQL functions, it might also start with"BEGIN" or "RETURN". Fix that on the psql side, and add someregression 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
1 parentb23cd18 commitcabfb82

File tree

4 files changed

+94
-26
lines changed

4 files changed

+94
-26
lines changed

‎src/backend/utils/adt/ruleutils.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2867,8 +2867,8 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
28672867
*
28682868
* Note: if you change the output format of this function, be careful not
28692869
* to break psql's rules (in \ef and \sf) for identifying the start of the
2870-
* function body. To wit: the function body starts on a line that begins
2871-
*with"AS ", and no preceding line will look like that.
2870+
* function body. To wit: the function body starts on a line that begins with
2871+
* "AS ", "BEGIN ", or "RETURN ", and no preceding line will look like that.
28722872
*/
28732873
Datum
28742874
pg_get_functiondef(PG_FUNCTION_ARGS)

‎src/bin/psql/command.c

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,7 @@ static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid,
168168
PQExpBufferbuf);
169169
staticintstrip_lineno_from_objdesc(char*obj);
170170
staticintcount_lines_in_buf(PQExpBufferbuf);
171-
staticvoidprint_with_linenumbers(FILE*output,char*lines,
172-
constchar*header_keyword);
171+
staticvoidprint_with_linenumbers(FILE*output,char*lines,boolis_func);
173172
staticvoidminimal_error_message(PGresult*res);
174173

175174
staticvoidprintSSLInfo(void);
@@ -1201,17 +1200,19 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
12011200
/*
12021201
* lineno "1" should correspond to the first line of the
12031202
* function body. We expect that pg_get_functiondef() will
1204-
* emit that on a line beginning with "AS ",and that there
1205-
* can be no such line before the real start of the function
1206-
* body. Increment lineno by the number of lines before that
1207-
* line, so that it becomes relative to the first line of the
1208-
* function definition.
1203+
* emit that on a line beginning with "AS ","BEGIN ", or
1204+
*"RETURN ", and that therecan be no such line before the
1205+
*real start of the functionbody. Increment lineno by the
1206+
*number of lines before thatline, so that it becomes
1207+
*relative to the first line of thefunction definition.
12091208
*/
12101209
constchar*lines=query_buf->data;
12111210

12121211
while (*lines!='\0')
12131212
{
1214-
if (strncmp(lines,"AS ",3)==0)
1213+
if (strncmp(lines,"AS ",3)==0||
1214+
strncmp(lines,"BEGIN ",6)==0||
1215+
strncmp(lines,"RETURN ",7)==0)
12151216
break;
12161217
lineno++;
12171218
/* find start of next line */
@@ -2528,15 +2529,8 @@ exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
25282529

25292530
if (show_linenumbers)
25302531
{
2531-
/*
2532-
* For functions, lineno "1" should correspond to the first
2533-
* line of the function body. We expect that
2534-
* pg_get_functiondef() will emit that on a line beginning
2535-
* with "AS ", and that there can be no such line before the
2536-
* real start of the function body.
2537-
*/
2538-
print_with_linenumbers(output,buf->data,
2539-
is_func ?"AS " :NULL);
2532+
/* add line numbers */
2533+
print_with_linenumbers(output,buf->data,is_func);
25402534
}
25412535
else
25422536
{
@@ -5611,24 +5605,28 @@ count_lines_in_buf(PQExpBuffer buf)
56115605
/*
56125606
* Write text at *lines to output with line numbers.
56135607
*
5614-
* If header_keyword isn't NULL, then line 1 should be the first line beginning
5615-
* with header_keyword; lines before that are unnumbered.
5608+
* For functions, lineno "1" should correspond to the first line of the
5609+
* function body; lines before that are unnumbered. We expect that
5610+
* pg_get_functiondef() will emit that on a line beginning with "AS ",
5611+
* "BEGIN ", or "RETURN ", and that there can be no such line before
5612+
* the real start of the function body.
56165613
*
56175614
* Caution: this scribbles on *lines.
56185615
*/
56195616
staticvoid
5620-
print_with_linenumbers(FILE*output,char*lines,
5621-
constchar*header_keyword)
5617+
print_with_linenumbers(FILE*output,char*lines,boolis_func)
56225618
{
5623-
boolin_header= (header_keyword!=NULL);
5624-
size_theader_sz=in_header ?strlen(header_keyword) :0;
5619+
boolin_header=is_func;
56255620
intlineno=0;
56265621

56275622
while (*lines!='\0')
56285623
{
56295624
char*eol;
56305625

5631-
if (in_header&&strncmp(lines,header_keyword,header_sz)==0)
5626+
if (in_header&&
5627+
(strncmp(lines,"AS ",3)==0||
5628+
strncmp(lines,"BEGIN ",6)==0||
5629+
strncmp(lines,"RETURN ",7)==0))
56325630
in_header= false;
56335631

56345632
/* increment lineno only for body's lines */

‎src/test/regress/expected/psql.out

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5226,6 +5226,13 @@ reset work_mem;
52265226
pg_catalog | bit_xor | smallint | smallint | agg
52275227
(3 rows)
52285228

5229+
\df *._pg_expandarray
5230+
List of functions
5231+
Schema | Name | Result data type | Argument data types | Type
5232+
--------------------+-----------------+------------------+-------------------------------------------+------
5233+
information_schema | _pg_expandarray | SETOF record | anyarray, OUT x anyelement, OUT n integer | func
5234+
(1 row)
5235+
52295236
\do - pg_catalog.int4
52305237
List of operators
52315238
Schema | Name | Left arg type | Right arg type | Result type | Description
@@ -5240,6 +5247,61 @@ reset work_mem;
52405247
pg_catalog | && | anyarray | anyarray | boolean | overlaps
52415248
(1 row)
52425249

5250+
-- check \sf
5251+
\sf information_schema._pg_expandarray
5252+
CREATE OR REPLACE FUNCTION information_schema._pg_expandarray(anyarray, OUT x anyelement, OUT n integer)
5253+
RETURNS SETOF record
5254+
LANGUAGE sql
5255+
IMMUTABLE PARALLEL SAFE STRICT
5256+
AS $function$select $1[s],
5257+
s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1
5258+
from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
5259+
pg_catalog.array_upper($1,1),
5260+
1) as g(s)$function$
5261+
\sf+ information_schema._pg_expandarray
5262+
CREATE OR REPLACE FUNCTION information_schema._pg_expandarray(anyarray, OUT x anyelement, OUT n integer)
5263+
RETURNS SETOF record
5264+
LANGUAGE sql
5265+
IMMUTABLE PARALLEL SAFE STRICT
5266+
1 AS $function$select $1[s],
5267+
2 s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1
5268+
3 from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
5269+
4 pg_catalog.array_upper($1,1),
5270+
5 1) as g(s)$function$
5271+
\sf+ interval_pl_time
5272+
CREATE OR REPLACE FUNCTION pg_catalog.interval_pl_time(interval, time without time zone)
5273+
RETURNS time without time zone
5274+
LANGUAGE sql
5275+
IMMUTABLE PARALLEL SAFE STRICT COST 1
5276+
1 RETURN ($2 + $1)
5277+
\sf ts_debug(text)
5278+
CREATE OR REPLACE FUNCTION pg_catalog.ts_debug(document text, OUT alias text, OUT description text, OUT token text, OUT dictionaries regdictionary[], OUT dictionary regdictionary, OUT lexemes text[])
5279+
RETURNS SETOF record
5280+
LANGUAGE sql
5281+
STABLE PARALLEL SAFE STRICT
5282+
BEGIN ATOMIC
5283+
SELECT ts_debug.alias,
5284+
ts_debug.description,
5285+
ts_debug.token,
5286+
ts_debug.dictionaries,
5287+
ts_debug.dictionary,
5288+
ts_debug.lexemes
5289+
FROM ts_debug(get_current_ts_config(), ts_debug.document) ts_debug(alias, description, token, dictionaries, dictionary, lexemes);
5290+
END
5291+
\sf+ ts_debug(text)
5292+
CREATE OR REPLACE FUNCTION pg_catalog.ts_debug(document text, OUT alias text, OUT description text, OUT token text, OUT dictionaries regdictionary[], OUT dictionary regdictionary, OUT lexemes text[])
5293+
RETURNS SETOF record
5294+
LANGUAGE sql
5295+
STABLE PARALLEL SAFE STRICT
5296+
1 BEGIN ATOMIC
5297+
2 SELECT ts_debug.alias,
5298+
3 ts_debug.description,
5299+
4 ts_debug.token,
5300+
5 ts_debug.dictionaries,
5301+
6 ts_debug.dictionary,
5302+
7 ts_debug.lexemes
5303+
8 FROM ts_debug(get_current_ts_config(), ts_debug.document) ts_debug(alias, description, token, dictionaries, dictionary, lexemes);
5304+
9 END
52435305
-- AUTOCOMMIT
52445306
CREATE TABLE ac_test (a int);
52455307
\set AUTOCOMMIT off

‎src/test/regress/sql/psql.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,9 +1271,17 @@ reset work_mem;
12711271
\df has_database_privilegeoidtext
12721272
\df has_database_privilegeoidtext-
12731273
\dfabit* small*
1274+
\df*._pg_expandarray
12741275
\do-pg_catalog.int4
12751276
\do && anyarray*
12761277

1278+
-- check \sf
1279+
\sfinformation_schema._pg_expandarray
1280+
\sf+information_schema._pg_expandarray
1281+
\sf+ interval_pl_time
1282+
\sf ts_debug(text)
1283+
\sf+ ts_debug(text)
1284+
12771285
-- AUTOCOMMIT
12781286

12791287
CREATETABLEac_test (aint);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp