diff --git a/src/Parsers/IParser.cpp b/src/Parsers/IParser.cpp index 857009680b1..9d7a0a65b34 100644 --- a/src/Parsers/IParser.cpp +++ b/src/Parsers/IParser.cpp @@ -45,6 +45,16 @@ void Expected::highlight(HighlightedRange range) return; auto it = highlights.lower_bound(range); + + /// Highlights are sorted by their starting position. + /// lower_bound(range) will find the first highlight where begin >= range.begin. + /// However, this does not ensure that the previous highlight's end <= range.begin. + /// By checking the previous highlight, if it exists, we ensure that + /// for each highlight x and the next one y: x.end <= y.begin, thus preventing any overlap. + + if (it != highlights.begin()) + it = std::prev(it); + while (it != highlights.end() && range.begin < it->end) { if (intersects(range.begin, range.end, it->begin, it->end)) diff --git a/tests/queries/0_stateless/03272_client_highlighting_bug.expect b/tests/queries/0_stateless/03272_client_highlighting_bug.expect new file mode 100755 index 00000000000..1ed5d9a324f --- /dev/null +++ b/tests/queries/0_stateless/03272_client_highlighting_bug.expect @@ -0,0 +1,39 @@ +#!/usr/bin/expect -f + +set basedir [file dirname $argv0] +set basename [file tail $argv0] +if {[info exists env(CLICKHOUSE_TMP)]} { + set CLICKHOUSE_TMP $env(CLICKHOUSE_TMP) +} else { + set CLICKHOUSE_TMP "." +} +exp_internal -f $CLICKHOUSE_TMP/$basename.debuglog 0 +set history_file $CLICKHOUSE_TMP/$basename.history + +log_user 0 +set timeout 60 +match_max 100000 + +expect_after { + # Do not ignore eof from expect + -i $any_spawn_id eof { exp_continue } + # A default timeout action is to do nothing, change it to fail + -i $any_spawn_id timeout { exit 1 } +} + +spawn bash -c "source $basedir/../shell_config.sh ; \$CLICKHOUSE_CLIENT_BINARY \$CLICKHOUSE_CLIENT_OPT --disable_suggestion --enable-progress-table-toggle=0 --history_file=$history_file" + +# (?n) - Do not match new lines +expect -re "(?n)ClickHouse client version \[\\d\]{2}\.\[\\d\]{1,2}\.\[\\d\]{1,2}\.\[\\d\]{1,}.*\r" +expect -re "(?n)Connecting to database .* at localhost:9000 as user default\.\r" +expect -re "(?n)Connected to ClickHouse server version \[\\d\]{2}\.\[\\d\]{1,2}\.\[\\d\]{1,2}\.\r" +expect ":) " + +send -- "SELECT (+123) AS x" +expect {SELECT (+1) AS x} + +send -- "\r" +expect ":) " + +send -- "" +expect eof diff --git a/tests/queries/0_stateless/03272_client_highlighting_bug.reference b/tests/queries/0_stateless/03272_client_highlighting_bug.reference new file mode 100644 index 00000000000..e69de29bb2d