Переглянути джерело

HUE-7986 [autocomplete] Update the autocompleter and UDF library for Impala

- Added new boolean operators impala (IS TRUE, IS NOT TRUE, IS FALSE, IS NOT FALSE, IS UNKNOWN, and IS NOT UNKNOWN)
- Add support for SET ALL
- Add support for altering Kudu columns using ALTER TABLE
- Support SET COLUMN STATS through ALTER TABLE
- Update the UDF function library
Johan Ahlen 7 роки тому
батько
коміт
953d14f4d3

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/ace/mode-impala.js


+ 1 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql.jisonlex

@@ -316,6 +316,7 @@
 <impala>'ROLE'                             { return '<impala>ROLE'; }
 <impala>'ROLES'                            { return '<impala>ROLES'; }
 <impala>'STRUCT'                           { return 'STRUCT'; }
+<impala>'UNKNOWN'                          { return '<impala>UNKNOWN'; }
 <impala>\[BROADCAST\]                      { return '<impala>BROADCAST'; }
 <impala>\[NOSHUFFLE\]                      { return '<impala>NOSHUFFLE'; }
 <impala>\[SHUFFLE\]                        { return '<impala>SHUFFLE'; }

+ 121 - 4
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_alter.jison

@@ -140,6 +140,7 @@ AlterTable
  | AlterTableLeftSide AnyAdd '<hive>CONSTRAINT' RegularOrBacktickedIdentifier HiveForeignKeySpecification
  | AlterTableLeftSide AnyRename 'TO' RegularOrBackTickedSchemaQualifiedName
  | AlterTableLeftSide HiveSpecificOperations
+ | AlterTableLeftSide ImpalaSpecificOperations
  | AlterTableLeftSide DropOperations
  | AlterTableLeftSide OptionalPartitionOperations
  | AlterTableLeftSide PartitionSpec OptionalPartitionOperations
@@ -151,6 +152,7 @@ AlterTable_EDIT
  | AlterTableLeftSide_EDIT AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation OptionalPartitionSpecs OptionalCachedInOrUncached
  | AlterTableLeftSide_EDIT AnyRename 'TO' RegularOrBackTickedSchemaQualifiedName
  | AlterTableLeftSide_EDIT HiveSpecificOperations
+ | AlterTableLeftSide_EDIT ImpalaSpecificOperations
  | AlterTableLeftSide_EDIT DropOperations
  | AlterTableLeftSide_EDIT OptionalPartitionOperations
  | AlterTableLeftSide_EDIT PartitionSpec OptionalPartitionOperations
@@ -218,6 +220,7 @@ AlterTable_EDIT
  | AlterTableLeftSide AnyAdd '<hive>CONSTRAINT' RegularOrBacktickedIdentifier HivePrimaryKeySpecification_EDIT
  | AlterTableLeftSide AnyAdd '<hive>CONSTRAINT' RegularOrBacktickedIdentifier HiveForeignKeySpecification_EDIT
  | AlterTableLeftSide HiveSpecificOperations_EDIT
+ | AlterTableLeftSide ImpalaSpecificOperations_EDIT
  | AlterTableLeftSide OptionalPartitionOperations_EDIT
  | AlterTableLeftSide DropOperations_EDIT
  | AlterTableLeftSide 'CURSOR'
@@ -229,9 +232,10 @@ AlterTable_EDIT
          'RECOVER PARTITIONS', 'RENAME TO', 'REPLACE COLUMNS', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDE',
          'SET SERDEPROPERTIES', 'SET SKEWED LOCATION', 'SET TBLPROPERTIES', 'SKEWED BY', 'TOUCH', 'UNARCHIVE PARTITION']);
      } else if (parser.isImpala()) {
-       parser.suggestKeywords(['ADD COLUMNS', 'ADD PARTITION', 'ADD RANGE PARTITION', 'CHANGE', 'DROP COLUMN',
-         'DROP PARTITION', 'DROP RANGE PARTITION', 'PARTITION', 'RECOVER PARTITIONS', 'RENAME TO', 'REPLACE COLUMNS',
-         'SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION','SET SERDEPROPERTIES', 'SET TBLPROPERTIES', 'SET UNCACHED']);
+       parser.suggestKeywords(['ADD COLUMNS', 'ADD PARTITION', 'ADD RANGE PARTITION', 'ALTER', 'ALTER COLUMN', 'CHANGE',
+         'DROP COLUMN', 'DROP PARTITION', 'DROP RANGE PARTITION', 'PARTITION', 'RECOVER PARTITIONS', 'RENAME TO',
+         'REPLACE COLUMNS', 'SET CACHED IN', 'SET COLUMN STATS', 'SET FILEFORMAT', 'SET LOCATION','SET SERDEPROPERTIES',
+         'SET TBLPROPERTIES', 'SET UNCACHED']);
      }
    }
  | AlterTableLeftSide PartitionSpec 'CURSOR'
