Attached is the patch for the TODO item mentioned at
http://archives.postgresql.org/pgsql-hackers/2007-09/msg00352.php

The command has the following synopsis:

\#: displays the command history. Like \s but prefixes the lines with line
numbers

\# <line_no>: executes the command(if any) executed at the line specified by
line_no

regards,
-- 
Sibte Abbas
? GNUmakefile
? config.log
? config.status
? mydiff.diff
? psql_slash#.patch
? src/Makefile.global
? src/backend/postgres
? src/backend/catalog/postgres.bki
? src/backend/catalog/postgres.description
? src/backend/catalog/postgres.shdescription
? src/backend/snowball/libdict_snowball.so.0.0
? src/backend/snowball/snowball_create.sql
? src/backend/utils/mb/conversion_procs/conversion_create.sql
? src/backend/utils/mb/conversion_procs/ascii_and_mic/libascii_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/libcyrillic_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/libeuc_cn_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_jis_2004_and_shift_jis_2004/libeuc_jis_2004_and_shift_jis_2004.so.0.0
? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/libeuc_jp_and_sjis.so.0.0
? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/libeuc_kr_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/libeuc_tw_and_big5.so.0.0
? src/backend/utils/mb/conversion_procs/latin2_and_win1250/liblatin2_and_win1250.so.0.0
? src/backend/utils/mb/conversion_procs/latin_and_mic/liblatin_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_ascii/libutf8_and_ascii.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_big5/libutf8_and_big5.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/libutf8_and_cyrillic.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/libutf8_and_euc_cn.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jis_2004/libutf8_and_euc_jis_2004.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/libutf8_and_euc_jp.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/libutf8_and_euc_kr.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/libutf8_and_euc_tw.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/libutf8_and_gb18030.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_gbk/libutf8_and_gbk.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/libutf8_and_iso8859.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/libutf8_and_iso8859_1.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_johab/libutf8_and_johab.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_shift_jis_2004/libutf8_and_shift_jis_2004.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_sjis/libutf8_and_sjis.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_uhc/libutf8_and_uhc.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_win/libutf8_and_win.so.0.0
? src/bin/initdb/initdb
? src/bin/ipcclean/ipcclean
? src/bin/pg_config/pg_config
? src/bin/pg_controldata/pg_controldata
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_dump/pg_restore
? src/bin/pg_resetxlog/pg_resetxlog
? src/bin/psql/.command.c.swp
? src/bin/psql/cscope.out
? src/bin/psql/psql
? src/bin/scripts/clusterdb
? src/bin/scripts/createdb
? src/bin/scripts/createlang
? src/bin/scripts/createuser
? src/bin/scripts/dropdb
? src/bin/scripts/droplang
? src/bin/scripts/dropuser
? src/bin/scripts/reindexdb
? src/bin/scripts/vacuumdb
? src/include/pg_config.h
? src/include/stamp-h
? src/interfaces/ecpg/compatlib/libecpg_compat.so.2.3
? src/interfaces/ecpg/ecpglib/libecpg.so.6.0
? src/interfaces/ecpg/include/ecpg_config.h
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.2.3
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/libpq/exports.list
? src/interfaces/libpq/libpq.so.5.1
? src/pl/plpgsql/src/libplpgsql.so.1.0
? src/port/pg_config_paths.h
? src/test/regress/libregress.so.0.0
? src/test/regress/pg_regress
? src/test/regress/results
? src/test/regress/testtablespace
? src/test/regress/expected/constraints.out
? src/test/regress/expected/copy.out
? src/test/regress/expected/create_function_1.out
? src/test/regress/expected/create_function_2.out
? src/test/regress/expected/largeobject.out
? src/test/regress/expected/largeobject_1.out
? src/test/regress/expected/misc.out
? src/test/regress/expected/tablespace.out
? src/test/regress/sql/constraints.sql
? src/test/regress/sql/copy.sql
? src/test/regress/sql/create_function_1.sql
? src/test/regress/sql/create_function_2.sql
? src/test/regress/sql/largeobject.sql
? src/test/regress/sql/misc.sql
? src/test/regress/sql/tablespace.sql
? src/timezone/zic
Index: src/bin/psql/command.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/command.c,v
retrieving revision 1.181
diff -c -r1.181 command.c
*** src/bin/psql/command.c	21 Aug 2007 01:11:22 -0000	1.181
--- src/bin/psql/command.c	9 Sep 2007 15:23:41 -0000
***************
*** 55,61 ****
  static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
  static bool do_connect(char *dbname, char *user, char *host, char *port);
  static bool do_shell(const char *command);
