1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Attached is a patch that replaces a bunch of places where StringInfos

are unnecessarily allocated on the heap rather than the stack. If the
StringInfo doesn't outlive the stack frame in which it is created,
there is no need to allocate it on the heap via makeStringInfo() --
stack allocation is faster.  While it's not a big deal unless the
code is in a critical path, I don't see a reason not to save a few
cycles -- using stack allocation is not less readable.

I also cleaned up a bit of code along the way: moved variable
declarations into a more tightly-enclosing scope where possible,
fixed some pointless copying of strings in dblink, etc.
This commit is contained in:
Neil Conway
2006-03-01 06:51:01 +00:00
parent 8e5a10d46c
commit 0d9742f99a
5 changed files with 126 additions and 140 deletions

View File

@ -301,11 +301,12 @@ dblink_open(PG_FUNCTION_ARGS)
char *curname = NULL;
char *sql = NULL;
char *conname = NULL;
StringInfo str = makeStringInfo();
StringInfoData buf;
remoteConn *rconn = NULL;
bool fail = true; /* default to backward compatible behavior */
DBLINK_INIT;
initStringInfo(&buf);
if (PG_NARGS() == 2)
{
@ -361,8 +362,8 @@ dblink_open(PG_FUNCTION_ARGS)
if (rconn->newXactForCursor)
(rconn->openCursorCount)++;
appendStringInfo(str, "DECLARE %s CURSOR FOR %s", curname, sql);
res = PQexec(conn, str->data);
appendStringInfo(&buf, "DECLARE %s CURSOR FOR %s", curname, sql);
res = PQexec(conn, buf.data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
{
if (fail)
@ -389,12 +390,13 @@ dblink_close(PG_FUNCTION_ARGS)
PGresult *res = NULL;
char *curname = NULL;
char *conname = NULL;
StringInfo str = makeStringInfo();
StringInfoData buf;
char *msg;
remoteConn *rconn = NULL;
bool fail = true; /* default to backward compatible behavior */
DBLINK_INIT;
initStringInfo(&buf);
if (PG_NARGS() == 1)
{
@ -432,10 +434,10 @@ dblink_close(PG_FUNCTION_ARGS)
else
conn = rconn->conn;
appendStringInfo(str, "CLOSE %s", curname);
appendStringInfo(&buf, "CLOSE %s", curname);
/* close the cursor */
res = PQexec(conn, str->data);
res = PQexec(conn, buf.data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
{
if (fail)
@ -493,7 +495,7 @@ dblink_fetch(PG_FUNCTION_ARGS)
if (SRF_IS_FIRSTCALL())
{
PGconn *conn = NULL;
StringInfo str = makeStringInfo();
StringInfoData buf;
char *curname = NULL;
int howmany = 0;
bool fail = true; /* default to backward compatible */
@ -542,6 +544,9 @@ dblink_fetch(PG_FUNCTION_ARGS)
if (!conn)
DBLINK_CONN_NOT_AVAIL;
initStringInfo(&buf);
appendStringInfo(&buf, "FETCH %d FROM %s", howmany, curname);
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
@ -550,9 +555,7 @@ dblink_fetch(PG_FUNCTION_ARGS)
*/
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
appendStringInfo(str, "FETCH %d FROM %s", howmany, curname);
res = PQexec(conn, str->data);
res = PQexec(conn, buf.data);
if (!res ||
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
@ -1547,13 +1550,14 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
HeapTuple tuple;
TupleDesc tupdesc;
int natts;
StringInfo str = makeStringInfo();
char *sql;
StringInfoData buf;
char *val;
int16 key;
int i;
bool needComma;
initStringInfo(&buf);
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name(relid);
@ -1570,7 +1574,7 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
(errcode(ERRCODE_CARDINALITY_VIOLATION),
errmsg("source row not found")));
appendStringInfo(str, "INSERT INTO %s(", relname);
appendStringInfo(&buf, "INSERT INTO %s(", relname);
needComma = false;
for (i = 0; i < natts; i++)
@ -1579,14 +1583,14 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
continue;
if (needComma)
appendStringInfo(str, ",");
appendStringInfo(&buf, ",");
appendStringInfo(str, "%s",
appendStringInfoString(&buf,
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
needComma = true;
}
appendStringInfo(str, ") VALUES(");
appendStringInfo(&buf, ") VALUES(");
/*
* remember attvals are 1 based
@ -1598,7 +1602,7 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
continue;
if (needComma)
appendStringInfo(str, ",");
appendStringInfo(&buf, ",");
if (tgt_pkattvals != NULL)
key = get_attnum_pk_pos(pkattnums, pknumatts, i + 1);
@ -1612,21 +1616,17 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
if (val != NULL)
{
appendStringInfo(str, "%s", quote_literal_cstr(val));
appendStringInfoString(&buf, quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, "NULL");
appendStringInfo(&buf, "NULL");
needComma = true;
}
appendStringInfo(str, ")");
appendStringInfo(&buf, ")");
sql = pstrdup(str->data);
pfree(str->data);
pfree(str);
relation_close(rel, AccessShareLock);
return (sql);
return (buf.data);
}
static char *
@ -1636,10 +1636,11 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
char *relname;
TupleDesc tupdesc;
int natts;
StringInfo str = makeStringInfo();
char *sql;
StringInfoData buf;
int i;
initStringInfo(&buf);
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name(relid);
@ -1650,15 +1651,15 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
tupdesc = rel->rd_att;
natts = tupdesc->natts;
appendStringInfo(str, "DELETE FROM %s WHERE ", relname);
appendStringInfo(&buf, "DELETE FROM %s WHERE ", relname);
for (i = 0; i < pknumatts; i++)
{
int16 pkattnum = pkattnums->values[i];
if (i > 0)
appendStringInfo(str, " AND ");
appendStringInfo(&buf, " AND ");
appendStringInfo(str, "%s",
appendStringInfoString(&buf,
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
if (tgt_pkattvals == NULL)
@ -1666,18 +1667,14 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
elog(ERROR, "target key array must not be NULL");
if (tgt_pkattvals[i] != NULL)
appendStringInfo(str, " = %s",
appendStringInfo(&buf, " = %s",
quote_literal_cstr(tgt_pkattvals[i]));
else
appendStringInfo(str, " IS NULL");
appendStringInfo(&buf, " IS NULL");
}
sql = pstrdup(str->data);
pfree(str->data);
pfree(str);
relation_close(rel, AccessShareLock);
return (sql);
return (buf.data);
}
static char *
@ -1688,13 +1685,14 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
HeapTuple tuple;
TupleDesc tupdesc;
int natts;
StringInfo str = makeStringInfo();
char *sql;
StringInfoData buf;
char *val;
int16 key;
int i;
bool needComma;
initStringInfo(&buf);
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name(relid);
@ -1711,7 +1709,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
(errcode(ERRCODE_CARDINALITY_VIOLATION),
errmsg("source row not found")));
appendStringInfo(str, "UPDATE %s SET ", relname);
appendStringInfo(&buf, "UPDATE %s SET ", relname);
needComma = false;
for (i = 0; i < natts; i++)
@ -1720,9 +1718,9 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
continue;
if (needComma)
appendStringInfo(str, ", ");
appendStringInfo(&buf, ", ");
appendStringInfo(str, "%s = ",
appendStringInfo(&buf, "%s = ",
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
if (tgt_pkattvals != NULL)
@ -1737,24 +1735,24 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
if (val != NULL)
{
appendStringInfo(str, "%s", quote_literal_cstr(val));
appendStringInfoString(&buf, quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, "NULL");
appendStringInfoString(&buf, "NULL");
needComma = true;
}
appendStringInfo(str, " WHERE ");
appendStringInfo(&buf, " WHERE ");
for (i = 0; i < pknumatts; i++)
{
int16 pkattnum = pkattnums->values[i];
if (i > 0)
appendStringInfo(str, " AND ");
appendStringInfo(&buf, " AND ");
appendStringInfo(str, "%s",
appendStringInfo(&buf, "%s",
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
if (tgt_pkattvals != NULL)
@ -1764,19 +1762,15 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
if (val != NULL)
{
appendStringInfo(str, " = %s", quote_literal_cstr(val));
appendStringInfo(&buf, " = %s", quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, " IS NULL");
appendStringInfo(&buf, " IS NULL");
}
sql = pstrdup(str->data);
pfree(str->data);
pfree(str);
relation_close(rel, AccessShareLock);
return (sql);
return (buf.data);
}
/*
@ -1836,12 +1830,13 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
Relation rel;
char *relname;
TupleDesc tupdesc;
StringInfo str = makeStringInfo();
char *sql = NULL;
StringInfoData buf;
int ret;
HeapTuple tuple;
int i;
initStringInfo(&buf);
/* get relation name including any needed schema prefix and quoting */
relname = generate_relation_name(relid);
@ -1863,34 +1858,30 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
* Build sql statement to look up tuple of interest Use src_pkattvals as
* the criteria.
*/
appendStringInfo(str, "SELECT * FROM %s WHERE ", relname);
appendStringInfo(&buf, "SELECT * FROM %s WHERE ", relname);
for (i = 0; i < pknumatts; i++)
{
int16 pkattnum = pkattnums->values[i];
if (i > 0)
appendStringInfo(str, " AND ");
appendStringInfo(&buf, " AND ");
appendStringInfo(str, "%s",
appendStringInfoString(&buf,
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
if (src_pkattvals[i] != NULL)
appendStringInfo(str, " = %s",
appendStringInfo(&buf, " = %s",
quote_literal_cstr(src_pkattvals[i]));
else
appendStringInfo(str, " IS NULL");
appendStringInfo(&buf, " IS NULL");
}
sql = pstrdup(str->data);
pfree(str->data);
pfree(str);
/*
* Retrieve the desired tuple
*/
ret = SPI_exec(sql, 0);
pfree(sql);
ret = SPI_exec(buf.data, 0);
pfree(buf.data);
/*
* Only allow one qualifying tuple