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

Reply via email to