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

Commit97299cf

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 parentebf87c0 commit97299cf

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
@@ -2872,8 +2872,8 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
28722872
*
28732873
* Note: if you change the output format of this function, be careful not
28742874
* to break psql's rules (in \ef and \sf) for identifying the start of the
2875-
* function body. To wit: the function body starts on a line that begins
2876-
*with"AS ", and no preceding line will look like that.
2875+
* function body. To wit: the function body starts on a line that begins with
2876+
* "AS ", "BEGIN ", or "RETURN ", and no preceding line will look like that.
28772877
*/
28782878
Datum
28792879
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
@@ -167,8 +167,7 @@ static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid,
167167
PQExpBufferbuf);
168168
staticintstrip_lineno_from_objdesc(char*obj);
169169
staticintcount_lines_in_buf(PQExpBufferbuf);
170-
staticvoidprint_with_linenumbers(FILE*output,char*lines,
171-
constchar*header_keyword);
170+
staticvoidprint_with_linenumbers(FILE*output,char*lines,boolis_func);
172171
staticvoidminimal_error_message(PGresult*res);
173172

174173
staticvoidprintSSLInfo(void);
@@ -1170,17 +1169,19 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
11701169
/*
11711170
* lineno "1" should correspond to the first line of the
11721171
* function body. We expect that pg_get_functiondef() will
1173-
* emit that on a line beginning with "AS ",and that there
1174-
* can be no such line before the real start of the function
1175-
* body. Increment lineno by the number of lines before that
1176-
* line, so that it becomes relative to the first line of the
1177-
* function definition.
1172+
* emit that on a line beginning with "AS ","BEGIN ", or
1173+
*"RETURN ", and that therecan be no such line before the
1174+
*real start of the functionbody. Increment lineno by the
1175+
*number of lines before thatline, so that it becomes
1176+
*relative to the first line of thefunction definition.
11781177
*/
11791178
constchar*lines=query_buf->data;
11801179