@@ -262,7 +266,7 @@ AlterTable_EDIT
      if (parser.isHive()) {
        parser.suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES', 'SKEWED LOCATION', 'TBLPROPERTIES']);
      } else if (parser.isImpala()) {
-       parser.suggestKeywords(['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES', 'TBLPROPERTIES', 'UNCACHED']);
+       parser.suggestKeywords(['CACHED IN', 'COLUMN STATS', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES', 'TBLPROPERTIES', 'UNCACHED']);
      }
    }
  | AlterTableLeftSide PartitionSpec OptionalPartitionOperations_EDIT
@@ -357,6 +361,119 @@ HiveSpecificOperations_EDIT
  | '<hive>TOUCH' OptionalPartitionSpec_EDIT
  ;
 
+ImpalaSpecificOperations
+ : 'ALTER' OptionalImpalaColumn ColumnIdentifier 'SET' KuduStorageAttribute SetValue
+   {
+     parser.addColumnLocation($3.location, [ $3.identifier ]);
+   }
+ | 'ALTER' OptionalImpalaColumn ColumnIdentifier 'DROP' '<impala>DEFAULT'
+   {
+     parser.addColumnLocation($3.location, [ $3.identifier ]);
+   }
+ | 'SET' '<impala>COLUMN' '<impala>STATS' ColumnIdentifier ParenthesizedStatsList
+   {
+     parser.addColumnLocation($4.location, [ $4.identifier ]);
+   }
+ ;
+
+ImpalaSpecificOperations_EDIT
+ : 'ALTER' OptionalImpalaColumn 'CURSOR'
+   {
+     if (parser.isImpala()) {
+       if (!$2) {
+         parser.suggestKeywords(['COLUMN']);
+       }
+       parser.suggestColumns();
+     }
+   }
+ | 'ALTER' OptionalImpalaColumn ColumnIdentifier 'CURSOR'
+   {
+     if (parser.isImpala()) {
+       parser.suggestKeywords(['DROP DEFAULT', 'SET BLOCK_SIZE', 'SET COMMENT', 'SET COMPRESSION', 'SET DEFAULT',
+         'SET ENCODING']);
+        parser.addColumnLocation($3.location, [ $3.identifier ]);
+     }
+   }
+ | 'ALTER' OptionalImpalaColumn ColumnIdentifier 'DROP' 'CURSOR'
+   {
+     if (parser.isImpala()) {
+       parser.suggestKeywords(['DEFAULT']);
+       parser.addColumnLocation($3.location, [ $3.identifier ]);
+     }
+   }
+ | 'ALTER' OptionalImpalaColumn ColumnIdentifier 'SET' 'CURSOR'
+   {
+     if (parser.isImpala()) {
+       parser.suggestKeywords(['BLOCK_SIZE', 'COMMENT', 'COMPRESSION', 'DEFAULT', 'ENCODING']);
+       parser.addColumnLocation($3.location, [ $3.identifier ]);
+     }
+   }
+ | 'ALTER' OptionalImpalaColumn ColumnIdentifier 'SET' KuduStorageAttribute 'CURSOR'
+   {
+     parser.addColumnLocation($3.location, [ $3.identifier ]);
+   }
+ | 'SET' '<impala>COLUMN' 'CURSOR'
+   {
+     parser.suggestKeywords(['STATS']);
+   }
+ | 'SET' '<impala>COLUMN' '<impala>STATS' 'CURSOR'
+   {
+     parser.suggestColumns();
+   }
+ | 'SET' '<impala>COLUMN' '<impala>STATS' ColumnIdentifier 'CURSOR'
+   {
+     parser.addColumnLocation($4.location, [ $4.identifier ]);
+   }
+ | 'SET' '<impala>COLUMN' '<impala>STATS' ColumnIdentifier ParenthesizedStatsList_EDIT
+   {
+     parser.addColumnLocation($4.location, [ $4.identifier ]);
+   }
+ ;
+
+KuduStorageAttribute
+ : '<impala>BLOCK_SIZE'
+ | '<impala>COMMENT'
+ | '<impala>COMPRESSION'
+ | '<impala>DEFAULT'
+ | '<impala>ENCODING'
+ ;
+
+OptionalImpalaColumn
+ :
+ | '<impala>COLUMN'
+ ;
+
+ParenthesizedStatsList
+ : '(' StatsList ')'
+ ;
+
+ParenthesizedStatsList_EDIT
+ : '(' StatsList_EDIT RightParenthesisOrError
+ ;
+
+StatsList
+ : StatsAssignment
+ | StatsList ',' StatsAssignment
+ ;
+
+StatsList_EDIT
+ : StatsAssignment_EDIT
+ | StatsList ',' StatsAssignment_EDIT
+ | StatsList ',' StatsAssignment_EDIT ',' StatsList
+ | StatsAssignment_EDIT ',' StatsList
+ ;
+
+StatsAssignment
+ : QuotedValue '=' QuotedValue
+ ;
+
+StatsAssignment_EDIT
+ : 'CURSOR'
+   {
+     parser.suggestIdentifiers(['\'avgSize\'', '\'maxSize\'', '\'numDVs\'', '\'numNulls\'']);
+   }
+ ;
+
 OptionalPartitionOperations
  : 'SET' AnyFileFormat FileFormat
  | 'SET' HdfsLocation

+ 1 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_main.jison

@@ -247,6 +247,7 @@ NonReservedKeyword
  | '<impala>ROLES'
  | '<impala>URI'
  | '<impala>SERVER'
+ | '<impala>UNKNOWN'
 // | '<impala>BROADCAST'
 // | '<impala>NOSHUFFLE'
 // | '<impala>SHUFFLE'

+ 4 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_set.jison

@@ -27,11 +27,15 @@ DataDefinition_EDIT
      if (parser.isHive()) {
        parser.suggestKeywords(['ROLE']);
      }
+     if (parser.isImpala()) {
+       parser.suggestKeywords(['ALL']);
+     }
    }
  ;
 
 SetSpecification
  : 'SET' SetOption '=' SetValue
