Skip to content

Commit 328a221

Browse files
rafsun42jrgemignani
authored andcommitted
Optmize vertex and edge builder functions (#1252)
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 81233ce commit 328a221

File tree

4 files changed

+353
-77
lines changed

4 files changed

+353
-77
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"
@@ -2181,74 +2182,64 @@ PG_FUNCTION_INFO_V1(_agtype_build_vertex);
21812182
*/
21822183
Datum _agtype_build_vertex(PG_FUNCTION_ARGS)
21832184
{
2184-
agtype_in_state result;
21852185
graphid id;
2186+
char *label;
2187+
agtype *properties;
2188+
agtype_build_state *bstate;
2189+
agtype *rawscalar;
2190+
agtype *vertex;
21862191

2187-
memset(&result, 0, sizeof(agtype_in_state));
2188-
2189-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2190-
NULL);
2191-
2192-
/* process graphid */
2193-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2194-
string_to_agtype_value("id"));
2195-
2192+
/* handles null */
21962193
if (fcinfo->args[0].isnull)
21972194
{
21982195
ereport(ERROR,
21992196
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
22002197
errmsg("_agtype_build_vertex() graphid cannot be NULL")));
22012198
}
22022199

2203-
id = AG_GETARG_GRAPHID(0);
2204-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2205-
integer_to_agtype_value(id));
2206-
2207-
/* process label */
2208-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2209-
string_to_agtype_value("label"));
2210-
22112200
if (fcinfo->args[1].isnull)
22122201
{
22132202
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
22142203
errmsg("_agtype_build_vertex() label cannot be NULL")));
22152204
}
22162205

2217-
result.res =
2218-
push_agtype_value(&result.parse_state, WAGT_VALUE,
2219-
string_to_agtype_value(PG_GETARG_CSTRING(1)));
2220-
2221-
/* process properties */
2222-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2223-
string_to_agtype_value("properties"));
2206+
id = AG_GETARG_GRAPHID(0);
2207+
label = PG_GETARG_CSTRING(1);
22242208

2225-
//if the properties object is null, push an empty object
22262209
if (fcinfo->args[2].isnull)
22272210
{
2228-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2229-
NULL);
2230-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT,
2231-
NULL);
2211+
agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
2212+
properties = build_agtype(bstate);
2213+
pfree_agtype_build_state(bstate);
22322214
}
22332215
else
22342216
{
2235-
agtype *properties = AG_GET_ARG_AGTYPE_P(2);
2217+
properties = AG_GET_ARG_AGTYPE_P(2);
22362218

22372219
if (!AGT_ROOT_IS_OBJECT(properties))
22382220
{
22392221
ereport(ERROR,
22402222
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
22412223
errmsg("_agtype_build_vertex() properties argument must be an object")));
22422224
}
2243-
2244-
add_agtype((Datum)properties, false, &result, AGTYPEOID, false);
22452225
}
22462226

2247-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);
2227+
bstate = init_agtype_build_state(3, AGT_FOBJECT);
2228+
write_string(bstate, "id");
2229+
write_string(bstate, "label");
2230+
write_string(bstate, "properties");
2231+
write_graphid(bstate, id);
2232+
write_string(bstate, label);
2233+
write_container(bstate, properties);
2234+
vertex = build_agtype(bstate);
2235+
pfree_agtype_build_state(bstate);
22482236

2249-
result.res->type = AGTV_VERTEX;
2237+
bstate = init_agtype_build_state(1, AGT_FARRAY | AGT_FSCALAR);
2238+
write_extended(bstate, vertex, AGT_HEADER_VERTEX);
2239+
rawscalar = build_agtype(bstate);
2240+
pfree_agtype_build_state(bstate);
22502241

2251-
PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
2242+
PG_RETURN_POINTER(rawscalar);
22522243
}
22532244

22542245
Datum make_vertex(Datum id, Datum label, Datum properties)
@@ -2263,18 +2254,13 @@ PG_FUNCTION_INFO_V1(_agtype_build_edge);
22632254
*/
22642255
Datum _agtype_build_edge(PG_FUNCTION_ARGS)
22652256
{
2266-
agtype_in_state result;
2257+
agtype_build_state *bstate;
2258+
agtype *edge, *rawscalar;
22672259
graphid id, start_id, end_id;
2268-
2269-
memset(&result, 0, sizeof(agtype_in_state));
2270-
2271-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2272-
NULL);
2260+
char *label;
2261+
agtype *properties;
22732262

