Explorar el Código

HUE-7971 [editor] Make sure a database is set for column locations

Johan Ahlen hace 7 años
padre
commit
266665b30c
Se han modificado 1 ficheros con 90 adiciones y 63 borrados
  1. 90 63
      desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

+ 90 - 63
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -3562,9 +3562,26 @@
 
       self.disposeFunctions = [];
 
+      self.databaseIndex = {};
+
       self.attachStatementLocator();
       self.attachSqlWorker();
       self.attachGutterHandler();
+
+      var updateDatabaseIndex = function (databaseList) {
+        self.databaseIndex = {};
+        databaseList.forEach(function (database) {
+          self.databaseIndex[database.toLowerCase()] = true;
+        })
+      };
+
+      var databaseSub = self.snippet.availableDatabases.subscribe(updateDatabaseIndex);
+
+      self.disposeFunctions.push(function () {
+        databaseSub.dispose();
+      });
+
+      updateDatabaseIndex(self.snippet.availableDatabases());
     }
 
     AceLocationHandler.prototype.attachGutterHandler = function () {
@@ -4109,6 +4126,15 @@
       verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
     };
 
+    AceLocationHandler.prototype.isDatabase = function (databaseIdentifier) {
+      var self = this;
+      if (!databaseIdentifier) {
+        return false;
+      }
+      var cleanIdentifier = databaseIdentifier.replace(/^\s*`/, '').replace(/`\s*$/, '').toLowerCase();
+      return self.databaseIndex[cleanIdentifier];
+    };
+
     AceLocationHandler.prototype.attachSqlWorker = function () {
       var self = this;
 
@@ -4127,85 +4153,86 @@
         getLocationsSub.remove();
       });
 
