text: /*
  * Copyright 2018-2020 Redis Labs Ltd. and Contributors
  *
  * This file is available under the Redis Labs Source Available License Agreement
  */
  
  #include "gtest.h"
  
  //#ifdef __cplusplus
  //extern "C" {
  //#endif
  
  #include <stdio.h>
  #include "../../src/util/rmalloc.h"
  #include "../../src/util/arr.h"
  #include "../../src/ast/ast.h"
  
  //#ifdef __cplusplus
  //}
  //#endif
  
  class TestReferencedEntities: public ::testing::Test {
    protected:
  	static void SetUpTestCase() {// Use the malloc family for allocations
  		Alloc_Reset();
  	}
  };
  
  // Parse query to AST.
  AST *buildAST(const char *query) {
  	cypher_parse_result_t *parse_result = cypher_parse(query, NULL, NULL, CYPHER_PARSE_ONLY_STATEMENTS);
  	return AST_Build(parse_result);
  }
  
  uint *getASTSegmentIndices(AST *ast) {
  	// Retrieve the indices of each WITH clause to properly set the bounds of each segment.
  	uint *segment_indices = AST_GetClauseIndices(ast, CYPHER_AST_WITH);
  	bool query_has_return = AST_ContainsClause(ast, CYPHER_AST_RETURN);
  	if(query_has_return) {
  		segment_indices = array_append(segment_indices, cypher_ast_query_nclauses(ast->root) - 1);
  	}
  	segment_indices = array_append(segment_indices, cypher_ast_query_nclauses(ast->root));
  	return segment_indices;
  }
  
  TEST_F(TestReferencedEntities, TestMatch) {
  	// Test for no inline filters.
  	char *q = "MATCH (n)";
  	AST *ast = buildAST(q);
  	uint *segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	AST *astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	AST_Free(astSegment);
  
  	q = "MATCH (n)-[e]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	AST_Free(astSegment);
  
  	// Inline node label filter.
  	q = "MATCH (n:X)-[e]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Inline node property filter.
  	q = "MATCH (n {val:42})-[e]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Inline edge relationship type.
  	q = "MATCH (n)-[e:T]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Inline edge properties.
  	q = "MATCH (n)-[e {val:42}]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Explicit filters: EQ, NE, GT, LT, IS NULL, IS NOT NULL.
  	q = "MATCH (n)-[e]->(m) WHERE n.v = 1";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH (n)-[e]->(m) WHERE n.v <> 1";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH (n)-[e]->(m) WHERE n.v > 1";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH (n)-[e]->(m) WHERE n.v < 1";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH (n)-[e]->(m) WHERE n.v IS NULL 1";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH (n)-[e]->(m) WHERE n.v IS NOT NULL 1";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  }
  
  TEST_F(TestReferencedEntities, TestSet) {
  	// Simple match and set property.
  	char *q = "MATCH (n) SET n.v=1";
  	AST *ast = buildAST(q);
  	uint *segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	AST *astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	AST_Free(astSegment);
  
  	// Path match and set property.
  	q = "MATCH (n)-[e]->(x)-[]->(m) SET n.v=x.v";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(2, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Reference from MATCH and SET caluse.
  	q = "MATCH (n)-[e:r]->(m) SET n.v=1";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  }
  
  TEST_F(TestReferencedEntities, TestMerge) {
  	// Simple merge.
  	char *q = "MERGE (n)";
  	AST *ast = buildAST(q);
  	uint *segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	AST *astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	AST_Free(astSegment);
  
  	q = "MERGE (n)-[e]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	AST_Free(astSegment);
  
  	// Inline node label filter.
  	q = "MERGE (n:X)-[e]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Inline node property filter.
  	q = "MERGE (n {val:42})-[e]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Inline edge relationship type.
  	q = "MERGE (n)-[e:T]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Inline edge properties.
  	q = "MERGE (n)-[e {val:42}]->(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  
  	// On match.
  	q = "MERGE (n)-[e]->(m) ON MATCH SET n.v=1, m.v=2";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(2, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// On create.
  	q = "MERGE (n)-[e]->(m) ON CREATE SET n.v=1, m.v=2";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(2, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	// Mixed.
  	q = "MERGE (n)-[e]->(m) ON CREATE SET n.v=1, m.v=2 ON MATCH SET e.v = 3";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(3, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  }
  
  TEST_F(TestReferencedEntities, TestUnwind) {
  	char *q = "UNWIND [1,2] as x";
  	AST *ast = buildAST(q);
  	uint *segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	AST *astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(0, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  }
  
  TEST_F(TestReferencedEntities, TestWith) {
  	char *q = "MATCH (n),(m) with n as x";
  	AST *ast = buildAST(q);
  	uint *segmentIndices = getASTSegmentIndices(ast);
  	// Two segments: first is the MATCH clause, the second is the WITH clause.
  	ASSERT_EQ(2, array_len(segmentIndices));
  
  	// Only n is projected from the first segment.
  	AST *astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  
  	// Only x is projected from the second segment.
  	astSegment = AST_NewSegment(ast, segmentIndices[0], segmentIndices[1]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH (n),(m) with n as x ORDER BY m.value";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	// Two segments: first is the MATCH clause, the second is the WITH clause.
  	ASSERT_EQ(2, array_len(segmentIndices));
  
  	// Only n and m projected from the first segment.
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(2, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  
  	// Only m and x projected from the second segment.
  	astSegment = AST_NewSegment(ast, segmentIndices[0], segmentIndices[1]);
  	ASSERT_EQ(2, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  }
  
  TEST_F(TestReferencedEntities, TestReturn) {
  	char *q = "MATCH (n),(m) RETURN n as x";
  	AST *ast = buildAST(q);
  	uint *segmentIndices = getASTSegmentIndices(ast);
  	// Two segments: first is the MATCH clause, the second is the RETURN clause.
  	ASSERT_EQ(2, array_len(segmentIndices));
  
  	// Only n is projected from the first segment.
  	AST *astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  
  	// Only x is projected from the second segment.
  	astSegment = AST_NewSegment(ast, segmentIndices[0], segmentIndices[1]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH (n),(m) RETURN n as x ORDER BY m.value";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	// Two segments: first is the MATCH clause, the second is the RETURN clause.
  	ASSERT_EQ(2, array_len(segmentIndices));
  
  	// Only n and m projected from the first segment.
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(2, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  
  	// Only m and x projected from the second segment.
  	astSegment = AST_NewSegment(ast, segmentIndices[0], segmentIndices[1]);
  	ASSERT_EQ(2, raxSize(astSegment->referenced_entities));
  	ASSERT_EQ(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"x", 1));
  	AST_Free(astSegment);
  }
  
  TEST_F(TestReferencedEntities, TestNamedPath) {
  	char *q = "MATCH p=()";
  	AST *ast = buildAST(q);
  	uint *segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	AST *astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(1, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"anon_0", 6));
  	AST_Free(astSegment);
  
  	q = "MATCH p =()-[]-()";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(3, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"anon_0", 6));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"anon_1", 6));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"anon_2", 6));
  	AST_Free(astSegment);
  
  	q = "MATCH p =(n)-[e]-(m)";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(3, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"n", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  	q = "MATCH p =(:Label1 {value:1})-[e:Rel*]-(m:Label2 {value:2})";
  	ast = buildAST(q);
  	segmentIndices = getASTSegmentIndices(ast);
  	ASSERT_EQ(1, array_len(segmentIndices));
  
  	astSegment = AST_NewSegment(ast, 0, segmentIndices[0]);
  	ASSERT_EQ(3, raxSize(astSegment->referenced_entities));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"anon_0", 6));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"e", 1));
  	ASSERT_NE(raxNotFound, raxFind(astSegment->referenced_entities, (unsigned char *)"m", 1));
  	AST_Free(astSegment);
  
  }
  