diff --git a/src/utils/sql.ts b/src/utils/sql.ts index 0d42a0edb..174cc3d38 100644 --- a/src/utils/sql.ts +++ b/src/utils/sql.ts @@ -84,6 +84,8 @@ export const findStatementAtPosition = ( statements: { text: string; start: number; end: number }[], position: number ) => { + if (statements.length === 0) return null + // Check if cursor is exactly after a semicolon if (position > 0) { for (let i = 0; i < statements.length; i += 1) { @@ -99,6 +101,13 @@ export const findStatementAtPosition = ( return { statement, index: statements.indexOf(statement) } } + // Cursor in trailing whitespace after a statement (e.g. on empty lines below `;`) + for (let i = statements.length - 1; i >= 0; i -= 1) { + if (position > statements[i].start) { + return { statement: statements[i], index: i } + } + } + return null } diff --git a/src/views/dashboard/query/editor.vue b/src/views/dashboard/query/editor.vue index 40f1b55c6..5aa899be8 100644 --- a/src/views/dashboard/query/editor.vue +++ b/src/views/dashboard/query/editor.vue @@ -286,13 +286,6 @@ a-modal( return false }) - const handleReadySql = (payload: any) => { - sqlView.value = payload.view - } - const handleReadyPromql = (payload: any) => { - promqlView.value = payload.view - } - const remeasureEditors = () => { nextTick(() => { requestAnimationFrame(() => { @@ -345,6 +338,15 @@ a-modal( } } + const handleReadySql = (payload: any) => { + sqlView.value = payload.view + codeUpdate('sql') + } + const handleReadyPromql = (payload: any) => { + promqlView.value = payload.view + codeUpdate('promql') + } + const executeRunAll = async () => { const res = await runQuery(codes.value[queryType.value].trim(), queryType.value, false, promForm, 'run-all') if ((res as { cancelled?: boolean })?.cancelled) return @@ -352,8 +354,21 @@ a-modal( if (res?.log) session.appendLog(res.log) } + const resolveStatementToRun = () => { + if (queryType.value === 'promql') { + return currentStatement.value || codes.value.promql + } + const view = sqlView.value + if (view) { + const statements = parseSqlStatements(view.state.doc.toString()) + const result = findStatementAtPosition(statements, view.state.selection.main.from) + if (result) return result.statement.text + } + return currentStatement.value + } + const executePartQuery = async () => { - const res = await runQuery(currentStatement.value, queryType.value, false, promForm, 'run-part') + const res = await runQuery(resolveStatementToRun(), queryType.value, false, promForm, 'run-part') if ((res as { cancelled?: boolean })?.cancelled) return if (res?.results?.length) session.appendResults(res.results) if (res?.log) session.appendLog(res.log)