11811180
while (*lines!='\0')
11821181
{
1183-
if (strncmp(lines,"AS ",3)==0)
1182+
if (strncmp(lines,"AS ",3)==0||
1183+
strncmp(lines,"BEGIN ",6)==0||
1184+
strncmp(lines,"RETURN ",7)==0)
11841185
break;
11851186
lineno++;
11861187
/* find start of next line */
@@ -2502,15 +2503,8 @@ exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
25022503

25032504
if (show_linenumbers)
25042505
{
2505-
/*
2506-
* For functions, lineno "1" should correspond to the first
2507-
* line of the function body. We expect that
2508-
* pg_get_functiondef() will emit that on a line beginning
2509-
* with "AS ", and that there can be no such line before the
2510-
* real start of the function body.
2511-
*/
2512-
print_with_linenumbers(output,buf->data,
2513-
is_func ?"AS " :NULL);
2506+
/* add line numbers */
2507+
print_with_linenumbers(output,buf->data,is_func);
25142508
}
25152509
else
25162510
{
@@ -5530,24 +5524,28 @@ count_lines_in_buf(PQExpBuffer buf)
55305524
/*
55315525
* Write text at *lines to output with line numbers.
55325526
*
5533-
* If header_keyword isn't NULL, then line 1 should be the first line beginning
5534-
* with header_keyword; lines before that are unnumbered.
5527+
* For functions, lineno "1" should correspond to the first line of the
5528+
* function body; lines before that are unnumbered. We expect that
5529+
* pg_get_functiondef() will emit that on a line beginning with "AS ",
5530+
* "BEGIN ", or "RETURN ", and that there can be no such line before
5531+
* the real start of the function body.
55355532
*
55365533
* Caution: this scribbles on *lines.
55375534
*/
55385535
staticvoid
5539-
print_with_linenumbers(FILE*output,char*lines,
5540-
constchar*header_keyword)
5536+
print_with_linenumbers(FILE*output,char*lines,boolis_func)
55415537
{
5542-
boolin_header= (header_keyword!=NULL);
5543-
size_theader_sz=in_header ?strlen(header_keyword) :0;
5538+
boolin_header=is_func;
55445539
intlineno=0;
55455540

55465541
while (*lines!='\0')
55475542
{
55485543
char*eol;
55495544

5550-
if (in_header&&strncmp(lines,header_keyword,header_sz)==0)
5545+
if (in_header&&
5546+
(strncmp(lines,"AS ",3)==0||
5547+
strncmp(lines,"BEGIN ",6)==0||
5548+
strncmp(lines,"RETURN ",7)==0))
55515549
in_header= false;
55525550

55535551
/* 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
@@ -5194,6 +5194,13 @@ reset work_mem;
51945194
pg_catalog | bit_xor | smallint | smallint | agg
51955195
(3 rows)
51965196

5197+
\df *._pg_expandarray
5198+
List of functions
5199+
Schema | Name | Result data type | Argument data types | Type
5200+
--------------------+-----------------+------------------+-------------------------------------------+------
5201+
information_schema | _pg_expandarray | SETOF record | anyarray, OUT x anyelement, OUT n integer | func
5202+
(1 row)
5203+
51975204
\do - pg_catalog.int4
51985205
List of operators
51995206
Schema | Name | Left arg type | Right arg type | Result type | Description
@@ -5208,6 +5215,61 @@ reset work_mem;
52085215
pg_catalog | && | anyarray | anyarray | boolean | overlaps
52095216
(1 row)
52105217

5218+
-- check \sf
5219+
\sf information_schema._pg_expandarray
5220+
CREATE OR REPLACE FUNCTION information_schema._pg_expandarray(anyarray, OUT x anyelement, OUT n integer)
5221+
RETURNS SETOF record
5222+
LANGUAGE sql
5223+
IMMUTABLE PARALLEL SAFE STRICT
5224+
AS $function$select $1[s],
5225+
s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1
5226+
from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
5227+
pg_catalog.array_upper($1,1),
5228+
1) as g(s)$function$
5229+
\sf+ information_schema._pg_expandarray
5230+
CREATE OR REPLACE FUNCTION information_schema._pg_expandarray(anyarray, OUT x anyelement, OUT n integer)
5231+
RETURNS SETOF record
5232+
LANGUAGE sql
5233+
IMMUTABLE PARALLEL SAFE STRICT
5234+
1 AS $function$select $1[s],
5235+
2 s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1
5236+
3 from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
5237+
4 pg_catalog.array_upper($1,1),
5238+
5 1) as g(s)$function$
5239+
\sf+ interval_pl_time
5240+
CREATE OR REPLACE FUNCTION pg_catalog.interval_pl_time(interval, time without time zone)
5241+
RETURNS time without time zone
5242+
LANGUAGE sql
5243+
IMMUTABLE PARALLEL SAFE STRICT COST 1
5244+
1 RETURN ($2 + $1)
5245+
\sf ts_debug(text)
5246+
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[])
5247+
RETURNS SETOF record
5248+
LANGUAGE sql
5249+
STABLE PARALLEL SAFE STRICT
5250+
BEGIN ATOMIC
5251+
SELECT ts_debug.alias,
5252+
ts_debug.description,
5253+
ts_debug.token,
5254+
ts_debug.dictionaries,
5255+
ts_debug.dictionary,
5256+
ts_debug.lexemes
5257+
FROM ts_debug(get_current_ts_config(), ts_debug.document) ts_debug(alias, description, token, dictionaries, dictionary, lexemes);
5258+
END
5259+
\sf+ ts_debug(text)
5260+
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[])
5261+
RETURNS SETOF record
5262+
LANGUAGE sql
5263+
STABLE PARALLEL SAFE STRICT
5264+
1 BEGIN ATOMIC
5265+
2 SELECT ts_debug.alias,
5266+
3 ts_debug.description,
5267+
4 ts_debug.token,
5268+
5 ts_debug.dictionaries,
5269+
6 ts_debug.dictionary,
5270+
7 ts_debug.lexemes
5271+
8 FROM ts_debug(get_current_ts_config(), ts_debug.document) ts_debug(alias, description, token, dictionaries, dictionary, lexemes);
5272+
9 END
52115273
-- AUTOCOMMIT
52125274
CREATE TABLE ac_test (a int);
52135275
\set AUTOCOMMIT off

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,9 +1257,17 @@ reset work_mem;
12571257
\df has_database_privilegeoidtext
12581258
\df has_database_privilegeoidtext-
12591259
\dfabit* small*
1260+
\df*._pg_expandarray
12601261
\do-pg_catalog.int4
12611262
\do && anyarray*
12621263

1264+
-- check \sf
1265+
\sfinformation_schema._pg_expandarray
1266+
\sf+information_schema._pg_expandarray
1267+
\sf+ interval_pl_time
1268+
\sf ts_debug(text)
1269+
\sf+ ts_debug(text)
1270+
12631271
-- AUTOCOMMIT
12641272

12651273
CREATETABLEac_test (aint);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp