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