This is an automated email from the ASF dual-hosted git repository.
mtaha pushed a commit to branch PG11
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/PG11 by this push:
new 1bb3aff5 Fix issue 2093: pfree() called with a NULL pointer (#2095)
(#2105)
1bb3aff5 is described below
commit 1bb3aff56470499a1c036ae36eee4dfeeb9566b4
Author: John Gemignani <[email protected]>
AuthorDate: Wed Sep 11 12:42:01 2024 -0700
Fix issue 2093: pfree() called with a NULL pointer (#2095) (#2105)
Fixed issue 2093 where pfree() was called with a NULL pointer.
The issue is due to some confusion with pfree(). There are 2
definitions for it, one that checks for a passed NULL and the
other which does not.
Created a function, pfree_if_not_null(), to check for NULL and
call pfree() if a NULL wasn't passed.
Modified the pfree references in the following files -
src/backend/commands/label_commands.c
src/backend/executor/cypher_merge.c
src/backend/executor/cypher_set.c
src/backend/executor/cypher_utils.c
src/backend/parser/ag_scanner.l
src/backend/parser/cypher_analyze.c
src/backend/parser/cypher_expr.c
src/backend/parser/cypher_gram.y
src/backend/parser/cypher_parse_agg.c
src/backend/utils/adt/age_global_graph.c
src/backend/utils/adt/age_graphid_ds.c
src/backend/utils/adt/age_session_info.c
src/backend/utils/adt/age_vle.c
src/backend/utils/adt/agtype.c
src/backend/utils/adt/agtype_gin.c
src/backend/utils/adt/agtype_raw.c
src/backend/utils/adt/agtype_util.c
src/backend/utils/load/ag_load_edges.c
src/backend/utils/load/ag_load_labels.c
src/include/utils/age_graphid_ds.h
src/include/utils/age_session_info.h
src/include/utils/agtype.h
Added regression tests for the original issue.
Resolved Conflicts:
src/backend/commands/label_commands.c
src/backend/parser/cypher_expr.c
src/backend/parser/cypher_parse_agg.c
src/backend/utils/adt/age_global_graph.c
src/backend/utils/adt/agtype.c
Resolved Conflicts:
src/backend/utils/load/ag_load_edges.c
src/backend/utils/load/ag_load_labels.c
---
regress/expected/expr.out | 15 ++++++
regress/sql/expr.sql | 6 +++
src/backend/commands/label_commands.c | 2 -
src/backend/executor/cypher_merge.c | 6 +--
src/backend/executor/cypher_set.c | 2 +-
src/backend/executor/cypher_utils.c | 2 +-
src/backend/parser/ag_scanner.l | 11 ++--
src/backend/parser/cypher_analyze.c | 4 +-
src/backend/parser/cypher_gram.y | 3 +-
src/backend/parser/cypher_parse_agg.c | 3 +-
src/backend/utils/adt/age_global_graph.c | 14 ++---
src/backend/utils/adt/age_graphid_ds.c | 8 +--
src/backend/utils/adt/age_session_info.c | 4 +-
src/backend/utils/adt/age_vle.c | 14 ++---
src/backend/utils/adt/agtype.c | 89 ++++++++++++++++++--------------
src/backend/utils/adt/agtype_gin.c | 2 +-
src/backend/utils/adt/agtype_raw.c | 4 +-
src/backend/utils/adt/agtype_util.c | 24 ++++-----
src/backend/utils/load/ag_load_edges.c | 6 +--
src/backend/utils/load/ag_load_labels.c | 18 +++----
src/include/utils/age_graphid_ds.h | 1 +
src/include/utils/age_session_info.h | 2 +
src/include/utils/agtype.h | 1 +
23 files changed, 140 insertions(+), 101 deletions(-)
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 281c3e66..3da13ca7 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -8505,6 +8505,21 @@ SELECT agtype_to_int8(bool('neither'));
ERROR: invalid input syntax for type boolean: "neither"
LINE 1: SELECT agtype_to_int8(bool('neither'));
^
+--
+-- Issue 2093: Server crashes when executing SELECT
agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
+--
+SELECT agtype_access_operator(agtype_in('[null, null]'));
+ agtype_access_operator
+------------------------
+
+(1 row)
+
+SELECT agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
+ agtype_hash_cmp
+-----------------
+ -505290721
+(1 row)
+
--
-- Cleanup
--
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 19d9b1b8..e150e2ab 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -3453,6 +3453,12 @@ SELECT agtype_to_int2(bool('neither'));
SELECT agtype_to_int4(bool('neither'));
SELECT agtype_to_int8(bool('neither'));
+--
+-- Issue 2093: Server crashes when executing SELECT
agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
+--
+SELECT agtype_access_operator(agtype_in('[null, null]'));
+SELECT agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
+
--
-- Cleanup
--
diff --git a/src/backend/commands/label_commands.c
b/src/backend/commands/label_commands.c
index ead3879d..80226e7c 100644
--- a/src/backend/commands/label_commands.c
+++ b/src/backend/commands/label_commands.c
@@ -94,8 +94,6 @@ static void range_var_callback_for_remove_relation(const
RangeVar *rel,
Oid odl_rel_oid,
void *arg);
-
-
PG_FUNCTION_INFO_V1(create_vlabel);
/*
diff --git a/src/backend/executor/cypher_merge.c
b/src/backend/executor/cypher_merge.c
index 83ff1266..db1de18e 100644
--- a/src/backend/executor/cypher_merge.c
+++ b/src/backend/executor/cypher_merge.c
@@ -347,7 +347,7 @@ static void free_path_entry_array(path_entry **path_array,
int length)
for (index = 0; index < length; index++)
{
- pfree(path_array[index]);
+ pfree_if_not_null(path_array[index]);
}
}
@@ -901,10 +901,10 @@ static void end_cypher_merge(CustomScanState *node)
free_path_entry_array(entry, path_length);
/* free up the array container */
- pfree(entry);
+ pfree_if_not_null(entry);
/* free up the created_path container */
- pfree(css->created_paths_list);
+ pfree_if_not_null(css->created_paths_list);
css->created_paths_list = next;
}
diff --git a/src/backend/executor/cypher_set.c
b/src/backend/executor/cypher_set.c
index 552395c9..ee2322d5 100644
--- a/src/backend/executor/cypher_set.c
+++ b/src/backend/executor/cypher_set.c
@@ -555,7 +555,7 @@ static void process_update_list(CustomScanState *node)
lidx++;
}
/* free our lookup array */
- pfree(luindex);
+ pfree_if_not_null(luindex);
}
static TupleTableSlot *exec_cypher_set(CustomScanState *node)
diff --git a/src/backend/executor/cypher_utils.c
b/src/backend/executor/cypher_utils.c
index 44158eb2..445a3e8f 100644
--- a/src/backend/executor/cypher_utils.c
+++ b/src/backend/executor/cypher_utils.c
@@ -76,7 +76,7 @@ uint32 datum_image_hash(Datum value, bool typByVal, int
typLen)
/* Only free memory if it's a copy made here. */
if ((Pointer) val != (Pointer) value)
{
- pfree(val);
+ pfree_if_not_null(val);
}
}
else if (typLen == -2)
diff --git a/src/backend/parser/ag_scanner.l b/src/backend/parser/ag_scanner.l
index 6fc9baf8..3af55827 100644
--- a/src/backend/parser/ag_scanner.l
+++ b/src/backend/parser/ag_scanner.l
@@ -34,6 +34,7 @@
#include "mb/pg_wchar.h"
#include "parser/ag_scanner.h"
+#include "utils/agtype.h"
}
%option 8bit
@@ -795,7 +796,7 @@ void *ag_yyrealloc(void *ptr, yy_size_t size, yyscan_t
yyscanner)
{
if (size == 0)
{
- pfree(ptr);
+ pfree_if_not_null(ptr);
return NULL;
}
else
@@ -812,7 +813,7 @@ void *ag_yyrealloc(void *ptr, yy_size_t size, yyscan_t
yyscanner)
void ag_yyfree(void *ptr, yyscan_t yyscanner)
{
if (ptr)
- pfree(ptr);
+ pfree_if_not_null(ptr);
}
static void strbuf_init(strbuf *sb, int capacity)
@@ -825,7 +826,7 @@ static void strbuf_init(strbuf *sb, int capacity)
static void strbuf_cleanup(strbuf *sb)
{
if (sb->buffer)
- pfree(sb->buffer);
+ pfree_if_not_null(sb->buffer);
}
static void strbuf_append_buf(strbuf *sb, const char *b, const int len)
@@ -1121,8 +1122,8 @@ static void _numstr_to_decimal(const char *numstr, const
int base, strbuf *sb)
strbuf_append_buf(sb, &buf[buf_i], ndigits_per_remainder - buf_i);
}
- pfree(remainders);
- pfree(words);
+ pfree_if_not_null(remainders);
+ pfree_if_not_null(words);
}
static uint32 hexdigit_value(const char c)
diff --git a/src/backend/parser/cypher_analyze.c
b/src/backend/parser/cypher_analyze.c
index c868070a..080d489d 100644
--- a/src/backend/parser/cypher_analyze.c
+++ b/src/backend/parser/cypher_analyze.c
@@ -108,7 +108,7 @@ static void post_parse_analyze(ParseState *pstate, Query
*query)
}
/* reset extra_node */
- pfree(extra_node);
+ pfree_if_not_null(extra_node);
extra_node = NULL;
}
}
@@ -277,7 +277,7 @@ static void build_explain_query(Query *query, Node
*explain_node)
((ExplainStmt *)explain_node)->options = NULL;
/* we need to free query_node as it is no longer needed */
- pfree(query_node);
+ pfree_if_not_null(query_node);
}
static bool is_rte_cypher(RangeTblEntry *rte)
diff --git a/src/backend/parser/cypher_gram.y b/src/backend/parser/cypher_gram.y
index 0825c206..e8652f21 100644
--- a/src/backend/parser/cypher_gram.y
+++ b/src/backend/parser/cypher_gram.y
@@ -26,6 +26,7 @@
#include "parser/cypher_gram.h"
#include "parser/cypher_parse_node.h"
#include "parser/scansup.h"
+#include "utils/agtype.h"
// override the default action for locations
#define YYLLOC_DEFAULT(current, rhs, n) \
@@ -2714,7 +2715,7 @@ static char *create_unique_name(char *prefix_name)
/* if we created the prefix, we need to free it */
if (prefix_name == NULL || strlen(prefix_name) <= 0)
{
- pfree(prefix);
+ pfree_if_not_null(prefix);
}
return name;
diff --git a/src/backend/parser/cypher_parse_agg.c
b/src/backend/parser/cypher_parse_agg.c
index b5654e77..54c57657 100644
--- a/src/backend/parser/cypher_parse_agg.c
+++ b/src/backend/parser/cypher_parse_agg.c
@@ -31,6 +31,7 @@
#include "parser/cypher_parse_agg.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteManip.h"
+#include "utils/agtype.h"
typedef struct
{
@@ -846,7 +847,7 @@ static List * expand_grouping_sets(List *groupingSets, int
limit)
while (result_len-- > 0)
result = lappend(result, *ptr++);
- pfree(buf);
+ pfree_if_not_null(buf);
}
return result;
diff --git a/src/backend/utils/adt/age_global_graph.c
b/src/backend/utils/adt/age_global_graph.c
index d16e628b..e1a50e73 100644
--- a/src/backend/utils/adt/age_global_graph.c
+++ b/src/backend/utils/adt/age_global_graph.c
@@ -181,7 +181,7 @@ static void
create_GRAPH_global_hashtables(GRAPH_global_context *ggctx)
ggctx->vertex_hashtable = hash_create(vhn, VERTEX_HTAB_INITIAL_SIZE,
&vertex_ctl,
HASH_ELEM | HASH_FUNCTION);
- pfree(vhn);
+ pfree_if_not_null(vhn);
/* initialize the edge hashtable */
MemSet(&edge_ctl, 0, sizeof(edge_ctl));
@@ -190,7 +190,7 @@ static void
create_GRAPH_global_hashtables(GRAPH_global_context *ggctx)
edge_ctl.hash = tag_hash;
ggctx->edge_hashtable = hash_create(ehn, EDGE_HTAB_INITIAL_SIZE, &edge_ctl,
HASH_ELEM | HASH_FUNCTION);
- pfree(ehn);
+ pfree_if_not_null(ehn);
}
/* helper function to get a List of all label names for the specified graph */
@@ -624,7 +624,7 @@ static bool
free_specific_GRAPH_global_context(GRAPH_global_context *ggctx)
}
/* free the graph name */
- pfree(ggctx->graph_name);
+ pfree_if_not_null(ggctx->graph_name);
ggctx->graph_name = NULL;
ggctx->graph_oid = InvalidOid;
@@ -656,7 +656,7 @@ static bool
free_specific_GRAPH_global_context(GRAPH_global_context *ggctx)
}
/* free the vertex's datumCopy properties */
- pfree(DatumGetPointer(value->vertex_properties));
+ pfree_if_not_null(DatumGetPointer(value->vertex_properties));
value->vertex_properties = 0;
/* free the edge list associated with this vertex */
@@ -698,7 +698,7 @@ static bool
free_specific_GRAPH_global_context(GRAPH_global_context *ggctx)
}
/* free the edge's datumCopy properties */
- pfree(DatumGetPointer(value->edge_properties));
+ pfree_if_not_null(DatumGetPointer(value->edge_properties));
value->edge_properties = 0;
/* move to the next edge */
@@ -721,7 +721,7 @@ static bool
free_specific_GRAPH_global_context(GRAPH_global_context *ggctx)
ggctx->edge_hashtable = NULL;
/* free the context */
- pfree(ggctx);
+ pfree_if_not_null(ggctx);
ggctx = NULL;
return true;
@@ -1224,7 +1224,7 @@ Datum age_vertex_stats(PG_FUNCTION_ARGS)
ggctx = manage_GRAPH_global_contexts(graph_name, graph_oid);
/* free the graph name */
- pfree(graph_name);
+ pfree_if_not_null(graph_name);
/* get the id */
agtv_temp = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_vertex, "id");
diff --git a/src/backend/utils/adt/age_graphid_ds.c
b/src/backend/utils/adt/age_graphid_ds.c
index 73be8dc2..625a6947 100644
--- a/src/backend/utils/adt/age_graphid_ds.c
+++ b/src/backend/utils/adt/age_graphid_ds.c
@@ -144,14 +144,14 @@ void free_ListGraphId(ListGraphId *container)
{
next_node = curr_node->next;
/* we can do this because this is just a list of ints */
- pfree(curr_node);
+ pfree_if_not_null(curr_node);
container->size--;
curr_node = next_node;
}
Assert(container->size == 0);
/* free the container */
- pfree(container);
+ pfree_if_not_null(container);
}
/* helper function to create a new, empty, graphid stack */
@@ -188,7 +188,7 @@ void free_graphid_stack(ListGraphId *stack)
GraphIdNode *next = stack->head->next;
/* free the head element */
- pfree(stack->head);
+ pfree_if_not_null(stack->head);
/* move the head to the next */
stack->head = next;
}
@@ -253,7 +253,7 @@ graphid pop_graphid_stack(ListGraphId *stack)
stack->head = stack->head->next;
stack->size--;
/* free the element */
- pfree(node);
+ pfree_if_not_null(node);
/* return the id */
return id;
diff --git a/src/backend/utils/adt/age_session_info.c
b/src/backend/utils/adt/age_session_info.c
index 350273eb..f224d406 100644
--- a/src/backend/utils/adt/age_session_info.c
+++ b/src/backend/utils/adt/age_session_info.c
@@ -125,12 +125,12 @@ void reset_session_info(void)
{
if (session_info_graph_name != NULL)
{
- pfree(session_info_graph_name);
+ pfree_if_not_null(session_info_graph_name);
}
if (session_info_cypher_statement != NULL)
{
- pfree(session_info_cypher_statement);
+ pfree_if_not_null(session_info_cypher_statement);
}
}
diff --git a/src/backend/utils/adt/age_vle.c b/src/backend/utils/adt/age_vle.c
index 856cdb6c..3c0119a1 100644
--- a/src/backend/utils/adt/age_vle.c
+++ b/src/backend/utils/adt/age_vle.c
@@ -314,7 +314,7 @@ static void
create_VLE_local_state_hashtable(VLE_local_context *vlelctx)
EDGE_STATE_HTAB_INITIAL_SIZE,
&edge_state_ctl,
HASH_ELEM | HASH_FUNCTION);
- pfree(eshn);
+ pfree_if_not_null(eshn);
}
/*
@@ -401,14 +401,14 @@ static void free_VLE_local_context(VLE_local_context
*vlelctx)
/* free the stored graph name */
if (vlelctx->graph_name != NULL)
{
- pfree(vlelctx->graph_name);
+ pfree_if_not_null(vlelctx->graph_name);
vlelctx->graph_name = NULL;
}
/* free the stored edge label name */
if (vlelctx->edge_label_name != NULL)
{
- pfree(vlelctx->edge_label_name);
+ pfree_if_not_null(vlelctx->edge_label_name);
vlelctx->edge_label_name = NULL;
}
@@ -430,15 +430,15 @@ static void free_VLE_local_context(VLE_local_context
*vlelctx)
}
/* free the containers */
- pfree(vlelctx->dfs_vertex_stack);
- pfree(vlelctx->dfs_edge_stack);
- pfree(vlelctx->dfs_path_stack);
+ pfree_if_not_null(vlelctx->dfs_vertex_stack);
+ pfree_if_not_null(vlelctx->dfs_edge_stack);
+ pfree_if_not_null(vlelctx->dfs_path_stack);
vlelctx->dfs_vertex_stack = NULL;
vlelctx->dfs_edge_stack = NULL;
vlelctx->dfs_path_stack = NULL;
/* and finally the context itself */
- pfree(vlelctx);
+ pfree_if_not_null(vlelctx);
vlelctx = NULL;
}
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 073b4f59..b3a13fbc 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -179,6 +179,19 @@ static agtype_value*
agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo);
agtype_value *agtype_composite_to_agtype_value_binary(agtype *a);
static agtype_value *tostring_helper(Datum arg, Oid type, char *msghdr);
+/*
+ * Due to how pfree can be implemented, it may not check for a passed NULL.
This
+ * wrapper does just that, it will only call pfree is the pointer passed is not
+ * NULL.
+ */
+void pfree_if_not_null(void *ptr)
+{
+ if (ptr != NULL)
+ {
+ pfree(ptr);
+ }
+}
+
/* global storage of OID for agtype and _agtype */
static Oid g_AGTYPEOID = InvalidOid;
static Oid g_AGTYPEARRAYOID = InvalidOid;
@@ -295,7 +308,7 @@ Datum agtype_recv(PG_FUNCTION_ARGS)
result = agtype_from_cstring(str, nbytes);
PG_FREE_IF_COPY(buf, 0);
- pfree(str);
+ pfree_if_not_null(str);
return result;
}
@@ -320,8 +333,8 @@ Datum agtype_send(PG_FUNCTION_ARGS)
pq_begintypsend(&buf);
pq_sendint8(&buf, version);
pq_sendtext(&buf, agtype_text->data, agtype_text->len);
- pfree(agtype_text->data);
- pfree(agtype_text);
+ pfree_if_not_null(agtype_text->data);
+ pfree_if_not_null(agtype_text);
PG_FREE_IF_COPY(agt, 0);
@@ -1542,7 +1555,7 @@ static void datum_to_agtype(Datum val, bool is_null,
agtype_in_state *result,
intd = DirectFunctionCall1(int8in, CStringGetDatum(outputstr));
agtv.type = AGTV_INTEGER;
agtv.val.int_value = DatumGetInt64(intd);
- pfree(outputstr);
+ pfree_if_not_null(outputstr);
}
break;
case AGT_TYPE_FLOAT:
@@ -1587,7 +1600,7 @@ static void datum_to_agtype(Datum val, bool is_null,
agtype_in_state *result,
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
agtv.val.numeric = DatumGetNumeric(numd);
- pfree(outputstr);
+ pfree_if_not_null(outputstr);
}
else
{
@@ -1817,8 +1830,8 @@ static void array_to_agtype_internal(Datum array,
agtype_in_state *result)
array_dim_to_agtype(result, 0, ndim, dim, elements, nulls, &count,
tcategory, outfuncoid);
- pfree(elements);
- pfree(nulls);
+ pfree_if_not_null(elements);
+ pfree_if_not_null(nulls);
}
/*
@@ -2216,7 +2229,7 @@ Datum make_path(List *path)
if ((Pointer) (agt) != lfirst(lc))
{
- pfree(agt);
+ pfree_if_not_null(agt);
}
pfree_agtype_value(elem);
@@ -2469,7 +2482,7 @@ static agtype_value*
agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo)
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
agtv);
/* free the agtype_value from tostring_helper */
- pfree(agtv);
+ pfree_if_not_null(agtv);
}
else
{
@@ -2832,7 +2845,7 @@ Datum agtype_to_int8(PG_FUNCTION_ARGS)
/* free the container, if it was used */
if (container)
{
- pfree(container);
+ pfree_if_not_null(container);
}
PG_FREE_IF_COPY(arg_agt, 0);
@@ -2953,7 +2966,7 @@ Datum agtype_to_int4(PG_FUNCTION_ARGS)
/* free the container, if it was used */
if (container)
{
- pfree(container);
+ pfree_if_not_null(container);
}
PG_FREE_IF_COPY(arg_agt, 0);
@@ -3075,7 +3088,7 @@ Datum agtype_to_int2(PG_FUNCTION_ARGS)
/* free the container, if it was used */
if (container)
{
- pfree(container);
+ pfree_if_not_null(container);
}
PG_FREE_IF_COPY(arg_agt, 0);
@@ -3225,7 +3238,7 @@ Datum agtype_to_json(PG_FUNCTION_ARGS)
result = DirectFunctionCall1(json_in, CStringGetDatum(json_str));
PG_FREE_IF_COPY(agt, 0);
- pfree(json_str);
+ pfree_if_not_null(json_str);
PG_RETURN_DATUM(result);
}
@@ -3999,9 +4012,9 @@ Datum agtype_access_operator(PG_FUNCTION_ARGS)
*/
if (args == NULL || nargs == 0 || nulls[0] == true)
{
- pfree(args);
- pfree(types);
- pfree(nulls);
+ pfree_if_not_null(args);
+ pfree_if_not_null(types);
+ pfree_if_not_null(nulls);
PG_RETURN_NULL();
}
@@ -4012,9 +4025,9 @@ Datum agtype_access_operator(PG_FUNCTION_ARGS)
/* if we have a NULL, return NULL */
if (nulls[i] == true)
{
- pfree(args);
- pfree(types);
- pfree(nulls);
+ pfree_if_not_null(args);
+ pfree_if_not_null(types);
+ pfree_if_not_null(nulls);
PG_RETURN_NULL();
}
}
@@ -4133,9 +4146,9 @@ Datum agtype_access_operator(PG_FUNCTION_ARGS)
container = NULL;
}
- pfree(args);
- pfree(types);
- pfree(nulls);
+ pfree_if_not_null(args);
+ pfree_if_not_null(types);
+ pfree_if_not_null(nulls);
/* serialize and return the result */
result = agtype_value_to_agtype(container_value);
@@ -4610,8 +4623,8 @@ Datum agtype_string_match_contains(PG_FUNCTION_ARGS)
{
result = true;
}
- pfree(l);
- pfree(r);
+ pfree_if_not_null(l);
+ pfree_if_not_null(r);
}
pfree_agtype_value(lhs_value);
pfree_agtype_value(rhs_value);
@@ -4667,7 +4680,7 @@ Datum agtype_hash_cmp(PG_FUNCTION_ARGS)
seed = LEFT_ROTATE(seed, 1);
}
- pfree(r);
+ pfree_if_not_null(r);
PG_FREE_IF_COPY(agt, 0);
PG_RETURN_INT32(hash);
@@ -4773,7 +4786,7 @@ Datum agtype_typecast_numeric(PG_FUNCTION_ARGS)
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
/* free the string */
- pfree(string);
+ pfree_if_not_null(string);
string = NULL;
break;
/* what was given doesn't cast to a numeric */
@@ -4861,7 +4874,7 @@ Datum agtype_typecast_int(PG_FUNCTION_ARGS)
d = DirectFunctionCall1(int8in, CStringGetDatum(string));
/* free the string */
- pfree(string);
+ pfree_if_not_null(string);
string = NULL;
break;
/* what was given doesn't cast to an int */
@@ -4998,7 +5011,7 @@ Datum agtype_typecast_float(PG_FUNCTION_ARGS)
d = DirectFunctionCall1(float8in, CStringGetDatum(string));
/* free the string */
- pfree(string);
+ pfree_if_not_null(string);
string = NULL;
break;
/* what was given doesn't cast to a float */
@@ -7088,7 +7101,7 @@ Datum age_tostring(PG_FUNCTION_ARGS)
/* convert to agtype and free the agtype_value */
agt = agtype_value_to_agtype(agtv);
- pfree(agtv);
+ pfree_if_not_null(agtv);
PG_RETURN_POINTER(agt);
}
@@ -10292,9 +10305,9 @@ agtype
*get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
/* if null, return null */
if (nulls[0])
{
- pfree(args);
- pfree(nulls);
- pfree(types);
+ pfree_if_not_null(args);
+ pfree_if_not_null(nulls);
+ pfree_if_not_null(types);
return NULL;
}
@@ -10315,9 +10328,9 @@ agtype
*get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
{
PG_FREE_IF_COPY(agtype_result, variadic_offset);
- pfree(args);
- pfree(nulls);
- pfree(types);
+ pfree_if_not_null(args);
+ pfree_if_not_null(nulls);
+ pfree_if_not_null(types);
return NULL;
}
}
@@ -10341,9 +10354,9 @@ agtype
*get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
pfree_agtype_in_state(&state);
}
- pfree(args);
- pfree(nulls);
- pfree(types);
+ pfree_if_not_null(args);
+ pfree_if_not_null(nulls);
+ pfree_if_not_null(types);
return agtype_result;
}
diff --git a/src/backend/utils/adt/agtype_gin.c
b/src/backend/utils/adt/agtype_gin.c
index 312fcffa..3a02f4b3 100644
--- a/src/backend/utils/adt/agtype_gin.c
+++ b/src/backend/utils/adt/agtype_gin.c
@@ -552,7 +552,7 @@ static Datum make_scalar_key(const agtype_value *scalarVal,
bool is_key)
*/
cstr = numeric_normalize(scalarVal->val.numeric);
item = make_text_key(AGT_GIN_FLAG_NUM, cstr, strlen(cstr));
- pfree(cstr);
+ pfree_if_not_null(cstr);
break;
case AGTV_STRING:
item = make_text_key(is_key ? AGT_GIN_FLAG_KEY : AGT_GIN_FLAG_STR,
diff --git a/src/backend/utils/adt/agtype_raw.c
b/src/backend/utils/adt/agtype_raw.c
index f5406806..9c695457 100644
--- a/src/backend/utils/adt/agtype_raw.c
+++ b/src/backend/utils/adt/agtype_raw.c
@@ -172,8 +172,8 @@ void pfree_agtype_build_state(agtype_build_state *bstate)
* bstate->buffer->data is not pfree'd because this pointer
* is returned by the `build_agtype` function.
*/
- pfree(bstate->buffer);
- pfree(bstate);
+ pfree_if_not_null(bstate->buffer);
+ pfree_if_not_null(bstate);
}
void write_string(agtype_build_state *bstate, char *str)
diff --git a/src/backend/utils/adt/agtype_util.c
b/src/backend/utils/adt/agtype_util.c
index 44780eca..2044d47f 100644
--- a/src/backend/utils/adt/agtype_util.c
+++ b/src/backend/utils/adt/agtype_util.c
@@ -433,14 +433,14 @@ int
compare_agtype_containers_orderability(agtype_container *a,
{
agtype_iterator *i = ita->parent;
- pfree(ita);
+ pfree_if_not_null(ita);
ita = i;
}
while (itb != NULL)
{
agtype_iterator *i = itb->parent;
- pfree(itb);
+ pfree_if_not_null(itb);
itb = i;
}
@@ -557,7 +557,7 @@ agtype_value
*find_agtype_value_from_container(agtype_container *container,
}
/* Not found */
- pfree(result);
+ pfree_if_not_null(result);
return NULL;
}
@@ -1217,7 +1217,7 @@ static agtype_iterator
*free_and_get_parent(agtype_iterator *it)
{
agtype_iterator *v = it->parent;
- pfree(it);
+ pfree_if_not_null(it);
return v;
}
@@ -1469,9 +1469,9 @@ bool agtype_deep_contains(agtype_iterator **val,
contains = agtype_deep_contains(&nestval, &nest_contained,
false);
if (nestval)
- pfree(nestval);
+ pfree_if_not_null(nestval);
if (nest_contained)
- pfree(nest_contained);
+ pfree_if_not_null(nest_contained);
if (contains)
break;
}
@@ -2438,7 +2438,7 @@ char *agtype_value_type_to_string(enum agtype_value_type
type)
void pfree_agtype_value(agtype_value* value)
{
pfree_agtype_value_content(value);
- pfree(value);
+ pfree_if_not_null(value);
}
/*
@@ -2456,7 +2456,7 @@ void pfree_agtype_value_content(agtype_value* value)
switch (value->type)
{
case AGTV_NUMERIC:
- pfree(value->val.numeric);
+ pfree_if_not_null(value->val.numeric);
break;
case AGTV_STRING:
@@ -2464,7 +2464,7 @@ void pfree_agtype_value_content(agtype_value* value)
* The char pointer (val.string.val) is not free'd because
* it is not allocated by an agtype helper function.
*/
- pfree(value->val.string.val);
+ pfree_if_not_null(value->val.string.val);
break;
case AGTV_ARRAY:
@@ -2473,7 +2473,7 @@ void pfree_agtype_value_content(agtype_value* value)
{
pfree_agtype_value_content(&value->val.array.elems[i]);
}
- pfree(value->val.array.elems);
+ pfree_if_not_null(value->val.array.elems);
break;
case AGTV_OBJECT:
@@ -2484,11 +2484,11 @@ void pfree_agtype_value_content(agtype_value* value)
pfree_agtype_value_content(&value->val.object.pairs[i].key);
pfree_agtype_value_content(&value->val.object.pairs[i].value);
}
- pfree(value->val.object.pairs);
+ pfree_if_not_null(value->val.object.pairs);
break;
case AGTV_BINARY:
- pfree(value->val.binary.data);
+ pfree_if_not_null(value->val.binary.data);
break;
case AGTV_NULL:
diff --git a/src/backend/utils/load/ag_load_edges.c
b/src/backend/utils/load/ag_load_edges.c
index 65ce9366..e7f1442b 100644
--- a/src/backend/utils/load/ag_load_edges.c
+++ b/src/backend/utils/load/ag_load_edges.c
@@ -281,7 +281,7 @@ static void finish_edge_batch_insert(batch_insert_state
**batch_state,
}
// Clean up batch state
- pfree((*batch_state)->buffered_tuples);
- pfree(*batch_state);
+ pfree_if_not_null((*batch_state)->buffered_tuples);
+ pfree_if_not_null(*batch_state);
*batch_state = NULL;
-}
\ No newline at end of file
+}
diff --git a/src/backend/utils/load/ag_load_labels.c
b/src/backend/utils/load/ag_load_labels.c
index 194a6dc8..abefcbad 100644
--- a/src/backend/utils/load/ag_load_labels.c
+++ b/src/backend/utils/load/ag_load_labels.c
@@ -327,8 +327,8 @@ static void setup_temp_table_for_vertex_ids(char
*graph_name)
SPI_finish();
- pfree(create_as_query);
- pfree(index_query);
+ pfree_if_not_null(create_as_query);
+ pfree_if_not_null(index_query);
}
/*
@@ -366,7 +366,7 @@ static void insert_batch_in_temp_table(batch_insert_state
*batch_state,
for (i = 0; i < batch_state->num_tuples; i++)
{
TupleTableSlot *slot;
-
+
slot = MakeSingleTupleTableSlot(batch_state->id_desc);
ExecStoreTuple(batch_state->buffered_id_tuples[i],
slot, InvalidBuffer, false);
@@ -379,14 +379,14 @@ static void insert_batch_in_temp_table(batch_insert_state
*batch_state,
bool isnull;
id = slot_getattr(slot, 1, &isnull);
- pfree(slot);
+ pfree_if_not_null(slot);
ereport(ERROR, (errmsg("Cannot insert duplicate vertex id: %ld",
DATUM_GET_GRAPHID(id)),
errhint("Entry id %ld is already used",
get_graphid_entry_id(id))));
}
- pfree(slot);
+ pfree_if_not_null(slot);
}
/* Clean up and close the indices */
ExecCloseIndices(resultRelInfo);
@@ -442,8 +442,8 @@ static void finish_vertex_batch_insert(batch_insert_state
**batch_state,
}
/* Clean up batch state */
- pfree((*batch_state)->buffered_tuples);
- pfree((*batch_state)->buffered_id_tuples);
- pfree(*batch_state);
+ pfree_if_not_null((*batch_state)->buffered_tuples);
+ pfree_if_not_null((*batch_state)->buffered_id_tuples);
+ pfree_if_not_null(*batch_state);
*batch_state = NULL;
-}
\ No newline at end of file
+}
diff --git a/src/include/utils/age_graphid_ds.h
b/src/include/utils/age_graphid_ds.h
index ea9dabdc..a5bb5273 100644
--- a/src/include/utils/age_graphid_ds.h
+++ b/src/include/utils/age_graphid_ds.h
@@ -21,6 +21,7 @@
#define AG_AGE_GRAPHID_DS_H
#include "utils/graphid.h"
+#include "utils/agtype.h"
#define IS_GRAPHID_STACK_EMPTY(stack) \
get_stack_size(stack) == 0
diff --git a/src/include/utils/age_session_info.h
b/src/include/utils/age_session_info.h
index ebf0035a..5bd072fb 100644
--- a/src/include/utils/age_session_info.h
+++ b/src/include/utils/age_session_info.h
@@ -20,6 +20,8 @@
#ifndef AGE_SESSION_INFO_H
#define AGE_SESSION_INFO_H
+#include "utils/agtype.h"
+
bool is_session_info_prepared(void);
char *get_session_info_graph_name(void);
char *get_session_info_cypher_statement(void);
diff --git a/src/include/utils/agtype.h b/src/include/utils/agtype.h
index 44fdea1b..65f3e8aa 100644
--- a/src/include/utils/agtype.h
+++ b/src/include/utils/agtype.h
@@ -557,6 +557,7 @@ agtype_iterator *get_next_list_element(agtype_iterator *it,
void pfree_agtype_value(agtype_value* value);
void pfree_agtype_value_content(agtype_value* value);
void pfree_agtype_in_state(agtype_in_state* value);
+void pfree_if_not_null(void *ptr);
agtype_value *agtype_value_from_cstring(char *str, int len);
/* Oid accessors for AGTYPE */
Oid get_AGTYPEOID(void);