Skip to content

Commit 29feb45

Browse files
committed
Merge remote-tracking branch 'origin/backlog/add-sql-query-support-to-logexplorer-via-opensearch' into backlog/add-sql-query-support-to-logexplorer-via-opensearch
2 parents f68a622 + fb3deb6 commit 29feb45

2 files changed

Lines changed: 53 additions & 8 deletions

File tree

frontend/src/app/shared/components/code-editor/code-editor.component.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,28 @@
99
class="btn utm-button utm-button-primary"
1010
ngbTooltip="Execute Query" tooltipClass="utm-tooltip-top"
1111
(click)="executeQuery()"
12-
[disabled]="isExecuting || !sqlQuery.trim()"
12+
[disabled]="!sqlQuery.trim()"
1313
>
14-
<i [ngClass]="isExecuting ? 'icon-spinner4 spinner' : 'icon-play3'"></i>
14+
<i [ngClass]="'icon-play4'"></i>
1515
</button>
1616
<button class="btn utm-button utm-button-primary"
1717
ngbTooltip="Format SQL" tooltipClass="utm-tooltip-top"
1818
(click)="formatQuery()"
19-
[disabled]="isExecuting || !sqlQuery.trim()"
19+
[disabled]="!sqlQuery.trim()"
2020
>
2121
<i class="fa fa-indent"></i>
2222
</button>
2323
<button class="btn utm-button utm-button-primary"
2424
ngbTooltip="Copy Query" tooltipClass="utm-tooltip-top"
2525
(click)="copyQuery()"
26-
[disabled]="isExecuting || !sqlQuery.trim()"
26+
[disabled]="!sqlQuery.trim()"
2727
>
2828
<i class="icon-copy3"></i>
2929
</button>
3030
<button class="btn utm-button utm-button-primary"
3131
ngbTooltip="Clear" tooltipClass="utm-tooltip-top"
3232
(click)="clearQuery()"
33-
[disabled]="isExecuting || !sqlQuery.trim()">
33+
[disabled]="!sqlQuery.trim()">
3434
<i class="icon-trash"></i>
3535
</button>
3636
</div>

frontend/src/app/shared/components/code-editor/code-editor.component.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ export class CodeEditorComponent implements OnInit {
3030
@Output() execute = new EventEmitter<string>();
3131
@Output() clearData = new EventEmitter<void>();
3232
@Input() queryError: string | null = null;
33-
34-
isExecuting = false;
3533
sqlQuery = '';
3634
errorMessage = '';
3735
successMessage = '';
@@ -61,7 +59,6 @@ export class CodeEditorComponent implements OnInit {
6159

6260
executeQuery(): void {
6361
this.resetMessages();
64-
6562
const query = this.sqlQuery ? this.sqlQuery.trim() : '';
6663
if (!query) {
6764
this.errorMessage = 'The query cannot be empty.';
@@ -150,6 +147,14 @@ export class CodeEditorComponent implements OnInit {
150147
return 'Parentheses are not balanced.';
151148
}
152149

150+
if (this.hasMisplacedCommas(trimmed)) {
151+
return 'Query contains misplaced commas.';
152+
}
153+
154+
if (this.hasSubqueryWithoutAlias(trimmed)) {
155+
return 'Subquery in FROM must have an alias.';
156+
}
157+
153158
const functions = this.extractFunctions(upper);
154159
for (const func of functions) {
155160
if (!allowedFunctions.has(func)) {
@@ -202,4 +207,44 @@ export class CodeEditorComponent implements OnInit {
202207

203208
return funcs;
204209
}
210+
211+
private hasMisplacedCommas(query: string): boolean {
212+
const upperQuery = query.toUpperCase();
213+
214+
if (upperQuery.startsWith('SELECT ,') || upperQuery.includes(',,')) {
215+
return true;
216+
}
217+
218+
if (/,\s*FROM/i.test(upperQuery)) {
219+
return true;
220+
}
221+
222+
const selectPart = query
223+
.replace(/^SELECT\s+/i, '')
224+
.replace(/\s+FROM.*$/i, '')
225+
.trim();
226+
227+
if (selectPart.startsWith(',') || selectPart.endsWith(',')) {
228+
return true;
229+
}
230+
231+
const fields = selectPart.split(',');
232+
for (const f of fields) {
233+
if (f.trim() === '') {
234+
return true;
235+
}
236+
}
237+
238+
return false;
239+
}
240+
241+
private hasSubqueryWithoutAlias(query: string): boolean {
242+
const subqueryRegex = /FROM\s*\([^)]*\)/i;
243+
if (!subqueryRegex.test(query)) {
244+
return false;
245+
}
246+
const aliasRegex = /FROM\s*\([^)]*\)\s+(AS\s+\w+|\w+)/i;
247+
return !aliasRegex.test(query);
248+
}
249+
205250
}

0 commit comments

Comments
 (0)