Skip to content

Commit aae2e49

Browse files
committed
Optmize vertex and edge builder functions
Changes: - Added the agtype_raw module, which contains helper functions to build agtype directly without building an agtype_value first - Optimize _agtype_build_vertex and _agtype_build_edge functions The agtype_raw module: Inserting a composite agtype (i.e. object) into another agtype (i.e. as an array element) requires the first agtype to be deserialized into agtype_value. Then, the agtype_value to be serialized back into the second agtype. This module provides functions that can perform such insertion without deserializing first. It is meant to speed up queries that does deserialization-serialization back and forth involving deeply nested agtype objects.
1 parent 85b41b0 commit aae2e49

File tree

6 files changed

+343
-81
lines changed

6 files changed

+343
-81
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ OBJS = src/backend/age.o \
5656
src/backend/utils/adt/agtype_ops.o \
5757
src/backend/utils/adt/agtype_parser.o \
5858
src/backend/utils/adt/agtype_util.o \
59+
src/backend/utils/adt/agtype_raw.o \
5960
src/backend/utils/adt/age_global_graph.o \
6061
src/backend/utils/adt/age_session_info.o \
6162
src/backend/utils/adt/age_vle.o \

src/backend/utils/adt/agtype.c

Lines changed: 55 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#include "utils/agtype.h"
6565
#include "utils/agtype_parser.h"
6666
#include "utils/ag_float8_supp.h"
67+
#include "utils/agtype_raw.h"
6768
#include "catalog/ag_graph.h"
6869
#include "catalog/ag_label.h"
6970
#include "utils/graphid.h"
@@ -2172,74 +2173,64 @@ PG_FUNCTION_INFO_V1(_agtype_build_vertex);
21722173
*/
21732174
Datum _agtype_build_vertex(PG_FUNCTION_ARGS)
21742175
{
2175-
agtype_in_state result;
21762176
graphid id;
2177+
char *label;
2178+
agtype *properties;
2179+
agtype_build_state *bstate;
2180+
agtype *rawscalar;
2181+
agtype *vertex;
21772182

2178-
memset(&result, 0, sizeof(agtype_in_state));
2179-
2180-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2181-
NULL);
2182-
2183-
/* process graphid */
2184-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2185-
string_to_agtype_value("id"));
2186-
2183+
/* handles null */
21872184
if (fcinfo->args[0].isnull)
21882185
{
21892186
ereport(ERROR,
21902187
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
21912188
errmsg("_agtype_build_vertex() graphid cannot be NULL")));
21922189
}
21932190

2194-
id = AG_GETARG_GRAPHID(0);
2195-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2196-
integer_to_agtype_value(id));
2197-
2198-
/* process label */
2199-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2200-
string_to_agtype_value("label"));
2201-
22022191
if (fcinfo->args[1].isnull)
22032192
{
22042193
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
22052194
errmsg("_agtype_build_vertex() label cannot be NULL")));
22062195
}
22072196

2208-
result.res =
2209-
push_agtype_value(&result.parse_state, WAGT_VALUE,
2210-
string_to_agtype_value(PG_GETARG_CSTRING(1)));
2211-
2212-
/* process properties */
2213-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2214-
string_to_agtype_value("properties"));
2197+
id = AG_GETARG_GRAPHID(0);
2198+
label = PG_GETARG_CSTRING(1);
22152199

2216-
//if the properties object is null, push an empty object
22172200
if (fcinfo->args[2].isnull)
22182201
{
2219-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2220-
NULL);
2221-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT,
2222-
NULL);
2202+
agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
2203+
properties = build_agtype(bstate);
2204+
pfree_agtype_build_state(bstate);
22232205
}
22242206
else
22252207
{
2226-
agtype *properties = AG_GET_ARG_AGTYPE_P(2);
2208+
properties = AG_GET_ARG_AGTYPE_P(2);
22272209

22282210
if (!AGT_ROOT_IS_OBJECT(properties))
22292211
{
22302212
ereport(ERROR,
22312213
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
22322214
errmsg("_agtype_build_vertex() properties argument must be an object")));
22332215
}
2234-
2235-
add_agtype((Datum)properties, false, &result, AGTYPEOID, false);
22362216
}
22372217

2238-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);
2218+
bstate = init_agtype_build_state(3, AGT_FOBJECT);
2219+
write_string(bstate, "id");
2220+
write_string(bstate, "label");
2221+
write_string(bstate, "properties");
2222+
write_graphid(bstate, id);
2223+
write_string(bstate, label);
2224+
write_container(bstate, properties);
2225+
vertex = build_agtype(bstate);
2226+
pfree_agtype_build_state(bstate);
22392227

2240-
result.res->type = AGTV_VERTEX;
2228+
bstate = init_agtype_build_state(1, AGT_FARRAY | AGT_FSCALAR);
2229+
write_extended(bstate, vertex, AGT_HEADER_VERTEX);
2230+
rawscalar = build_agtype(bstate);
2231+
pfree_agtype_build_state(bstate);
22412232

2242-
PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
2233+
PG_RETURN_POINTER(rawscalar);
22432234
}
22442235

