*** ./src/bin/psql/common.c.orig Thu Mar 11 15:42:17 2004 --- ./src/bin/psql/common.c Fri Mar 12 09:24:13 2004 *************** *** 345,350 **** --- 345,537 ---- } + #define DISPLAY_SIZE (60) + #define MIN_RIGHT_CUT (10) + #define EXTRACT_FORMAT "LINE %d: " + + /* 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 && loc>0) + { + int clen, slen, i, *qidx, ibeg, iend, last_nl, + loc_line, nb_lines, prefix_len, figure_len; + char *wquery, *cursor, *ex_prefix, *sp_prefix; + 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' && i=0 && locloc) + 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) + { + iend = loc+MIN_RIGHT_CUT; + end_trunc = true; + } + + /* still too long? + * we know that loc is at the end + * (loc+MIN_RIGHT_CUT>=iend from above) + * now we truncate left. + */ + if (iend-ibeg > DISPLAY_SIZE) + { + ibeg = iend-DISPLAY_SIZE; + beg_trunc = true; + } + } + } + + /* (5) if the line is too short, we could fix it here. */ + + /* the extract MUST contain the localisation! */ + psql_assert(ibeg<=loc && loc= + prefix_len) + { + /* very unlikely. */ + psql_error("INTERNAL ERROR: bad alloc fmt=\"%s\" len=%d loc=%d\n", + EXTRACT_FORMAT, prefix_len, loc_line); + pfree(ex_prefix); + pfree(sp_prefix); + pfree(wquery); + pfree(qidx); + pfree(cursor); + return; + } + + /* actual len used? mbstrlen? how do we know that the locale + * translation is compatible with the client encoding? + */ + prefix_len = strlen(ex_prefix); + for (i=0; i