+ | 'SET' 'ALL'
  ;
 
 SetOption

+ 20 - 7
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_valueExpression.jison

@@ -33,6 +33,9 @@ ValueExpression
      $2.types = ['NUMBER'];
    }
  | ValueExpression 'IS' OptionalNot 'NULL'                             -> { types: [ 'BOOLEAN' ] }
+ | ValueExpression 'IS' OptionalNot 'TRUE'                             -> { types: [ 'BOOLEAN' ] }
+ | ValueExpression 'IS' OptionalNot 'FALSE'                            -> { types: [ 'BOOLEAN' ] }
+ | ValueExpression 'IS' OptionalNot '<impala>UNKNOWN'                  -> { types: [ 'BOOLEAN' ] }
  | ValueExpression 'IS' OptionalNot 'DISTINCT' 'FROM' ValueExpression  -> { types: [ 'BOOLEAN' ] }
  ;
 
@@ -74,21 +77,21 @@ ValueExpression_EDIT
    }
  | ValueExpression 'IS' 'CURSOR'
    {
+     var keywords = ['FALSE', 'NOT NULL', 'NOT TRUE', 'NOT FALSE', 'NULL', 'TRUE'];
      if (parser.isImpala()) {
-       parser.suggestKeywords(['DISTINCT FROM', 'NOT DISTINCT FROM', 'NOT NULL', 'NULL']);
-     } else {
-       parser.suggestKeywords(['NOT NULL', 'NULL']);
+       keywords = keywords.concat(['DISTINCT FROM', 'NOT DISTINCT FROM', 'NOT UNKNOWN', 'UNKNOWN']);
      }
+     parser.suggestKeywords(keywords);
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'IS' 'NOT' 'CURSOR'
    {
+     var keywords = ['FALSE', 'NULL', 'TRUE'];
      if (parser.isImpala()) {
-       parser.suggestKeywords(['DISTINCT FROM', 'NULL']);
-     } else {
-       parser.suggestKeywords(['NULL']);
+       keywords = keywords.concat(['DISTINCT FROM', 'UNKNOWN']);
      }
-      $$ = { types: [ 'BOOLEAN' ] };
+     parser.suggestKeywords(keywords);
+     $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'IS' OptionalNot 'DISTINCT' 'CURSOR'
    {
@@ -102,6 +105,16 @@ ValueExpression_EDIT
      parser.suggestKeywords(['NOT']);
      $$ = { types: [ 'BOOLEAN' ] };
    }
+ | ValueExpression 'IS' 'CURSOR' 'FALSE'
+   {
+     parser.suggestKeywords(['NOT']);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | ValueExpression 'IS' 'CURSOR' 'TRUE'
+   {
+     parser.suggestKeywords(['NOT']);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
  | ValueExpression 'IS' OptionalNot 'DISTINCT' 'FROM' PartialBacktickedOrAnyCursor
    {
      parser.valueExpressionSuggest($1, $3 ? 'IS NOT DISTINCT FROM' : 'IS DISTINCT FROM');

+ 140 - 4
desktop/core/src/desktop/static/desktop/js/autocomplete/spec/sqlSpecAlter.js

@@ -228,6 +228,32 @@
     });
 
     describe('ALTER TABLE', function () {
+      it('should handle "ALTER TABLE foo ALTER COLUMN bar SET COMMENT \'boo\'; |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'ALTER TABLE foo ALTER COLUMN bar SET COMMENT \'boo\';  ',
+          afterCursor: '',
+          noErrors: true,
+          dialect: 'impala',
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should handle "ALTER TABLE foo ALTER bar DROP DEFAULT; |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'ALTER TABLE foo ALTER bar DROP DEFAULT;  ',
+          afterCursor: '',
+          noErrors: true,
+          dialect: 'impala',
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
       it('should suggest keywords for "ALTER |"', function() {
         assertAutoComplete({
           beforeCursor: 'ALTER ',
@@ -1559,7 +1585,20 @@
 
       });
 
-      describe('Impala specific', function () {
+     describe('Impala specific', function () {
+        it('should handle "ALTER TABLE db.tbl SET COLUMN STATS foo (\'numDVs\'=\'2\',\'numNulls\'=\'0\'); |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE db.tbl SET COLUMN STATS foo (\'numDVs\'=\'2\',\'numNulls\'=\'0\'); ',
+            afterCursor: '',
+            dialect: 'impala',
+            noErrors: true,
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
         it('should suggest databases for "ALTER TABLE db.tbl RENAME TO |"', function() {
           assertAutoComplete({
             beforeCursor: 'ALTER TABLE db.tbl RENAME TO  ',
@@ -1627,14 +1666,111 @@
             dialect: 'impala',
             expectedResult: {
               lowerCase: false,
-              suggestKeywords: ['ADD COLUMNS', 'ADD PARTITION', 'ADD RANGE PARTITION', 'CHANGE',
-                'DROP COLUMN', 'DROP PARTITION', 'DROP RANGE PARTITION', 'PARTITION', 'RECOVER PARTITIONS',
-                'RENAME TO', 'REPLACE COLUMNS', 'SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION',
+              suggestKeywords: ['ADD COLUMNS', 'ADD PARTITION', 'ADD RANGE PARTITION', 'ALTER', 'ALTER COLUMN',
+                'CHANGE', 'DROP COLUMN', 'DROP PARTITION', 'DROP RANGE PARTITION', 'PARTITION', 'RECOVER PARTITIONS',
+                'RENAME TO', 'REPLACE COLUMNS', 'SET CACHED IN', 'SET COLUMN STATS', 'SET FILEFORMAT', 'SET LOCATION',
                 'SET SERDEPROPERTIES', 'SET TBLPROPERTIES', 'SET UNCACHED' ]
             }
           });
         });
 
+        it('should suggest keywords for "ALTER TABLE bar SET |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CACHED IN', 'COLUMN STATS', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES', 'TBLPROPERTIES', 'UNCACHED']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SET COLUMN |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET COLUMN ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['STATS']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar SET COLUMN STATS |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET COLUMN STATS ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { tables: [{ identifierChain: [{ name: 'bar' }] }] }
+            }
+          });
+        });
+
+       it('should handle "ALTER TABLE db.tbl SET COLUMN STATS foo (|"', function() {
+         assertAutoComplete({
+           beforeCursor: 'ALTER TABLE db.tbl SET COLUMN STATS foo (',
+           afterCursor: '',
+           dialect: 'impala',
+           expectedResult: {
+             lowerCase: false,
+             suggestIdentifiers: ['\'avgSize\'', '\'maxSize\'', '\'numDVs\'', '\'numNulls\''],
+           }
+         });
+       });
+
+        it('should suggest keywords for "ALTER TABLE bar ALTER |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ALTER ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { tables: [{ identifierChain: [{ name: 'bar' }] }] },
+              suggestKeywords: ['COLUMN']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ALTER foo |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ALTER foo ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['DROP DEFAULT', 'SET BLOCK_SIZE', 'SET COMMENT', 'SET COMPRESSION', 'SET DEFAULT', 'SET ENCODING']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ALTER foo SET |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ALTER foo SET ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['BLOCK_SIZE', 'COMMENT', 'COMPRESSION', 'DEFAULT', 'ENCODING']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ALTER foo DROP |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ALTER foo DROP ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['DEFAULT']
+            }
+          });
+        });
+
         it('should suggest keywords for "ALTER TABLE bar ADD |"', function() {
           assertAutoComplete({
             beforeCursor: 'ALTER TABLE bar ADD ',

+ 29 - 7
desktop/core/src/desktop/static/desktop/js/autocomplete/spec/sqlSpecSelect.js

@@ -4565,7 +4565,7 @@
             lowerCase: false,
             suggestGroupBys: { prefix: 'GROUP BY', tables: [{ identifierChain: [{ name: 'foo' }] }] },
             suggestOrderBys: { prefix: 'ORDER BY', tables: [{ identifierChain: [{ name: 'foo' }] }] },
-            suggestKeywords: ['GROUP BY', 'HAVING', 'ORDER BY', 'LIMIT', 'UNION', '<', '<=', '<=>', '<>', '=', '>', '>=', 'AND', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'NOT BETWEEN', 'NOT IN', 'OR']
+            suggestKeywords: ['GROUP BY', 'HAVING', 'ORDER BY', 'LIMIT', 'UNION', '<', '<=', '<=>', '<>', '=', '>', '>=', 'AND', 'BETWEEN', 'IN', 'IS FALSE', 'IS NOT FALSE', 'IS NOT NULL', 'IS NOT TRUE', 'IS NULL', 'IS TRUE', 'NOT BETWEEN', 'NOT IN', 'OR']
           }
         });
       });
@@ -4579,7 +4579,7 @@
             lowerCase: false,
             suggestGroupBys: { prefix: 'GROUP BY', tables: [{ identifierChain: [{ name: 'foo' }] }] },
             suggestOrderBys: { prefix: 'ORDER BY', tables: [{ identifierChain: [{ name: 'foo' }] }] },
-            suggestKeywords: ['GROUP BY', 'HAVING', 'ORDER BY', 'LIMIT', 'UNION', '<', '<=', '<=>', '<>', '=', '>', '>=', 'AND', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'NOT BETWEEN', 'NOT IN', 'OR']
+            suggestKeywords: ['GROUP BY', 'HAVING', 'ORDER BY', 'LIMIT', 'UNION', '<', '<=', '<=>', '<>', '=', '>', '>=', 'AND', 'BETWEEN', 'IN', 'IS FALSE', 'IS NOT FALSE', 'IS NOT NULL', 'IS NOT TRUE', 'IS NULL', 'IS TRUE', 'NOT BETWEEN', 'NOT IN', 'OR']
           }
         });
       });