22742263
/* process graph id */
2275-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2276-
string_to_agtype_value("id"));
2277-
22782264
if (fcinfo->args[0].isnull)
22792265
{
22802266
ereport(ERROR,
@@ -2283,27 +2269,17 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
22832269
}
22842270

22852271
id = AG_GETARG_GRAPHID(0);
2286-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2287-
integer_to_agtype_value(id));
22882272

22892273
/* process label */
2290-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2291-
string_to_agtype_value("label"));
2292-
22932274
if (fcinfo->args[3].isnull)
22942275
{
22952276
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
22962277
errmsg("_agtype_build_vertex() label cannot be NULL")));
22972278
}
22982279

2299-
result.res =
2300-
push_agtype_value(&result.parse_state, WAGT_VALUE,
2301-
string_to_agtype_value(PG_GETARG_CSTRING(3)));
2280+
label = PG_GETARG_CSTRING(3);
23022281

23032282
/* process end_id */
2304-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2305-
string_to_agtype_value("end_id"));
2306-
23072283
if (fcinfo->args[2].isnull)
23082284
{
23092285
ereport(ERROR,
@@ -2312,13 +2288,8 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
23122288
}
23132289

23142290
end_id = AG_GETARG_GRAPHID(2);
2315-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2316-
integer_to_agtype_value(end_id));
23172291

23182292
/* process start_id */
2319-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2320-
string_to_agtype_value("start_id"));
2321-
23222293
if (fcinfo->args[1].isnull)
23232294
{
23242295
ereport(ERROR,
@@ -2327,40 +2298,47 @@ Datum _agtype_build_edge(PG_FUNCTION_ARGS)
23272298
}
23282299

23292300
start_id = AG_GETARG_GRAPHID(1);
2330-
result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
2331-
integer_to_agtype_value(start_id));
23322301

23332302
/* process properties */
2334-
result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
2335-
string_to_agtype_value("properties"));
23362303

23372304
/* if the properties object is null, push an empty object */
23382305
if (fcinfo->args[4].isnull)
23392306
{
2340-
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
2341-
NULL);
2342-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT,
2343-
NULL);
2307+
agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
2308+
properties = build_agtype(bstate);
2309+
pfree_agtype_build_state(bstate);
23442310
}
23452311
else
23462312
{
2347-
agtype *properties = AG_GET_ARG_AGTYPE_P(4);
2313+
properties = AG_GET_ARG_AGTYPE_P(4);
23482314

23492315
if (!AGT_ROOT_IS_OBJECT(properties))
23502316
{
23512317
ereport(ERROR,
23522318
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
23532319
errmsg("_agtype_build_edge() properties argument must be an object")));
23542320
}
2355-
2356-
add_agtype((Datum)properties, false, &result, AGTYPEOID, false);
23572321
}
23582322

2359-
result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);
2360-
2361-
result.res->type = AGTV_EDGE;
2362-
2363-
PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
2323+
bstate = init_agtype_build_state(5, AGT_FOBJECT);
2324+
write_string(bstate, "id");
2325+
write_string(bstate, "label");
2326+
write_string(bstate, "end_id");
2327+
write_string(bstate, "start_id");
2328+
write_string(bstate, "properties");
2329+
write_graphid(bstate, id);
2330+
write_string(bstate, label);
2331+
write_graphid(bstate, end_id);
2332+
write_graphid(bstate, start_id);
2333+
write_container(bstate, properties);
2334+
edge = build_agtype(bstate);
2335+
pfree_agtype_build_state(bstate);
2336+
2337+
bstate = init_agtype_build_state(1, AGT_FARRAY | AGT_FSCALAR);
2338+
write_extended(bstate, edge, AGT_HEADER_EDGE);
2339+
rawscalar = build_agtype(bstate);
2340+
pfree_agtype_build_state(bstate);
2341+
PG_RETURN_POINTER(rawscalar);
23642342
}
23652343

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

0 commit comments

Comments
 (0)