Hello. I don't know whether this is a bug fix or improvement,
anyway show you a patch for psql completion.


psql completes identifiers in many places but donesn't for
multibyte identifiers.

=> ALTER TABLE "[tab]
"いろは" "with space"

=> ALTER TABLE "い[tab]
<none>

Currently psql counts the length of the string to complete in
bytes but it is desirable to count in client encoding. The
attached patch does so and the uncompleted completion would
be completed.

=> ALTER TABLE "い[tab]
=> ALTER TABLE "いろは" _

During the investigation into this issue, I found a mistake in
the comment for PQmblen. It give the byte length of the character
at the point, not word. The attached patche also fixes it.

> /*
>  * returns the byte length of the word beginning s, using the
>  * specified encoding.
>  */
> int
> PQmblen(const char *s, int encoding)


What do you think about this?

regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From 7311e03b4656b724754be4697e59291844901fb8 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyot...@lab.ntt.co.jp>
Date: Mon, 2 Nov 2015 12:46:45 +0900
Subject: [PATCH] Fix identifier completion of multibyte characters.

_copletion_from_query took the byte length of the given text as its
character length. This should be counted in the environmental
encoding.

This patch also fixes a comment for PQmblen.
---
 src/bin/psql/tab-complete.c    | 13 ++++++++++---
 src/interfaces/libpq/fe-misc.c |  4 ++--
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 0e8d395..e6e22c4 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -4283,8 +4283,8 @@ complete_from_schema_query(const char *text, int state)
 static char *
 _complete_from_query(int is_schema_query, const char *text, int state)
 {
-	static int	list_index,
-				string_length;
+	static int	list_index;
+	int 		string_length = 0;
 	static PGresult *result = NULL;
 
 	/*
@@ -4297,9 +4297,16 @@ _complete_from_query(int is_schema_query, const char *text, int state)
 		char	   *e_text;
 		char	   *e_info_charp;
 		char	   *e_info_charp2;
+		const char *pstr = text;
 
 		list_index = 0;
-		string_length = strlen(text);
+
+		/* count length as a multibyte text */
+		while (*pstr)
+		{
+			string_length++;
+			pstr += PQmblen(pstr, pset.encoding);
+		}
 
 		/* Free any prior result */
 		PQclear(result);
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 0dbcf73..9eb09e3 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -1179,8 +1179,8 @@ pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time)
  */
 
 /*
- * returns the byte length of the word beginning s, using the
- * specified encoding.
+ * returns the byte length of the character beginning s, using the specified
+ * encoding.
  */
 int
 PQmblen(const char *s, int encoding)
-- 
1.8.3.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to