@@ -4588,7 +4588,7 @@
         assertAutoComplete({
           beforeCursor: 'SELECT * FROM foo WHERE id IS ',
           afterCursor: '',
-          containsKeywords: ['NOT NULL', 'NULL'],
+          containsKeywords: ['NOT NULL', 'NULL', 'NOT TRUE', 'TRUE', 'NOT FALSE', 'FALSE'],
           expectedResult: {
             lowerCase: false
           }
@@ -4599,7 +4599,7 @@
         assertAutoComplete({
           beforeCursor: 'SELECT * FROM foo WHERE id IS NOT ',
           afterCursor: '',
-          containsKeywords: ['NULL'],
+          containsKeywords: ['NULL', 'FALSE', 'TRUE'],
           expectedResult: {
             lowerCase: false
           }
@@ -4617,6 +4617,28 @@
         });
       });
 
+      it('should suggest keywords for "SELECT * FROM foo WHERE id IS | FALSE"', function () {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM foo WHERE id IS ',
+          afterCursor: ' FALSE',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['NOT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "SELECT * FROM foo WHERE id IS | TRUE"', function () {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM foo WHERE id IS ',
+          afterCursor: ' TRUE',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['NOT']
+          }
+        });
+      });
+
       // Fails because "NOT" is missing
       xit('should suggest keywords for "SELECT * FROM foo WHERE id | LIKE \'bla bla\'"', function () {
         assertAutoComplete({
@@ -4803,7 +4825,7 @@
             afterCursor: '',
             dialect: 'impala',
             noErrors: true,
-            containsKeywords: ['DISTINCT FROM', 'NOT DISTINCT FROM'],
+            containsKeywords: ['DISTINCT FROM', 'NOT DISTINCT FROM', 'NOT UNKNOWN', 'UNKNOWN'],
             expectedResult: {
               lowerCase: false
             }
@@ -4816,7 +4838,7 @@
             afterCursor: '',
             dialect: 'impala',
             noErrors: true,
-            containsKeywords: ['DISTINCT FROM'],
+            containsKeywords: ['DISTINCT FROM', 'UNKNOWN'],
             expectedResult: {
               lowerCase: false
             }
@@ -4889,7 +4911,7 @@
               lowerCase: false,
               suggestGroupBys: { prefix: 'GROUP BY', tables: [{ identifierChain: [{ name: 'foo' }] }] },
               suggestOrderBys: { prefix: 'ORDER BY', tables: [{ identifierChain: [{ name: 'foo' }] }] },
-              suggestKeywords: ['GROUP BY', 'HAVING', 'WINDOW', 'ORDER BY', 'CLUSTER BY', 'DISTRIBUTE BY', 'SORT BY', 'LIMIT', 'UNION', '<', '<=', '<=>', '<>', '=', '>', '>=', 'AND', 'BETWEEN',  'IN', 'IS NOT NULL', 'IS NULL',  'NOT BETWEEN', 'NOT IN', 'OR']
+              suggestKeywords: ['GROUP BY', 'HAVING', 'WINDOW', 'ORDER BY', 'CLUSTER BY', 'DISTRIBUTE BY', 'SORT BY', 'LIMIT', 'UNION', '<', '<=', '<=>', '<>', '=', '>', '>=', 'AND', 'BETWEEN', 'IN', 'IS FALSE', 'IS NOT FALSE', 'IS NOT NULL', 'IS NOT TRUE', 'IS NULL', 'IS TRUE', 'NOT BETWEEN', 'NOT IN', 'OR']
             }
           });
         });

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

