This patch replaces a bunch of call sites of appendStringInfo() with appendStringInfoString(). (For those without the code in front of you, the difference between these two functions is that the former takes a sprintf-style format string and a variable list of arguments, whereas the latter just takes a single NUL-terminated string; therefore, the latter is faster if you're just appending a single string to the buffer).
For the sake of minimizing how much of my time I've wasted if someone objects, this patch only changes a portion of the call sites that could be changed; I'll do the rest before committing the patch. I was tempted to make appendStringInfoString() a macro, since (a) it's just one line of code (b) I'd expect plenty of compilers to be smart enough to optimize-out a strlen() on a string-literal arg. The downside is that it would require that appendStringInfoString() evaluate its arguments more than once. Any comments on whether this is worth doing? Unless anyone objects, I intend to apply the full version of this patch within 48 hours. -Neil
Index: src/backend/commands/explain.c =================================================================== RCS file: /var/lib/cvs/pgsql-server/src/backend/commands/explain.c,v retrieving revision 1.118 diff -c -r1.118 explain.c *** src/backend/commands/explain.c 29 Nov 2003 19:51:47 -0000 1.118 --- src/backend/commands/explain.c 25 Jan 2004 03:32:01 -0000 *************** *** 589,595 **** planstate->instrument->nloops); } else if (es->printAnalyze) ! appendStringInfo(str, " (never executed)"); } appendStringInfoChar(str, '\n'); --- 589,595 ---- planstate->instrument->nloops); } else if (es->printAnalyze) ! appendStringInfoString(str, " (never executed)"); } appendStringInfoChar(str, '\n'); *************** *** 702,709 **** List *lst; for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " InitPlan\n"); foreach(lst, planstate->initPlan) { SubPlanState *sps = (SubPlanState *) lfirst(lst); --- 702,709 ---- List *lst; for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " InitPlan\n"); foreach(lst, planstate->initPlan) { SubPlanState *sps = (SubPlanState *) lfirst(lst); *************** *** 711,718 **** es->rtable = sp->rtable; for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " -> "); explain_outNode(str, sp->plan, sps->planstate, NULL, --- 711,718 ---- es->rtable = sp->rtable; for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " -> "); explain_outNode(str, sp->plan, sps->planstate, NULL, *************** *** 725,732 **** if (outerPlan(plan)) { for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " -> "); explain_outNode(str, outerPlan(plan), outerPlanState(planstate), NULL, --- 725,732 ---- if (outerPlan(plan)) { for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " -> "); explain_outNode(str, outerPlan(plan), outerPlanState(planstate), NULL, *************** *** 737,744 **** if (innerPlan(plan)) { for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " -> "); explain_outNode(str, innerPlan(plan), innerPlanState(planstate), outerPlan(plan), --- 737,744 ---- if (innerPlan(plan)) { for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " -> "); explain_outNode(str, innerPlan(plan), innerPlanState(planstate), outerPlan(plan), *************** *** 758,765 **** Plan *subnode = (Plan *) lfirst(lst); for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " -> "); explain_outNode(str, subnode, appendstate->appendplans[j], --- 758,765 ---- Plan *subnode = (Plan *) lfirst(lst); for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " -> "); explain_outNode(str, subnode, appendstate->appendplans[j], *************** *** 782,789 **** es->rtable = rte->subquery->rtable; for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " -> "); explain_outNode(str, subnode, subquerystate->subplan, --- 782,789 ---- es->rtable = rte->subquery->rtable; for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " -> "); explain_outNode(str, subnode, subquerystate->subplan, *************** *** 800,807 **** List *lst; for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " SubPlan\n"); foreach(lst, planstate->subPlan) { SubPlanState *sps = (SubPlanState *) lfirst(lst); --- 800,807 ---- List *lst; for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " SubPlan\n"); foreach(lst, planstate->subPlan) { SubPlanState *sps = (SubPlanState *) lfirst(lst); *************** *** 809,816 **** es->rtable = sp->rtable; for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); ! appendStringInfo(str, " -> "); explain_outNode(str, sp->plan, sps->planstate, NULL, --- 809,816 ---- es->rtable = sp->rtable; for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); ! appendStringInfoString(str, " -> "); explain_outNode(str, sp->plan, sps->planstate, NULL, *************** *** 885,891 **** /* And add to str */ for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); appendStringInfo(str, " %s: %s\n", qlabel, exprstr); } --- 885,891 ---- /* And add to str */ for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); appendStringInfo(str, " %s: %s\n", qlabel, exprstr); } *************** *** 932,938 **** /* And add to str */ for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); appendStringInfo(str, " %s: %s\n", qlabel, exprstr); } --- 932,938 ---- /* And add to str */ for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); appendStringInfo(str, " %s: %s\n", qlabel, exprstr); } *************** *** 955,961 **** return; for (i = 0; i < indent; i++) ! appendStringInfo(str, " "); appendStringInfo(str, " %s: ", qlabel); /* --- 955,961 ---- return; for (i = 0; i < indent; i++) ! appendStringInfoString(str, " "); appendStringInfo(str, " %s: ", qlabel); /* *************** *** 1001,1011 **** useprefix, true); /* And add to str */ if (keyno > 0) ! appendStringInfo(str, ", "); ! appendStringInfo(str, "%s", exprstr); } ! appendStringInfo(str, "\n"); } /* --- 1001,1011 ---- useprefix, true); /* And add to str */ if (keyno > 0) ! appendStringInfoString(str, ", "); ! appendStringInfoString(str, exprstr); } ! appendStringInfoString(str, "\n"); } /* Index: src/backend/nodes/outfuncs.c =================================================================== RCS file: /var/lib/cvs/pgsql-server/src/backend/nodes/outfuncs.c,v retrieving revision 1.231 diff -c -r1.231 outfuncs.c *** src/backend/nodes/outfuncs.c 22 Jan 2004 00:34:31 -0000 1.231 --- src/backend/nodes/outfuncs.c 25 Jan 2004 03:12:40 -0000 *************** *** 1427,1433 **** * We assume the value is a valid numeric literal and so does * not need quoting. */ ! appendStringInfo(str, "%s", value->val.str); break; case T_String: appendStringInfoChar(str, '"'); --- 1427,1433 ---- * We assume the value is a valid numeric literal and so does * not need quoting. */ ! appendStringInfoString(str, value->val.str); break; case T_String: appendStringInfoChar(str, '"'); *************** *** 1436,1442 **** break; case T_BitString: /* internal representation already has leading 'b' */ ! appendStringInfo(str, "%s", value->val.str); break; default: elog(ERROR, "unrecognized node type: %d", (int) value->type); --- 1436,1442 ---- break; case T_BitString: /* internal representation already has leading 'b' */ ! appendStringInfoString(str, value->val.str); break; default: elog(ERROR, "unrecognized node type: %d", (int) value->type); Index: src/backend/utils/adt/regproc.c =================================================================== RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/regproc.c,v retrieving revision 1.85 diff -c -r1.85 regproc.c *** src/backend/utils/adt/regproc.c 29 Nov 2003 19:51:59 -0000 1.85 --- src/backend/utils/adt/regproc.c 25 Jan 2004 03:13:16 -0000 *************** *** 340,346 **** if (i > 0) appendStringInfoChar(&buf, ','); ! appendStringInfo(&buf, "%s", format_type_be(thisargtype)); } appendStringInfoChar(&buf, ')'); --- 340,346 ---- if (i > 0) appendStringInfoChar(&buf, ','); ! appendStringInfoString(&buf, format_type_be(thisargtype)); } appendStringInfoChar(&buf, ')'); Index: src/backend/utils/adt/ruleutils.c =================================================================== RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/ruleutils.c,v retrieving revision 1.161 diff -c -r1.161 ruleutils.c *** src/backend/utils/adt/ruleutils.c 28 Dec 2003 21:57:37 -0000 1.161 --- src/backend/utils/adt/ruleutils.c 25 Jan 2004 03:24:37 -0000 *************** *** 752,758 **** attname = get_relid_attribute_name(indrelid, attnum); if (!colno || colno == keyno + 1) ! appendStringInfo(&buf, "%s", quote_identifier(attname)); keycoltype = get_atttype(indrelid, attnum); } else --- 752,758 ---- attname = get_relid_attribute_name(indrelid, attnum); if (!colno || colno == keyno + 1) ! appendStringInfoString(&buf, quote_identifier(attname)); keycoltype = get_atttype(indrelid, attnum); } else *************** *** 772,778 **** /* Need parens if it's not a bare function call */ if (indexkey && IsA(indexkey, FuncExpr) && ((FuncExpr *) indexkey)->funcformat == COERCE_EXPLICIT_CALL) ! appendStringInfo(&buf, "%s", str); else appendStringInfo(&buf, "(%s)", str); } --- 772,778 ---- /* Need parens if it's not a bare function call */ if (indexkey && IsA(indexkey, FuncExpr) && ((FuncExpr *) indexkey)->funcformat == COERCE_EXPLICIT_CALL) ! appendStringInfoString(&buf, str); else appendStringInfo(&buf, "(%s)", str); } *************** *** 947,953 **** string = ""; /* keep compiler quiet */ break; } ! appendStringInfo(&buf, "%s", string); /* Add ON UPDATE and ON DELETE clauses, if needed */ switch (conForm->confupdtype) --- 947,953 ---- string = ""; /* keep compiler quiet */ break; } ! appendStringInfoString(&buf, string); /* Add ON UPDATE and ON DELETE clauses, if needed */ switch (conForm->confupdtype) *************** *** 1126,1133 **** colName = get_relid_attribute_name(relId, DatumGetInt16(keys[j])); if (j == 0) ! appendStringInfo(buf, "%s", ! quote_identifier(colName)); else appendStringInfo(buf, ", %s", quote_identifier(colName)); --- 1126,1132 ---- colName = get_relid_attribute_name(relId, DatumGetInt16(keys[j])); if (j == 0) ! appendStringInfoString(buf, quote_identifier(colName)); else appendStringInfo(buf, ", %s", quote_identifier(colName)); *************** *** 2134,2140 **** appendStringInfo(buf, sep); sep = ", "; ! appendStringInfo(buf, "%s", quote_identifier(get_relid_attribute_name(rte->relid, tle->resdom->resno))); } --- 2133,2139 ---- appendStringInfo(buf, sep); sep = ", "; ! appendStringInfoString(buf, quote_identifier(get_relid_attribute_name(rte->relid, tle->resdom->resno))); } *************** *** 2753,2761 **** quote_identifier(refname)); } if (attname) ! appendStringInfo(buf, "%s", quote_identifier(attname)); else ! appendStringInfo(buf, "*"); } break; --- 2752,2760 ---- quote_identifier(refname)); } if (attname) ! appendStringInfoString(buf, quote_identifier(attname)); else ! appendStringInfoString(buf, "*"); } break; *************** *** 3763,3769 **** { if (col != rte->alias->colnames) appendStringInfo(buf, ", "); ! appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(col)))); } appendStringInfoChar(buf, ')'); --- 3762,3768 ---- { if (col != rte->alias->colnames) appendStringInfo(buf, ", "); ! appendStringInfoString(buf, quote_identifier(strVal(lfirst(col)))); } appendStringInfoChar(buf, ')'); *************** *** 3785,3791 **** if (coldeflist != NIL) { if (!gavealias) ! appendStringInfo(buf, " AS "); get_from_clause_coldeflist(coldeflist, context); } } --- 3784,3790 ---- if (coldeflist != NIL) { if (!gavealias) ! appendStringInfoString(buf, " AS "); get_from_clause_coldeflist(coldeflist, context); } } *************** *** 3897,3915 **** { List *col; ! appendStringInfo(buf, " USING ("); foreach(col, j->using) { if (col != j->using) appendStringInfo(buf, ", "); ! appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(col)))); } appendStringInfoChar(buf, ')'); } else if (j->quals) { ! appendStringInfo(buf, " ON "); if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, '('); get_rule_expr(j->quals, context, false); --- 3896,3914 ---- { List *col; ! appendStringInfoString(buf, " USING ("); foreach(col, j->using) { if (col != j->using) appendStringInfo(buf, ", "); ! appendStringInfoString(buf, quote_identifier(strVal(lfirst(col)))); } appendStringInfoChar(buf, ')'); } else if (j->quals) { ! appendStringInfoString(buf, " ON "); if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, '('); get_rule_expr(j->quals, context, false); *************** *** 3933,3940 **** foreach(col, j->alias->colnames) { if (col != j->alias->colnames) ! appendStringInfo(buf, ", "); ! appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(col)))); } appendStringInfoChar(buf, ')'); --- 3932,3939 ---- foreach(col, j->alias->colnames) { if (col != j->alias->colnames) ! appendStringInfoString(buf, ", "); ! appendStringInfoString(buf, quote_identifier(strVal(lfirst(col)))); } appendStringInfoChar(buf, ')'); *************** *** 4164,4170 **** initStringInfo(&buf); if (namespace) appendStringInfo(&buf, "%s.", quote_identifier(namespace)); ! appendStringInfo(&buf, "%s", quote_identifier(ident)); return buf.data; } --- 4163,4169 ---- initStringInfo(&buf); if (namespace) appendStringInfo(&buf, "%s.", quote_identifier(namespace)); ! appendStringInfoString(&buf, quote_identifier(ident)); return buf.data; } *************** *** 4316,4322 **** appendStringInfo(&buf, "OPERATOR(%s.", quote_identifier(nspname)); } ! appendStringInfo(&buf, "%s", oprname); if (nspname) appendStringInfoChar(&buf, ')'); --- 4315,4321 ---- appendStringInfo(&buf, "OPERATOR(%s.", quote_identifier(nspname)); } ! appendStringInfoString(&buf, oprname); if (nspname) appendStringInfoChar(&buf, ')'); *************** *** 4338,4344 **** int nnames = length(opname); if (nnames == 1) ! appendStringInfo(buf, "%s", strVal(lfirst(opname))); else { appendStringInfo(buf, "OPERATOR("); --- 4337,4343 ---- int nnames = length(opname); if (nnames == 1) ! appendStringInfoString(buf, strVal(lfirst(opname))); else { appendStringInfo(buf, "OPERATOR("); Index: src/backend/utils/adt/varlena.c =================================================================== RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/varlena.c,v retrieving revision 1.109 diff -c -r1.109 varlena.c *** src/backend/utils/adt/varlena.c 19 Dec 2003 04:56:41 -0000 1.109 --- src/backend/utils/adt/varlena.c 25 Jan 2004 03:18:09 -0000 *************** *** 2213,2219 **** if (i > 0) appendStringInfo(result_str, "%s%s", fldsep, value); else ! appendStringInfo(result_str, "%s", value); p = att_addlength(p, typlen, PointerGetDatum(p)); p = (char *) att_align(p, typalign); --- 2213,2219 ---- if (i > 0) appendStringInfo(result_str, "%s%s", fldsep, value); else ! appendStringInfoString(result_str, value); p = att_addlength(p, typlen, PointerGetDatum(p)); p = (char *) att_align(p, typalign); Index: src/backend/utils/misc/guc.c =================================================================== RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/misc/guc.c,v retrieving revision 1.180 diff -c -r1.180 guc.c *** src/backend/utils/misc/guc.c 24 Jan 2004 20:00:45 -0000 1.180 --- src/backend/utils/misc/guc.c 25 Jan 2004 03:18:55 -0000 *************** *** 3259,3265 **** break; case T_Float: /* represented as a string, so just copy it */ ! appendStringInfo(&buf, "%s", strVal(&arg->val)); break; case T_String: val = strVal(&arg->val); --- 3259,3265 ---- break; case T_Float: /* represented as a string, so just copy it */ ! appendStringInfoString(&buf, strVal(&arg->val)); break; case T_String: val = strVal(&arg->val); *************** *** 3293,3301 **** * mode, quote it if it's not a vanilla identifier. */ if (flags & GUC_LIST_QUOTE) ! appendStringInfo(&buf, "%s", quote_identifier(val)); else ! appendStringInfo(&buf, "%s", val); } break; default: --- 3293,3301 ---- * mode, quote it if it's not a vanilla identifier. */ if (flags & GUC_LIST_QUOTE) ! appendStringInfoString(&buf, quote_identifier(val)); else ! appendStringInfoString(&buf, val); } break; default:
---------------------------(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