diff --git a/doc/src/sgml/ref/psql-ref.sgmlin b/doc/src/sgml/ref/psql-ref.sgmlin
index bfbc6b136..8e387204e 100644
--- a/doc/src/sgml/ref/psql-ref.sgmlin
+++ b/doc/src/sgml/ref/psql-ref.sgmlin
@@ -2833,6 +2833,22 @@ bar
+
+ HISTSIZE
+
+
+ The number of commands to store in the command history. The
+ default value is 500.
+
+
+
+ This feature was shamelessly plagiarized from
+ Bash.
+
+
+
+
+
HOST
diff --git a/src/bin/psql/command.cpp b/src/bin/psql/command.cpp
index 56a5413a8..f0587febd 100644
--- a/src/bin/psql/command.cpp
+++ b/src/bin/psql/command.cpp
@@ -1051,6 +1051,12 @@ static backslashResult exec_command(const char* cmd, PsqlScanState scan_state, P
success = false;
}
+#ifdef USE_READLINE
+ if (useReadline && pset.cur_cmd_interactive) {
+ setHistSize(opt0, newval, false);
+ }
+#endif
+
free(newval);
newval = NULL;
if (temp_opt != NULL)
@@ -1255,6 +1261,12 @@ static backslashResult exec_command(const char* cmd, PsqlScanState scan_state, P
success = false;
}
+#ifdef USE_READLINE
+ if (useReadline && pset.cur_cmd_interactive) {
+ setHistSize(opt, NULL, true);
+ }
+#endif
+
if (NULL != opt) {
free(opt);
opt = NULL;
diff --git a/src/bin/psql/input.cpp b/src/bin/psql/input.cpp
index aac0ab555..cc48a2559 100644
--- a/src/bin/psql/input.cpp
+++ b/src/bin/psql/input.cpp
@@ -248,6 +248,45 @@ bool SensitiveStrCheck(const char* target)
}
}
+void setHistSize(const char* targetName, const char* targetValue, bool setToDefault)
+{
+#ifndef ENABLE_LLT
+ char* end = NULL;
+ long int result;
+#define MAXHISTSIZE 500
+#define DEFHISTSIZE 32
+ if (targetName == NULL) {
+ return;
+ }
+ if (strcmp(targetName, "HISTSIZE") == 0) {
+ if (!setToDefault) {
+ if (targetValue == NULL || strlen(targetValue) == 0) {
+ fprintf(stderr, "warning:\"HISTSIZE\" is not changed,because its value can not be null\n");
+ return;
+ } else {
+ errno = 0;
+ result = strtol(targetValue, &end, 0);
+ if ((errno == ERANGE && (result == LONG_MAX || result == LONG_MIN)) || (errno != 0 && result == 0)) {
+ fprintf(stderr, "warning:\"HISTSIZE\" is not changed,because its value overflows\n");
+ return;
+ }
+ if (*end || result < 0) {
+ fprintf(stderr, "warning:\"HISTSIZE\" is not changed,because its value must be positive integer\n");
+ return;
+ }
+ }
+ if (result > MAXHISTSIZE) {
+ fprintf(stderr, "warning:\"HISTSIZE\" is set to 500,because its value can not be greater than 500\n");
+ result = MAXHISTSIZE;
+ }
+ } else {
+ result = DEFHISTSIZE;
+ }
+ stifle_history((int)result);
+ }
+#endif
+}
+
/*
* Put any startup stuff related to input in here. It's good to maintain
* abstraction this way.
diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h
index b184f0217..5e871518f 100644
--- a/src/bin/psql/input.h
+++ b/src/bin/psql/input.h
@@ -8,7 +8,6 @@
#ifndef INPUT_H
#define INPUT_H
-#ifdef HAVE_LIBREADLINE
/*
* If some other file needs to have access to readline/history, include this
* file and save yourself all this work.
@@ -17,6 +16,8 @@
*/
#define USE_READLINE 1
+#ifdef HAVE_LIBREADLINE
+
#if defined(HAVE_READLINE_READLINE_H)
#include
#include
@@ -36,6 +37,7 @@ char* gets_fromFile(FILE* source);
void pg_append_history(const char* s, PQExpBuffer history_buf);
void pg_send_history(PQExpBuffer history_buf);
+void setHistSize(const char* targetName, const char* targetValue, bool setToDefault);
extern bool useReadline;
extern bool SensitiveStrCheck(const char* target);
diff --git a/src/bin/psql/mainloop.cpp b/src/bin/psql/mainloop.cpp
index 1931e7c84..ecd7cc09b 100644
--- a/src/bin/psql/mainloop.cpp
+++ b/src/bin/psql/mainloop.cpp
@@ -148,6 +148,11 @@ int MainLoop(FILE* source, char* querystring)
}
pset.lineno = 0;
+ if (pset.cur_cmd_interactive) {
+ const char* val = GetVariable(pset.vars, "HISTSIZE");
+ setHistSize("HISTSIZE", val, val == NULL);
+ }
+
/* Create working state */
scan_state = psql_scan_create();
diff --git a/src/bin/psql/startup.cpp b/src/bin/psql/startup.cpp
index 288140366..f20c593c4 100755
--- a/src/bin/psql/startup.cpp
+++ b/src/bin/psql/startup.cpp
@@ -781,6 +781,7 @@ static void parse_psql_options(int argc, char* const argv[], struct adhoc_opts*
fprintf(stderr, _("%s: could not set variable \"%s\"\n"), pset.progname, value);
exit(EXIT_FAILURE);
}
+ setHistSize(value, equal_loc + 1, false);
}
free(value);
diff --git a/src/bin/psql/tab-complete.cpp b/src/bin/psql/tab-complete.cpp
index 5942fdd98..cf854c436 100644
--- a/src/bin/psql/tab-complete.cpp
+++ b/src/bin/psql/tab-complete.cpp
@@ -754,8 +754,12 @@ void initialize_readline(void)
{
rl_readline_name = (char *)pset.progname;
+#ifdef HAVE_READLINE_READLINE_H
/* PsqlCompletion is deleted because it's too complex and not be used at all. */
rl_attempted_completion_function = PsqlCompletion;
+#else
+ rl_attempted_completion_function = NULL;
+#endif
rl_basic_word_break_characters = WORD_BREAKS;
diff --git a/src/test/regress/expected/readline.out b/src/test/regress/expected/readline.out
index 048f3b4b6..a2d33fb25 100644
--- a/src/test/regress/expected/readline.out
+++ b/src/test/regress/expected/readline.out
@@ -7,3 +7,11 @@ select * from 数据库;
1
(1 row)
+\set HISTSIZE -1
+\set HISTSIZE 30.5
+\set HISTSIZE 0
+\set HISTSIZE 6
+\set HISTSIZE 500
+\set HISTSIZE 600
+\set HISTSIZE 66666666666666666666666600
+\set HISTSIZE -666666666666666666666666666
diff --git a/src/test/regress/sql/readline.sql b/src/test/regress/sql/readline.sql
index de975aab3..0e81f8368 100644
--- a/src/test/regress/sql/readline.sql
+++ b/src/test/regress/sql/readline.sql
@@ -2,3 +2,11 @@
create table 数据库(f int);
insert into 数据库 values (1);
select * from 数据库;
+\set HISTSIZE -1
+\set HISTSIZE 30.5
+\set HISTSIZE 0
+\set HISTSIZE 6
+\set HISTSIZE 500
+\set HISTSIZE 600
+\set HISTSIZE 66666666666666666666666600
+\set HISTSIZE -666666666666666666666666666