Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions regress/age_load/data/pipe_edges.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
start_id|start_vertex_type|end_id|end_vertex_type|distance
1|City|2|City|2500
2|City|3|City|1050
4 changes: 4 additions & 0 deletions regress/age_load/data/pipe_vertices.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
id|name|country
1|Moscow|Russia
2|Berlin|Germany
3|Paris|France
19 changes: 19 additions & 0 deletions regress/sql/age_load.sql
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,25 @@ SELECT load_labels_from_file('agload_delim', 'V', 'age_load/labels_long_row.csv'

SELECT drop_graph('agload_delim', true);

--
-- Test delimiter parameter for pipe-delimited files
--
SELECT create_graph('agload_pipe');
SELECT create_vlabel('agload_pipe', 'City');
SELECT create_elabel('agload_pipe', 'Connected');

-- pipe-delimited vertex file with delimiter parameter
SELECT load_labels_from_file('agload_pipe', 'City', 'age_load/pipe_vertices.csv', true, false, '|');

-- pipe-delimited edge file with delimiter parameter
SELECT load_edges_from_file('agload_pipe', 'Connected', 'age_load/pipe_edges.csv', false, '|');

-- verify data loaded correctly
MATCH (n:City) RETURN n.name, n.country ORDER BY n.name;
MATCH (a:City)-[e:Connected]->(b:City) RETURN a.name, b.name, e.distance ORDER BY a.name;

SELECT drop_graph('agload_pipe', true);

--
-- Test security and permissions
--
Expand Down
6 changes: 4 additions & 2 deletions sql/age_main.sql
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,17 @@ CREATE FUNCTION ag_catalog.load_labels_from_file(graph_name name,
label_name name,
file_path text,
id_field_exists bool default true,
load_as_agtype bool default false)
load_as_agtype bool default false,
delimiter text default ',')
RETURNS void
LANGUAGE c
AS 'MODULE_PATHNAME';

CREATE FUNCTION ag_catalog.load_edges_from_file(graph_name name,
label_name name,
file_path text,
load_as_agtype bool default false)
load_as_agtype bool default false,
delimiter text default ',')
RETURNS void
LANGUAGE c
AS 'MODULE_PATHNAME';
Expand Down
18 changes: 15 additions & 3 deletions src/backend/utils/load/ag_load_edges.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static void process_edge_row(char **fields, int nfields,
* Create COPY options for CSV parsing.
* Returns a List of DefElem nodes.
*/
static List *create_copy_options(void)
static List *create_copy_options(char delimiter)
{
List *options = NIL;

Expand All @@ -150,6 +150,17 @@ static List *create_copy_options(void)
(Node *) makeBoolean(false),
-1));

/* DELIMITER */
{
char delimiter_str[2];
delimiter_str[0] = delimiter;
delimiter_str[1] = '\0';
options = lappend(options,
makeDefElem("delimiter",
(Node *) makeString(pstrdup(delimiter_str)),
-1));
}

return options;
}