@@ -37,6 +37,34 @@
       });
     });
 
+    describe('Impala specific', function () {
+      it('should handle "SET ALL; |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'SET ALL; ',
+          afterCursor: '',
+          noErrors: true,
+          dialect: 'impala',
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest keywords for "SET |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'SET ',
+          afterCursor: '',
+          dialect: 'impala',
+          expectedResult: {
+            lowerCase: false,
+            suggestSetOptions: true,
+            suggestKeywords: ['ALL']
+          }
+        });
+      });
+    });
+
     describe('SET ROLE', function () {
 
       it('should handle "SET ROLE baaa;', function () {

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlAutocompleteParser.js


+ 7 - 4
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlParseSupport.js

@@ -215,10 +215,9 @@ var SqlParseSupport = (function () {
     parser.getValueExpressionKeywords = function (valueExpression, extras) {
       var types = valueExpression.lastType ? valueExpression.lastType.types : valueExpression.types;
       // We could have valueExpression.columnReference to suggest based on column type
-      var keywords = ['<', '<=', '<=>', '<>', '=', '>', '>=', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'NOT BETWEEN', 'NOT IN'];
+      var keywords = ['<', '<=', '<=>', '<>', '=', '>', '>=', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'IS NOT TRUE', 'IS TRUE', 'IS NOT FALSE', 'IS FALSE', 'NOT BETWEEN', 'NOT IN'];
       if (parser.isImpala()) {
-        keywords.push('IS DISTINCT FROM');
-        keywords.push('IS NOT DISTINCT FROM');
+        keywords = keywords.concat(['IS DISTINCT FROM', 'IS NOT DISTINCT FROM', 'IS NOT UNKNOWN', 'IS UNKNOWN']);
       }
       if (extras) {
         keywords = keywords.concat(extras);
@@ -1322,6 +1321,10 @@ var SqlParseSupport = (function () {
       parser.yy.result.suggestSetOptions = true;
     };
 
+    parser.suggestIdentifiers = function (identifiers) {
+      parser.yy.result.suggestIdentifiers = identifiers;
+    };
+
     parser.suggestColumns = function (details) {
       if (typeof details === 'undefined') {
         details = {identifierChain: []};
@@ -1843,7 +1846,7 @@ var SqlParseSupport = (function () {
     'suggestJoins', 'valueExpressionSuggest', 'applyTypeToSuggestions', 'applyArgumentTypesToSuggestions', 'commitLocations', 'identifyPartials',
     'getSubQuery', 'addTablePrimary', 'suggestFileFormats', 'suggestDdlAndDmlKeywords', 'checkForSelectListKeywords', 'checkForKeywords',
     'suggestKeywords', 'suggestColRefKeywords', 'suggestTablesOrColumns', 'suggestFunctions', 'suggestAggregateFunctions', 'suggestAnalyticFunctions',
-    'suggestColumns', 'suggestGroupBys', 'suggestOrderBys', 'suggestFilters', 'suggestKeyValues', 'suggestTables', 'addFunctionLocation',
+    'suggestColumns', 'suggestGroupBys', 'suggestIdentifiers', 'suggestOrderBys', 'suggestFilters', 'suggestKeyValues', 'suggestTables', 'addFunctionLocation',
     'addStatementLocation', 'firstDefined', 'addClauseLocation', 'addHdfsLocation', 'addDatabaseLocation', 'addColumnAliasLocation', 'addTableAliasLocation',
     'addSubqueryAliasLocation', 'addTableLocation', 'addAsteriskLocation', 'addVariableLocation', 'addColumnLocation', 'addCteAliasLocation', 'addUnknownLocation',
     'addColRefToVariableIfExists', 'suggestDatabases', 'suggestHdfs', 'suggestValues'];

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlSyntaxParser.js


+ 10 - 3
desktop/core/src/desktop/static/desktop/js/sqlFunctions.js

@@ -1835,6 +1835,13 @@ var SqlFunctions = (function () {
         draggable: 'date_sub()',
         description: 'Subtracts a specified number of days from a TIMESTAMP value. The first argument can be a string, which is automatically cast to TIMESTAMP if it uses the recognized format. With an INTERVAL expression as the second argument, you can calculate a delta value using other units such as weeks, years, hours, seconds, and so on.'
       },
+      date_trunc: {
+        returnTypes: ['TIMESTAMP'],
+        arguments: [[{type: 'STRING'}], [{type: 'TIMESTAMP'}]],
+        signature: 'date_trunc(STRING unit, TIMESTAMP timestamp)',
+        draggable: 'date_trunc()',
+        description: 'Truncates a TIMESTAMP value to the specified precision. The unit argument value for truncating TIMESTAMP values is not case-sensitive. This argument string can be one of: \'microseconds\', \'milliseconds\', \'second\', \'minute\', \'hour\', \'day\', \'week\', \'month\', \'year\', \'decade\', \'century\' or \'millennium\'.'
+      },
       datediff: {
         returnTypes: ['INT'],
         arguments: [[{type: 'TIMESTAMP'}], [{type: 'TIMESTAMP'}]],
@@ -1968,11 +1975,11 @@ var SqlFunctions = (function () {
 				draggable: 'microseconds_sub()',
         description: 'Returns the specified date and time minus some number of microseconds.'
       },
-      milliseconds: {
+      millisecond: {
         returnTypes: ['INT'],
         arguments: [[{type: 'TIMESTAMP'}]],
-        signature: 'milliseconds(TIMESTAMP date)',
-        draggable: 'milliseconds()',
+        signature: 'millisecond(TIMESTAMP date)',
+        draggable: 'millisecond()',
         description: 'Returns the millisecond portion of a TIMESTAMP value.'
       },
       milliseconds_add: {

+ 2 - 2
tools/ace-editor/lib/ace/mode/impala_highlight_rules.js

@@ -25,11 +25,11 @@ define(function (require, exports, module) {
     // regexps are ordered -> the first match is used
 
     var keywords = (
-        "ADD|AGGREGATE|ALL|ALTER|ANALYTIC|AND|ANTI|API_VERSION|AS|ASC|AVRO|BETWEEN|BINARY|BLOCK_SIZE|BY|CACHED|CASCADE|CASE|CAST|CHANGE|CLASS|CLOSE_FN|COLUMN|COLUMNS|COMMENT|COMPRESSION|COMPUTE|CREATE|CROSS|CURRENT|DATA|DATABASE|DATABASES|DATE|DATETIME|DEFAULT|DELETE|DELIMITED|DESC|DESCRIBE|DISTINCT|DIV|DROP|ELSE|ENCODING|END|ESCAPED|EXISTS|EXPLAIN|EXTENDED|EXTERNAL|FIELDS|FILEFORMAT|FILES|FINALIZE_FN|FIRST|FOLLOWING|FOR|FORMAT|FORMATTED|FROM|FULL|FUNCTION|FUNCTIONS|GRANT|GROUP|HASH|HAVING|IF|ILIKE|IN|INCREMENTAL|INIT_FN|INNER|INPATH|IREGEXP|INSERT|INTEGER|INTERMEDIATE|INTERVAL|INTO|INVALIDATE|IS|JOIN|KEY|LAST|LEFT|LIKE|LIMIT|LINES|LOAD|LOCATION|MERGE_FN|METADATA|NOT|NULLS|OFFSET|ON|OR|ORDER|OUTER|OVER|OVERWRITE|PARQUET|PARTITION|PARTITIONED|PARTITIONS|PRECEDING|PREPARE_FN|PRIMARY|PRODUCED|PURGE|RANGE|RECOVER|REFRESH|REGEXP|RENAME|RESTRICT|REPEATABLE|REPLACE|REPLICATION|RETURNS|REVOKE|RIGHT|RLIKE|ROLE|ROLES|ROW|ROWS|SCHEMA|SCHEMAS|SELECT|SEMI|SERDEPROPERTIES|SERIALIZE_FN|SET|SHOW|SORT|STATS|STORED|STRAIGHT_JOIN|SYMBOL|TABLE|TABLES|TABLESAMPLE|TBLPROPERTIES|TERMINATED|THEN|TO|UNBOUNDED|UNCACHED|UNION|UPDATE|UPDATE_FN|UPSERT|USE|USING|VALUES|VIEW|WHEN|WHERE|WITH"
+        "ADD|AGGREGATE|ALL|ALTER|ANALYTIC|AND|ANTI|API_VERSION|AS|ASC|AVRO|BETWEEN|BINARY|BLOCK_SIZE|BY|CACHED|CASCADE|CASE|CAST|CHANGE|CLASS|CLOSE_FN|COLUMN|COLUMNS|COMMENT|COMPRESSION|COMPUTE|CREATE|CROSS|CURRENT|DATA|DATABASE|DATABASES|DATE|DATETIME|DEFAULT|DELETE|DELIMITED|DESC|DESCRIBE|DISTINCT|DIV|DROP|ELSE|ENCODING|END|ESCAPED|EXISTS|EXPLAIN|EXTENDED|EXTERNAL|FIELDS|FILEFORMAT|FILES|FINALIZE_FN|FIRST|FOLLOWING|FOR|FORMAT|FORMATTED|FROM|FULL|FUNCTION|FUNCTIONS|GRANT|GROUP|HASH|HAVING|IF|ILIKE|IN|INCREMENTAL|INIT_FN|INNER|INPATH|IREGEXP|INSERT|INTEGER|INTERMEDIATE|INTERVAL|INTO|INVALIDATE|IS|JOIN|KEY|LAST|LEFT|LIKE|LIMIT|LINES|LOAD|LOCATION|MERGE_FN|METADATA|NOT|NULLS|OFFSET|ON|OR|ORDER|OUTER|OVER|OVERWRITE|PARQUET|PARTITION|PARTITIONED|PARTITIONS|PRECEDING|PREPARE_FN|PRIMARY|PRODUCED|PURGE|RANGE|RECOVER|REFRESH|REGEXP|RENAME|RESTRICT|REPEATABLE|REPLACE|REPLICATION|RETURNS|REVOKE|RIGHT|RLIKE|ROLE|ROLES|ROW|ROWS|SCHEMA|SCHEMAS|SELECT|SEMI|SERDEPROPERTIES|SERIALIZE_FN|SET|SHOW|SORT|STATS|STORED|STRAIGHT_JOIN|SYMBOL|TABLE|TABLES|TABLESAMPLE|TBLPROPERTIES|TERMINATED|THEN|TO|TRUNCATE|UNBOUNDED|UNCACHED|UNION|UPDATE|UPDATE_FN|UPSERT|USE|USING|VALUES|VIEW|WHEN|WHERE|WITH"
     );
 
     var builtinConstants = (
-        "DAY|DAYS|FALSE|HOUR|HOURS|MINUTE|MINUTES|MICROSECOND|MICROSECONDS|MILLISECOND|MILLISECONDS|MONTH|MONTHS|NANOSECOND|NANOSECONDS|NULL|SECOND|SECONDS|TRUE|WEEK|WEEKS|YEAR|YEARS"
+        "DAY|DAYS|FALSE|HOUR|HOURS|MINUTE|MINUTES|MICROSECOND|MICROSECONDS|MILLISECOND|MILLISECONDS|MONTH|MONTHS|NANOSECOND|NANOSECONDS|NULL|SECOND|SECONDS|TRUE|UNKNOWN|WEEK|WEEKS|YEAR|YEARS"
     );
 
     var builtinFunctions = (

Деякі файли не було показано, через те що забагато файлів було змінено