Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 51bb795

Browse files
committed
Add psql PROMPT variable showing which line of a statement is being edited.
The new %l substitution shows the line number inside a (potentially multi-line) statement starting from one. Author: Sawada Masahiko, heavily editorialized by me. Reviewed-By: Jeevan Chalke, Alvaro Herrera
1 parent bd3b7a9 commit 51bb795

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

doc/src/sgml/ref/psql-ref.sgml

+9
Original file line numberDiff line numberDiff line change
@@ -3315,6 +3315,15 @@ testdb=&gt; <userinput>INSERT INTO my_table VALUES (:'content');</userinput>
33153315
</listitem>
33163316
</varlistentry>
33173317

3318+
<varlistentry>
3319+
<term><literal>%l</literal></term>
3320+
<listitem>
3321+
<para>
3322+
The line number inside the current statement, starting from <literal>1</>.
3323+
</para>
3324+
</listitem>
3325+
</varlistentry>
3326+
33183327
<varlistentry>
33193328
<term><literal>%</literal><replaceable class="parameter">digits</replaceable></term>
33203329
<listitem>

src/bin/psql/copy.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,8 @@ bool
517517
handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
518518
{
519519
bool OK;
520-
const char *prompt;
521520
char buf[COPYBUFSIZ];
521+
bool showprompt = false;
522522

523523
/*
524524
* Establish longjmp destination for exiting from wait-for-input. (This is
@@ -540,21 +540,20 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
540540
/* Prompt if interactive input */
541541
if (isatty(fileno(copystream)))
542542
{
543+
showprompt = true;
543544
if (!pset.quiet)
544545
puts(_("Enter data to be copied followed by a newline.\n"
545546
"End with a backslash and a period on a line by itself."));
546-
prompt = get_prompt(PROMPT_COPY);
547547
}
548-
else
549-
prompt = NULL;
550548

551549
OK = true;
552550

553551
if (isbinary)
554552
{
555553
/* interactive input probably silly, but give one prompt anyway */
556-
if (prompt)
554+
if (showprompt)
557555
{
556+
const char *prompt = get_prompt(PROMPT_COPY);
558557
fputs(prompt, stdout);
559558
fflush(stdout);
560559
}
@@ -589,8 +588,9 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
589588
bool firstload;
590589
bool linedone;
591590

592-
if (prompt)
591+
if (showprompt)
593592
{
593+
const char *prompt = get_prompt(PROMPT_COPY);
594594
fputs(prompt, stdout);
595595
fflush(stdout);
596596
}
@@ -650,7 +650,10 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
650650
}
651651

652652
if (copystream == pset.cur_cmd_source)
653+
{
653654
pset.lineno++;
655+
pset.stmt_lineno++;
656+
}
654657
}
655658
}
656659

src/bin/psql/mainloop.c

+23
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ MainLoop(FILE *source)
5858
pset.cur_cmd_source = source;
5959
pset.cur_cmd_interactive = ((source == stdin) && !pset.notty);
6060
pset.lineno = 0;
61+
pset.stmt_lineno = 1;
6162

6263
/* Create working state */
6364
scan_state = psql_scan_create();
@@ -110,6 +111,7 @@ MainLoop(FILE *source)
110111
count_eof = 0;
111112
slashCmdStatus = PSQL_CMD_UNKNOWN;
112113
prompt_status = PROMPT_READY;
114+
pset.stmt_lineno = 1;
113115
cancel_pressed = false;
114116

115117
if (pset.cur_cmd_interactive)
@@ -225,7 +227,10 @@ MainLoop(FILE *source)
225227
{
226228
PsqlScanResult scan_result;
227229
promptStatus_t prompt_tmp = prompt_status;
230+
size_t pos_in_query;
231+
char *tmp_line;
228232

233+
pos_in_query = query_buf->len;
229234
scan_result = psql_scan(scan_state, query_buf, &prompt_tmp);
230235
prompt_status = prompt_tmp;
231236

@@ -235,6 +240,22 @@ MainLoop(FILE *source)
235240
exit(EXIT_FAILURE);
236241
}
237242

243+
/*
244+
* Increase statement line number counter for each linebreak added
245+
* to the query buffer by the last psql_scan() call. There only
246+
* will be ones to add when navigating to a statement in
247+
* readline's history containing newlines.
248+
*/
249+
tmp_line = query_buf->data + pos_in_query;
250+
while (*tmp_line != '\0')
251+
{
252+
if (*(tmp_line++) == '\n')
253+
pset.stmt_lineno++;
254+
}
255+
256+
if (scan_result == PSCAN_EOL)
257+
pset.stmt_lineno++;
258+
238259
/*
239260
* Send command if semicolon found, or if end of line and we're in
240261
* single-line mode.
@@ -256,6 +277,7 @@ MainLoop(FILE *source)
256277
/* execute query */
257278
success = SendQuery(query_buf->data);
258279
slashCmdStatus = success ? PSQL_CMD_SEND : PSQL_CMD_ERROR;
280+
pset.stmt_lineno = 1;
259281

260282
/* transfer query to previous_buf by pointer-swapping */
261283
{
@@ -303,6 +325,7 @@ MainLoop(FILE *source)
303325
query_buf : previous_buf);
304326

305327
success = slashCmdStatus != PSQL_CMD_ERROR;
328+
pset.stmt_lineno = 1;
306329

307330
if ((slashCmdStatus == PSQL_CMD_SEND || slashCmdStatus == PSQL_CMD_NEWEDIT) &&
308331
query_buf->len == 0)

src/bin/psql/prompt.c

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* in prompt2 -, *, ', or ";
4545
* in prompt3 nothing
4646
* %x - transaction status: empty, *, !, ? (unknown or no connection)
47+
* %l - The line number inside the current statement, starting from 1.
4748
* %? - the error code of the last query (not yet implemented)
4849
* %% - a percent sign
4950
*
@@ -229,6 +230,10 @@ get_prompt(promptStatus_t status)
229230
}
230231
break;
231232

233+
case 'l':
234+
snprintf(buf, sizeof(buf), UINT64_FORMAT, pset.stmt_lineno);
235+
break;
236+
232237
case '?':
233238
/* not here yet */
234239
break;

src/bin/psql/settings.h

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ typedef struct _psqlSettings
8888
const char *progname; /* in case you renamed psql */
8989
char *inputfile; /* file being currently processed, if any */
9090
uint64 lineno; /* also for error reporting */
91+
uint64 stmt_lineno; /* line number inside the current statement */
9192

9293
bool timing; /* enable timing of all queries */
9394

0 commit comments

Comments
 (0)