浏览代码

[core] Autocomplete values in Impala statement conditions

Johan Ahlen 10 年之前
父节点
当前提交
d7ecb07

+ 50 - 1
desktop/core/src/desktop/static/desktop/js/sqlAutocompleter.js

@@ -170,6 +170,41 @@
     return result;
     return result;
   };
   };
 
 
+  SqlAutocompleter.prototype.getValueReferences = function (conditionMatch, fromReferences, tableAndComplexRefs, callback) {
+    var self = this;
+
+    var fields = conditionMatch[1].split(".");
+    var tableName = null;
+    if (fields[0] in fromReferences.complex) {
+      var complexRef = fields.shift();
+      fields = fromReferences.complex[complexRef].concat(fields);
+    }
+    if (fields[0] in fromReferences.tables) {
+      tableName = fromReferences.tables[fields.shift()];
+    }
+    if (! tableName && tableAndComplexRefs.length === 1) {
+      tableName = tableAndComplexRefs[0].value;
+    }
+    if (tableName) {
+      self.snippet.getAssistHelper().fetchFields(self.snippet, tableName, fields, function(data) {
+        if (data.sample) {
+          var isString = data.type === "string";
+          var values = $.map(data.sample.sort(), function(value, index) {
+            return {
+              meta: "value",
+              score: 900 - index,
+              value: isString ? "'" + value + "'" : new String(value)
+            }
+          });
+          callback(tableAndComplexRefs.concat(values));
+        } else {
+          callback(tableAndComplexRefs);
+        }
+      });
+      return;
+    }
+  };
+
   SqlAutocompleter.prototype.extractFields = function (data, valuePrefix, includeStar, extraSuggestions) {
   SqlAutocompleter.prototype.extractFields = function (data, valuePrefix, includeStar, extraSuggestions) {
     var fields = [];
     var fields = [];
     var result = [];
     var result = [];
@@ -298,6 +333,7 @@
 
 
       var fromReferences = self.getFromReferenceIndex(beforeCursor + afterCursor);
       var fromReferences = self.getFromReferenceIndex(beforeCursor + afterCursor);
       var viewReferences = self.getViewReferenceIndex(beforeCursor + afterCursor, hiveSyntax);
       var viewReferences = self.getViewReferenceIndex(beforeCursor + afterCursor, hiveSyntax);
+      var conditionMatch = beforeCursor.match(/(\S+)\s*=\s*$/);
 
 
       var tableName = "";
       var tableName = "";
 
 
@@ -333,13 +369,26 @@
           };
           };
         });
         });
 
 
-        callback(tableRefs.concat(complexRefs));
+        if (conditionMatch && impalaSyntax) {
+          self.getValueReferences(conditionMatch, fromReferences, tableRefs.concat(complexRefs), callback);
+        } else {
+          callback(tableRefs.concat(complexRefs));
+        }
         return;
         return;
       } else if (Object.keys(fromReferences.tables).length == 1) {
       } else if (Object.keys(fromReferences.tables).length == 1) {
         // SELECT column. or just SELECT
         // SELECT column. or just SELECT
         // We use first and only table reference if exist
         // We use first and only table reference if exist
         // if there are no parts the call to getFields will fetch the columns
         // if there are no parts the call to getFields will fetch the columns
         tableName = fromReferences.tables[Object.keys(fromReferences.tables)[0]];
         tableName = fromReferences.tables[Object.keys(fromReferences.tables)[0]];
+        if (conditionMatch && impalaSyntax) {
+          var tableRefs = [{
+            value: tableName,
+            score: 1000,
+            meta: 'table'
+          }];
+          self.getValueReferences(conditionMatch, fromReferences, tableRefs, callback);
+          return;
+        }
       } else if (parts.length > 0 && viewReferences.index[parts[0]] && viewReferences.index[parts[0]].leadingPath.length > 0) {
       } else if (parts.length > 0 && viewReferences.index[parts[0]] && viewReferences.index[parts[0]].leadingPath.length > 0) {
         tableName = fromReferences.tables[viewReferences.index[parts[0]].leadingPath[0]];
         tableName = fromReferences.tables[viewReferences.index[parts[0]].leadingPath[0]];
       } else {
       } else {

+ 28 - 0
desktop/core/src/desktop/static/desktop/spec/sqlAutocompleterSpec.js

@@ -695,6 +695,34 @@ define([
           expectedSuggestions: ["fieldA", "fieldB"]
           expectedSuggestions: ["fieldA", "fieldB"]
         });
         });
       });
       });
+
+      it("should suggest values for map keys", function() {
+        assertAutoComplete({
+          serverResponses: {
+            "/notebook/api/autocomplete/testDb/testTable/testMap/key" : {
+              sample: ["value1", "value2"],
+              type: "string"
+            }
+          },
+          beforeCursor: "SELECT * FROM testTable t, t.testMap tm WHERE tm.key =",
+          afterCursor: "",
+          expectedSuggestions: ["t.", "tm.", "'value1'", "'value2'"]
+        });
+      });
+
+      it("should suggest values for columns in conditions", function() {
+        assertAutoComplete({
+          serverResponses: {
+            "/notebook/api/autocomplete/testDb/testTable/id" : {
+              sample: [1, 2, 3],
+              type: "int"
+            }
+          },
+          beforeCursor: "SELECT * FROM testTable WHERE id =",
+          afterCursor: "",
+          expectedSuggestions: ["testTable", "1", "2", "3"]
+        });
+      });
     });
     });
 
 
     describe("field completion", function() {
     describe("field completion", function() {