Преглед изворни кода

[analyser] Add checkMissingLimit() in SQL statement

Romain Rigaux пре 4 година
родитељ
комит
9e829bd35c

+ 1 - 0
desktop/core/src/desktop/js/apps/editor/execution/sqlExecutable.ts

@@ -50,6 +50,7 @@ export default class SqlExecutable extends Executable {
 
   getStatement(): string {
     let statement = this.getRawStatement();
+
     if (
       this.parsedStatement.firstToken &&
       this.parsedStatement.firstToken.toLowerCase() === 'select' &&

+ 17 - 7
desktop/core/src/desktop/js/catalog/optimizer/SqlAnalyzer.ts

@@ -59,15 +59,10 @@ export default class SqlAnalyzer implements Optimizer {
         apiPromise.cancel();
       });
 
-      const autocompleter = await sqlParserRepository.getAutocompleteParser(this.connector.dialect);
       const snippet = JSON.parse(options.snippetJson);
-      const sqlParseResult = autocompleter.parseSql(snippet.statement + ' ', '');
+      const missingLimit = await this.checkMissingLimit(snippet.statement, this.connector.dialect);
 
-      const hasLimit = sqlParseResult.locations.some(
-        location => location.type === 'limitClause' && !location.missing
-      );
-
-      const hints: RiskHint[] = !hasLimit
+      const hints: RiskHint[] = missingLimit
         ? [
             {
               riskTables: [],
@@ -98,6 +93,21 @@ export default class SqlAnalyzer implements Optimizer {
     });
   }
 
+  async checkMissingLimit(statement: string, dialect: string): Promise<boolean> {
+    const autocompleter = await sqlParserRepository.getAutocompleteParser(dialect);
+    const parsedStatement = autocompleter.parseSql(statement + ' ', '');
+
+    return (
+      parsedStatement.locations.some(
+        location => location.type === 'statementType' && location.identifier === 'SELECT'
+      ) &&
+      parsedStatement.locations.some(location => location.type === 'table') &&
+      parsedStatement.locations.some(location => {
+        return location.type === 'limitClause' && location.missing;
+      })
+    );
+  }
+
   fetchTopJoins(options: PopularityOptions): CancellablePromise<TopJoins> {
     const apiPromise = this.apiStrategy.fetchTopJoins(options);
 

+ 1 - 0
desktop/core/src/desktop/js/parse/types.ts

@@ -51,6 +51,7 @@ export interface SyntaxError {
 }
 
 export interface IdentifierLocation {
+  identifier: string;
   type: string;
   alias?: string;
   source?: string;