-      // The parser isn't aware of the DDL so sometimes it marks complex columns as tables
-      // I.e. "Impala SELECT a FROM b.c" Is 'b' a database or a table? If table then 'c' is complex
-      var identifyComplexLocations = function (locations, callback) {
-        if (self.snippet.type() === 'impala') {
-          apiHelper.getDatabases(self.snippet.type()).done(function (databases) {
-            locations.forEach(function (location) {
-              if (location.identifierChain && location.identifierChain.length > 2
-                && (location.type === 'table' || location.type === 'column')
-                && databases.indexOf(location.identifierChain[0].name.toLowerCase()) !== -1) {
-                  location.type = 'complex';
-              }
-            });
-            callback();
-          });
-        } else {
-          callback();
-        }
-      };
-
       var locationWorkerSub = huePubSub.subscribe('ace.sql.location.worker.message', function (e) {
         if (e.data.id !== self.snippet.id() || e.data.editorChangeTime !== self.editor.lastChangeTime || !self.snippet.isSqlDialect()) {
           return;
         }
 
-        identifyComplexLocations(e.data.locations, function () {
-          lastKnownLocations = {
-            id: self.editorId,
-            type: self.snippet.type(),
-            defaultDatabase: self.snippet.database(),
-            locations: e.data.locations,
-            editorChangeTime: e.data.editorChangeTime,
-            activeStatementLocations: e.data.activeStatementLocations,
-            totalStatementCount: e.data.totalStatementCount,
-            activeStatementIndex: e.data.activeStatementIndex
-          };
+        lastKnownLocations = {
+          id: self.editorId,
+          type: self.snippet.type(),
+          defaultDatabase: self.snippet.database(),
+          locations: e.data.locations,
+          editorChangeTime: e.data.editorChangeTime,
+          activeStatementLocations: e.data.activeStatementLocations,
+          totalStatementCount: e.data.totalStatementCount,
+          activeStatementIndex: e.data.activeStatementIndex
+        };
 
-          // Clear out old parse locations to prevent them from being shown when there's a syntax error in the statement
-          while(activeTokens.length > 0) {
-            delete activeTokens.pop().parseLocation;
+        // Clear out old parse locations to prevent them from being shown when there's a syntax error in the statement
+        while(activeTokens.length > 0) {
+          delete activeTokens.pop().parseLocation;
+        }
+
+        var tokensToVerify = [];
+
+        e.data.locations.forEach(function (location) {
+          if (['statement', 'selectList', 'whereClause', 'limitClause'].indexOf(location.type) !== -1
+            || ((location.type === 'table' || location.type === 'column') && typeof location.identifierChain === 'undefined')) {
+            return;
           }
 
-          var tokensToVerify = [];
+          if (location.identifierChain && location.identifierChain.length && location.identifierChain[0].name) {
+            // Add databases if missing in the table identifier chains
+            if (location.tables) {
+              location.tables.forEach(function (table) {
+                if (table.identifierChain && table.identifierChain.length === 1 && table.identifierChain[0].name) {
+                  table.identifierChain.unshift({ name: self.snippet.database() });
+                }
+              });
+            }
 
-          e.data.locations.forEach(function (location) {
-            if (['statement', 'selectList', 'whereClause', 'limitClause'].indexOf(location.type) !== -1 ||  ((location.type === 'table' || location.type === 'column') && typeof location.identifierChain === 'undefined')) {
-              return;
+            // The parser isn't aware of the DDL so sometimes it marks complex columns as tables
+            // I.e. "Impala SELECT a FROM b.c" Is 'b' a database or a table? If table then 'c' is complex
+            if (self.snippet.type() === 'impala' &&
+              location.identifierChain.length > 2 &&
+              (location.type === 'table' || location.type === 'column') &&
+              self.isDatabase(location.identifierChain[0].name)) {
+              location.type = 'complex';
             }
+          }
 
-            var token = self.editor.getSession().getTokenAt(location.location.first_line - 1, location.location.first_column);
+          var token = self.editor.getSession().getTokenAt(location.location.first_line - 1, location.location.first_column);
 
-            if (token && token.value && /`$/.test(token.value)) {
-              // Ace getTokenAt() thinks the first ` is a token, column +1 will include the first and last.
-              token = self.editor.getSession().getTokenAt(location.location.first_line - 1, location.location.first_column + 1);
-            }
-            if (token && token.value && /^\s*\$\{\s*$/.test(token.value)) {
-              token = null;
-            }
-            if (token && token.value) {
-              var AceRange = ace.require('ace/range').Range;
-              // The Ace tokenizer also splits on '{', '(' etc. hence the actual value;
-              token.actualValue = self.editor.getSession().getTextRange(new AceRange(location.location.first_line - 1, location.location.first_column - 1, location.location.last_line - 1, location.location.last_column - 1));
-            }
+          if (token && token.value && /`$/.test(token.value)) {
+            // Ace getTokenAt() thinks the first ` is a token, column +1 will include the first and last.
+            token = self.editor.getSession().getTokenAt(location.location.first_line - 1, location.location.first_column + 1);
+          }
+          if (token && token.value && /^\s*\$\{\s*$/.test(token.value)) {
+            token = null;
+          }
+          if (token && token.value) {
+            var AceRange = ace.require('ace/range').Range;
+            // The Ace tokenizer also splits on '{', '(' etc. hence the actual value;
+            token.actualValue = self.editor.getSession().getTextRange(new AceRange(location.location.first_line - 1, location.location.first_column - 1, location.location.last_line - 1, location.location.last_column - 1));
+          }
 
-            if (token !== null) {
-              token.parseLocation = location;
-              activeTokens.push(token);
-              delete token.notFound;
-              delete token.syntaxError;
-              if (location.active) {
-                tokensToVerify.push(token);
-              }
+          if (token !== null) {
+            token.parseLocation = location;
+            activeTokens.push(token);
+            delete token.notFound;
+            delete token.syntaxError;
+            if (location.active) {
+              tokensToVerify.push(token);
             }
-          });
-
-          if (self.snippet.type() === 'impala' || self.snippet.type() === 'hive') {
-            self.verifyExists(tokensToVerify, e.data.activeStatementLocations);
           }
-          huePubSub.publish('editor.active.locations', lastKnownLocations);
         });
+
+        if (self.snippet.type() === 'impala' || self.snippet.type() === 'hive') {
+          self.verifyExists(tokensToVerify, e.data.activeStatementLocations);
+        }
+        huePubSub.publish('editor.active.locations', lastKnownLocations);
+
       });
 
       self.disposeFunctions.push(function () {