mirror of https://github.com/apache/druid.git
make completions smarter (#13830)
This commit is contained in:
parent
70f9052f1d
commit
e4e6c7ed01
|
@ -72,9 +72,10 @@ export interface FlexibleQueryInputProps {
|
|||
|
||||
export interface FlexibleQueryInputState {
|
||||
// For reasons (https://github.com/securingsincity/react-ace/issues/415) react ace editor needs an explicit height
|
||||
// Since this component will grown and shrink dynamically we will measure its height and then set it.
|
||||
// Since this component will grow and shrink dynamically we will measure its height and then set it.
|
||||
editorHeight: number;
|
||||
completions: any[];
|
||||
quotedCompletions: Ace.Completion[];
|
||||
unquotedCompletions: Ace.Completion[];
|
||||
prevColumnMetadata?: readonly ColumnMetadata[];
|
||||
prevCurrentTable?: string;
|
||||
prevCurrentSchema?: string;
|
||||
|
@ -89,7 +90,7 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
static replaceDefaultAutoCompleter(): void {
|
||||
if (!langTools) return;
|
||||
|
||||
const keywordList = ([] as any[]).concat(
|
||||
const keywordList = ([] as Ace.Completion[]).concat(
|
||||
SQL_KEYWORDS.map(v => ({ name: v, value: v, score: 0, meta: 'keyword' })),
|
||||
SQL_EXPRESSION_PARTS.map(v => ({ name: v, value: v, score: 0, meta: 'keyword' })),
|
||||
SQL_CONSTANTS.map(v => ({ name: v, value: v, score: 0, meta: 'constant' })),
|
||||
|
@ -108,7 +109,13 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
langTools.snippetCompleter,
|
||||
langTools.textCompleter,
|
||||
{
|
||||
getCompletions: (_editor: any, _session: any, _pos: any, _prefix: any, callback: any) => {
|
||||
getCompletions: (
|
||||
_state: string,
|
||||
_session: Ace.EditSession,
|
||||
_pos: Ace.Point,
|
||||
_prefix: string,
|
||||
callback: any,
|
||||
) => {
|
||||
return callback(null, keywordList);
|
||||
},
|
||||
getDocTooltip: (item: any) => {
|
||||
|
@ -123,17 +130,19 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
static addFunctionAutoCompleter(): void {
|
||||
if (!langTools) return;
|
||||
|
||||
const functionList: any[] = Object.entries(SQL_FUNCTIONS).flatMap(([name, versions]) => {
|
||||
return versions.map(([args, description]) => ({
|
||||
name: name,
|
||||
value: versions.length > 1 ? `${name}(${args})` : name,
|
||||
score: 1100, // Use a high score to appear over the 'local' suggestions that have a score of 1000
|
||||
meta: 'function',
|
||||
syntax: `${name}(${args})`,
|
||||
description,
|
||||
completer: COMPLETER,
|
||||
}));
|
||||
});
|
||||
const functionList: Ace.Completion[] = Object.entries(SQL_FUNCTIONS).flatMap(
|
||||
([name, versions]) => {
|
||||
return versions.map(([args, description]) => ({
|
||||
name: name,
|
||||
value: versions.length > 1 ? `${name}(${args})` : name,
|
||||
score: 1100, // Use a high score to appear over the 'local' suggestions that have a score of 1000
|
||||
meta: 'function',
|
||||
syntax: `${name}(${args})`,
|
||||
description,
|
||||
completer: COMPLETER,
|
||||
}));
|
||||
},
|
||||
);
|
||||
|
||||
langTools.addCompleter({
|
||||
getCompletions: (_editor: any, _session: any, _pos: any, _prefix: any, callback: any) => {
|
||||
|
@ -154,6 +163,43 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
<div class="doc-description">${item.description}</div>`;
|
||||
}
|
||||
|
||||
static getCompletions(
|
||||
columnMetadata: readonly ColumnMetadata[],
|
||||
currentSchema: string | undefined,
|
||||
currentTable: string | undefined,
|
||||
quote: boolean,
|
||||
): Ace.Completion[] {
|
||||
return ([] as Ace.Completion[]).concat(
|
||||
uniq(columnMetadata.map(d => d.TABLE_SCHEMA)).map(v => ({
|
||||
value: quote ? String(T(v)) : v,
|
||||
score: 10,
|
||||
meta: 'schema',
|
||||
})),
|
||||
uniq(
|
||||
columnMetadata
|
||||
.filter(d => (currentSchema ? d.TABLE_SCHEMA === currentSchema : true))
|
||||
.map(d => d.TABLE_NAME),
|
||||
).map(v => ({
|
||||
value: quote ? String(T(v)) : v,
|
||||
score: 49,
|
||||
meta: 'datasource',
|
||||
})),
|
||||
uniq(
|
||||
columnMetadata
|
||||
.filter(d =>
|
||||
currentTable && currentSchema
|
||||
? d.TABLE_NAME === currentTable && d.TABLE_SCHEMA === currentSchema
|
||||
: true,
|
||||
)
|
||||
.map(d => d.COLUMN_NAME),
|
||||
).map(v => ({
|
||||
value: quote ? String(C(v)) : v,
|
||||
score: 50,
|
||||
meta: 'column',
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(props: FlexibleQueryInputProps, state: FlexibleQueryInputState) {
|
||||
const { columnMetadata, currentSchema, currentTable } = props;
|
||||
|
||||
|
@ -163,38 +209,19 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
currentSchema !== state.prevCurrentSchema ||
|
||||
currentTable !== state.prevCurrentTable)
|
||||
) {
|
||||
const completions = ([] as any[]).concat(
|
||||
uniq(columnMetadata.map(d => d.TABLE_SCHEMA)).map(v => ({
|
||||
value: String(T(v)),
|
||||
score: 10,
|
||||
meta: 'schema',
|
||||
})),
|
||||
uniq(
|
||||
columnMetadata
|
||||
.filter(d => (currentSchema ? d.TABLE_SCHEMA === currentSchema : true))
|
||||
.map(d => d.TABLE_NAME),
|
||||
).map(v => ({
|
||||
value: String(T(v)),
|
||||
score: 49,
|
||||
meta: 'datasource',
|
||||
})),
|
||||
uniq(
|
||||
columnMetadata
|
||||
.filter(d =>
|
||||
currentTable && currentSchema
|
||||
? d.TABLE_NAME === currentTable && d.TABLE_SCHEMA === currentSchema
|
||||
: true,
|
||||
)
|
||||
.map(d => d.COLUMN_NAME),
|
||||
).map(v => ({
|
||||
value: String(C(v)),
|
||||
score: 50,
|
||||
meta: 'column',
|
||||
})),
|
||||
);
|
||||
|
||||
return {
|
||||
completions,
|
||||
quotedCompletions: FlexibleQueryInput.getCompletions(
|
||||
columnMetadata,
|
||||
currentSchema,
|
||||
currentTable,
|
||||
true,
|
||||
),
|
||||
unquotedCompletions: FlexibleQueryInput.getCompletions(
|
||||
columnMetadata,
|
||||
currentSchema,
|
||||
currentTable,
|
||||
false,
|
||||
),
|
||||
prevColumnMetadata: columnMetadata,
|
||||
prevCurrentSchema: currentSchema,
|
||||
prevCurrentTable: currentTable,
|
||||
|
@ -207,7 +234,8 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
super(props, context);
|
||||
this.state = {
|
||||
editorHeight: 200,
|
||||
completions: [],
|
||||
quotedCompletions: [],
|
||||
unquotedCompletions: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -216,8 +244,20 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
FlexibleQueryInput.addFunctionAutoCompleter();
|
||||
if (langTools) {
|
||||
langTools.addCompleter({
|
||||
getCompletions: (_editor: any, _session: any, _pos: any, _prefix: any, callback: any) => {
|
||||
callback(null, this.state.completions);
|
||||
getCompletions: (
|
||||
_state: string,
|
||||
session: Ace.EditSession,
|
||||
pos: Ace.Point,
|
||||
prefix: string,
|
||||
callback: any,
|
||||
) => {
|
||||
const charBeforePrefix = session.getLine(pos.row)[pos.column - prefix.length - 1];
|
||||
callback(
|
||||
null,
|
||||
charBeforePrefix === '"'
|
||||
? this.state.unquotedCompletions
|
||||
: this.state.quotedCompletions,
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue