On Thu, 10 Mar 2005 19:21:41 -0500 (EST), Bruce Momjian <pgman@candle.pha.pa.us> wrote: > > The CVS-tip implementation is fundamentally broken and won't work even > > for our internal uses. I've not wasted time complaining about it > > because I thought we were going to replace it. If we can't find a > > usable replacement then we're going to have to put a lot of effort > > into fixing what's there. On the whole I think the effort would be > > better spent importing someone else's solution. > > Oh, so our existing implementation doesn't even meet our needs. OK.
Which made me wander why did I not aggree with Tom Lane's suggestion to make do three passes instead of two. Tom was right, as usual. It happened to be much easier than I expected. The patch is attached. Please apply. Tom, what do you think? Will it be fine with you? Best regards, Nicolai
*** ./src/port/snprintf.c.orig Sat Mar 12 01:28:49 2005 --- ./src/port/snprintf.c Sat Mar 12 01:08:30 2005 *************** *** 195,200 **** --- 195,202 ---- int pointflag; char func; int realpos; + int longflag; + int longlongflag; } *fmtpar, **fmtparptr; /* Create enough structures to hold all arguments */ *************** *** 263,274 **** --- 265,278 ---- realpos = position; len = 0; goto nextch; + /* case '*': if (pointflag) maxwidth = va_arg(args, int); else len = va_arg(args, int); goto nextch; + */ case '.': pointflag = 1; goto nextch; *************** *** 300,315 **** #endif case 'u': case 'U': ! /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */ ! if (longflag) ! { ! if (longlongflag) ! value = va_arg(args, uint64); ! else ! value = va_arg(args, unsigned long); ! } ! else ! value = va_arg(args, unsigned int); fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; --- 304,311 ---- #endif case 'u': case 'U': ! fmtpar[fmtpos].longflag = longflag; ! fmtpar[fmtpos].longlongflag = longlongflag; fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; *************** *** 324,339 **** break; case 'o': case 'O': ! /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */ ! if (longflag) ! { ! if (longlongflag) ! value = va_arg(args, uint64); ! else ! value = va_arg(args, unsigned long); ! } ! else ! value = va_arg(args, unsigned int); fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; --- 320,327 ---- break; case 'o': case 'O': ! fmtpar[fmtpos].longflag = longflag; ! fmtpar[fmtpos].longlongflag = longlongflag; fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; *************** *** 348,364 **** break; case 'd': case 'D': ! if (longflag) ! { ! if (longlongflag) ! { ! value = va_arg(args, int64); ! } ! else ! value = va_arg(args, long); ! } ! else ! value = va_arg(args, int); fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; --- 336,343 ---- break; case 'd': case 'D': ! fmtpar[fmtpos].longflag = longflag; ! fmtpar[fmtpos].longlongflag = longlongflag; fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; *************** *** 372,386 **** fmtpos++; break; case 'x': ! if (longflag) ! { ! if (longlongflag) ! value = va_arg(args, uint64); ! else ! value = va_arg(args, unsigned long); ! } ! else ! value = va_arg(args, unsigned int); fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; --- 351,358 ---- fmtpos++; break; case 'x': ! fmtpar[fmtpos].longflag = longflag; ! fmtpar[fmtpos].longlongflag = longlongflag; fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; *************** *** 394,408 **** fmtpos++; break; case 'X': ! if (longflag) ! { ! if (longlongflag) ! value = va_arg(args, uint64); ! else ! value = va_arg(args, unsigned long); ! } ! else ! value = va_arg(args, unsigned int); fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; --- 366,373 ---- fmtpos++; break; case 'X': ! fmtpar[fmtpos].longflag = longflag; ! fmtpar[fmtpos].longlongflag = longlongflag; fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].numvalue = value; *************** *** 416,422 **** fmtpos++; break; case 's': - strvalue = va_arg(args, char *); if (maxwidth > 0 || !pointflag) { if (pointflag && len > maxwidth) --- 381,386 ---- *************** *** 434,440 **** } break; case 'c': - ch = va_arg(args, int); fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].charvalue = ch; --- 398,403 ---- *************** *** 447,453 **** case 'f': case 'g': case 'G': - fvalue = va_arg(args, double); fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].fvalue = fvalue; --- 410,415 ---- *************** *** 455,460 **** --- 417,423 ---- fmtpar[fmtpos].ljust = ljust; fmtpar[fmtpos].len = len; fmtpar[fmtpos].maxwidth = maxwidth; + fmtpar[fmtpos].precision = maxwidth; fmtpar[fmtpos].pointflag = pointflag; fmtpar[fmtpos].func = FMTFLOAT; fmtpar[fmtpos].realpos = realpos?realpos:fmtpos; *************** *** 472,480 **** } } performpr: ! /* shuffle pointers */ for(i = 1; i < fmtpos; i++) fmtparptr[i] = &fmtpar[fmtpar[i].realpos]; output = buffer; format = format_save; while ((ch = *format++)) --- 435,471 ---- } } performpr: ! /* reorder pointers */ for(i = 1; i < fmtpos; i++) fmtparptr[i] = &fmtpar[fmtpar[i].realpos]; + + /* assign values */ + for(i = 1; i < fmtpos; i++){ + switch(fmtparptr[i]->func){ + case FMTSTR: + fmtparptr[i]->value = va_arg(args, char *); + break; + case FMTNUM: + if (fmtparptr[i]->longflag) + { + if (fmtparptr[i]->longlongflag) + fmtparptr[i]->numvalue = va_arg(args, uint64); + else + fmtparptr[i]->numvalue = va_arg(args, unsigned long); + } + else + fmtparptr[i]->numvalue = va_arg(args, unsigned int); + break; + case FMTFLOAT: + fmtparptr[i]->fvalue = va_arg(args, double); + break; + case FMTCHAR: + fmtparptr[i]->charvalue = va_arg(args, int); + break; + } + } + + /* do the output */ output = buffer; format = format_save; while ((ch = *format++))
---------------------------(end of broadcast)--------------------------- TIP 9: the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match