! 
  
  /*----------
   * HandleSlashCmds:
--- 55,62 ----
  static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
  static bool do_connect(char *dbname, char *user, char *host, char *port);
  static bool do_shell(const char *command);
! static bool get_hist_entry(const char *lno_s, HIST_ENTRY *hist_ent);
! static int str_to_pint(const char *str);
  
  /*----------
   * HandleSlashCmds:
***************
*** 834,839 ****
--- 835,878 ----
  		free(fname);
  	}
  
+ 	/* \# show history on screen with all lines prefixed with incrementing line numbers 
+ 	 * OR execute a history command at a specific line number
+ 	 */
+ 	else if (strcmp(cmd, "#") == 0)
+ 	{
+ 		char	   *next = psql_scan_slash_option(scan_state,
+ 												   OT_NORMAL, NULL, true);
+ 		if (next) 
+ 		{
+ 			/* something follows after \#, hence consider it a \# <lineno> case */
+ 			HIST_ENTRY	he;
+ 			success = get_hist_entry(next, &he);
+ 
+ 			if (success)
+ 			{
+ 				resetPQExpBuffer(query_buf);
+ 				psql_scan_reset(scan_state);
+ 
+ 				appendPQExpBuffer(query_buf, he.line);
+ 				status = PSQL_CMD_SEND;
+ 			}
+ 			free(next);
+ 		}
+ 		else
+ 		{
+ 			/* only \#, simply display the history contents on the screen */
+ 			register HIST_ENTRY **the_list;
+ 			register int i;
+ 	
+ 			the_list = history_list();
+ 			if (the_list)
+ 			{
+ 				for (i = 0; the_list[i]; i++)
+ 			    	printf ("%d: %s\n", i + history_base, the_list[i]->line);
+ 			}
+ 		}
+ 	}
+ 
  	/* \set -- generalized set variable/option command */
  	else if (strcmp(cmd, "set") == 0)
  	{
***************
*** 1807,1809 ****
--- 1846,1908 ----
  	}
  	return true;
  }
+ 
+ /*
+  * get_hist_entry
+  *
+  * Returns the history entry corresponding to the line number specificed by 'lno_s' string.
+  * The returned value is copied in 'hist_ent'
+  */
+ static bool get_hist_entry(const char *lno_s, HIST_ENTRY *hist_ent)
+ {
+ 	int 		lno_i = 0;
+ 	HIST_ENTRY	*he;	
+ 
+ 	psql_assert(lno_s);
+ 	psql_assert(hist_ent);
+ 
+ 	/* convert the line no string to integer form */
+ 	if ((lno_i = str_to_pint(lno_s)) == -1)
+ 	{
+ 		fprintf(stderr, _("%s is an invalid value for line number\n"), lno_s);
+ 		return false;
+ 	}
+ 
+ 	/* lookup the history corresponding to the line no */
+ 	if ((he = history_get(lno_i)) != NULL)
+ 	{
+ 		memcpy(hist_ent, he, sizeof(HIST_ENTRY));
+ 		return true;
+ 	}
+ 
+ 	/* else */
+ 	fprintf(stderr, _("Could'nt find any command at line number %d\n"), lno_i);
+ 	return false;
+ }
+ 
+ /*
+  * str_to_pint
+  *
+  * converts the given string into a positive int. Returns an error if "str" 
+  * represents a negative integer.
+  *
+  * Returns, the converted value
+  * On Error, -1 is returned
+  */
+ static int str_to_pint(const char *str)
+ {
+ 	char	*end = NULL;
+ 	int		result = -1;
+ 	int		save_errno = errno;
+ 	psql_assert(str);
+ 
+ 	errno = 0;
+ 	result = strtol(str, &end, 10);
+ 
+ 	if ((errno == ERANGE) || (strlen(end) != 0) || (result < 0))
+ 		result = -1;
+ 	
+ 	errno = save_errno;
+ 	return result;
+ }
+ 
Index: src/bin/psql/help.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/help.c,v
retrieving revision 1.118
diff -c -r1.118 help.c
*** src/bin/psql/help.c	21 Aug 2007 01:11:22 -0000	1.118
--- src/bin/psql/help.c	9 Sep 2007 15:23:41 -0000
***************
*** 196,201 ****
--- 196,202 ----
  	fprintf(output, _("  \\r             reset (clear) the query buffer\n"));
  #ifdef USE_READLINE
  	fprintf(output, _("  \\s [FILE]      display history or save it to file\n"));
+ 	fprintf(output, _("  \\# [LINENO]    display history in lineno:<command> format or execute a line from that history\n"));
  #endif
  	fprintf(output, _("  \\w FILE        write query buffer to file\n"));
  	fprintf(output, "\n");
Index: src/bin/psql/tab-complete.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.166
diff -c -r1.166 tab-complete.c
*** src/bin/psql/tab-complete.c	3 Jul 2007 01:30:37 -0000	1.166
--- src/bin/psql/tab-complete.c	9 Sep 2007 15:23:42 -0000
***************
*** 544,550 ****
  		"\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
  		"\\o", "\\p", "\\password", "\\prompt", "\\pset", "\\q", "\\qecho", "\\r",
  		"\\set", "\\t", "\\T",
! 		"\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", NULL
  	};
  
  	(void) end;					/* not used */
--- 544,550 ----
  		"\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
  		"\\o", "\\p", "\\password", "\\prompt", "\\pset", "\\q", "\\qecho", "\\r",
  		"\\set", "\\t", "\\T",
! 		"\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", "\\#", NULL
  	};
  
  	(void) end;					/* not used */
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

               http://archives.postgresql.org

Reply via email to