Add index on id columns (#2117)

- Whenever a label will be created, indices on id columns will be
  created by default. In case of vertex, a unique index on id column
  will be created, which will also serve as a unique constraint.
  In case of edge, a non-unique index on start_id and end_id columns
  will be created.

- This change is expected to improve the performance of queries that
  involve joins. From some performance tests, it was observed that
  the performance of queries improved alot.

- Loader was updated to insert tuples in indices as well. This has
  caused to slow the loader down a bit, but it was necessary.

- A bug related to command ids in cypher_delete executor was also fixed.
diff --git a/regress/expected/age_load.out b/regress/expected/age_load.out
index b638e63..5f2bdab 100644
--- a/regress/expected/age_load.out
+++ b/regress/expected/age_load.out
@@ -43,13 +43,6 @@
  
 (1 row)
 
--- A temporary table should have been created with 54 ids; 1 from CREATE and 53 from file
-SELECT COUNT(*)=54 FROM "_agload_test_graph_ag_vertex_ids";
- ?column? 
-----------
- t
-(1 row)
-
 -- Sequence should be equal to max entry id i.e. 248
 SELECT currval('agload_test_graph."Country_id_seq"')=248;
  ?column? 
@@ -74,13 +67,6 @@
  
 (1 row)
 
--- Temporary table should have 54+72485 rows now
-SELECT COUNT(*)=54+72485 FROM "_agload_test_graph_ag_vertex_ids";
- ?column? 
-----------
- t
-(1 row)
-
 -- Sequence should be equal to max entry id i.e. 146941
 SELECT currval('agload_test_graph."City_id_seq"')=146941;
  ?column? 
diff --git a/regress/expected/cypher_match.out b/regress/expected/cypher_match.out
index e83ba3b..72ca1cd 100644
--- a/regress/expected/cypher_match.out
+++ b/regress/expected/cypher_match.out
@@ -79,8 +79,8 @@
 $$) AS (a agtype);
                                                                                                                                                                                                                                                        a                                                                                                                                                                                                                                                       
 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path
  [{"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex]::path
+ [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -88,8 +88,8 @@
 $$) AS (a agtype);
                                         a                                         
 ----------------------------------------------------------------------------------
- {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
  {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
+ {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -97,8 +97,8 @@
 $$) AS (a agtype);
                                         a                                         
 ----------------------------------------------------------------------------------
- {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
  {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
+ {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -115,8 +115,8 @@
 $$) AS (a agtype);
                                                              a                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -132,10 +132,10 @@
 $$) AS (a agtype);
                                                              a                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
- {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
  {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
 (4 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -143,10 +143,10 @@
 $$) AS (a agtype);
                                                              a                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
- {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
  {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
 (4 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -154,10 +154,10 @@
 $$) AS (a agtype);
                                                              a                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
- {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
  {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
 (4 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -165,8 +165,8 @@
 $$) AS (a agtype);
                                                              a                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -174,8 +174,8 @@
 $$) AS (a agtype);
                                         a                                         
 ----------------------------------------------------------------------------------
- {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
  {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
+ {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
 (2 rows)
 
 -- Right Path Test
@@ -250,8 +250,8 @@
 $$) AS (a agtype);
                                                              a                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
 (2 rows)
 
 --Left Path Test
@@ -308,8 +308,8 @@
 $$) AS (a agtype);
                                                              a                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
 (2 rows)
 
 --Divergent Path Tests
@@ -412,8 +412,8 @@
 $$) AS (i agtype);
                                                              i                                                             
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge
  {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge
+ {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -712,8 +712,8 @@
  {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
  {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge
  {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge
- {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge
  {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge
+ {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge
 (6 rows)
 
 SELECT * FROM cypher('cypher_match', $$
@@ -775,8 +775,8 @@
  {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge
  {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge
  {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge
- {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge
  {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge
+ {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge
  {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge
 (12 rows)
 
@@ -1055,8 +1055,8 @@
  {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex  | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex  | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex  | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex
- {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
  {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex     | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
+ {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
 (6 rows)
 
 SELECT * FROM cypher('cypher_match',
@@ -1068,8 +1068,8 @@
  {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex  | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex  | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex  | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex
- {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
  {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex     | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
+ {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
 (6 rows)
 
 -- Property Constraint in EXISTS
@@ -1123,8 +1123,8 @@
  {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex    | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge   | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex    | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge   | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex    | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge   | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex
- {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex   | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge   | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
  {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex       | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge   | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
+ {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex   | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge   | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
  {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex | {"id": 3096224743817217, "label": "self", "end_id": 2814749767106561, "start_id": 2814749767106561, "properties": {}}::edge | {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex
 (7 rows)
 
@@ -1156,8 +1156,8 @@
  {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex    | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge   | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex    | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge   | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex
  {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex    | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge   | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex
- {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex   | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge   | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
  {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex       | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge   | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
+ {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex   | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge   | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex
  {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex | {"id": 3096224743817217, "label": "self", "end_id": 2814749767106561, "start_id": 2814749767106561, "properties": {}}::edge | {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex
 (7 rows)
 
@@ -2164,8 +2164,8 @@
                                                                                                                                                                                                                                                     p                                                                                                                                                                                                                                                     
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  [{"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex, {"id": 4785074604081155, "label": "knows", "end_id": 281474976710667, "start_id": 281474976710668, "properties": {}}::edge, {"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex, {"id": 4785074604081156, "label": "knows", "end_id": 281474976710668, "start_id": 281474976710667, "properties": {}}::edge, {"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex]::path
- [{"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex, {"id": 4785074604081155, "label": "knows", "end_id": 281474976710667, "start_id": 281474976710668, "properties": {}}::edge, {"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex, {"id": 4785074604081156, "label": "knows", "end_id": 281474976710668, "start_id": 281474976710667, "properties": {}}::edge, {"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex]::path
  [{"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex, {"id": 4785074604081156, "label": "knows", "end_id": 281474976710668, "start_id": 281474976710667, "properties": {}}::edge, {"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex, {"id": 4785074604081155, "label": "knows", "end_id": 281474976710667, "start_id": 281474976710668, "properties": {}}::edge, {"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex]::path
+ [{"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex, {"id": 4785074604081155, "label": "knows", "end_id": 281474976710667, "start_id": 281474976710668, "properties": {}}::edge, {"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex, {"id": 4785074604081156, "label": "knows", "end_id": 281474976710668, "start_id": 281474976710667, "properties": {}}::edge, {"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex]::path
  [{"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex, {"id": 4785074604081156, "label": "knows", "end_id": 281474976710668, "start_id": 281474976710667, "properties": {}}::edge, {"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex, {"id": 4785074604081155, "label": "knows", "end_id": 281474976710667, "start_id": 281474976710668, "properties": {}}::edge, {"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex]::path
 (4 rows)
 
@@ -2407,15 +2407,15 @@
 SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship: u.relationship}]->(b) RETURN p $$) as (a agtype);
                                                                                                                                                                      a                                                                                                                                                                     
 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
  [{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
+ [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship: u.relationship, years: u.years}]->(b) RETURN p $$) as (a agtype);
                                                                                                                                                                      a                                                                                                                                                                     
 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
  [{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
+ [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
 (2 rows)
 
 SELECT * FROM cypher('cypher_match', $$ MATCH p=(a {name:a.name})-[u {relationship: u.relationship}]->(b {age:b.age}) RETURN p $$) as (a agtype);
@@ -3514,19 +3514,17 @@
 (1 row)
 
 SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (costs off) MATCH (x:Customer)-[:bought ={store: 'Amazon', addr:{city: 'Vancouver', street: 30}}]->(y:Product) RETURN 0 $$) as (a agtype);
-                                                                                                                         QUERY PLAN                                                                                                                          
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- Hash Join
-   Hash Cond: (y.id = _age_default_alias_0.end_id)
-   ->  Seq Scan on "Product" y
-   ->  Hash
-         ->  Hash Join
-               Hash Cond: (x.id = _age_default_alias_0.start_id)
-               ->  Seq Scan on "Customer" x
-               ->  Hash
-                     ->  Seq Scan on bought _age_default_alias_0
-                           Filter: ((agtype_access_operator(VARIADIC ARRAY[properties, '"store"'::agtype]) = '"Amazon"'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"addr"'::agtype]) = '{"city": "Vancouver", "street": 30}'::agtype))
-(10 rows)
+                                                                                                                   QUERY PLAN                                                                                                                    
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Nested Loop
+   ->  Nested Loop
+         ->  Seq Scan on bought _age_default_alias_0
+               Filter: ((agtype_access_operator(VARIADIC ARRAY[properties, '"store"'::agtype]) = '"Amazon"'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"addr"'::agtype]) = '{"city": "Vancouver", "street": 30}'::agtype))
+         ->  Index Only Scan using "Customer_pkey" on "Customer" x
+               Index Cond: (id = _age_default_alias_0.start_id)
+   ->  Index Only Scan using "Product_pkey" on "Product" y
+         Index Cond: (id = _age_default_alias_0.end_id)
+(8 rows)
 
 SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (costs off) MATCH (x:Customer ={school: { name: 'XYZ College',program: { major: 'Psyc', degree: 'BSc'} },phone: [ 123456789, 987654321, 456987123 ]}) RETURN 0 $$) as (a agtype);
                                                                                                                                             QUERY PLAN                                                                                                                                             
diff --git a/regress/expected/cypher_merge.out b/regress/expected/cypher_merge.out
index 238a4c4..56a23f5 100644
--- a/regress/expected/cypher_merge.out
+++ b/regress/expected/cypher_merge.out
@@ -655,8 +655,8 @@
        name        |    bornin    |                                          city                                           
 -------------------+--------------+-----------------------------------------------------------------------------------------
  "Rob Reiner"      | "New York"   | {"id": 1970324836974593, "label": "City", "properties": {"name": "New York"}}::vertex
- "Martin Sheen"    | "Ohio"       | {"id": 1970324836974595, "label": "City", "properties": {"name": "Ohio"}}::vertex
  "Michael Douglas" | "New Jersey" | {"id": 1970324836974594, "label": "City", "properties": {"name": "New Jersey"}}::vertex
+ "Martin Sheen"    | "Ohio"       | {"id": 1970324836974595, "label": "City", "properties": {"name": "Ohio"}}::vertex
 (3 rows)
 
 --validate
diff --git a/regress/expected/cypher_subquery.out b/regress/expected/cypher_subquery.out
index ff5672b..934549f 100644
--- a/regress/expected/cypher_subquery.out
+++ b/regress/expected/cypher_subquery.out
@@ -668,8 +668,8 @@
 									RETURN a $$) AS (result agtype);
                                              result                                              
 -------------------------------------------------------------------------------------------------
- {"id": 844424930131975, "label": "person", "properties": {"age": 6, "name": "Calvin"}}::vertex
  {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex
+ {"id": 844424930131975, "label": "person", "properties": {"age": 6, "name": "Calvin"}}::vertex
  {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex
 (3 rows)
 
diff --git a/regress/expected/cypher_vle.out b/regress/expected/cypher_vle.out
index 9cbb342..57f930d 100644
--- a/regress/expected/cypher_vle.out
+++ b/regress/expected/cypher_vle.out
@@ -508,37 +508,37 @@
 SELECT * FROM cypher('cypher_vle', $$MATCH p=()-[*0..0]->()-[]->() RETURN p $$) AS (p agtype);
                                                                                                                                                                                                      p                                                                                                                                                                                                     
 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2251799813685249, "label": "alternate_edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "alternate edge", "number": 1, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path
  [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 1125899906842628, "label": "edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "main edge", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
- [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842627, "label": "edge", "end_id": 1407374883553282, "start_id": 1407374883553281, "properties": {"name": "main edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1970324836974593, "label": "self_loop", "end_id": 1407374883553281, "start_id": 1407374883553281, "properties": {"name": "self loop", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2251799813685249, "label": "alternate_edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "alternate edge", "number": 1, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842627, "label": "edge", "end_id": 1407374883553282, "start_id": 1407374883553281, "properties": {"name": "main edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842626, "label": "edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "main edge", "number": 3, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685250, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "alternate edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path
- [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395905, "label": "bypass_edge", "end_id": 1688849860263937, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
- [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path
- [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842625, "label": "edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "main edge", "number": 4, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
- [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path
- [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685251, "label": "alternate_edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "alternate edge", "number": 3, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
  [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685251, "label": "alternate_edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "alternate edge", "number": 3, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
+ [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395905, "label": "bypass_edge", "end_id": 1688849860263937, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
  [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
+ [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842625, "label": "edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "main edge", "number": 4, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
 (13 rows)
 
 SELECT * FROM cypher('cypher_vle', $$MATCH p=()-[]->()-[*0..0]->() RETURN p $$) AS (p agtype);
                                                                                                                                                                                                      p                                                                                                                                                                                                     
 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path
- [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2251799813685249, "label": "alternate_edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "alternate edge", "number": 1, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 1125899906842628, "label": "edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "main edge", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2251799813685249, "label": "alternate_edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "alternate edge", "number": 1, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1970324836974593, "label": "self_loop", "end_id": 1407374883553281, "start_id": 1407374883553281, "properties": {"name": "self loop", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path
- [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842627, "label": "edge", "end_id": 1407374883553282, "start_id": 1407374883553281, "properties": {"name": "main edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path
- [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842626, "label": "edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "main edge", "number": 3, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685250, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "alternate edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path
  [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395905, "label": "bypass_edge", "end_id": 1688849860263937, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
- [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
+ [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path
  [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842625, "label": "edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "main edge", "number": 4, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
  [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685251, "label": "alternate_edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "alternate edge", "number": 3, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
+ [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path
+ [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path
 (13 rows)
 
 --
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 513ea14..d0546d8 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -2644,10 +2644,10 @@
 SELECT * FROM cypher('expr', $$ MATCH ()-[e]-() RETURN e $$) AS (expression agtype);
                                                         expression                                                         
 ---------------------------------------------------------------------------------------------------------------------------
- {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
- {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
  {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
  {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
 (4 rows)
 
 -- id()
@@ -2656,10 +2656,10 @@
 $$) AS (id agtype);
         id        
 ------------------
- 1407374883553281
- 1407374883553281
  1407374883553282
  1407374883553282
+ 1407374883553281
+ 1407374883553281
 (4 rows)
 
 SELECT * FROM cypher('expr', $$
@@ -2698,10 +2698,10 @@
 $$) AS (start_id agtype);
      start_id     
 ------------------
- 1125899906842626
- 1125899906842626
  1125899906842625
  1125899906842625
+ 1125899906842626
+ 1125899906842626
 (4 rows)
 
 -- should return null
@@ -2731,10 +2731,10 @@
 $$) AS (end_id agtype);
       end_id      
 ------------------
- 1125899906842627
- 1125899906842627
  1125899906842626
  1125899906842626
+ 1125899906842627
+ 1125899906842627
 (4 rows)
 
 -- should return null
@@ -2764,10 +2764,10 @@
 $$) AS (id agtype, start_id agtype, startNode agtype);
         id        |     start_id     |                                    startnode                                     
 ------------------+------------------+----------------------------------------------------------------------------------
- 1407374883553281 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
- 1407374883553281 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
  1407374883553282 | 1125899906842625 | {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
  1407374883553282 | 1125899906842625 | {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
+ 1407374883553281 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
+ 1407374883553281 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
 (4 rows)
 
 -- should return null
@@ -2797,10 +2797,10 @@
 $$) AS (id agtype, end_id agtype, endNode agtype);
         id        |      end_id      |                                     endnode                                     
 ------------------+------------------+---------------------------------------------------------------------------------
- 1407374883553281 | 1125899906842627 | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
- 1407374883553281 | 1125899906842627 | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
  1407374883553282 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
  1407374883553282 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
+ 1407374883553281 | 1125899906842627 | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
+ 1407374883553281 | 1125899906842627 | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
 (4 rows)
 
 -- should return null
@@ -7496,10 +7496,10 @@
 SELECT * FROM cypher('opt_forms', $$MATCH (u)--(v) RETURN u.i, v.i$$) AS (u agtype, v agtype);
  u | v 
 ---+---
- 2 | 3
- 3 | 2
  1 | 2
  2 | 1
+ 2 | 3
+ 3 | 2
 (4 rows)
 
 SELECT * FROM cypher('opt_forms', $$MATCH (u)-->(v) RETURN u.i, v.i$$) AS (u agtype, v agtype);
@@ -7686,12 +7686,12 @@
 SELECT * FROM cypher('keys', $$MATCH ()-[e]-() RETURN keys(e)$$) AS (edge_keys agtype);
  edge_keys 
 -----------
- []
+ ["song"]
+ ["song"]
  []
  ["song"]
  ["song"]
- ["song"]
- ["song"]
+ []
 (6 rows)
 
 SELECT * FROM cypher('keys', $$RETURN keys({a:1,b:'two',c:[1,2,3]})$$) AS (keys agtype);
diff --git a/regress/expected/graph_generation.out b/regress/expected/graph_generation.out
index 235052a..ca511ea 100644
--- a/regress/expected/graph_generation.out
+++ b/regress/expected/graph_generation.out
@@ -43,15 +43,15 @@
                                                              n                                                              
 ----------------------------------------------------------------------------------------------------------------------------
  {"id": 1125899906842625, "label": "edges", "end_id": 844424930131970, "start_id": 844424930131969, "properties": {}}::edge
- {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge
  {"id": 1125899906842626, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131969, "properties": {}}::edge
- {"id": 1125899906842630, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131970, "properties": {}}::edge
+ {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge
  {"id": 1125899906842627, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131969, "properties": {}}::edge
+ {"id": 1125899906842630, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131970, "properties": {}}::edge
  {"id": 1125899906842632, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131971, "properties": {}}::edge
- {"id": 1125899906842631, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131970, "properties": {}}::edge
- {"id": 1125899906842634, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131972, "properties": {}}::edge
- {"id": 1125899906842633, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131971, "properties": {}}::edge
  {"id": 1125899906842628, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131969, "properties": {}}::edge
+ {"id": 1125899906842631, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131970, "properties": {}}::edge
+ {"id": 1125899906842633, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131971, "properties": {}}::edge
+ {"id": 1125899906842634, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131972, "properties": {}}::edge
 (10 rows)
 
 SELECT * FROM create_complete_graph('gp1',5,'edges','vertices');
@@ -140,25 +140,25 @@
                                                              n                                                              
 ----------------------------------------------------------------------------------------------------------------------------
  {"id": 1125899906842625, "label": "edges", "end_id": 844424930131970, "start_id": 844424930131969, "properties": {}}::edge
- {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge
  {"id": 1125899906842626, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131969, "properties": {}}::edge
+ {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge
  {"id": 1125899906842627, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131969, "properties": {}}::edge
- {"id": 1125899906842632, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131971, "properties": {}}::edge
  {"id": 1125899906842630, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131970, "properties": {}}::edge
- {"id": 1125899906842634, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131972, "properties": {}}::edge
+ {"id": 1125899906842632, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131971, "properties": {}}::edge
  {"id": 1125899906842628, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131969, "properties": {}}::edge
  {"id": 1125899906842631, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131970, "properties": {}}::edge
  {"id": 1125899906842633, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131971, "properties": {}}::edge
+ {"id": 1125899906842634, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131972, "properties": {}}::edge
  {"id": 1125899906842635, "label": "edges", "end_id": 844424930131975, "start_id": 844424930131974, "properties": {}}::edge
- {"id": 1125899906842639, "label": "edges", "end_id": 844424930131976, "start_id": 844424930131975, "properties": {}}::edge
  {"id": 1125899906842636, "label": "edges", "end_id": 844424930131976, "start_id": 844424930131974, "properties": {}}::edge
+ {"id": 1125899906842639, "label": "edges", "end_id": 844424930131976, "start_id": 844424930131975, "properties": {}}::edge
  {"id": 1125899906842637, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131974, "properties": {}}::edge
- {"id": 1125899906842642, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131976, "properties": {}}::edge
  {"id": 1125899906842640, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131975, "properties": {}}::edge
- {"id": 1125899906842644, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131977, "properties": {}}::edge
+ {"id": 1125899906842642, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131976, "properties": {}}::edge
  {"id": 1125899906842638, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131974, "properties": {}}::edge
  {"id": 1125899906842641, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131975, "properties": {}}::edge
  {"id": 1125899906842643, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131976, "properties": {}}::edge
+ {"id": 1125899906842644, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131977, "properties": {}}::edge
  {"id": 1125899906842645, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131969, "properties": {}}::edge
 (21 rows)
 
diff --git a/regress/expected/index.out b/regress/expected/index.out
index f911900..3ed7b1c 100644
--- a/regress/expected/index.out
+++ b/regress/expected/index.out
@@ -264,18 +264,22 @@
 ---
 (0 rows)
 
-ALTER TABLE cypher_index."Country" ADD PRIMARY KEY (id);
-CREATE UNIQUE INDEX CONCURRENTLY cntry_id_idx ON cypher_index."Country" (id);
-ALTER TABLE cypher_index."Country"  CLUSTER ON cntry_id_idx;
-ALTER TABLE cypher_index."City" ADD PRIMARY KEY (id);
-CREATE UNIQUE INDEX city_id_idx ON cypher_index."City" (id);
-ALTER TABLE cypher_index."City" CLUSTER ON city_id_idx;
-ALTER TABLE cypher_index.has_city
-ADD CONSTRAINT has_city_end_fk FOREIGN KEY (end_id)
-REFERENCES cypher_index."Country"(id) MATCH FULL;
-CREATE INDEX load_has_city_eid_idx ON cypher_index.has_city (end_id);
-CREATE INDEX load_has_city_sid_idx ON cypher_index.has_city (start_id);
-ALTER TABLE cypher_index."has_city" CLUSTER ON load_has_city_eid_idx;
+-- Verify that the incices are created on id columns
+SELECT indexname, indexdef FROM pg_indexes WHERE schemaname= 'cypher_index';
+          indexname          |                                            indexdef                                            
+-----------------------------+------------------------------------------------------------------------------------------------
+ _ag_label_edge_pkey         | CREATE UNIQUE INDEX _ag_label_edge_pkey ON cypher_index._ag_label_edge USING btree (id)
+ _ag_label_edge_start_id_idx | CREATE INDEX _ag_label_edge_start_id_idx ON cypher_index._ag_label_edge USING btree (start_id)
+ _ag_label_edge_end_id_idx   | CREATE INDEX _ag_label_edge_end_id_idx ON cypher_index._ag_label_edge USING btree (end_id)
+ _ag_label_vertex_pkey       | CREATE UNIQUE INDEX _ag_label_vertex_pkey ON cypher_index._ag_label_vertex USING btree (id)
+ idx_pkey                    | CREATE UNIQUE INDEX idx_pkey ON cypher_index.idx USING btree (id)
+ cypher_index_idx_props_uq   | CREATE UNIQUE INDEX cypher_index_idx_props_uq ON cypher_index.idx USING btree (properties)
+ Country_pkey                | CREATE UNIQUE INDEX "Country_pkey" ON cypher_index."Country" USING btree (id)
+ has_city_start_id_idx       | CREATE INDEX has_city_start_id_idx ON cypher_index.has_city USING btree (start_id)
+ has_city_end_id_idx         | CREATE INDEX has_city_end_id_idx ON cypher_index.has_city USING btree (end_id)
+ City_pkey                   | CREATE UNIQUE INDEX "City_pkey" ON cypher_index."City" USING btree (id)
+(10 rows)
+
 SET enable_mergejoin = ON;
 SET enable_hashjoin = OFF;
 SET enable_nestloop = OFF;
@@ -288,6 +292,29 @@
     10
 (1 row)
 
+SELECT COUNT(*) FROM cypher('cypher_index', $$
+    EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-()
+    RETURN e
+$$) as (n agtype);
+                                                QUERY PLAN                                                
+----------------------------------------------------------------------------------------------------------
+ Aggregate
+   ->  Merge Join
+         Merge Cond: (_age_default_alias_0.id = e.start_id)
+         ->  Merge Append
+               Sort Key: _age_default_alias_0.id
+               ->  Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0_1
+               ->  Index Only Scan using idx_pkey on idx _age_default_alias_0_2
+               ->  Index Only Scan using "Country_pkey" on "Country" _age_default_alias_0_3
+               ->  Index Only Scan using "City_pkey" on "City" _age_default_alias_0_4
+         ->  Sort
+               Sort Key: e.start_id
+               ->  Merge Join
+                     Merge Cond: (a.id = e.end_id)
+                     ->  Index Only Scan using "Country_pkey" on "Country" a
+                     ->  Index Scan using has_city_end_id_idx on has_city e
+(15 rows)
+
 SET enable_mergejoin = OFF;
 SET enable_hashjoin = ON;
 SET enable_nestloop = OFF;
@@ -300,17 +327,53 @@
     10
 (1 row)
 
+SELECT COUNT(*) FROM cypher('cypher_index', $$
+    EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-()
+    RETURN e
+$$) as (n agtype);
+                                                QUERY PLAN                                                
+----------------------------------------------------------------------------------------------------------
+ Aggregate
+   ->  Hash Join
+         Hash Cond: (_age_default_alias_0.id = e.start_id)
+         ->  Append
+               ->  Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0_1
+               ->  Index Only Scan using idx_pkey on idx _age_default_alias_0_2
+               ->  Index Only Scan using "Country_pkey" on "Country" _age_default_alias_0_3
+               ->  Index Only Scan using "City_pkey" on "City" _age_default_alias_0_4
+         ->  Hash
+               ->  Hash Join
+                     Hash Cond: (e.end_id = a.id)
+                     ->  Index Scan using has_city_end_id_idx on has_city e
+                     ->  Hash
+                           ->  Index Only Scan using "Country_pkey" on "Country" a
+(14 rows)
+
 SET enable_mergejoin = OFF;
 SET enable_hashjoin = OFF;
 SET enable_nestloop = ON;
 SELECT COUNT(*) FROM cypher('cypher_index', $$
-    MATCH (a:Country)<-[e:has_city]-()
+    EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-()
     RETURN e
 $$) as (n agtype);
- count 
--------
-    10
-(1 row)
+                                                QUERY PLAN                                                
+----------------------------------------------------------------------------------------------------------
+ Aggregate
+   ->  Nested Loop
+         ->  Nested Loop
+               ->  Index Scan using has_city_start_id_idx on has_city e
+               ->  Index Only Scan using "Country_pkey" on "Country" a
+                     Index Cond: (id = e.end_id)
+         ->  Append
+               ->  Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0_1
+                     Index Cond: (id = e.start_id)
+               ->  Index Only Scan using idx_pkey on idx _age_default_alias_0_2
+                     Index Cond: (id = e.start_id)
+               ->  Index Only Scan using "Country_pkey" on "Country" _age_default_alias_0_3
+                     Index Cond: (id = e.start_id)
+               ->  Index Only Scan using "City_pkey" on "City" _age_default_alias_0_4
+                     Index Cond: (id = e.start_id)
+(15 rows)
 
 SET enable_mergejoin = ON;
 SET enable_hashjoin = ON;
diff --git a/regress/expected/map_projection.out b/regress/expected/map_projection.out
index dcb7f0e..f0c45c5 100644
--- a/regress/expected/map_projection.out
+++ b/regress/expected/map_projection.out
@@ -152,7 +152,7 @@
 $$) as (a agtype);
                                                                                                       a                                                                                                       
 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- [{"name": "Christian Bale", "movies": [{"title": "The Prestige"}, {"title": "The Dark Knight"}]}, {"name": "Tom Hanks", "movies": [{"title": "Forrest Gump"}, {"title": "Finch"}, {"title": "The Circle"}]}]
+ [{"name": "Tom Hanks", "movies": [{"title": "Forrest Gump"}, {"title": "Finch"}, {"title": "The Circle"}]}, {"name": "Christian Bale", "movies": [{"title": "The Prestige"}, {"title": "The Dark Knight"}]}]
 (1 row)
 
 -- drop
diff --git a/regress/sql/age_load.sql b/regress/sql/age_load.sql
index 425ca54..180248b 100644
--- a/regress/sql/age_load.sql
+++ b/regress/sql/age_load.sql
@@ -34,9 +34,6 @@
 SELECT load_labels_from_file('agload_test_graph', 'Country',
     'age_load/countries.csv', true);
 
--- A temporary table should have been created with 54 ids; 1 from CREATE and 53 from file
-SELECT COUNT(*)=54 FROM "_agload_test_graph_ag_vertex_ids";
-
 -- Sequence should be equal to max entry id i.e. 248
 SELECT currval('agload_test_graph."Country_id_seq"')=248;
 
@@ -52,9 +49,6 @@
 SELECT load_labels_from_file('agload_test_graph', 'City',
     'age_load/cities.csv', true);
 
--- Temporary table should have 54+72485 rows now
-SELECT COUNT(*)=54+72485 FROM "_agload_test_graph_ag_vertex_ids";
-
 -- Sequence should be equal to max entry id i.e. 146941
 SELECT currval('agload_test_graph."City_id_seq"')=146941;
 
diff --git a/regress/sql/index.sql b/regress/sql/index.sql
index aac1dc4..d9a4331 100644
--- a/regress/sql/index.sql
+++ b/regress/sql/index.sql
@@ -166,26 +166,8 @@
         (mx)<-[:has_city]-(:City {city_id: 10, name:"Tijuana", west_coast: false, country_code:"MX"})
 $$) as (n agtype);
 
-ALTER TABLE cypher_index."Country" ADD PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX CONCURRENTLY cntry_id_idx ON cypher_index."Country" (id);
-ALTER TABLE cypher_index."Country"  CLUSTER ON cntry_id_idx;
-
-ALTER TABLE cypher_index."City" ADD PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX city_id_idx ON cypher_index."City" (id);
-
-ALTER TABLE cypher_index."City" CLUSTER ON city_id_idx;
-
-ALTER TABLE cypher_index.has_city
-ADD CONSTRAINT has_city_end_fk FOREIGN KEY (end_id)
-REFERENCES cypher_index."Country"(id) MATCH FULL;
-
-CREATE INDEX load_has_city_eid_idx ON cypher_index.has_city (end_id);
-
-CREATE INDEX load_has_city_sid_idx ON cypher_index.has_city (start_id);
-
-ALTER TABLE cypher_index."has_city" CLUSTER ON load_has_city_eid_idx;
+-- Verify that the incices are created on id columns
+SELECT indexname, indexdef FROM pg_indexes WHERE schemaname= 'cypher_index';
 
 SET enable_mergejoin = ON;
 SET enable_hashjoin = OFF;
@@ -196,6 +178,11 @@
     RETURN e
 $$) as (n agtype);
 
+SELECT COUNT(*) FROM cypher('cypher_index', $$
+    EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-()
+    RETURN e
+$$) as (n agtype);
+
 SET enable_mergejoin = OFF;
 SET enable_hashjoin = ON;
 SET enable_nestloop = OFF;
@@ -205,12 +192,17 @@
     RETURN e
 $$) as (n agtype);
 
+SELECT COUNT(*) FROM cypher('cypher_index', $$
+    EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-()
+    RETURN e
+$$) as (n agtype);
+
 SET enable_mergejoin = OFF;
 SET enable_hashjoin = OFF;
 SET enable_nestloop = ON;
 
 SELECT COUNT(*) FROM cypher('cypher_index', $$
-    MATCH (a:Country)<-[e:has_city]-()
+    EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-()
     RETURN e
 $$) as (n agtype);
 
diff --git a/src/backend/commands/label_commands.c b/src/backend/commands/label_commands.c
index f603ec9..c9fdfad 100644
--- a/src/backend/commands/label_commands.c
+++ b/src/backend/commands/label_commands.c
@@ -79,6 +79,10 @@
                                                    Oid rel_oid,
                                                    Oid odl_rel_oid,
                                                    void *arg);
+static void create_index_on_column(char *schema_name,
+                                   char *rel_name,
+                                   char *colname,
+                                   bool unique);
 
 PG_FUNCTION_INFO_V1(age_is_valid_label_name);
 
@@ -379,16 +383,24 @@
      * inheritance system.
      */
     if (list_length(parents) != 0)
+    {
         create_stmt->tableElts = NIL;
+    }
     else if (label_type == LABEL_TYPE_EDGE)
+    {
         create_stmt->tableElts = create_edge_table_elements(
             graph_name, label_name, schema_name, rel_name, seq_name);
+    }
     else if (label_type == LABEL_TYPE_VERTEX)
+    {
         create_stmt->tableElts = create_vertex_table_elements(
             graph_name, label_name, schema_name, rel_name, seq_name);
+    }
     else
+    {
         ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
                         errmsg("undefined label type \'%c\'", label_type)));
+    }
 
     create_stmt->inhRelations = parents;
     create_stmt->partbound = NULL;
@@ -409,7 +421,69 @@
     ProcessUtility(wrapper, "(generated CREATE TABLE command)", false,
                    PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, None_Receiver,
                    NULL);
-    /* CommandCounterIncrement() is called in ProcessUtility() */
+    
+    /* Create index on id columns */
+    if (label_type == LABEL_TYPE_VERTEX)
+    {
+        create_index_on_column(schema_name, rel_name, "id", true);
+    }
+    else if (label_type == LABEL_TYPE_EDGE)
+    {
+        create_index_on_column(schema_name, rel_name, "start_id", false);
+        create_index_on_column(schema_name, rel_name, "end_id", false);
+    }
+}
+
+static void create_index_on_column(char *schema_name,
+                                   char *rel_name,
+                                   char *colname,
+                                   bool unique)
+{
+    IndexStmt *index_stmt;
+    IndexElem *index_col;
+    PlannedStmt *index_wrapper;
+
+    index_stmt = makeNode(IndexStmt);
+    index_col = makeNode(IndexElem);
+    index_col->name = colname;
+    index_col->expr = NULL;
+    index_col->indexcolname = NULL;
+    index_col->collation = InvalidOid;
+    index_col->opclass = list_make1(makeString("graphid_ops"));
+    index_col->opclassopts = NIL;
+    index_col->ordering = SORTBY_DEFAULT;
+    index_col->nulls_ordering = SORTBY_NULLS_DEFAULT;
+
+    index_stmt->relation = makeRangeVar(schema_name, rel_name, -1);
+    index_stmt->accessMethod = "btree";
+    index_stmt->tableSpace = NULL;
+    index_stmt->indexParams = list_make1(index_col);
+    index_stmt->options = NIL;
+    index_stmt->whereClause = NULL;
+    index_stmt->excludeOpNames = NIL;
+    index_stmt->idxcomment = NULL;
+    index_stmt->indexOid = InvalidOid;
+    index_stmt->unique = unique;
+    index_stmt->nulls_not_distinct = false;
+    index_stmt->primary = unique;
+    index_stmt->isconstraint = unique;
+    index_stmt->deferrable = false;
+    index_stmt->initdeferred = false;
+    index_stmt->transformed = false;
+    index_stmt->concurrent = false;
+    index_stmt->if_not_exists = false;
+    index_stmt->reset_default_tblspc = false;
+
+    index_wrapper = makeNode(PlannedStmt);
+    index_wrapper->commandType = CMD_UTILITY;
+    index_wrapper->canSetTag = false;
+    index_wrapper->utilityStmt = (Node *)index_stmt;
+    index_wrapper->stmt_location = -1;
+    index_wrapper->stmt_len = 0;
+
+    ProcessUtility(index_wrapper, "(generated CREATE INDEX command)", false,
+                   PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, None_Receiver,
+                   NULL);
 }
 
 /* 
@@ -468,7 +542,7 @@
 
     /* "id" graphid PRIMARY KEY DEFAULT "ag_catalog"."_graphid"(...) */
     id = makeColumnDef(AG_VERTEX_COLNAME_ID, GRAPHIDOID, -1, InvalidOid);
-    id->constraints = list_make2(build_pk_constraint(),
+    id->constraints = list_make2(build_not_null_constraint(),
                                  build_id_default(graph_name, label_name,
                                                   schema_name, seq_name));
 
diff --git a/src/backend/executor/cypher_delete.c b/src/backend/executor/cypher_delete.c
index 6bb8698..5f9aa56 100644
--- a/src/backend/executor/cypher_delete.c
+++ b/src/backend/executor/cypher_delete.c
@@ -340,6 +340,10 @@
         }
         /* increment the command counter */
         CommandCounterIncrement();
+
+        /* Update command id in estate */
+        estate->es_snapshot->curcid = GetCurrentCommandId(false);
+        estate->es_output_cid = GetCurrentCommandId(false);
     }
     else if (lock_result != TM_Invisible && lock_result != TM_SelfModified)
     {
diff --git a/src/backend/utils/load/ag_load_edges.c b/src/backend/utils/load/ag_load_edges.c
index 30dc476..6704943 100644
--- a/src/backend/utils/load/ag_load_edges.c
+++ b/src/backend/utils/load/ag_load_edges.c
@@ -22,11 +22,6 @@
 #include "utils/load/ag_load_edges.h"
 #include "utils/load/csv.h"
 
-void init_edge_batch_insert(batch_insert_state **batch_state,
-                            char *label_name, Oid graph_oid);
-void finish_edge_batch_insert(batch_insert_state **batch_state,
-                              char *label_name, Oid graph_oid);
-
 void edge_field_cb(void *field, size_t field_len, void *data)
 {
 
@@ -131,7 +126,7 @@
         if (batch_state->num_tuples >= batch_state->max_tuples)
         {
             /* Insert the batch when it is full (i.e. BATCH_SIZE) */
-            insert_batch(batch_state, cr->label_name, cr->graph_oid);
+            insert_batch(batch_state);
             batch_state->num_tuples = 0;
         }
     }
@@ -223,7 +218,7 @@
     cr.load_as_agtype = load_as_agtype;
 
     /* Initialize the batch insert state */
-    init_edge_batch_insert(&cr.batch_state, label_name, graph_oid);
+    init_batch_insert(&cr.batch_state, label_name, graph_oid);
 
     while ((bytes_read=fread(buf, 1, 1024, fp)) > 0)
     {
@@ -238,7 +233,7 @@
     csv_fini(&p, edge_field_cb, edge_row_cb, &cr);
 
     /* Finish any remaining batch inserts */
-    finish_edge_batch_insert(&cr.batch_state, label_name, graph_oid);
+    finish_batch_insert(&cr.batch_state);
 
     if (ferror(fp))
     {
@@ -250,66 +245,4 @@
     free(cr.fields);
     csv_free(&p);
     return EXIT_SUCCESS;
-}
-
-/*
- * Initialize the batch insert state for edges.
- */
-void init_edge_batch_insert(batch_insert_state **batch_state,
-                            char *label_name, Oid graph_oid)
-{
-    Relation relation;
-    int i;
-
-    // Open a temporary relation to get the tuple descriptor
-    relation = table_open(get_label_relation(label_name, graph_oid), AccessShareLock);
-
-    // Initialize the batch insert state
-    *batch_state = (batch_insert_state *) palloc0(sizeof(batch_insert_state));
-    (*batch_state)->max_tuples = BATCH_SIZE;
-    (*batch_state)->slots = palloc(sizeof(TupleTableSlot *) * BATCH_SIZE);
-    (*batch_state)->num_tuples = 0;
-
-    // Create slots
-    for (i = 0; i < BATCH_SIZE; i++)
-    {
-        (*batch_state)->slots[i] = MakeSingleTupleTableSlot(
-                                            RelationGetDescr(relation),
-                                            &TTSOpsHeapTuple);
-    }
-
-    table_close(relation, AccessShareLock);
-}
-
-/*
- * Finish the batch insert for edges. Insert the
- * remaining tuples in the batch state and clean up.
- */
-void finish_edge_batch_insert(batch_insert_state **batch_state,
-                              char *label_name, Oid graph_oid)
-{
-    int i;
-    Relation relation;
-
-    if ((*batch_state)->num_tuples > 0)
-    {
-        insert_batch(*batch_state, label_name, graph_oid);
-        (*batch_state)->num_tuples = 0;
-    }
-
-    // Open a temporary relation to ensure resources are properly cleaned up
-    relation = table_open(get_label_relation(label_name, graph_oid), AccessShareLock);
-
-    // Free slots
-    for (i = 0; i < BATCH_SIZE; i++)
-    {
-        ExecDropSingleTupleTableSlot((*batch_state)->slots[i]);
-    }
-
-    // Clean up batch state
-    pfree_if_not_null((*batch_state)->slots);
-    pfree_if_not_null(*batch_state);
-    *batch_state = NULL;
-
-    table_close(relation, AccessShareLock);
-}
+}
\ 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 2ab2233..4a04f3c 100644
--- a/src/backend/utils/load/ag_load_labels.c
+++ b/src/backend/utils/load/ag_load_labels.c
@@ -24,18 +24,6 @@
 #include "utils/load/ag_load_labels.h"
 #include "utils/load/csv.h"
 
-static void setup_temp_table_for_vertex_ids(char *graph_name);
-static void insert_batch_in_temp_table(batch_insert_state *batch_state,
-                                       Oid graph_oid, Oid relid);
-static void init_vertex_batch_insert(batch_insert_state **batch_state,
-                                     char *label_name, Oid graph_oid,
-                                     Oid temp_table_relid);
-static void finish_vertex_batch_insert(batch_insert_state **batch_state,
-                                       char *label_name, Oid graph_oid,
-                                       Oid temp_table_relid);
-static void insert_vertex_batch(batch_insert_state *batch_state, char *label_name,
-                                Oid graph_oid, Oid temp_table_relid);
-
 void vertex_field_cb(void *field, size_t field_len, void *data)
 {
 
@@ -75,7 +63,6 @@
     graphid vertex_id;
     int64 entry_id;
     TupleTableSlot *slot;
-    TupleTableSlot *temp_id_slot;
 
     n_fields = cr->cur_field;
 
@@ -114,11 +101,9 @@
 
         /* Get the appropriate slot from the batch state */
         slot = batch_state->slots[batch_state->num_tuples];
-        temp_id_slot = batch_state->temp_id_slots[batch_state->num_tuples];
 
         /* Clear the slots contents */
         ExecClearTuple(slot);
-        ExecClearTuple(temp_id_slot);
 
         /* Fill the values in the slot */
         slot->tts_values[0] = GRAPHID_GET_DATUM(vertex_id);
@@ -129,20 +114,15 @@
         slot->tts_isnull[0] = false;
         slot->tts_isnull[1] = false;
 
-        temp_id_slot->tts_values[0] = GRAPHID_GET_DATUM(vertex_id);
-        temp_id_slot->tts_isnull[0] = false;
-
         /* Make the slot as containing virtual tuple */
         ExecStoreVirtualTuple(slot);
-        ExecStoreVirtualTuple(temp_id_slot);
 
         batch_state->num_tuples++;
 
         if (batch_state->num_tuples >= batch_state->max_tuples)
         {
             /* Insert the batch when it is full (i.e. BATCH_SIZE) */
-            insert_vertex_batch(batch_state, cr->label_name, cr->graph_oid,
-                                cr->temp_table_relid);
+            insert_batch(batch_state);
             batch_state->num_tuples = 0;
         }
     }
@@ -202,7 +182,6 @@
     unsigned char options = 0;
     csv_vertex_reader cr;
     char *label_seq_name;
-    Oid temp_table_relid;
 
     if (csv_init(&p, options) != 0)
     {
@@ -210,13 +189,6 @@
                 (errmsg("Failed to initialize csv parser\n")));
     }
 
-    temp_table_relid = RelnameGetRelid(GET_TEMP_VERTEX_ID_TABLE(graph_name));
-    if (!OidIsValid(temp_table_relid))
-    {
-        setup_temp_table_for_vertex_ids(graph_name);
-        temp_table_relid = RelnameGetRelid(GET_TEMP_VERTEX_ID_TABLE(graph_name));
-    }
-
     csv_set_space_func(&p, is_space);
     csv_set_term_func(&p, is_term);
 
@@ -243,7 +215,6 @@
     cr.id_field_exists = id_field_exists;
     cr.label_seq_relid = get_relname_relid(label_seq_name, graph_oid);
     cr.load_as_agtype = load_as_agtype;
-    cr.temp_table_relid = temp_table_relid;
     
     if (cr.id_field_exists)
     {
@@ -258,8 +229,7 @@
     }
 
     /* Initialize the batch insert state */
-    init_vertex_batch_insert(&cr.batch_state, label_name, graph_oid,
-                             cr.temp_table_relid);
+    init_batch_insert(&cr.batch_state, label_name, graph_oid);
 
     while ((bytes_read=fread(buf, 1, 1024, fp)) > 0)
     {
@@ -274,8 +244,7 @@
     csv_fini(&p, vertex_field_cb, vertex_row_cb, &cr);
 
     /* Finish any remaining batch inserts */
-    finish_vertex_batch_insert(&cr.batch_state, label_name, graph_oid,
-                               cr.temp_table_relid);
+    finish_batch_insert(&cr.batch_state);
 
     if (ferror(fp))
     {
@@ -288,180 +257,4 @@
     free(cr.fields);
     csv_free(&p);
     return EXIT_SUCCESS;
-}
-
-static void insert_vertex_batch(batch_insert_state *batch_state, char *label_name,
-                                Oid graph_oid, Oid temp_table_relid)
-{
-    insert_batch_in_temp_table(batch_state, graph_oid, temp_table_relid);
-    insert_batch(batch_state, label_name, graph_oid);
-}
-
-/*
- * Create and populate a temporary table with vertex ids that are already
- * present in the graph. This table will be used to check if the new vertex
- * id generated by loader is a duplicate.
- * Unique index is created to enforce uniqueness of the ids.
- * 
- * We dont need this for loading edges since the ids are generated using
- * sequence and are unique.
- */ 
-static void setup_temp_table_for_vertex_ids(char *graph_name)
-{
-    char *create_as_query;
-    char *index_query;
-
-    create_as_query = psprintf("CREATE TEMP TABLE IF NOT EXISTS %s AS "
-                               "SELECT DISTINCT id FROM \"%s\".%s",
-                                GET_TEMP_VERTEX_ID_TABLE(graph_name), graph_name,
-                                AG_DEFAULT_LABEL_VERTEX);
-
-    index_query = psprintf("CREATE UNIQUE INDEX ON %s (id)",
-                           GET_TEMP_VERTEX_ID_TABLE(graph_name));
-    SPI_connect();
-    SPI_execute(create_as_query, false, 0);
-    SPI_execute(index_query, false, 0);
-
-    SPI_finish();
-}
-
-/*
- * Inserts batch of tuples into the temporary table.
- * This function also updates the index to check for
- * uniqueness of the ids.
- */
-static void insert_batch_in_temp_table(batch_insert_state *batch_state,
-                                       Oid graph_oid, Oid relid)
-{
-    int i;
-    EState *estate;
-    ResultRelInfo *resultRelInfo;
-    Relation rel;
-    List *result;
-
-    rel = table_open(relid, RowExclusiveLock);
-
-    /* Initialize executor state */
-    estate = CreateExecutorState();
-
-    /* Initialize result relation information */
-    resultRelInfo = makeNode(ResultRelInfo);
-    InitResultRelInfo(resultRelInfo, rel, 1, NULL, estate->es_instrument);
-    estate->es_result_relations = &resultRelInfo;
-
-    /* Open the indices */
-    ExecOpenIndices(resultRelInfo, false);
-
-    /* Insert the batch into the temporary table */
-    heap_multi_insert(rel, batch_state->temp_id_slots, batch_state->num_tuples,
-                      GetCurrentCommandId(true), 0, NULL);
-
-    for (i = 0; i < batch_state->num_tuples; i++)
-    {
-        result = ExecInsertIndexTuples(resultRelInfo, batch_state->temp_id_slots[i],
-                                       estate, false, true, NULL, NIL, false);
-        /* Check if the unique cnstraint is violated */
-        if (list_length(result) != 0)
-        {
-            Datum id;
-            bool isnull;
-
-            id = slot_getattr(batch_state->temp_id_slots[i], 1, &isnull);
-            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))));
-        }
-    }
-    /* Clean up and close the indices */
-    ExecCloseIndices(resultRelInfo);
-
-    FreeExecutorState(estate);
-    table_close(rel, RowExclusiveLock);
-
-    CommandCounterIncrement();
-}
-
-/*
- * Initialize the batch insert state for vertices.
- */
-static void init_vertex_batch_insert(batch_insert_state **batch_state,
-                                     char *label_name, Oid graph_oid,
-                                     Oid temp_table_relid)
-{
-    Relation relation;
-    Oid relid;
-
-    Relation temp_table_relation;
-    int i;
-
-    /* Open a temporary relation to get the tuple descriptor */
-    relid = get_label_relation(label_name, graph_oid);
-    relation = table_open(relid, AccessShareLock);
-
-    temp_table_relation = table_open(temp_table_relid, AccessShareLock);
-
-    /* Initialize the batch insert state */
-    *batch_state = (batch_insert_state *) palloc0(sizeof(batch_insert_state));
-    (*batch_state)->max_tuples = BATCH_SIZE;
-    (*batch_state)->slots = palloc(sizeof(TupleTableSlot *) * BATCH_SIZE);
-    (*batch_state)->temp_id_slots = palloc(sizeof(TupleTableSlot *) * BATCH_SIZE);
-    (*batch_state)->num_tuples = 0;
-
-    /* Create slots */
-    for (i = 0; i < BATCH_SIZE; i++)
-    {
-        (*batch_state)->slots[i] = MakeSingleTupleTableSlot(
-                                            RelationGetDescr(relation),
-                                            &TTSOpsHeapTuple);
-        (*batch_state)->temp_id_slots[i] = MakeSingleTupleTableSlot(
-                                        RelationGetDescr(temp_table_relation),
-                                        &TTSOpsHeapTuple);
-    }
-
-    table_close(relation, AccessShareLock);
-    table_close(temp_table_relation, AccessShareLock);
-}
-
-/*
- * Finish the batch insert for vertices. Insert the
- * remaining tuples in the batch state and clean up.
- */
-static void finish_vertex_batch_insert(batch_insert_state **batch_state,
-                                       char *label_name, Oid graph_oid,
-                                       Oid temp_table_relid)
-{
-    Relation relation;
-    Oid relid;
-
-    Relation temp_table_relation;
-    int i;
-
-    if ((*batch_state)->num_tuples > 0)
-    {
-        insert_vertex_batch(*batch_state, label_name, graph_oid, temp_table_relid);
-        (*batch_state)->num_tuples = 0;
-    }
-
-    /* Open a temporary relation to ensure resources are properly cleaned up */
-    relid = get_label_relation(label_name, graph_oid);
-    relation = table_open(relid, AccessShareLock);
-
-    temp_table_relation = table_open(temp_table_relid, AccessShareLock);
-
-    /* Free slots */
-    for (i = 0; i < BATCH_SIZE; i++)
-    {
-        ExecDropSingleTupleTableSlot((*batch_state)->slots[i]);
-        ExecDropSingleTupleTableSlot((*batch_state)->temp_id_slots[i]);
-    }
-
-    /* Clean up batch state */
-    pfree_if_not_null((*batch_state)->slots);
-    pfree_if_not_null((*batch_state)->temp_id_slots);
-    pfree_if_not_null(*batch_state);
-    *batch_state = NULL;
-
-    table_close(relation, AccessShareLock);
-    table_close(temp_table_relation, AccessShareLock);
-}
+}
\ No newline at end of file
diff --git a/src/backend/utils/load/age_load.c b/src/backend/utils/load/age_load.c
index 41233ff..307ec33 100644
--- a/src/backend/utils/load/age_load.c
+++ b/src/backend/utils/load/age_load.c
@@ -18,11 +18,14 @@
  */
 
 #include "postgres.h"
+#include "catalog/indexing.h"
+#include "executor/executor.h"
 #include "utils/json.h"
 
 #include "utils/load/ag_load_edges.h"
 #include "utils/load/ag_load_labels.h"
 #include "utils/load/age_load.h"
+#include "utils/rel.h"
 
 static agtype_value *csv_value_to_agtype_value(char *csv_val);
 static Oid get_or_create_graph(const Name graph_name);
@@ -217,18 +220,35 @@
                         errmsg("label %s already exists as vertex label", label_name)));
     }
 
+    /* Open the relation */
+    label_relation = table_open(get_label_relation(label_name, graph_oid),
+                                RowExclusiveLock);
+
+    /* Form the tuple */
     values[0] = GRAPHID_GET_DATUM(edge_id);
     values[1] = GRAPHID_GET_DATUM(start_id);
     values[2] = GRAPHID_GET_DATUM(end_id);
     values[3] = AGTYPE_P_GET_DATUM((edge_properties));
-
-    label_relation = table_open(get_label_relation(label_name, graph_oid),
-                                RowExclusiveLock);
-
     tuple = heap_form_tuple(RelationGetDescr(label_relation),
                             values, nulls);
-    heap_insert(label_relation, tuple,
-                GetCurrentCommandId(true), 0, NULL);
+
+    if (RelationGetForm(label_relation)->relhasindex)
+    {
+        /*
+         * CatalogTupleInsertWithInfo() is originally for PostgreSQL's
+         * catalog. However, it is used here for convenience.
+         */
+        CatalogIndexState indstate = CatalogOpenIndexes(label_relation);
+        CatalogTupleInsertWithInfo(label_relation, tuple, indstate);
+        CatalogCloseIndexes(indstate);
+    }
+    else
+    {
+        heap_insert(label_relation, tuple, GetCurrentCommandId(true),
+                    0, NULL);
+    }
+
+    /* Close the relation */
     table_close(label_relation, RowExclusiveLock);
     CommandCounterIncrement();
 }
@@ -246,46 +266,75 @@
     if (get_label_kind(label_name, graph_oid) == LABEL_KIND_EDGE)
     {
         ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                        errmsg("label %s already exists as edge label", label_name)));
+                        errmsg("label %s already exists as edge label",
+                                label_name)));
     }
 
-    values[0] = GRAPHID_GET_DATUM(vertex_id);
-    values[1] = AGTYPE_P_GET_DATUM((vertex_properties));
-
+    /* Open the relation */
     label_relation = table_open(get_label_relation(label_name, graph_oid),
                                 RowExclusiveLock);
+
+    /* Form the tuple */
+    values[0] = GRAPHID_GET_DATUM(vertex_id);
+    values[1] = AGTYPE_P_GET_DATUM((vertex_properties));
     tuple = heap_form_tuple(RelationGetDescr(label_relation),
                             values, nulls);
-    heap_insert(label_relation, tuple,
-                GetCurrentCommandId(true), 0, NULL);
+
+    if (RelationGetForm(label_relation)->relhasindex)
+    {
+        /*
+         * CatalogTupleInsertWithInfo() is originally for PostgreSQL's
+         * catalog. However, it is used here for convenience.
+         */
+        CatalogIndexState indstate = CatalogOpenIndexes(label_relation);
+        CatalogTupleInsertWithInfo(label_relation, tuple, indstate);
+        CatalogCloseIndexes(indstate);
+    }
+    else
+    {
+        heap_insert(label_relation, tuple, GetCurrentCommandId(true),
+                    0, NULL);
+    }
+
+    /* Close the relation */
     table_close(label_relation, RowExclusiveLock);
     CommandCounterIncrement();
 }
 
-void insert_batch(batch_insert_state *batch_state, char *label_name,
-                  Oid graph_oid)
+void insert_batch(batch_insert_state *batch_state)
 {
-    Relation label_relation;
-    BulkInsertState bistate;
-    Oid relid;
+    List *result;
+    int i;
 
-    // Get the relation OID
-    relid = get_label_relation(label_name, graph_oid);
+    /* Insert the tuples */
+    heap_multi_insert(batch_state->resultRelInfo->ri_RelationDesc,
+                      batch_state->slots, batch_state->num_tuples,
+                      GetCurrentCommandId(true), 0, NULL);
+    
+    /* Insert index entries for the tuples */
+    if (batch_state->resultRelInfo->ri_NumIndices > 0)
+    {
+        for (i = 0; i < batch_state->num_tuples; i++)
+        {
+            result = ExecInsertIndexTuples(batch_state->resultRelInfo,
+                                           batch_state->slots[i],
+                                           batch_state->estate, false,
+                                           true, NULL, NIL, false);
 
-    // Open the relation
-    label_relation = table_open(relid, RowExclusiveLock);
+            /* Check if the unique constraint is violated */
+            if (list_length(result) != 0)
+            {
+                Datum id;
+                bool isnull;
 
-    // Prepare the BulkInsertState
-    bistate = GetBulkInsertState();
-
-    // Perform the bulk insert
-    heap_multi_insert(label_relation, batch_state->slots,
-                      batch_state->num_tuples, GetCurrentCommandId(true),
-                      0, bistate);
-
-    // Clean up
-    FreeBulkInsertState(bistate);
-    table_close(label_relation, RowExclusiveLock);
+                id = slot_getattr(batch_state->slots[i], 1, &isnull);
+                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))));
+            }
+        }
+    }
 
     CommandCounterIncrement();
 }
@@ -475,3 +524,79 @@
 
     return label_id;
 }
+
+/*
+ * Initialize the batch insert state.
+ */
+void init_batch_insert(batch_insert_state **batch_state,
+                              char *label_name, Oid graph_oid)
+{
+    Relation relation;
+    Oid relid;
+    EState *estate;
+    ResultRelInfo *resultRelInfo;
+    int i;
+
+    /* Open the relation */
+    relid = get_label_relation(label_name, graph_oid);
+    relation = table_open(relid, RowExclusiveLock);
+
+    /* Initialize executor state */
+    estate = CreateExecutorState();
+
+    /* Initialize resultRelInfo */
+    resultRelInfo = makeNode(ResultRelInfo);
+    InitResultRelInfo(resultRelInfo, relation, 1, NULL, estate->es_instrument);
+    estate->es_result_relations = &resultRelInfo;
+
+    /* Open the indices */
+    ExecOpenIndices(resultRelInfo, false);
+
+    /* Initialize the batch insert state */
+    *batch_state = (batch_insert_state *) palloc0(sizeof(batch_insert_state));
+    (*batch_state)->slots = palloc(sizeof(TupleTableSlot *) * BATCH_SIZE);
+    (*batch_state)->estate = estate;
+    (*batch_state)->resultRelInfo = resultRelInfo;
+    (*batch_state)->max_tuples = BATCH_SIZE;
+    (*batch_state)->num_tuples = 0;
+
+    /* Create slots */
+    for (i = 0; i < BATCH_SIZE; i++)
+    {
+        (*batch_state)->slots[i] = MakeSingleTupleTableSlot(
+                                            RelationGetDescr(relation),
+                                            &TTSOpsHeapTuple);
+    }
+}
+
+/*
+ * Finish the batch insert for vertices. Insert the
+ * tuples remaining in the batch state and clean up.
+ */
+void finish_batch_insert(batch_insert_state **batch_state)
+{
+    int i;
+
+    if ((*batch_state)->num_tuples > 0)
+    {
+        insert_batch(*batch_state);
+        (*batch_state)->num_tuples = 0;
+    }
+
+    /* Free slots */
+    for (i = 0; i < BATCH_SIZE; i++)
+    {
+        ExecDropSingleTupleTableSlot((*batch_state)->slots[i]);
+    }
+
+    /* Clean up, close the indices and relation */
+    ExecCloseIndices((*batch_state)->resultRelInfo);
+    table_close((*batch_state)->resultRelInfo->ri_RelationDesc,
+                RowExclusiveLock);
+
+    /* Clean up batch state */
+    FreeExecutorState((*batch_state)->estate);
+    pfree((*batch_state)->slots);
+    pfree(*batch_state);
+    *batch_state = NULL;
+}
\ No newline at end of file
diff --git a/src/include/utils/load/ag_load_labels.h b/src/include/utils/load/ag_load_labels.h
index 3a70a5c..b8ed157 100644
--- a/src/include/utils/load/ag_load_labels.h
+++ b/src/include/utils/load/ag_load_labels.h
@@ -24,10 +24,6 @@
 #include "access/heapam.h"
 #include "utils/load/age_load.h"
 
-#define AGE_VERTIX 1
-#define AGE_EDGE 2
-
-
 struct counts {
     long unsigned fields;
     long unsigned allvalues;
@@ -51,7 +47,6 @@
     char *label_name;
     int label_id;
     Oid label_seq_relid;
-    Oid temp_table_relid;
     bool id_field_exists;
     bool load_as_agtype;
     int curr_seq_num;
diff --git a/src/include/utils/load/age_load.h b/src/include/utils/load/age_load.h
index b133558..72f1149 100644
--- a/src/include/utils/load/age_load.h
+++ b/src/include/utils/load/age_load.h
@@ -30,16 +30,13 @@
 #ifndef AGE_ENTITY_CREATOR_H
 #define AGE_ENTITY_CREATOR_H
 
-#define TEMP_VERTEX_ID_TABLE_SUFFIX "_ag_vertex_ids"
-#define GET_TEMP_VERTEX_ID_TABLE(graph_name) \
-    psprintf("_%s%s", graph_name, TEMP_VERTEX_ID_TABLE_SUFFIX)
-
 #define BATCH_SIZE 1000
 
-typedef struct
+typedef struct batch_insert_state
 {
+    EState *estate;
+    ResultRelInfo *resultRelInfo;
     TupleTableSlot **slots;
-    TupleTableSlot **temp_id_slots;
     int num_tuples;
     int max_tuples;
 } batch_insert_state;
@@ -57,7 +54,10 @@
 void insert_edge_simple(Oid graph_oid, char *label_name, graphid edge_id,
                         graphid start_id, graphid end_id,
                         agtype* end_properties);
-void insert_batch(batch_insert_state *batch_state, char *label_name,
-                  Oid graph_oid);
+void insert_batch(batch_insert_state *batch_state);
+
+void init_batch_insert(batch_insert_state **batch_state,
+                       char *label_name, Oid graph_oid);
+void finish_batch_insert(batch_insert_state **batch_state);
 
 #endif /* AGE_ENTITY_CREATOR_H */