Add destroyStringInfo function for cleaning up StringInfos
authorDaniel Gustafsson <dgustafsson@postgresql.org>
Sat, 16 Mar 2024 22:18:28 +0000 (23:18 +0100)
committerDaniel Gustafsson <dgustafsson@postgresql.org>
Sat, 16 Mar 2024 22:18:28 +0000 (23:18 +0100)
destroyStringInfo() is a counterpart to makeStringInfo(), freeing a
palloc'd StringInfo and its data. This is a convenience function to
align the StringInfo API with the PQExpBuffer API. Originally added
in the OAuth patchset, it was extracted and committed separately in
order to aid upcoming JSON work.

Author: Daniel Gustafsson <daniel@yesql.se>
Author: Jacob Champion <jacob.champion@enterprisedb.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CAOYmi+mWdTd6ujtyF7MsvXvk7ToLRVG_tYAcaGbQLvf=N4KrQw@mail.gmail.com

src/backend/backup/basebackup.c
src/backend/commands/subscriptioncmds.c
src/backend/utils/adt/jsonb.c
src/backend/utils/adt/xml.c
src/bin/pg_combinebackup/pg_combinebackup.c
src/common/stringinfo.c
src/include/lib/stringinfo.h
src/test/regress/pg_regress.c

index 5fbbe5ffd20fb893cb19a4ce6b99f61bc3734aa7..5fea86ad0fd301fb938b43e7995324114a40696f 100644 (file)
@@ -397,8 +397,7 @@ perform_base_backup(basebackup_options *opt, bbsink *sink,
        endtli = backup_state->stoptli;
 
        /* Deallocate backup-related variables. */
-       pfree(tablespace_map->data);
-       pfree(tablespace_map);
+       destroyStringInfo(tablespace_map);
        pfree(backup_state);
    }
    PG_END_ENSURE_ERROR_CLEANUP(do_pg_abort_backup, BoolGetDatum(false));
index a05d69922d9278f7dceb9be96eb57056ffe2a7fd..5a47fa984df011818dc52c18e107502d9c299d20 100644 (file)
@@ -506,8 +506,7 @@ check_publications(WalReceiverConn *wrconn, List *publications)
    appendStringInfoChar(cmd, ')');
 
    res = walrcv_exec(wrconn, cmd->data, 1, tableRow);
-   pfree(cmd->data);
-   pfree(cmd);
+   destroyStringInfo(cmd);
 
    if (res->status != WALRCV_OK_TUPLES)
        ereport(ERROR,
index a5e48744acb07d2d37d1c1527a7ddb017047e64c..a941654d5a363a20f6ae8e03a112a4779722d10a 100644 (file)
@@ -133,8 +133,7 @@ jsonb_send(PG_FUNCTION_ARGS)
    pq_begintypsend(&buf);
    pq_sendint8(&buf, version);
    pq_sendtext(&buf, jtext->data, jtext->len);
-   pfree(jtext->data);
-   pfree(jtext);
+   destroyStringInfo(jtext);
 
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
 }
index beecd0c2ac13ce280a5d304cb1a5414f3743d8c4..3e4ca874d81ade71d5034040d2a1a950c9648321 100644 (file)
@@ -2163,8 +2163,7 @@ xml_errorHandler(void *data, PgXmlErrorPtr error)
        appendBinaryStringInfo(&xmlerrcxt->err_buf, errorBuf->data,
                               errorBuf->len);
 
-       pfree(errorBuf->data);
-       pfree(errorBuf);
+       destroyStringInfo(errorBuf);
        return;
    }
 
@@ -2195,8 +2194,7 @@ xml_errorHandler(void *data, PgXmlErrorPtr error)
                (errmsg_internal("%s", errorBuf->data)));
    }
 
-   pfree(errorBuf->data);
-   pfree(errorBuf);
+   destroyStringInfo(errorBuf);
 }
 
 
index 6f0814d9ac6ee6394bcbf4aaf9ba691b3620d199..74f8be9eeac4bad72a04e99c51dd1155616f5d7e 100644 (file)
@@ -526,10 +526,7 @@ check_backup_label_files(int n_backups, char **backup_dirs)
 
    /* Free memory that we don't need any more. */
    if (lastbuf != buf)
-   {
-       pfree(buf->data);
-       pfree(buf);
-   }
+       destroyStringInfo(buf);
 
    /*
     * Return the data from the first backup_info that we read (which is the
index c61d5c58f30fc3415cf8222c9e7f040ef8d4c40d..ec5fc2422d81cf5431759f6da014308fbe12af10 100644 (file)
@@ -350,3 +350,19 @@ enlargeStringInfo(StringInfo str, int needed)
 
    str->maxlen = newlen;
 }
+
+/*
+ * destroyStringInfo
+ *
+ * Frees a StringInfo and its buffer (opposite of makeStringInfo()).
+ * This must only be called on palloc'd StringInfos.
+ */
+void
+destroyStringInfo(StringInfo str)
+{
+   /* don't allow destroys of read-only StringInfos */
+   Assert(str->maxlen != 0);
+
+   pfree(str->data);
+   pfree(str);
+}
index 2cd636b01cfbb0fe1f36521366bdf6a9e3913ca1..cd9632e3fcacf66e4506adb076383a3c77b62f82 100644 (file)
@@ -87,7 +87,8 @@ typedef StringInfoData *StringInfo;
  *     to be len + 1 in size.
  *
  * To destroy a StringInfo, pfree() the data buffer, and then pfree() the
- * StringInfoData if it was palloc'd.  There's no special support for this.
+ * StringInfoData if it was palloc'd.  For StringInfos created with
+ * makeStringInfo(), destroyStringInfo() is provided for this purpose.
  * However, if the StringInfo was initialized using initReadOnlyStringInfo()
  * then the caller will need to consider if it is safe to pfree the data
  * buffer.
@@ -233,4 +234,10 @@ extern void appendBinaryStringInfoNT(StringInfo str,
  */
 extern void enlargeStringInfo(StringInfo str, int needed);
 
+/*------------------------
+ * destroyStringInfo
+ * Frees a StringInfo and its buffer (opposite of makeStringInfo()).
+ */
+extern void destroyStringInfo(StringInfo str);
+
 #endif                         /* STRINGINFO_H */
index f1f6011ae0a337c4c6c24cf90218c57a730d4818..76f01c73f566b73272622e144ec978ad3e5c6951 100644 (file)
@@ -1174,8 +1174,7 @@ psql_end_command(StringInfo buf, const char *database)
    }
 
    /* Clean up */
-   pfree(buf->data);
-   pfree(buf);
+   destroyStringInfo(buf);
 }
 
 /*