Skip to content

Commit d5e10da

Browse files
Ruben Fiszelrobert3005
authored andcommitted
[SPARK-24345][SQL] Improve ParseError stop location when offending symbol is a token (apache-spark-on-k8s#375)
In the case where the offending symbol is a CommonToken, this PR increases the accuracy of the start and stop origin by leveraging the start and stop index information from CommonToken.
1 parent 52a122f commit d5e10da

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/ParseDriver.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,17 @@ case object ParseErrorListener extends BaseErrorListener {
192192
charPositionInLine: Int,
193193
msg: String,
194194
e: RecognitionException): Unit = {
195-
val position = Origin(Some(line), Some(charPositionInLine))
196-
throw new ParseException(None, msg, position, position)
195+
val (start, stop) = offendingSymbol match {
196+
case token: CommonToken =>
197+
val start = Origin(Some(line), Some(token.getCharPositionInLine))
198+
val length = token.getStopIndex - token.getStartIndex + 1
199+
val stop = Origin(Some(line), Some(token.getCharPositionInLine + length))
200+
(start, stop)
201+
case _ =>
202+
val start = Origin(Some(line), Some(charPositionInLine))
203+
(start, start)
204+
}
205+
throw new ParseException(None, msg, start, stop)
197206
}
198207
}
199208

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ErrorParserSuite.scala

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,21 @@ import org.apache.spark.SparkFunSuite
2222
* Test various parser errors.
2323
*/
2424
class ErrorParserSuite extends SparkFunSuite {
25-
def intercept(sql: String, line: Int, startPosition: Int, messages: String*): Unit = {
25+
def intercept(
26+
sql: String,
27+
line: Int,
28+
startPosition: Int,
29+
stopPosition: Int,
30+
messages: String*): Unit = {
2631
val e = intercept[ParseException](CatalystSqlParser.parsePlan(sql))
2732

2833
// Check position.
2934
assert(e.line.isDefined)
3035
assert(e.line.get === line)
3136
assert(e.startPosition.isDefined)
3237
assert(e.startPosition.get === startPosition)
38+
assert(e.stop.startPosition.isDefined)
39+
assert(e.stop.startPosition.get === stopPosition)
3340

3441
// Check messages.
3542
val error = e.getMessage
@@ -39,26 +46,27 @@ class ErrorParserSuite extends SparkFunSuite {
3946
}
4047

4148
test("no viable input") {
42-
intercept("select ((r + 1) ", 1, 16, "no viable alternative at input", "----------------^^^")
49+
intercept("select ((r + 1) ", 1, 16, 16,
50+
"no viable alternative at input", "----------------^^^")
4351
}
4452

4553
test("extraneous input") {
46-
intercept("select 1 1", 1, 9, "extraneous input '1' expecting", "---------^^^")
47-
intercept("select *\nfrom r as q t", 2, 12, "extraneous input", "------------^^^")
54+
intercept("select 1 1", 1, 9, 10, "extraneous input '1' expecting", "---------^^^")
55+
intercept("select *\nfrom r as q t", 2, 12, 13, "extraneous input", "------------^^^")
4856
}
4957

5058
test("mismatched input") {
51-
intercept("select * from r order by q from t", 1, 27,
59+
intercept("select * from r order by q from t", 1, 27, 31,
5260
"mismatched input",
5361
"---------------------------^^^")
54-
intercept("select *\nfrom r\norder by q\nfrom t", 4, 0, "mismatched input", "^^^")
62+
intercept("select *\nfrom r\norder by q\nfrom t", 4, 0, 4, "mismatched input", "^^^")
5563
}
5664

5765
test("semantic errors") {
58-
intercept("select *\nfrom r\norder by q\ncluster by q", 3, 0,
66+
intercept("select *\nfrom r\norder by q\ncluster by q", 3, 0, 11,
5967
"Combination of ORDER BY/SORT BY/DISTRIBUTE BY/CLUSTER BY is not supported",
6068
"^^^")
61-
intercept("select * from r except all select * from t", 1, 0,
69+
intercept("select * from r except all select * from t", 1, 0, 41,
6270
"EXCEPT ALL is not supported",
6371
"^^^")
6472
}

0 commit comments

Comments
 (0)