[PATCHES] client side syntax error position (v2)

2004-03-11 Thread Fabien COELHO

Dear patchers,

Please find enclosed a new patch submission which take into account
comments by Tom Lane about version 1.

(1) the function is renamed as localisation does not mean what I meant.

(2) three dots ... appear after and before the line when truncated.

However, I still put the line number that I found useful.

The new version validates for me against current cvs head.

Same comment as with version one, I don't know how to test the multi-byte
part.

Have a nice day,

-- 
Fabien Coelho - [EMAIL PROTECTED]*** ./src/bin/psql/common.c.origThu Mar 11 15:42:17 2004
--- ./src/bin/psql/common.c Thu Mar 11 18:05:22 2004
***
*** 345,350 
--- 345,506 
  }
  
  
+ #define DISPLAY_SIZE (60)
+ #define MIN_RIGHT_CUT (10)
+ 
+ /* on errors, print syntax error position if available.
+  * the query is expected to be in the client encoding.
+  */
+ static void
+ ReportSyntaxErrorPosition(const PGresult *result, const char *query)
+ {
+   int loc = 0;
+   char * sp = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION);
+ 
+   if (sp  sscanf(sp, %d, loc)!=1)
+   {
+   psql_error(INTERNAL ERROR: unexpected statement position '%s'\n, sp);
+   return;
+   }
+   
+   /* do we have something to show? */
+   if (query!=NULL  loc0)
+   {
+   int clen, slen, i, * qidx, ibeg, iend, last_nl, loc_line;
+   char *wquery, *cursor;
+   bool beg_trunc, end_trunc;
+ 
+   /* (1) let us first compute a character index for the query. */
+ 
+   /* we need a safe allocation size... */
+   slen = strlen(query); 
+ 
+   /* the last one is needed to store last char mb length */
+   qidx = (int*) palloc(sizeof(int)*(slen+1));
+ 
+   qidx[0] = 0;
+   for (i=1; query[qidx[i-1]]!='\0'  islen+1; i++)
+   qidx[i] = qidx[i-1] + PQmblen(query[qidx[i-1]], 
pset.encoding);
+   
+   clen = i-1;
+ 
+   /* we must be at the end! */
+   psql_assert(query[qidx[clen]] == '\0');
+ 
+   /* our localisation index start at 0! it must be in the query! */
+   loc--; 
+   psql_assert(loc=0  locclen);
+ 
+   /* (2) now we build a working copy of the query. */
+   wquery = (char*) palloc(sizeof(char)*(strlen(query)+1));
+   strcpy(wquery, query);
+ 
+   /* the character number of the last newline. */
+   last_nl = -1;
+/* input line number of our syntax error. */
+   loc_line = 1;
+   /* first included char of extract. */
+   ibeg = 0; 
+   /* last not-included char of extract. */
+   iend = clen; 
+ 
+   /* (3) we clean wquery string from tabs, carriage return and new lines.
+* extract error line number and begin and end indexes.
+*/
+   for (i=0; iclen; i++)
+   {
+   /* how to find a '\t', a '\r' or a '\n'? 
+* I assume here that all encodings must be ascii compatible...
+*/
+   if ((qidx[i+1]-qidx[i]) == 1)
+   {
+   if (wquery[qidx[i]] == '\t') 
+   wquery[qidx[i]] = ' ';
+   if (wquery[qidx[i]] == '\r' || wquery[qidx[i]] == '\n')
+   {
+   /* count lines */
+   if (wquery[qidx[i]]=='\n'  iloc) 
+   loc_line++;
+ 
+   /* set extract end. */
+   if (iend==clen  iloc)
+   iend = i;
+ 
+   wquery[qidx[i]] = ' ';
+   last_nl = i;
+   }
+   }
+   /* set extract beginning. */
+   if (i==loc  last_nl!=-1)
+   ibeg = last_nl+1;
+   }
+ 
+   /* (4) if the line extracted is too long, we truncate it. */
+   beg_trunc = false;
+   end_trunc = false;
+   if (iend-ibeg  DISPLAY_SIZE)
+   {
+   /* we first truncate right if it is enough. */
+   if (ibeg+DISPLAY_SIZE  loc+MIN_RIGHT_CUT)
+   {
+   iend = ibeg+DISPLAY_SIZE;
+   end_trunc = true;
+   }
+   else
+   {
+   /* we truncate right. */
+   if (loc+MIN_RIGHT_CUT  iend)
+ 

Re: [PATCHES] client side syntax error position (v2)

2004-03-11 Thread Tom Lane
Fabien COELHO [EMAIL PROTECTED] writes:
 Same comment as with version one, I don't know how to test the multi-byte
 part.

It should be fairly easy to test if you use UNICODE client encoding;
anything outside the 7-bit-ASCII set will be 2 or more bytes.

regards, tom lane

---(end of broadcast)---
TIP 7: don't forget to increase your free space map settings