Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


...

Page properties

...


Discussion

...

threadhttps://

...

...

thread/8d580jcqzpcbmfwqvhjso82hdd2x0461
Vote threadhttps://lists.apache.org/thread/f14jjhrscrdv7h6zw6h1k72nfx232qxs
JIRA

Jira
serverASF JIRA
serverId5aa69414-a9e9-3523-82ec-879b028fb15b
keyFLINK-24890

Release1.18.0


POC Demo: https://asciinema.org/a/446247?speed=3.0

...

JIRAhere (<- link to https://issues.apache.org/jira/browse/FLINK-XXXX)

Released: <Flink Version>

Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).

...

  1. line numbers + editing query consuming more than screen space
  2. autopairing[6] for single quote, sql identifier quote, square and round brackets could be turn on/off via property
    (requires update at least till 3.13.3) 
  3. Enabling/Disabling description for completion candidates via property. An example how it looks like is here [7]

Prompts

Prompts should be configured via property: both left and right prompts.


Implementation Details

Parsing

The main idea is to extend existing org.apache.flink.table.client.cli.SqlMultiLineParser . => No need to use Flink SQL parser
It should check the input if all quotes, comments, hints, brackets (square and round) are closed otherwise it throws new EOFError  - normal behavior in jline in case input should be continued on a new line.
During parsing need to keep track of cursor states if it is a comment, keyword, quoted string.

Code Block
java
java
public enum State {
        DEFAULT,
        KEYWORD, // used only for highlighting
        SINGLE_QUOTED,
        SQL_IDENTIFIER_QUOTED,
        HINT,
        LINE_COMMENTED,
        BLOCK_COMMENTED;
    }


This track could be used to answer a question at what state parser by the end of a query.
Also such track with recorded state for every cursor position could be used to do highlighting.

Highlighting

To do highlighting it is necessary to implement  org.jline.reader.impl.DefaultHighlighter.
From parser it could receive a track of state for each position and do highlighting.
Colors for different states are going to be defined in a separate SyntaxHighlightStyle class.

Code Block
java
java
private final AttributedStyle blockCommentStyle;
    private final AttributedStyle lineCommentStyle;
    private final AttributedStyle hintStyle;
    private final AttributedStyle defaultStyle;
    private final AttributedStyle keywordStyle;
    private final AttributedStyle numberStyle;
    private final AttributedStyle singleQuotedStyle;
    private final AttributedStyle sqlIdentifierStyle;

    public SyntaxHighlightStyle(
            AttributedStyle blockCommentStyle,
            AttributedStyle lineCommentStyle,
            AttributedStyle hintStyle,
            AttributedStyle defaultStyle,
            AttributedStyle keywordStyle,
            AttributedStyle numberStyle, 
            AttributedStyle singleQuotedStyle,
            AttributedStyle sqlIdentifierStyle) {
        this.blockCommentStyle = blockCommentStyle;
        this.lineCommentStyle = lineCommentStyle;
        this.hintStyle = hintStyle;
        this.defaultStyle = defaultStyle;
        this.keywordStyle = keywordStyle;
        this.numberStyle = numberStyle; 
        this.singleQuotedStyle = singleQuotedStyle;
        this.sqlIdentifierStyle = sqlIdentifierStyle;
    }


At the same time there could be enum of this styles and that will allow to add more styles for highlighting e.g.

Code Block
java
java
public enum BuiltInStyle {
        DEFAULT(null, null, null, null, null, null, null, null),
        DARK(BOLD_BLUE, WHITE, ITALIC_GREEN, ITALIC_GREEN, BOLD_GREEN, YELLOW, RED, MAGENTA),
        LIGHT(BOLD_RED, WHITE, ITALIC_CYAN, ITALIC_CYAN, BOLD_CYAN, YELLOW, GREEN, MAGENTA);
        private final SyntaxHighlightStyle style;

