@@ -230,6 +230,76 @@ START_TEST (track_error_position_over_embedded_newline)
230230END_TEST
231231
232232
233+ START_TEST (track_error_position_across_statements )
234+ {
235+ struct cypher_input_position last = cypher_input_position_zero ;
236+ result = cypher_parse (
237+ "match (n) return n;\n"
238+ "m atch (n) return n;\n"
239+ "match (d) return d;\n"
240+ "match (bc e) return a;\n" ,
241+ & last , NULL , 0 );
242+ ck_assert_ptr_ne (result , NULL );
243+ ck_assert_int_eq (last .offset , 84 );
244+
245+ ck_assert (cypher_parse_result_fprint_ast (result , memstream , 0 , NULL , 0 ) == 0 );
246+ fflush (memstream );
247+ const char * expected = "\n"
248+ " @0 0..19 statement body=@1\n"
249+ " @1 0..19 > query clauses=[@2, @7]\n"
250+ " @2 0..10 > > MATCH pattern=@3\n"
251+ " @3 6..9 > > > pattern paths=[@4]\n"
252+ " @4 6..9 > > > > pattern path (@5)\n"
253+ " @5 6..9 > > > > > node pattern (@6)\n"
254+ " @6 7..8 > > > > > > identifier `n`\n"
255+ " @7 10..18 > > RETURN projections=[@8]\n"
256+ " @8 17..18 > > > projection expression=@9\n"
257+ " @9 17..18 > > > > identifier `n`\n"
258+ "@10 20..30 error >>m atch (n)<<\n"
259+ "@11 30..40 statement body=@12\n"
260+ "@12 31..40 > query clauses=[@13]\n"
261+ "@13 31..39 > > RETURN projections=[@14]\n"
262+ "@14 38..39 > > > projection expression=@15\n"
263+ "@15 38..39 > > > > identifier `n`\n"
264+ "@16 41..60 statement body=@17\n"
265+ "@17 41..60 > query clauses=[@18, @23]\n"
266+ "@18 41..51 > > MATCH pattern=@19\n"
267+ "@19 47..50 > > > pattern paths=[@20]\n"
268+ "@20 47..50 > > > > pattern path (@21)\n"
269+ "@21 47..50 > > > > > node pattern (@22)\n"
270+ "@22 48..49 > > > > > > identifier `d`\n"
271+ "@23 51..59 > > RETURN projections=[@24]\n"
272+ "@24 58..59 > > > projection expression=@25\n"
273+ "@25 58..59 > > > > identifier `d`\n"
274+ "@26 61..73 error >>match (bc e)<<\n"
275+ "@27 73..83 statement body=@28\n"
276+ "@28 74..83 > query clauses=[@29]\n"
277+ "@29 74..82 > > RETURN projections=[@30]\n"
278+ "@30 81..82 > > > projection expression=@31\n"
279+ "@31 81..82 > > > > identifier `a`\n" ;
280+ ck_assert_str_eq (memstream_buffer , expected );
281+
282+ ck_assert_int_eq (cypher_parse_result_nerrors (result ), 2 );
283+
284+ const cypher_parse_error_t * err = cypher_parse_result_get_error (result , 0 );
285+ struct cypher_input_position pos = cypher_parse_error_position (err );
286+ ck_assert_int_eq (pos .line , 2 );
287+ ck_assert_int_eq (pos .column , 2 );
288+ ck_assert_int_eq (pos .offset , 21 );
289+ ck_assert_str_eq (cypher_parse_error_message (err ),
290+ "Invalid input ' ': expected MATCH or MERGE" );
291+
292+ err = cypher_parse_result_get_error (result , 1 );
293+ pos = cypher_parse_error_position (err );
294+ ck_assert_int_eq (pos .line , 4 );
295+ ck_assert_int_eq (pos .column , 11 );
296+ ck_assert_int_eq (pos .offset , 71 );
297+ ck_assert_str_eq (cypher_parse_error_message (err ),
298+ "Invalid input 'e': expected a label, '{', a parameter or ')'" );
299+ }
300+ END_TEST
301+
302+
233303TCase * errors_tcase (void )
234304{
235305 TCase * tc = tcase_create ("errors" );
@@ -240,5 +310,6 @@ TCase* errors_tcase(void)
240310 tcase_add_test (tc , parse_invalid_query_and_resync );
241311 tcase_add_test (tc , parse_single_invalid_query );
242312 tcase_add_test (tc , track_error_position_over_embedded_newline );
313+ tcase_add_test (tc , track_error_position_across_statements );
243314 return tc ;
244315}
0 commit comments