浏览代码

HUE-6159 [autocomplete] Don't mark column alias references as columns belonging to a table

i.e. the last 'foo' in "SELECT cast(id AS int) foo FROM tbl ORDER BY foo;" should not be marked as a column from the table 'tbl'
Johan Ahlen 8 年之前
父节点
当前提交
35c1587

+ 17 - 1
desktop/core/src/desktop/static/desktop/js/autocomplete/spec/sqlSpecLocations.js

@@ -35,6 +35,22 @@
       });
     };
 
+    it('should report locations for "select cos(1) as foo from customers order by foo;"', function () {
+      assertLocations({
+        beforeCursor: 'select cos(1) as foo from customers order by foo; ',
+        expectedLocations: [
+          { type: 'statement', location: { first_line: 1, last_line: 1, first_column: 1, last_column: 49 } },
+          { type: 'selectList', missing: false, location: { first_line: 1, last_line: 1, first_column: 8, last_column: 21 } },
+          { type: 'function', location: { first_line: 1, last_line: 1, first_column: 8, last_column: 10 }, function: 'cos' },
+          { type: 'alias', source: 'column', alias: 'foo', location: { first_line: 1, last_line: 1, first_column: 18, last_column: 21 }, parentLocation: { first_line: 1, last_line: 1, first_column: 8, last_column: 14 } },
+          { type: 'table', location: { first_line: 1, last_line: 1, first_column: 27, last_column: 36 }, identifierChain: [{ name: 'customers' }] },
+          { type: 'whereClause', missing: true, location: { first_line: 1, last_line: 1, first_column: 36, last_column: 36 } },
+          { type: 'alias', location: { first_line: 1, last_line: 1, first_column: 46, last_column: 49 }, alias: 'foo', source: 'column', parentLocation: { first_line: 1, last_line: 1, first_column: 8, last_column: 14 } },
+          { type: 'limitClause', missing: true, location: { first_line: 1, last_line: 1, first_column: 49, last_column: 49 } }
+        ]
+      });
+    });
+
     it('should report locations for "SELECT * FROM tbl WHERE tbl.mp[\'key\'].bla;"', function () {
       assertLocations({
         beforeCursor: 'SELECT * FROM tbl WHERE tbl.mp[\'key\'].bla; ',
@@ -839,7 +855,7 @@
             { type: 'limitClause', subquery: true, missing: true, location: { first_line: 1, last_line: 1, first_column: 241, last_column: 241 }},
             { type: 'alias', source: 'subquery', alias: 'tmp', location: { first_line: 1, last_line: 1, first_column: 243, last_column: 246 } },
             { type: 'whereClause', missing: true, location: { first_line: 1, last_line: 1, first_column: 246, last_column: 246 }},
-            { type: 'column', location: { first_line: 1, last_line: 1, first_column: 256, last_column: 257 }, identifierChain: [{ name: 'r' }], tables: [{ subQuery: 'tmp' }], qualified: false },
+            { type: 'alias', location: { first_line: 1, last_line: 1, first_column: 256, last_column: 257 }, alias: 'r', source: 'column', parentLocation: { first_line: 1, last_line: 1, first_column: 16, last_column: 31 } },
             { type: 'limitClause', missing: false, location: { first_line: 1, last_line: 1, first_column: 263, last_column: 271 }}
           ]
         });

+ 16 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlParseSupport.js

@@ -460,6 +460,22 @@ var SqlParseSupport = (function () {
         if (location.type === 'unknown') {
           location.type = 'column';
         }
+
+        // A column location might refer to a previously defined alias, i.e. last 'foo' in "SELECT cast(id AS int) foo FROM tbl ORDER BY foo;"
+        if (location.type === 'column') {
+          for (var j = i - 1; j >= 0; j--) {
+            var otherLocation = parser.yy.locations[j];
+            if (otherLocation.type === 'alias' && otherLocation.source === 'column' && location.identifierChain && location.identifierChain.length === 1 && location.identifierChain[0].name && otherLocation.alias && location.identifierChain[0].name.toLowerCase() === otherLocation.alias.toLowerCase()) {
+              location.type = 'alias';
+              location.source = 'column';
+              location.alias = location.identifierChain[0].name;
+              delete location.identifierChain;
+              location.parentLocation = otherLocation.parentLocation;
+              break;
+            }
+          }
+        }
+
         if (location.type === 'column') {
           if (parser.isHive() && !location.linked) {
             location.identifierChain = parser.expandLateralViews(parser.yy.lateralViews, location.identifierChain);