Skip to content

Commit 42ce8d9

Browse files
authored
Optmize vertex and edge builder functions (#1307)
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 4abf6eb commit 42ce8d9

File tree

4 files changed

+353
-77
lines changed

4 files changed

+353
-77
lines changed

Diff for: Makefile

+1
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 \

Diff for: src/backend/utils/adt/agtype.c

+55-77
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "utils/agtype.h"
6666
#include "utils/agtype_parser.h"
6767
#include "utils/ag_float8_supp.h"
68+
#include "utils/agtype_raw.h"
6869
#include "catalog/ag_graph.h"
6970
#include "catalog/ag_label.h"
7071
#include "utils/graphid.h"
@@ -2173,74 +2174,64 @@ PG_FUNCTION_INFO_V1(_agtype_build_vertex);
21732174
*/
21742175
Datum _agtype_build_vertex(PG_FUNCTION_ARGS)
21752176
{
2176-
agtype_in_state result;
21772177
graphid id;
2178+
char *label;
2179+
agtype *properties;
2180+
agtype_build_state *bstate;
2181+
agtype *rawscalar;
2182+
agtype *vertex;
21782183

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

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

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

2217-
//if the properties object is null, push an empty object
22182201
if (fcinfo->args[2].isnull)
22192202
{
2220-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2221-
NULL);
2222-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT,
2223-
NULL);
2203+
agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
2204+
properties = build_agtype(bstate);
2205+
pfree_agtype_build_state(bstate);
22242206
}
22252207
else
22262208
{
2227-
agtype *properties = AG_GET_ARG_AGTYPE_P(2);
2209+
properties = AG_GET_ARG_AGTYPE_P(2);
22282210

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

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

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

2243-
PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
2234+
PG_RETURN_POINTER(rawscalar);
22442235
}
22452236

22462237
Datum make_vertex(Datum id, Datum label, Datum properties)
@@ -2255,18 +2246,13 @@ PG_FUNCTION_INFO_V1(_agtype_build_edge);
22552246
*/
22562247
Datum _agtype_build_edge(PG_FUNCTION_ARGS)
22572248
{
2258-
agtype_in_state result;
2249+
agtype_build_state *bstate;
2250+
agtype *edge, *rawscalar;
22592251
graphid id, start_id, end_id;
2260-
2261-
memset(&result, 0, sizeof(agtype_in_state));
2262-
2263-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2264-
NULL);
2252+
char *label;
2253+
agtype *properties;
22652254

22662255
/* process graph id */
2267-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2268-
string_to_agtype_value("id"));
2269-
22702256
if (fcinfo->args[0].isnull)
22712257
{
22722258
ereport(ERROR,
@@ -2275,27 +2261,17 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
22752261
}
22762262

22772263
id = AG_GETARG_GRAPHID(0);
2278-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2279-
integer_to_agtype_value(id));
22802264

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

2291-
result.res =
2292-
push_agtype_value(&result.parse_state, WAGT_VALUE,
2293-
string_to_agtype_value(PG_GETARG_CSTRING(3)));
2272+
label = PG_GETARG_CSTRING(3);
22942273

22952274
/* process end_id */
2296-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2297-
string_to_agtype_value("end_id"));
2298-
22992275
if (fcinfo->args[2].isnull)
23002276
{
23012277
ereport(ERROR,
@@ -2304,13 +2280,8 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
23042280
}
23052281

23062282
end_id = AG_GETARG_GRAPHID(2);
2307-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2308-
integer_to_agtype_value(end_id));
23092283

23102284
/* process start_id */
2311-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2312-
string_to_agtype_value("start_id"));
2313-
23142285
if (fcinfo->args[1].isnull)
23152286
{
23162287
ereport(ERROR,
@@ -2319,40 +2290,47 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
23192290
}
23202291

23212292
start_id = AG_GETARG_GRAPHID(1);
2322-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2323-
integer_to_agtype_value(start_id));
23242293

23252294
/* process properties */
2326-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2327-
string_to_agtype_value("properties"));
23282295

23292296
/* if the properties object is null, push an empty object */
23302297
if (fcinfo->args[4].isnull)
23312298
{
2332-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2333-
NULL);
2334-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT,
2335-
NULL);
2299+
agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
2300+
properties = build_agtype(bstate);
2301+
pfree_agtype_build_state(bstate);
23362302
}
23372303
else
23382304
{
2339-
agtype *properties = AG_GET_ARG_AGTYPE_P(4);
2305+
properties = AG_GET_ARG_AGTYPE_P(4);
23402306

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

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

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

0 commit comments

Comments
 (0)