        BuiltInStyle(
                AttributedStyle keywordStyle,
                AttributedStyle defaultStyle,
                AttributedStyle blockCommentStyle,
                AttributedStyle lineCommentStyle,
                AttributedStyle hintStyle,
                AttributedStyle numberStyle,
                AttributedStyle singleQuotedStyle,
                AttributedStyle sqlIdentifierStyle) {
            style =
                    new SyntaxHighlightStyle(
                            blockCommentStyle,
                            lineCommentStyle,
                            hintStyle,
                            defaultStyle,
                            keywordStyle,
                            numberStyle,
                            singleQuotedStyle,
                            sqlIdentifierStyle);
        }

Completion

There are 2 types of completions: command completion and sql completion.

Currently for sql it is used CalciteAdviser.
Within this improvement the idea is to leave it except first words which are the same as Flink SQL command like "INSERT INTO", "BEGIN STATEMENT SET;" and so on...
For commands it is possible to use jline's org.jline.reader.impl.completer.ArgumentCompleter and org.jline.reader.impl.completer.AggregateCompleter.

The first one allows to build completers for commands consisting of several words e.g.  "BEGIN STATEMENT SET;" and the second one allows to unite them all together.

Cross dialect

Since there are at least 2 dialects in Flink (HIVE and DEFAULT). There could be a builtin dialect enum containing required info.
Taking current dialect it's possible to retrieve required info from that enum about quotes, comments and etc for parsing, highlighting and completion.

Code Block
java
java
public enum BuiltInDialect {
  DEFAULT("FlinkSQLDefaultDialect", () -> keywords(), '`', '\'', "\"", Pair.of("/*", "*/"), Pair.of("/*+", "*/"), "--");


  private final Supplier<Set<String>> keywords;
  private final char quote;
  private final char sqlIdentifierQuote;
  private final Pair<String, String> blockComments;
  private final Pair<String, String> hints;
  private final String lineComments;
...
}

So that means that adding a new dialect should be relatively simple.

Prompts

LineReader#readLine among other arguments has prompt and right  prompt value.

Widgets

Jline allows to define widgets implementing org.jline.reader.Widget and bind them to key strokes.

Within a widget it is possible to define an action e.g. changing a property and invoke redisplay - this is how toggle of line numbers or switching highlight schema could be done

Summary

After this FLIP finishes, the sql client will have the options.

...

OptionDefaultTypeDescription
sql-client.color-schema
'no'
Enum

Determine the color schema for syntax highlighting.

Will contain names of available color schemas

sql-client.autopairing`true`boolean

Determine whether autopairing is enabled or not.

sql-client.completion-description `false`booleanDetermine whether description for completion candidates is enabled or not.
sql-client.prompt.show-hint`false`boolean

Determine whether prompt shows hints about current input issue.

For more detailed about prompt values see Supported prompt hint values in sql client

sql-client.prompt.show-line-numbers`false`booleanDetermine whether prompt shows line numbers for multiline query.
sql-client.prompt.mask`default`StringDetermine a mask to build left prompt
sql-client.rightprompt.mask`default`StringDetermine a mask to build right prompt

Supported prompt hint values in sql client

PromptMeaning
;>Waiting for the next line of multi-line query, waiting for completion of query with semicolon (;)
'>Waiting for the next line, waiting for a completion of string that began with a single quote (')
`>Waiting for the next line, waiting for a completion of string that began with a back tick (`)
*\>Waiting for the next line, waiting for completion of a multi-line comment that began with (/*)
)>Waiting for the next line, waiting for completion of a string that began with a round bracket (
]>Waiting for the next line, waiting for completion of a string that began with a square bracket [
extra )>There is an extra round bracket ), that is not opened with (
extra ]>There is an extra square bracket ], that is not opened with [
extra *\>

There is an extra closing of multi-line comment *\, that is not opened with \*

Supported prompt options (both for left and right prompts)

OptionDescription
\cCurrent catalog
\dCurrent database
\:property_name:The value of Flink property_name property
\[ ... \]

Prompts can contain terminal control characters which, for example, change the color, background, or style of the prompt text.

These non-printing control characters must be designated as invisible by surrounding them with \[ and \].

Multiple pairs of these can occur within the prompt.

\{...\}Datetime pattern to convert current datetime. Compatible with Java’s SimpleDateFormat.
\DThe full current date (yyyy-MM-dd HH:mm:ss.SSS)
\mMinutes of the current time
\OThe current month in three-letter format (Jan, Feb, …)
\oThe current month in numeric format
\Pam/pm
\RThe current time, in 24-hour military time (0–23)
\rThe current time, standard 12-hour time (1–12)
\sSeconds of the current time
\wThe current day of the week in three-letter format (Mon, Tue, …)
\YThe current year, four digits
\yThe current year, two digits
\\A literal \ backslash character
\x

x, for any x not listed above

Compatibility, Deprecation, and Migration Plan

...