22452236
Datum make_vertex(Datum id, Datum label, Datum properties)
@@ -2254,18 +2245,13 @@ PG_FUNCTION_INFO_V1(_agtype_build_edge);
22542245
*/
22552246
Datum _agtype_build_edge(PG_FUNCTION_ARGS)
22562247
{
2257-
agtype_in_state result;
2248+
agtype_build_state *bstate;
2249+
agtype *edge, *rawscalar;
22582250
graphid id, start_id, end_id;
2259-
2260-
memset(&result, 0, sizeof(agtype_in_state));
2261-
2262-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2263-
NULL);
2251+
char *label;
2252+
agtype *properties;
22642253

22652254
/* process graph id */
2266-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2267-
string_to_agtype_value("id"));
2268-
22692255
if (fcinfo->args[0].isnull)
22702256
{
22712257
ereport(ERROR,
@@ -2274,27 +2260,17 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
22742260
}
22752261

22762262
id = AG_GETARG_GRAPHID(0);
2277-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2278-
integer_to_agtype_value(id));
22792263

22802264
/* process label */
2281-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2282-
string_to_agtype_value("label"));
2283-
22842265
if (fcinfo->args[3].isnull)
22852266
{
22862267
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
22872268
errmsg("_agtype_build_vertex() label cannot be NULL")));
22882269
}
22892270

2290-
result.res =
2291-
push_agtype_value(&result.parse_state, WAGT_VALUE,
2292-
string_to_agtype_value(PG_GETARG_CSTRING(3)));
2271+
label = PG_GETARG_CSTRING(3);
22932272

22942273
/* process end_id */
2295-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2296-
string_to_agtype_value("end_id"));
2297-
22982274
if (fcinfo->args[2].isnull)
22992275
{
23002276
ereport(ERROR,
@@ -2303,13 +2279,8 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
23032279
}
23042280

23052281
end_id = AG_GETARG_GRAPHID(2);
2306-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2307-
integer_to_agtype_value(end_id));
23082282

23092283
/* process start_id */
2310-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2311-
string_to_agtype_value("start_id"));
2312-
23132284
if (fcinfo->args[1].isnull)
23142285
{
23152286
ereport(ERROR,
@@ -2318,40 +2289,47 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
23182289
}
23192290

23202291
start_id = AG_GETARG_GRAPHID(1);
2321-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2322-
integer_to_agtype_value(start_id));
23232292

23242293
/* process properties */
2325-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2326-
string_to_agtype_value("properties"));
23272294

23282295
/* if the properties object is null, push an empty object */
23292296
if (fcinfo->args[4].isnull)
23302297
{
2331-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2332-
NULL);
2333-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT,
2334-
NULL);
2298+
agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
2299+
properties = build_agtype(bstate);
2300+
pfree_agtype_build_state(bstate);
23352301
}
23362302
else
23372303
{
2338-
agtype *properties = AG_GET_ARG_AGTYPE_P(4);
2304+
properties = AG_GET_ARG_AGTYPE_P(4);
23392305

23402306
if (!AGT_ROOT_IS_OBJECT(properties))
23412307
{
23422308
ereport(ERROR,
23432309
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
23442310
errmsg("_agtype_build_edge() properties argument must be an object")));
23452311
}
2346-
2347-
add_agtype((Datum)properties, false, &result, AGTYPEOID, false);
23482312
}
23492313

2350-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);
2351-
2352-
result.res->type = AGTV_EDGE;
2353-
2354-
PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
2314+
bstate = init_agtype_build_state(5, AGT_FOBJECT);
2315+
write_string(bstate, "id");
2316+
write_string(bstate, "label");
2317+
write_string(bstate, "end_id");
2318+
write_string(bstate, "start_id");
2319+
write_string(bstate, "properties");
2320+
write_graphid(bstate, id);
2321+
write_string(bstate, label);
2322+
write_graphid(bstate, end_id);
2323+
write_graphid(bstate, start_id);
2324+
write_container(bstate, properties);
2325+
edge = build_agtype(bstate);
2326+
pfree_agtype_build_state(bstate);
2327+
2328+
bstate = init_agtype_build_state(1, AGT_FARRAY | AGT_FSCALAR);
2329+
write_extended(bstate, edge, AGT_HEADER_EDGE);
2330+
rawscalar = build_agtype(bstate);
2331+
pfree_agtype_build_state(bstate);
2332+
PG_RETURN_POINTER(rawscalar);
23552333
}
23562334

23572335
Datum make_edge(Datum id, Datum startid, Datum endid, Datum label,

src/backend/utils/adt/agtype_ext.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121
#include "utils/agtype.h"
2222
#include "utils/graphid.h"
2323

24-
/* define the type and size of the agt_header */
25-
#define AGT_HEADER_TYPE uint32
26-
#define AGT_HEADER_SIZE sizeof(AGT_HEADER_TYPE)
27-
2824
static void ag_deserialize_composite(char *base, enum agtype_value_type type,
2925
agtype_value *result);
3026

0 commit comments

Comments
 (0)