Expand All @@ -161,7 +172,8 @@ int create_edges_from_csv_file(char *file_path,
Oid graph_oid,
char *label_name,
int label_id,
bool load_as_agtype)
bool load_as_agtype,
char delimiter)
{
Relation label_rel;
Oid label_relid;
Expand Down Expand Up @@ -196,7 +208,7 @@ int create_edges_from_csv_file(char *file_path,
init_batch_insert(&batch_state, label_name, graph_oid);

/* Create COPY options for CSV parsing */
copy_options = create_copy_options();
copy_options = create_copy_options(delimiter);

/* Create a minimal ParseState for BeginCopyFrom */
pstate = make_parsestate(NULL);
Expand Down
18 changes: 15 additions & 3 deletions src/backend/utils/load/ag_load_labels.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static void process_vertex_row(char **fields, int nfields,
* Create COPY options for csv parsing.
* Returns a List of DefElem nodes.
*/
static List *create_copy_options(void)
static List *create_copy_options(char delimiter)
{
List *options = NIL;

Expand All @@ -136,6 +136,17 @@ static List *create_copy_options(void)
(Node *) makeBoolean(false),
-1));

/* DELIMITER */
{
char delimiter_str[2];
delimiter_str[0] = delimiter;
delimiter_str[1] = '\0';
options = lappend(options,
makeDefElem("delimiter",
(Node *) makeString(pstrdup(delimiter_str)),
-1));
}

return options;
}

Expand All @@ -148,7 +159,8 @@ int create_labels_from_csv_file(char *file_path,
char *label_name,
int label_id,
bool id_field_exists,
bool load_as_agtype)
bool load_as_agtype,
char delimiter)
{
Relation label_rel;
Oid label_relid;
Expand Down Expand Up @@ -193,7 +205,7 @@ int create_labels_from_csv_file(char *file_path,
init_batch_insert(&batch_state, label_name, graph_oid);

/* Create COPY options for CSV parsing */
copy_options = create_copy_options();
copy_options = create_copy_options(delimiter);

/* Create a minimal ParseState for BeginCopyFrom */
pstate = make_parsestate(NULL);
Expand Down
41 changes: 39 additions & 2 deletions src/backend/utils/load/age_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ Datum load_labels_from_file(PG_FUNCTION_ARGS)
int32 label_id;
bool id_field_exists;
bool load_as_agtype;
char delimiter;

if (PG_ARGISNULL(0))
{
Expand Down Expand Up @@ -604,6 +605,23 @@ Datum load_labels_from_file(PG_FUNCTION_ARGS)
id_field_exists = PG_GETARG_BOOL(3);
load_as_agtype = PG_GETARG_BOOL(4);

if (PG_NARGS() > 5 && !PG_ARGISNULL(5))
{
text *delim_text = PG_GETARG_TEXT_P(5);
char *delim_str = text_to_cstring(delim_text);
if (strlen(delim_str) != 1)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("delimiter must be a single character")));
}
delimiter = delim_str[0];
}
else
{
delimiter = ',';
}

graph_name_str = NameStr(*graph_name);
label_name_str = NameStr(*label_name);

Expand All @@ -625,7 +643,7 @@ Datum load_labels_from_file(PG_FUNCTION_ARGS)

create_labels_from_csv_file(file_path_str, graph_name_str, graph_oid,
label_name_str, label_id, id_field_exists,
load_as_agtype);
load_as_agtype, delimiter);

free(file_path_str);

Expand All @@ -645,6 +663,7 @@ Datum load_edges_from_file(PG_FUNCTION_ARGS)
Oid label_relid;
int32 label_id;
bool load_as_agtype;
char delimiter;

if (PG_ARGISNULL(0))
{
Expand Down Expand Up @@ -672,6 +691,23 @@ Datum load_edges_from_file(PG_FUNCTION_ARGS)
file_name = PG_GETARG_TEXT_P(2);
load_as_agtype = PG_GETARG_BOOL(3);

if (PG_NARGS() > 4 && !PG_ARGISNULL(4))
{
text *delim_text = PG_GETARG_TEXT_P(4);
char *delim_str = text_to_cstring(delim_text);
if (strlen(delim_str) != 1)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("delimiter must be a single character")));
}
delimiter = delim_str[0];
}
else
{
delimiter = ',';
}

graph_name_str = NameStr(*graph_name);
label_name_str = NameStr(*label_name);

Expand All @@ -692,7 +728,8 @@ Datum load_edges_from_file(PG_FUNCTION_ARGS)
check_rls_for_load(label_relid);

create_edges_from_csv_file(file_path_str, graph_name_str, graph_oid,
label_name_str, label_id, load_as_agtype);
label_name_str, label_id, load_as_agtype,
delimiter);

free(file_path_str);

Expand Down
2 changes: 1 addition & 1 deletion src/include/utils/load/ag_load_edges.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@
*/
int create_edges_from_csv_file(char *file_path, char *graph_name, Oid graph_oid,
char *label_name, int label_id,
bool load_as_agtype);
bool load_as_agtype, char delimiter);

#endif /* AG_LOAD_EDGES_H */
3 changes: 2 additions & 1 deletion src/include/utils/load/ag_load_labels.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
*/
int create_labels_from_csv_file(char *file_path, char *graph_name, Oid graph_oid,
char *label_name, int label_id,
bool id_field_exists, bool load_as_agtype);
bool id_field_exists, bool load_as_agtype,
char delimiter);

#endif /* AG_LOAD_LABELS_H */