Explorar el Código

[frontend] Introduce a SQL Analyzer provider and rename optimizer to SQL Analyzer in the frontend code

Johan Åhlén hace 4 años
padre
commit
2e21d92afb
Se han modificado 51 ficheros con 597 adiciones y 549 borrados
  1. 1 1
      .eslintrc.js
  2. 5 5
      apps/metastore/src/metastore/templates/metastore.mako
  3. 2 2
      desktop/core/src/desktop/js/api/apiHelper.js
  4. 0 12
      desktop/core/src/desktop/js/api/urls.js
  5. 2 2
      desktop/core/src/desktop/js/apps/editor/EditorViewModel.js
  6. 4 4
      desktop/core/src/desktop/js/apps/editor/app.js
  7. 6 4
      desktop/core/src/desktop/js/apps/editor/components/aceEditor/acePredict.ts
  8. 62 51
      desktop/core/src/desktop/js/apps/editor/components/aceEditor/autocomplete/AutocompleteResults.ts
  9. 1 1
      desktop/core/src/desktop/js/apps/editor/execution/executable.ts
  10. 3 3
      desktop/core/src/desktop/js/apps/editor/execution/executor.ts
  11. 1 1
      desktop/core/src/desktop/js/apps/editor/notebook.test.js
  12. 20 17
      desktop/core/src/desktop/js/apps/editor/snippet.js
  13. 1 1
      desktop/core/src/desktop/js/apps/editor/snippet.test.js
  14. 2 2
      desktop/core/src/desktop/js/apps/notebook/NotebookViewModel.js
  15. 4 4
      desktop/core/src/desktop/js/apps/notebook/app.js
  16. 10 10
      desktop/core/src/desktop/js/apps/notebook/snippet.js
  17. 1 2
      desktop/core/src/desktop/js/apps/tableBrowser/app.js
  18. 8 8
      desktop/core/src/desktop/js/apps/tableBrowser/metastoreDatabase.js
  19. 3 3
      desktop/core/src/desktop/js/apps/tableBrowser/metastoreNamespace.js
  20. 2 2
      desktop/core/src/desktop/js/apps/tableBrowser/metastoreSource.js
  21. 8 8
      desktop/core/src/desktop/js/apps/tableBrowser/metastoreTable.js
  22. 2 4
      desktop/core/src/desktop/js/apps/tableBrowser/metastoreViewModel.js
  23. 68 68
      desktop/core/src/desktop/js/catalog/DataCatalogEntry.ts
  24. 24 23
      desktop/core/src/desktop/js/catalog/MultiTableEntry.ts
  25. 22 18
      desktop/core/src/desktop/js/catalog/analyzer/ApiSqlAnalyzer.ts
  26. 6 6
      desktop/core/src/desktop/js/catalog/analyzer/MixedSqlAnalyser.test.ts
  27. 33 33
      desktop/core/src/desktop/js/catalog/analyzer/MixedSqlAnalyzer.ts
  28. 10 10
      desktop/core/src/desktop/js/catalog/analyzer/NoopSqlAnalyzer.ts
  29. 45 0
      desktop/core/src/desktop/js/catalog/analyzer/sqlAnalyzerRepository.ts
  30. 19 37
      desktop/core/src/desktop/js/catalog/analyzer/types.ts
  31. 71 66
      desktop/core/src/desktop/js/catalog/dataCatalog.ts
  32. 1 1
      desktop/core/src/desktop/js/jest/jest.init.js
  33. 2 1
      desktop/core/src/desktop/js/ko/bindings/ko.sqlContextPopover.js
  34. 11 9
      desktop/core/src/desktop/js/ko/components/assist/assistDbEntry.js
  35. 5 5
      desktop/core/src/desktop/js/ko/components/assist/assistDbNamespace.js
  36. 3 3
      desktop/core/src/desktop/js/ko/components/assist/ko.assistEditorContextPanel.js
  37. 6 6
      desktop/core/src/desktop/js/ko/components/ko.catalogEntriesList.js
  38. 1 1
      desktop/core/src/desktop/js/ko/components/ko.fieldSamples.test.js
  39. 1 1
      desktop/core/src/desktop/js/ko/components/ko.navProperties.test.js
  40. 1 1
      desktop/core/src/desktop/js/ko/components/ko.navTags.test.js
  41. 53 45
      desktop/core/src/desktop/js/sql/autocompleteResults.js
  42. 3 3
      desktop/core/src/desktop/js/types/types.ts
  43. 2 2
      desktop/core/src/desktop/templates/common_header_m.mako
  44. 5 6
      desktop/core/src/desktop/templates/global_js_constants.mako
  45. 2 2
      desktop/core/src/desktop/templates/hue_ace_autocompleter.mako
  46. 0 0
      desktop/libs/notebook/src/notebook/static/notebook/css/editor2.css
  47. 0 0
      desktop/libs/notebook/src/notebook/static/notebook/css/notebook.css
  48. 4 4
      desktop/libs/notebook/src/notebook/static/notebook/less/editor2.less
  49. 4 4
      desktop/libs/notebook/src/notebook/static/notebook/less/notebook.less
  50. 24 24
      desktop/libs/notebook/src/notebook/templates/editor2.mako
  51. 23 23
      desktop/libs/notebook/src/notebook/templates/editor_components.mako

+ 1 - 1
.eslintrc.js

@@ -10,7 +10,7 @@ const hueGlobals = [
   'ENABLE_SQL_SYNTAX_CHECK',
   'HAS_MULTI_CLUSTER',
   'HAS_CATALOG',
-  'HAS_OPTIMIZER',
+  'HAS_SQL_ANALYZER',
   'HAS_WORKLOAD_ANALYTICS',
   'HUE_I18n',
   'HUE_VERSION',

+ 5 - 5
apps/metastore/src/metastore/templates/metastore.mako

@@ -692,7 +692,7 @@ ${ components.menubar(is_embeddable) }
 <script type="text/html" id="metastore-queries-tab">
   <br/>
   <i class="fa fa-spinner fa-spin" data-bind="visible: $root.loadingQueries"></i>
-  <table data-bind="visible: ! loadingQueries() && $data.optimizerDetails().queryList().length > 0" class="table table-condensed">
+  <table data-bind="visible: ! loadingQueries() && $data.sqlAnalyzerDetails().queryList().length > 0" class="table table-condensed">
     <thead>
     <tr>
       <th width="10%">${ _('Id') }</th>
@@ -704,11 +704,11 @@ ${ components.menubar(is_embeddable) }
       <th width="10%">${ _('Impala Compatible') }</th>
     </tr>
     </thead>
-    <tbody data-bind="hueach: { data: $data.optimizerDetails().queryList(), itemHeight: 32, scrollable: '${ MAIN_SCROLLABLE }', scrollableOffset: 200 }">
+    <tbody data-bind="hueach: { data: $data.sqlAnalyzerDetails().queryList(), itemHeight: 32, scrollable: '${ MAIN_SCROLLABLE }', scrollableOffset: 200 }">
     <tr>
       <td data-bind="text: qid"></td>
       <td style="height: 10px; width: 70px; margin-top:5px;" data-bind="attr: {'title': queryCount()}">
-        <div class="progress bar" style="background-color: #0B7FAD" data-bind="style: { 'width' : Math.round(queryCount() / $parent.optimizerDetails().queryCount() * 100) + '%' }"></div>
+        <div class="progress bar" style="background-color: #0B7FAD" data-bind="style: { 'width' : Math.round(queryCount() / $parent.sqlAnalyzerDetails().queryCount() * 100) + '%' }"></div>
       </td>
       <td><code data-bind="text: queryChar"></code></td>
       <td><code data-bind="text: query().substring(0, 100) + '...'"></code></td>
@@ -718,7 +718,7 @@ ${ components.menubar(is_embeddable) }
     </tr>
     </tbody>
   </table>
-  <div data-bind="visible: ! loadingQueries() && $data.optimizerDetails().queryList().length == 0" class="empty-message">
+  <div data-bind="visible: ! loadingQueries() && $data.sqlAnalyzerDetails().queryList().length == 0" class="empty-message">
     ${ _('No queries found for the current table.') }
   </div>
 </script>
@@ -807,7 +807,7 @@ ${ components.menubar(is_embeddable) }
         <!-- ko template: 'metastore-sample-tab' --><!-- /ko -->
       <!-- /ko -->
 
-      <!-- ko if: $root.optimizerEnabled() && $root.currentTab() === 'queries' -->
+      <!-- ko if: $root.sqlAnalyzerEnabled() && $root.currentTab() === 'queries' -->
         <!-- ko template: { name: 'metastore-queries-tab', data: $root.database().table() } --><!-- /ko -->
       <!-- /ko -->
 

+ 2 - 2
desktop/core/src/desktop/js/api/apiHelper.js

@@ -107,7 +107,7 @@ class ApiHelper {
    * @param {string} [options.hash] - Optional hash to use as well as the url
    * @param {Function} options.fetchFunction
    * @param {Function} options.successCallback
-   * @param {string} [options.cacheType] - Possible values 'default'|'optimizer'. Default value 'default'
+   * @param {string} [options.cacheType] - Possible values 'default'|'sqlAnalyzer'. Default value 'default'
    * @param {Object} [options.editor] - Ace editor
    * @param {Object} [options.promise] - Optional promise that will be resolved if cached data exists
    */
@@ -1164,7 +1164,7 @@ class ApiHelper {
    * @param {string} options.sourceType
    * @param {string} [options.databaseName]
    * @param {string} [options.tableName]
-   * @param {string} [options.cacheType] - Possible values 'default', 'optimizer. Default value 'default'
+   * @param {string} [options.cacheType] - Possible values 'default', 'sqlAnalyzer'. Default value 'default'
    * @param {string[]} [options.fields]
    * @param {boolean} [options.clearAll]
    */

+ 0 - 12
desktop/core/src/desktop/js/api/urls.js

@@ -62,15 +62,3 @@ export const NAV_API = {
   LIST_TAGS: '/metadata/api/catalog/list_tags',
   UPDATE_PROPERTIES: '/metadata/api/catalog/update_properties'
 };
-
-export const OPTIMIZER_API = {
-  COMPATIBILITY: '/notebook/api/optimizer/statement/compatibility',
-  RISK: '/notebook/api/optimizer/statement/risk',
-  SIMILARITY: '/notebook/api/optimizer/statement/similarity',
-  TOP_AGGS: '/metadata/api/optimizer/top_aggs',
-  TOP_COLUMNS: '/metadata/api/optimizer/top_columns',
-  TOP_FILTERS: '/metadata/api/optimizer/top_filters',
-  TOP_JOINS: '/metadata/api/optimizer/top_joins',
-  TOP_TABLES: '/metadata/api/optimizer/top_tables',
-  TABLE_DETAILS: '/metadata/api/optimizer/table_details'
-};

+ 2 - 2
desktop/core/src/desktop/js/apps/editor/EditorViewModel.js

@@ -149,7 +149,7 @@ export default class EditorViewModel {
       () => this.selectedNotebook() && this.selectedNotebook().isHidingCode()
     );
     this.successUrl = ko.observable(options.success_url); // Deprecated
-    this.isOptimizerEnabled = ko.observable(options.is_optimizer_enabled);
+    this.isSqlAnalyzerEnabled = ko.observable(options.is_optimizer_enabled);
     this.isNavigatorEnabled = ko.observable(options.is_navigator_enabled);
 
     this.CoordinatorEditorViewModel = CoordinatorEditorViewModel; // TODO: Remove usage of global variables
@@ -184,7 +184,7 @@ export default class EditorViewModel {
       }
     });
 
-    this.isRightPanelAvailable = ko.observable(options.assistAvailable && HAS_OPTIMIZER);
+    this.isRightPanelAvailable = ko.observable(options.assistAvailable && window.HAS_SQL_ANALYZER);
     this.isRightPanelVisible = ko.observable(
       getFromLocalStorage('assist.right_assist_panel_visible', true)
     );

+ 4 - 4
desktop/core/src/desktop/js/apps/editor/app.js

@@ -509,8 +509,8 @@ huePubSub.subscribe('app.dom.loaded', app => {
 
     huePubSub.subscribe('editor.create.new', newKeyHandler, HUE_PUB_SUB_EDITOR_ID);
 
-    if (viewModel.isOptimizerEnabled()) {
-      if (window.OPTIMIZER_AUTO_UPLOAD_QUERIES) {
+    if (viewModel.isSqlAnalyzerEnabled()) {
+      if (window.SQL_ANALYZER_AUTO_UPLOAD_QUERIES) {
         huePubSub.subscribe(
           'editor.upload.query',
           query_id => {
@@ -520,7 +520,7 @@ huePubSub.subscribe('app.dom.loaded', app => {
         );
       }
 
-      if (window.OPTIMIZER_AUTO_UPLOAD_DDL) {
+      if (window.SQL_ANALYZER_AUTO_UPLOAD_DDL) {
         huePubSub.subscribe(
           'editor.upload.table.stats',
           options => {
@@ -530,7 +530,7 @@ huePubSub.subscribe('app.dom.loaded', app => {
         );
       }
 
-      if (window.OPTIMIZER_QUERY_HISTORY_UPLOAD_LIMIT !== 0) {
+      if (window.SQL_ANALYZER_QUERY_HISTORY_UPLOAD_LIMIT !== 0) {
         huePubSub.subscribe(
           'editor.upload.history',
           () => {

+ 6 - 4
desktop/core/src/desktop/js/apps/editor/components/aceEditor/acePredict.ts

@@ -15,10 +15,12 @@
 // limitations under the License.
 
 import { Ace } from 'ext/ace';
+
+import { CancellablePromise } from 'api/cancellablePromise';
+import { sqlAnalyzerRepository } from 'catalog/analyzer/sqlAnalyzerRepository';
+import { PredictResponse } from 'catalog/analyzer/types';
 import { Disposable } from 'components/utils/SubscriptionTracker';
 import { Connector } from 'config/types';
-import { getOptimizer, PredictResponse } from 'catalog/optimizer/optimizer';
-import { CancellablePromise } from 'api/cancellablePromise';
 import { defer } from 'utils/hueUtils';
 
 type ActivePredict = { text: string; element: HTMLElement };
@@ -26,7 +28,7 @@ type ActivePredict = { text: string; element: HTMLElement };
 export const attachPredictTypeahead = (editor: Ace.Editor, connector: Connector): Disposable => {
   let activePredict: { text: string; element: HTMLElement } | undefined;
 
-  const optimizer = getOptimizer(connector);
+  const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(connector);
 
   const addPredictElement = (text: string): ActivePredict => {
     const element = document.createElement('div');
@@ -68,7 +70,7 @@ export const attachPredictTypeahead = (editor: Ace.Editor, connector: Connector)
         removeActivePredict();
       }
       if (editorText.length && !activePredict) {
-        optimizer
+        sqlAnalyzer
           .predict({
             beforeCursor: editor.getTextBeforeCursor(),
             afterCursor: editor.getTextAfterCursor()

+ 62 - 51
desktop/core/src/desktop/js/apps/editor/components/aceEditor/autocomplete/AutocompleteResults.ts

@@ -23,7 +23,7 @@ import DataCatalogEntry, {
   SourceMeta,
   TableSourceMeta
 } from 'catalog/DataCatalogEntry';
-import { OptimizerPopularity, OptimizerPopularitySubType } from 'catalog/dataCatalog';
+import { SqlAnalyzerPopularity, SqlAnalyzerPopularitySubType } from 'catalog/dataCatalog';
 import MultiTableEntry, {
   TopAggs,
   TopAggValue,
@@ -1251,7 +1251,7 @@ class AutocompleteResults {
 
   async handleJoins(): Promise<Suggestion[]> {
     const suggestJoins = this.parseResult.suggestJoins;
-    if (!(<hueWindow>window).HAS_OPTIMIZER || !suggestJoins) {
+    if (!(<hueWindow>window).HAS_SQL_ANALYZER || !suggestJoins) {
       return [];
     }
 
@@ -1308,7 +1308,7 @@ class AutocompleteResults {
             const tableParts = table.split('.');
             if (!existingTables.has(tableParts[tableParts.length - 1])) {
               tablesAdded = true;
-              const identifier = this.convertOptimizerQualifiedIdentifier(
+              const identifier = this.convertSqlAnalyzerQualifiedIdentifier(
                 table,
                 suggestJoins.tables
               );
@@ -1332,12 +1332,12 @@ class AutocompleteResults {
                 suggestionString += this.parseResult.lowerCase ? ' and ' : ' AND ';
               }
               suggestionString +=
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[0],
                   suggestJoins.tables
                 ) +
                 ' = ' +
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[1],
                   suggestJoins.tables
                 );
@@ -1371,7 +1371,7 @@ class AutocompleteResults {
 
   async handleJoinConditions(): Promise<Suggestion[]> {
     const suggestJoinConditions = this.parseResult.suggestJoinConditions;
-    if (!(<hueWindow>window).HAS_OPTIMIZER || !suggestJoinConditions) {
+    if (!(<hueWindow>window).HAS_SQL_ANALYZER || !suggestJoinConditions) {
       return [];
     }
 
@@ -1421,12 +1421,12 @@ class AutocompleteResults {
                 suggestionString += this.parseResult.lowerCase ? ' and ' : ' AND ';
               }
               suggestionString +=
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[0],
                   suggestJoinConditions.tables
                 ) +
                 ' = ' +
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[1],
                   suggestJoinConditions.tables
                 );
@@ -1459,7 +1459,7 @@ class AutocompleteResults {
   async handleAggregateFunctions(): Promise<Suggestion[]> {
     const suggestAggregateFunctions = this.parseResult.suggestAggregateFunctions;
     if (
-      !(<hueWindow>window).HAS_OPTIMIZER ||
+      !(<hueWindow>window).HAS_SQL_ANALYZER ||
       !suggestAggregateFunctions ||
       !suggestAggregateFunctions.tables.length
     ) {
@@ -1586,7 +1586,7 @@ class AutocompleteResults {
   }
 
   async handlePopularGroupByOrOrderBy(
-    optimizerAttribute: keyof OptimizerPopularitySubType,
+    sqlAnalyzerAttribute: keyof SqlAnalyzerPopularitySubType,
     suggestSpec: CommonPopularSuggestion,
     columnsPromise: Promise<Suggestion[]>
   ): Promise<Suggestion[]> {
@@ -1610,7 +1610,7 @@ class AutocompleteResults {
         this.onCancelFunctions.push(reject);
         const popularityPromise = dataCatalog
           .getCatalog(this.executor.connector())
-          .loadOptimizerPopularityForTables({
+          .loadSqlAnalyzerPopularityForTables({
             namespace: this.executor.namespace(),
             compute: this.executor.compute(),
             paths: paths,
@@ -1628,10 +1628,10 @@ class AutocompleteResults {
         : '';
 
       entries.forEach(entry => {
-        if (!entry.optimizerPopularity) {
+        if (!entry.sqlAnalyzerPopularity) {
           return;
         }
-        const popularity = entry.optimizerPopularity[optimizerAttribute];
+        const popularity = entry.sqlAnalyzerPopularity[sqlAnalyzerAttribute];
         if (popularity) {
           totalColumnCount += popularity.columnCount;
           matchedEntries.push(entry);
@@ -1642,20 +1642,21 @@ class AutocompleteResults {
         const suggestions: Suggestion[] = [];
         matchedEntries.forEach(entry => {
           const popularity =
-            entry.optimizerPopularity && entry.optimizerPopularity[optimizerAttribute];
+            entry.sqlAnalyzerPopularity && entry.sqlAnalyzerPopularity[sqlAnalyzerAttribute];
           if (!popularity) {
             return;
           }
-          const filterValue = this.createOptimizerIdentifierForColumn(
+          const filterValue = this.createSqlAnalyzerIdentifierForColumn(
             popularity,
             suggestSpec.tables
           );
           suggestions.push({
             value: prefix + filterValue,
             filterValue: filterValue,
-            meta: optimizerAttribute === 'groupByColumn' ? MetaLabels.GroupBy : MetaLabels.OrderBy,
+            meta:
+              sqlAnalyzerAttribute === 'groupByColumn' ? MetaLabels.GroupBy : MetaLabels.OrderBy,
             category:
-              optimizerAttribute === 'groupByColumn'
+              sqlAnalyzerAttribute === 'groupByColumn'
                 ? Category.PopularGroupBy
                 : Category.PopularOrderBy,
             weightAdjust: Math.round((100 * popularity.columnCount) / totalColumnCount),
@@ -1687,7 +1688,7 @@ class AutocompleteResults {
 
   async handleGroupBys(columnsPromise: Promise<Suggestion[]>): Promise<Suggestion[]> {
     const suggestGroupBys = this.parseResult.suggestGroupBys;
-    if (!(<hueWindow>window).HAS_OPTIMIZER || !suggestGroupBys) {
+    if (!(<hueWindow>window).HAS_SQL_ANALYZER || !suggestGroupBys) {
       return [];
     }
 
@@ -1700,7 +1701,7 @@ class AutocompleteResults {
 
   async handleOrderBys(columnsPromise: Promise<Suggestion[]>): Promise<Suggestion[]> {
     const suggestOrderBys = this.parseResult.suggestOrderBys;
-    if (!(<hueWindow>window).HAS_OPTIMIZER || !suggestOrderBys) {
+    if (!(<hueWindow>window).HAS_SQL_ANALYZER || !suggestOrderBys) {
       return [];
     }
     return await this.handlePopularGroupByOrOrderBy(
@@ -1712,7 +1713,7 @@ class AutocompleteResults {
 
   async handleFilters(): Promise<Suggestion[]> {
     const suggestFilters = this.parseResult.suggestFilters;
-    if (!(<hueWindow>window).HAS_OPTIMIZER || !suggestFilters) {
+    if (!(<hueWindow>window).HAS_SQL_ANALYZER || !suggestFilters) {
       return [];
     }
 
@@ -1759,7 +1760,7 @@ class AutocompleteResults {
                         ? suggestFilters.prefix.toLowerCase()
                         : suggestFilters.prefix) + ' '
                     : '';
-                  compVal += this.createOptimizerIdentifier(
+                  compVal += this.createSqlAnalyzerIdentifier(
                     value.tableName,
                     grp.columnName,
                     suggestFilters.tables
@@ -1799,7 +1800,7 @@ class AutocompleteResults {
 
   async handlePopularTables(tablesPromise: Promise<Suggestion[]>): Promise<Suggestion[]> {
     const suggestTables = this.parseResult.suggestTables;
-    if (!(<hueWindow>window).HAS_OPTIMIZER || !suggestTables) {
+    if (!(<hueWindow>window).HAS_SQL_ANALYZER || !suggestTables) {
       return [];
     }
 
@@ -1827,7 +1828,7 @@ class AutocompleteResults {
 
       const childEntries = await new Promise<DataCatalogEntry[]>((resolve, reject) => {
         this.onCancelFunctions.push(reject);
-        const popularityPromise = entry.loadOptimizerPopularityForChildren({
+        const popularityPromise = entry.loadSqlAnalyzerPopularityForChildren({
           silenceErrors: true,
           cancellable: true
         });
@@ -1839,9 +1840,9 @@ class AutocompleteResults {
       const popularityIndex = new Set<string>();
 
       childEntries.forEach(childEntry => {
-        if (childEntry.optimizerPopularity && childEntry.optimizerPopularity.popularity) {
+        if (childEntry.sqlAnalyzerPopularity && childEntry.sqlAnalyzerPopularity.popularity) {
           popularityIndex.add(childEntry.name);
-          totalPopularity += <number>childEntry.optimizerPopularity.popularity;
+          totalPopularity += <number>childEntry.sqlAnalyzerPopularity.popularity;
         }
       });
 
@@ -1851,7 +1852,7 @@ class AutocompleteResults {
           const details = <DataCatalogEntry>suggestion.details;
           if (popularityIndex.has(details.name)) {
             const popularity =
-              (details.optimizerPopularity && details.optimizerPopularity.popularity) || 0;
+              (details.sqlAnalyzerPopularity && details.sqlAnalyzerPopularity.popularity) || 0;
             suggestion.relativePopularity = Math.round((100 * popularity) / totalPopularity);
             if (suggestion.relativePopularity >= 5) {
               suggestion.popular = true;
@@ -1868,7 +1869,7 @@ class AutocompleteResults {
   async handlePopularColumns(columnsPromise: Promise<Suggestion[]>): Promise<Suggestion[]> {
     const suggestColumns = this.parseResult.suggestColumns;
 
-    if (!(<hueWindow>window).HAS_OPTIMIZER || !suggestColumns || !suggestColumns.source) {
+    if (!(<hueWindow>window).HAS_SQL_ANALYZER || !suggestColumns || !suggestColumns.source) {
       return [];
     }
 
@@ -1901,7 +1902,7 @@ class AutocompleteResults {
         this.onCancelFunctions.push(reject);
         const popularityPromise = dataCatalog
           .getCatalog(this.executor.connector())
-          .loadOptimizerPopularityForTables({
+          .loadSqlAnalyzerPopularityForTables({
             namespace: this.executor.namespace(),
             compute: this.executor.compute(),
             paths: paths,
@@ -1913,7 +1914,10 @@ class AutocompleteResults {
       });
 
       let valueAttribute:
-        | keyof Pick<OptimizerPopularitySubType, 'selectColumn' | 'groupByColumn' | 'orderByColumn'>
+        | keyof Pick<
+            SqlAnalyzerPopularitySubType,
+            'selectColumn' | 'groupByColumn' | 'orderByColumn'
+          >
         | undefined;
       switch (suggestColumns.source) {
         case 'select':
@@ -1931,8 +1935,8 @@ class AutocompleteResults {
       popularEntries.forEach(popularEntry => {
         if (
           valueAttribute &&
-          popularEntry.optimizerPopularity &&
-          popularEntry.optimizerPopularity[valueAttribute]
+          popularEntry.sqlAnalyzerPopularity &&
+          popularEntry.sqlAnalyzerPopularity[valueAttribute]
         ) {
           popularityIndex.add(popularEntry.getQualifiedPath());
         }
@@ -1950,7 +1954,7 @@ class AutocompleteResults {
           return;
         }
         const popularity =
-          details.optimizerPopularity && details.optimizerPopularity[valueAttribute];
+          details.sqlAnalyzerPopularity && details.sqlAnalyzerPopularity[valueAttribute];
         if (
           popularity &&
           suggestion.hasCatalogEntry &&
@@ -1963,10 +1967,10 @@ class AutocompleteResults {
       if (totalColumnCount > 0) {
         matchedSuggestions.forEach(matchedSuggestion => {
           const details = <DataCatalogEntry>matchedSuggestion.details;
-          if (!details.optimizerPopularity || !valueAttribute) {
+          if (!details.sqlAnalyzerPopularity || !valueAttribute) {
             return;
           }
-          const popularity = details.optimizerPopularity[valueAttribute];
+          const popularity = details.sqlAnalyzerPopularity[valueAttribute];
           if (!popularity) {
             return;
           }
@@ -1984,12 +1988,12 @@ class AutocompleteResults {
     return [];
   }
 
-  createOptimizerIdentifier(
-    optimizerTableName: string,
-    optimizerColumnName: string,
+  createSqlAnalyzerIdentifier(
+    sqlAnalyzerTableName: string,
+    sqlAnalyzerColumnName: string,
     tables: ParsedTable[]
   ): string {
-    let path = optimizerTableName + '.' + optimizerColumnName.split('.').pop();
+    let path = sqlAnalyzerTableName + '.' + sqlAnalyzerColumnName.split('.').pop();
     for (let i = 0; i < tables.length; i++) {
       let tablePath = '';
       if (tables[i].identifierChain.length === 2) {
@@ -2010,42 +2014,49 @@ class AutocompleteResults {
     return path;
   }
 
-  createOptimizerIdentifierForColumn(
-    optimizerColumn: OptimizerPopularity,
+  createSqlAnalyzerIdentifierForColumn(
+    sqlAnalyzerColumn: SqlAnalyzerPopularity,
     tables: ParsedTable[]
   ): string {
     for (let i = 0; i < tables.length; i++) {
       if (
-        optimizerColumn.dbName &&
-        (optimizerColumn.dbName !== this.activeDatabase ||
-          optimizerColumn.dbName !== tables[i].identifierChain[0].name)
+        sqlAnalyzerColumn.dbName &&
+        (sqlAnalyzerColumn.dbName !== this.activeDatabase ||
+          sqlAnalyzerColumn.dbName !== tables[i].identifierChain[0].name)
       ) {
         continue;
       }
       if (
-        optimizerColumn.tableName &&
+        sqlAnalyzerColumn.tableName &&
         hueUtils.equalIgnoreCase(
-          optimizerColumn.tableName,
+          sqlAnalyzerColumn.tableName,
           tables[i].identifierChain[tables[i].identifierChain.length - 1].name
         ) &&
         tables[i].alias
       ) {
-        return tables[i].alias + '.' + optimizerColumn.columnName;
+        return tables[i].alias + '.' + sqlAnalyzerColumn.columnName;
       }
     }
 
-    if (optimizerColumn.dbName && optimizerColumn.dbName !== this.activeDatabase) {
+    if (sqlAnalyzerColumn.dbName && sqlAnalyzerColumn.dbName !== this.activeDatabase) {
       return (
-        optimizerColumn.dbName + '.' + optimizerColumn.tableName + '.' + optimizerColumn.columnName
+        sqlAnalyzerColumn.dbName +
+        '.' +
+        sqlAnalyzerColumn.tableName +
+        '.' +
+        sqlAnalyzerColumn.columnName
       );
     }
     if (tables.length > 1) {
-      return optimizerColumn.tableName + '.' + optimizerColumn.columnName;
+      return sqlAnalyzerColumn.tableName + '.' + sqlAnalyzerColumn.columnName;
     }
-    return optimizerColumn.columnName || '';
+    return sqlAnalyzerColumn.columnName || '';
   }
 
-  convertOptimizerQualifiedIdentifier(qualifiedIdentifier: string, tables: ParsedTable[]): string {
+  convertSqlAnalyzerQualifiedIdentifier(
+    qualifiedIdentifier: string,
+    tables: ParsedTable[]
+  ): string {
     const aliases: { qualifiedName: string; alias: string }[] = [];
     let tablesHasDefaultDatabase = false;
     tables.forEach(table => {

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

@@ -256,7 +256,7 @@ export default abstract class Executable {
         }
       }
 
-      if (this.executor.isOptimizerEnabled && this.history) {
+      if (this.executor.isSqlAnalyzerEnabled && this.history) {
         huePubSub.publish('editor.upload.query', this.history.id);
       }
 

+ 3 - 3
desktop/core/src/desktop/js/apps/editor/execution/executor.ts

@@ -33,7 +33,7 @@ export interface ExecutorOptions {
   defaultLimit?: KnockoutObservable<number>;
   isSqlEngine?: boolean;
   snippet?: Snippet;
-  isOptimizerEnabled?: boolean;
+  isSqlAnalyzerEnabled?: boolean;
 }
 
 export default class Executor {
@@ -43,7 +43,7 @@ export default class Executor {
   database: KnockoutObservable<string>;
   defaultLimit?: KnockoutObservable<number>;
   isSqlEngine?: boolean;
-  isOptimizerEnabled?: boolean;
+  isSqlAnalyzerEnabled?: boolean;
   executables: Executable[] = [];
   snippet?: Snippet;
   activeExecutable?: Executable;
@@ -55,7 +55,7 @@ export default class Executor {
     this.namespace = options.namespace;
     this.database = options.database;
     this.isSqlEngine = options.isSqlEngine;
-    this.isOptimizerEnabled = options.isOptimizerEnabled;
+    this.isSqlAnalyzerEnabled = options.isSqlAnalyzerEnabled;
     this.executables = [];
     this.defaultLimit = options.defaultLimit;
     this.snippet = options.snippet;

+ 1 - 1
desktop/core/src/desktop/js/apps/editor/notebook.test.js

@@ -25,7 +25,7 @@ describe('notebook.js', () => {
     availableSnippets: () => ({}),
     editorMode: () => false,
     getSnippetViewSettings: () => ({ sqlDialect: true }),
-    isOptimizerEnabled: () => false
+    isSqlAnalyzerEnabled: () => false
   };
 
   window.HUE_CHARTS = {

+ 20 - 17
desktop/core/src/desktop/js/apps/editor/snippet.js

@@ -51,7 +51,7 @@ import {
 } from 'ko/bindings/ace/aceLocationHandler';
 import { findEditorConnector, getLastKnownConfig } from 'config/hueConfig';
 import { cancelActiveRequest } from 'api/apiUtils';
-import { getOptimizer } from 'catalog/optimizer/optimizer';
+import { sqlAnalyzerRepository } from 'catalog/analyzer/sqlAnalyzerRepository';
 import {
   ASSIST_GET_DATABASE_EVENT,
   ASSIST_GET_SOURCE_EVENT,
@@ -92,7 +92,7 @@ export const STATUS = {
   starting: 'starting',
   success: 'success',
   waiting: 'waiting',
-  withOptimizerReport: 'with-optimizer-report'
+  withSqlAnalyzerReport: 'with-sql-analyzer-report'
 };
 
 const STATUS_FOR_BUTTONS = {
@@ -250,9 +250,9 @@ export default class Snippet {
     this.aceErrorsHolder = ko.observableArray([]);
     this.aceWarningsHolder = ko.observableArray([]);
 
-    this.aceErrors = ko.pureComputed(() => (this.showOptimizer() ? this.aceErrorsHolder() : []));
+    this.aceErrors = ko.pureComputed(() => (this.showSqlAnalyzer() ? this.aceErrorsHolder() : []));
     this.aceWarnings = ko.pureComputed(() =>
-      this.showOptimizer() ? this.aceWarningsHolder() : []
+      this.showSqlAnalyzer() ? this.aceWarningsHolder() : []
     );
 
     this.availableSnippets = this.parentVm.availableSnippets();
@@ -528,10 +528,10 @@ export default class Snippet {
       COMPATIBILITY_TARGET_PLATFORMS[this.dialect()]
     );
 
-    this.showOptimizer = ko.observable(getFromLocalStorage('editor.show.optimizer', false));
-    this.showOptimizer.subscribe(newValue => {
+    this.showSqlAnalyzer = ko.observable(getFromLocalStorage('editor.show.sql.analyzer', false));
+    this.showSqlAnalyzer.subscribe(newValue => {
       if (newValue !== null) {
-        setInLocalStorage('editor.show.optimizer', newValue);
+        setInLocalStorage('editor.show.sql.analyzer', newValue);
       }
     });
 
@@ -585,14 +585,14 @@ export default class Snippet {
 
     this.activeExecutable = ko.observable();
 
-    // TODO: User connector instead of compute, namespace, sourceType, isOptimizerEnabled, isSqlEngine
+    // TODO: User connector instead of compute, namespace, sourceType, isSqlAnalyzerEnabled, isSqlEngine
     this.executor = new Executor({
       compute: this.compute,
       database: this.database,
       connector: this.connector,
       namespace: this.namespace,
       defaultLimit: this.defaultLimit,
-      isOptimizerEnabled: this.parentVm.isOptimizerEnabled(),
+      isSqlAnalyzerEnabled: this.parentVm.isSqlAnalyzerEnabled(),
       snippet: this,
       isSqlEngine: this.isSqlDialect
     });
@@ -634,8 +634,8 @@ export default class Snippet {
 
     huePubSub.publish(REFRESH_STATEMENT_LOCATIONS_EVENT, this);
 
-    // TODO: Add optimizer check per connector?
-    if (window.HAS_OPTIMIZER && !this.parentVm.isNotificationManager()) {
+    // TODO: Add SQL Analyzer check per connector?
+    if (window.HAS_SQL_ANALYZER && !this.parentVm.isNotificationManager()) {
       let lastComplexityRequest;
       let lastCheckedComplexityStatement;
       const knownResponses = [];
@@ -726,7 +726,8 @@ export default class Snippet {
           return true;
         });
         if (unknownResponse) {
-          lastComplexityRequest = getOptimizer(this.connector())
+          lastComplexityRequest = sqlAnalyzerRepository
+            .getSqlAnalyzer(this.connector())
             .analyzeRisk({
               notebookJson: await this.parentNotebook.toContextJson(),
               snippetJson: this.toContextJson()
@@ -856,7 +857,8 @@ export default class Snippet {
   async getSimilarQueries() {
     hueAnalytics.log('notebook', 'get_query_similarity');
 
-    getOptimizer(this.connector())
+    sqlAnalyzerRepository
+      .getSqlAnalyzer(this.connector())
       .analyzeSimilarity({
         notebookJson: await this.parentNotebook.toContextJson(),
         snippetJson: this.toContextJson(),
@@ -983,7 +985,8 @@ export default class Snippet {
     this.hasSuggestion(null);
     const positionStatement = this.positionStatement();
 
-    this.lastCompatibilityRequest = getOptimizer(this.connector())
+    this.lastCompatibilityRequest = sqlAnalyzerRepository
+      .getSqlAnalyzer(this.connector())
       .analyzeCompatibility({
         notebookJson: await this.parentNotebook.toContextJson(),
         snippetJson: this.toContextJson(),
@@ -1011,7 +1014,7 @@ export default class Snippet {
               col:
                 match === null ? null : typeof match[3] !== 'undefined' ? parseInt(match[3]) : null
             });
-            this.status(STATUS.withOptimizerReport);
+            this.status(STATUS.withSqlAnalyzerReport);
           }
           if (this.suggestion().parseError()) {
             const match = ERROR_REGEX.exec(this.suggestion().parseError());
@@ -1021,9 +1024,9 @@ export default class Snippet {
               col:
                 match === null ? null : typeof match[3] !== 'undefined' ? parseInt(match[3]) : null
             });
-            this.status(STATUS.withOptimizerReport);
+            this.status(STATUS.withSqlAnalyzerReport);
           }
-          this.showOptimizer(true);
+          this.showSqlAnalyzer(true);
           this.hasSuggestion(true);
         } else {
           $(document).trigger('error', data.message);

+ 1 - 1
desktop/core/src/desktop/js/apps/editor/snippet.test.js

@@ -25,7 +25,7 @@ describe('snippet.js', () => {
     availableSnippets: () => ({}),
     editorMode: () => false,
     getSnippetViewSettings: () => ({ sqlDialect: true }),
-    isOptimizerEnabled: () => false
+    isSqlAnalyzerEnabled: () => false
   };
 
   window.HUE_CHARTS = {

+ 2 - 2
desktop/core/src/desktop/js/apps/notebook/NotebookViewModel.js

@@ -186,7 +186,7 @@ export default class NotebookViewModel {
       return self.selectedNotebook() && self.selectedNotebook().isHidingCode();
     });
     self.successUrl = ko.observable(options.success_url); // Deprecated
-    self.isOptimizerEnabled = ko.observable(options.is_optimizer_enabled);
+    self.isSqlAnalyzerEnabled = ko.observable(options.is_optimizer_enabled);
     self.isNavigatorEnabled = ko.observable(options.is_navigator_enabled);
 
     self.CoordinatorEditorViewModel = CoordinatorEditorViewModel;
@@ -299,7 +299,7 @@ export default class NotebookViewModel {
       }
     });
 
-    self.isRightPanelAvailable = ko.observable(options.assistAvailable && HAS_OPTIMIZER);
+    self.isRightPanelAvailable = ko.observable(options.assistAvailable && window.HAS_SQL_ANALYZER);
     self.isRightPanelVisible = ko.observable(
       getFromLocalStorage('assist.right_assist_panel_visible', true)
     );

+ 4 - 4
desktop/core/src/desktop/js/apps/notebook/app.js

@@ -949,8 +949,8 @@ huePubSub.subscribe('app.dom.loaded', app => {
 
     huePubSub.subscribe('editor.create.new', newKeyHandler, HUE_PUB_SUB_EDITOR_ID);
 
-    if (viewModel.isOptimizerEnabled()) {
-      if (window.OPTIMIZER_AUTO_UPLOAD_QUERIES) {
+    if (viewModel.isSqlAnalyzerEnabled()) {
+      if (window.SQL_ANALYZER_AUTO_UPLOAD_QUERIES) {
         huePubSub.subscribe(
           'editor.upload.query',
           query_id => {
@@ -960,7 +960,7 @@ huePubSub.subscribe('app.dom.loaded', app => {
         );
       }
 
-      if (window.OPTIMIZER_AUTO_UPLOAD_DDL) {
+      if (window.SQL_ANALYZER_AUTO_UPLOAD_DDL) {
         huePubSub.subscribe(
           'editor.upload.table.stats',
           options => {
@@ -970,7 +970,7 @@ huePubSub.subscribe('app.dom.loaded', app => {
         );
       }
 
-      if (window.OPTIMIZER_QUERY_HISTORY_UPLOAD_LIMIT !== 0) {
+      if (window.SQL_ANALYZER_QUERY_HISTORY_UPLOAD_LIMIT !== 0) {
         huePubSub.subscribe(
           'editor.upload.history',
           () => {

+ 10 - 10
desktop/core/src/desktop/js/apps/notebook/snippet.js

@@ -250,10 +250,10 @@ class Snippet {
     self.aceWarningsHolder = ko.observableArray([]);
 
     self.aceErrors = ko.pureComputed(() => {
-      return self.showOptimizer() ? self.aceErrorsHolder() : [];
+      return self.showSqlAnalyzer() ? self.aceErrorsHolder() : [];
     });
     self.aceWarnings = ko.pureComputed(() => {
-      return self.showOptimizer() ? self.aceWarningsHolder() : [];
+      return self.showSqlAnalyzer() ? self.aceWarningsHolder() : [];
     });
 
     self.availableSnippets = vm.availableSnippets();
@@ -1445,14 +1445,14 @@ class Snippet {
     });
     self.compatibilityTargetPlatform = ko.observable(COMPATIBILITY_TARGET_PLATFORMS[self.type()]);
 
-    self.showOptimizer = ko.observable(getFromLocalStorage('editor.show.optimizer', false));
-    self.showOptimizer.subscribe(newValue => {
+    self.showSqlAnalyzer = ko.observable(getFromLocalStorage('editor.show.sql.analyzer', false));
+    self.showSqlAnalyzer.subscribe(newValue => {
       if (newValue !== null) {
-        setInLocalStorage('editor.show.optimizer', newValue);
+        setInLocalStorage('editor.show.sql.analyzer', newValue);
       }
     });
 
-    if (HAS_OPTIMIZER && !vm.isNotificationManager()) {
+    if (window.HAS_SQL_ANALYZER && !vm.isNotificationManager()) {
       let lastComplexityRequest;
       let lastCheckedComplexityStatement;
       const knownResponses = [];
@@ -1857,7 +1857,7 @@ class Snippet {
             } else if (!notebook.unloaded()) {
               self.checkStatus();
             }
-            if (vm.isOptimizerEnabled()) {
+            if (vm.isSqlAnalyzerEnabled()) {
               huePubSub.publish('editor.upload.query', data.history_id);
             }
           } else {
@@ -2093,7 +2093,7 @@ class Snippet {
                     ? parseInt(match[3])
                     : null
               });
-              self.status('with-optimizer-report');
+              self.status('with-sql-analyzer-report');
             }
             if (self.suggestion().parseError()) {
               const match = ERROR_REGEX.exec(self.suggestion().parseError());
@@ -2107,9 +2107,9 @@ class Snippet {
                     ? parseInt(match[3])
                     : null
               });
-              self.status('with-optimizer-report');
+              self.status('with-sql-analyzer-report');
             }
-            self.showOptimizer(true);
+            self.showSqlAnalyzer(true);
             self.hasSuggestion(true);
           } else {
             $(document).trigger('error', data.message);

+ 1 - 2
desktop/core/src/desktop/js/apps/tableBrowser/app.js

@@ -39,9 +39,8 @@ huePubSub.subscribe('app.dom.loaded', app => {
 
   const options = {
     user: window.LOGGED_USERNAME,
-    optimizerEnabled: window.HAS_OPTIMIZER,
+    sqlAnalyzerEnabled: window.HAS_SQL_ANALYZER,
     navigatorEnabled: window.HAS_CATALOG,
-    optimizerUrl: window.OPTIMIZER_URL,
     navigatorUrl: window.CATALOG_URL
   };
 

+ 8 - 8
desktop/core/src/desktop/js/apps/tableBrowser/metastoreDatabase.js

@@ -25,7 +25,7 @@ class MetastoreDatabase {
   /**
    * @param {object} options
    * @param {DataCatalogEntry} options.catalogEntry
-   * @param {observable} options.optimizerEnabled
+   * @param {observable} options.sqlAnalyzerEnabled
    * @param {MetastoreViewModel} options.metastoreViewModel;
    * @constructor
    */
@@ -99,13 +99,13 @@ class MetastoreDatabase {
     this.catalogEntry.clearCache().then(() => {
       this.load(
         () => {},
-        this.metastoreViewModel.optimizerEnabled(),
+        this.metastoreViewModel.sqlAnalyzerEnabled(),
         this.metastoreViewModel.navigatorEnabled()
       );
     });
   }
 
-  load(callback, optimizerEnabled, navigatorEnabled) {
+  load(callback, sqlAnalyzerEnabled, navigatorEnabled) {
     if (navigatorEnabled) {
       this.loadingComment(true);
       this.catalogEntry
@@ -128,8 +128,8 @@ class MetastoreDatabase {
               new MetastoreTable({
                 database: this,
                 catalogEntry: tableEntry,
-                optimizerEnabled: optimizerEnabled,
-                navigatorEnabled: navigatorEnabled
+                sqlAnalyzerEnabled,
+                navigatorEnabled
               })
           )
         );
@@ -146,13 +146,13 @@ class MetastoreDatabase {
               this.loadingTableComments(false);
             });
         }
-        if (optimizerEnabled) {
+        if (sqlAnalyzerEnabled) {
           this.loadingTablePopularity(true);
           this.catalogEntry
-            .loadOptimizerPopularityForChildren()
+            .loadSqlAnalyzerPopularityForChildren()
             .then(() => {
               this.tables().forEach(table => {
-                table.optimizerStats(table.catalogEntry.optimizerPopularity);
+                table.sqlAnalyzerStats(table.catalogEntry.sqlAnalyzerPopularity);
               });
             })
             .finally(() => {

+ 3 - 3
desktop/core/src/desktop/js/apps/tableBrowser/metastoreNamespace.js

@@ -33,7 +33,7 @@ class MetastoreNamespace {
     this.metastoreViewModel = options.metastoreViewModel;
     this.sourceType = options.sourceType;
     this.navigatorEnabled = options.navigatorEnabled;
-    this.optimizerEnabled = options.optimizerEnabled;
+    this.sqlAnalyzerEnabled = options.sqlAnalyzerEnabled;
 
     this.catalogEntry = ko.observable();
 
@@ -88,7 +88,7 @@ class MetastoreNamespace {
                 databaseEntry =>
                   new MetastoreDatabase({
                     catalogEntry: databaseEntry,
-                    optimizerEnabled: this.optimizerEnabled,
+                    sqlAnalyzerEnabled: this.sqlAnalyzerEnabled,
                     metastoreViewModel: this.metastoreViewModel
                   })
               )
@@ -116,7 +116,7 @@ class MetastoreNamespace {
     if (!metastoreDatabase.loaded()) {
       metastoreDatabase.load(
         callback,
-        this.optimizerEnabled(),
+        this.sqlAnalyzerEnabled(),
         this.navigatorEnabled(),
         this.sourceType
       );

+ 2 - 2
desktop/core/src/desktop/js/apps/tableBrowser/metastoreSource.js

@@ -161,7 +161,7 @@ class MetastoreSource {
                 () => {
                   setState(previousState);
                 },
-                this.metastoreViewModel.optimizerEnabled(),
+                this.metastoreViewModel.sqlAnalyzerEnabled(),
                 this.metastoreViewModel.navigatorEnabled()
               );
               return true;
@@ -199,7 +199,7 @@ class MetastoreSource {
                 metastoreViewModel: this.metastoreViewModel,
                 sourceType: this.type,
                 navigatorEnabled: this.metastoreViewModel.navigatorEnabled,
-                optimizerEnabled: this.metastoreViewModel.optimizerEnabled,
+                sqlAnalyzerEnabled: this.metastoreViewModel.sqlAnalyzerEnabled,
                 namespace: namespace
               })
           )

+ 8 - 8
desktop/core/src/desktop/js/apps/tableBrowser/metastoreTable.js

@@ -32,13 +32,13 @@ class MetastoreTable {
    * @param {Object} options
    * @param {MetastoreDatabase} options.database
    * @param {DataCatalogEntry} options.catalogEntry
-   * @param {observable} options.optimizerEnabled
+   * @param {observable} options.sqlAnalyzerEnabled
    * @param {observable} options.navigatorEnabled
    * @constructor
    */
   constructor(options) {
     this.database = options.database;
-    this.optimizerEnabled = options.optimizerEnabled;
+    this.sqlAnalyzerEnabled = options.sqlAnalyzerEnabled;
     this.navigatorEnabled = options.navigatorEnabled;
     this.catalogEntry = options.catalogEntry;
 
@@ -47,8 +47,8 @@ class MetastoreTable {
     this.isModel = ko.observable(this.catalogEntry.isModel());
     this.viewSql = ko.observable();
 
-    this.optimizerStats = ko.observable();
-    this.optimizerDetails = ko.observable();
+    this.sqlAnalyzerStats = ko.observable();
+    this.sqlAnalyzerDetails = ko.observable();
     this.topJoins = ko.observableArray();
     this.navigatorMeta = ko.observable();
     this.relationshipsDetails = ko.observable();
@@ -158,12 +158,12 @@ class MetastoreTable {
           );
 
           this.catalogEntry
-            .getOptimizerMeta()
-            .then(optimizerMeta => {
-              this.optimizerDetails(optimizerMeta);
+            .getSqlAnalyzerMeta()
+            .then(sqlAnalyzerMeta => {
+              this.sqlAnalyzerDetails(sqlAnalyzerMeta);
 
               const topColIndex = {};
-              optimizerMeta.topCols.forEach(topCol => {
+              sqlAnalyzerMeta.topCols.forEach(topCol => {
                 topColIndex[topCol.name] = topCol;
               });
 

+ 2 - 4
desktop/core/src/desktop/js/apps/tableBrowser/metastoreViewModel.js

@@ -31,10 +31,9 @@ class MetastoreViewModel {
    * @param {Object} options
    * @param {string} options.user
    * @param {Number} [options.partitionsLimit]
-   * @param {boolean} [options.optimizerEnabled]
+   * @param {boolean} [options.sqlAnalyzerEnabled]
    * @param {boolean} [options.navigatorEnabled]
    * @param {String} options.sourceType
-   * @param {String} options.optimizerUrl
    * @param {String} options.navigatorUrl
    * @constructor
    */
@@ -46,7 +45,7 @@ class MetastoreViewModel {
     this.isLeftPanelVisible.subscribe(() => {
       huePubSub.publish('assist.forceRender');
     });
-    this.optimizerEnabled = ko.observable(options.optimizerEnabled || false);
+    this.sqlAnalyzerEnabled = ko.observable(options.sqlAnalyzerEnabled || false);
     this.navigatorEnabled = ko.observable(options.navigatorEnabled || false);
     this.appConfig = ko.observable();
 
@@ -134,7 +133,6 @@ class MetastoreViewModel {
       huePubSub.publish('meta.navigator.enabled', newValue);
     });
 
-    this.optimizerUrl = ko.observable(options.optimizerUrl);
     this.navigatorUrl = ko.observable(options.navigatorUrl);
 
     this.currentTab = ko.observable('');

+ 68 - 68
desktop/core/src/desktop/js/catalog/DataCatalogEntry.ts

@@ -23,7 +23,7 @@ import {
   fetchSourceMetadata
 } from 'catalog/api';
 import MultiTableEntry, { TopAggs, TopFilters, TopJoins } from 'catalog/MultiTableEntry';
-import { getOptimizer } from './optimizer/optimizer';
+import { sqlAnalyzerRepository } from './analyzer/sqlAnalyzerRepository';
 import * as ko from 'knockout';
 
 import apiHelper from 'api/apiHelper';
@@ -35,9 +35,9 @@ import I18n from 'utils/i18n';
 import {
   CatalogGetOptions,
   DataCatalog,
-  OptimizerPopularity,
-  OptimizerResponse,
-  OptimizerResponsePopularity,
+  SqlAnalyzerPopularity,
+  SqlAnalyzerResponse,
+  SqlAnalyzerResponsePopularity,
   TimestampedData
 } from './dataCatalog';
 
@@ -47,7 +47,7 @@ export interface BaseDefinition extends TimestampedData {
   index?: number;
   type?: string;
   isMapValue?: boolean;
-  optimizerLoaded?: boolean;
+  sqlAnalyzerLoaded?: boolean;
   partitionKey?: boolean;
   primaryKey?: boolean;
   foreignKey?: KeySpecification;
@@ -218,7 +218,7 @@ export interface Sample {
   type: string;
 }
 
-export interface OptimizerMeta extends TimestampedData {
+export interface SqlAnalyzerMeta extends TimestampedData {
   hueTimestamp?: number;
 }
 
@@ -258,10 +258,10 @@ export default class DataCatalogEntry {
   navigatorMeta?: NavigatorMeta;
   navigatorMetaForChildrenPromise?: CancellablePromise<DataCatalogEntry[]>;
   navigatorMetaPromise?: CancellablePromise<NavigatorMeta>;
-  optimizerMeta?: OptimizerMeta;
-  optimizerMetaPromise?: CancellablePromise<OptimizerMeta>;
-  optimizerPopularity?: OptimizerPopularity;
-  optimizerPopularityForChildrenPromise?: CancellablePromise<DataCatalogEntry[]>;
+  sqlAnalyzerMeta?: SqlAnalyzerMeta;
+  sqlAnalyzerMetaPromise?: CancellablePromise<SqlAnalyzerMeta>;
+  sqlAnalyzerPopularity?: SqlAnalyzerPopularity;
+  sqlAnalyzerPopularityForChildrenPromise?: CancellablePromise<DataCatalogEntry[]>;
   partitions?: Partitions;
   partitionsPromise?: CancellablePromise<Partitions>;
   sample?: Sample;
@@ -313,10 +313,10 @@ export default class DataCatalogEntry {
     this.navigatorMeta = undefined;
     this.navigatorMetaForChildrenPromise = undefined;
     this.navigatorMetaPromise = undefined;
-    this.optimizerMeta = undefined;
-    this.optimizerMetaPromise = undefined;
-    this.optimizerPopularity = undefined;
-    this.optimizerPopularityForChildrenPromise = undefined;
+    this.sqlAnalyzerMeta = undefined;
+    this.sqlAnalyzerMetaPromise = undefined;
+    this.sqlAnalyzerPopularity = undefined;
+    this.sqlAnalyzerPopularityForChildrenPromise = undefined;
     this.partitions = undefined;
     this.partitionsPromise = undefined;
     this.sample = undefined;
@@ -334,7 +334,7 @@ export default class DataCatalogEntry {
         .then(parent => {
           if (parent) {
             parent.navigatorMetaForChildrenPromise = undefined;
-            parent.optimizerPopularityForChildrenPromise = undefined;
+            parent.sqlAnalyzerPopularityForChildrenPromise = undefined;
           }
         })
         .catch(err => {
@@ -355,8 +355,8 @@ export default class DataCatalogEntry {
       options = {};
     }
 
-    if (this.definition && this.definition.optimizerLoaded) {
-      delete this.definition.optimizerLoaded;
+    if (this.definition && this.definition.sqlAnalyzerLoaded) {
+      delete this.definition.sqlAnalyzerLoaded;
     }
 
     this.reset();
@@ -424,12 +424,12 @@ export default class DataCatalogEntry {
   /**
    * Helper function to reload the nav opt metadata for the given entry
    */
-  private reloadOptimizerMeta(options?: ReloadOptions): CancellablePromise<OptimizerMeta> {
-    const optimizer = getOptimizer(this.getConnector());
-    if (this.dataCatalog.canHaveOptimizerMeta()) {
-      this.optimizerMetaPromise = new CancellablePromise<OptimizerMeta>(
+  private reloadSqlAnalyzerMeta(options?: ReloadOptions): CancellablePromise<SqlAnalyzerMeta> {
+    const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(this.getConnector());
+    if (this.dataCatalog.canHaveSqlAnalyzerMeta()) {
+      this.sqlAnalyzerMetaPromise = new CancellablePromise<SqlAnalyzerMeta>(
         async (resolve, reject, onCancel) => {
-          const fetchPromise = optimizer.fetchOptimizerMeta({
+          const fetchPromise = sqlAnalyzer.fetchSqlAnalyzerMeta({
             path: this.path,
             silenceErrors: options && options.silenceErrors
           });
@@ -438,8 +438,8 @@ export default class DataCatalogEntry {
           });
 
           try {
-            this.optimizerMeta = await fetchPromise;
-            resolve(this.optimizerMeta);
+            this.sqlAnalyzerMeta = await fetchPromise;
+            resolve(this.sqlAnalyzerMeta);
           } catch (err) {
             reject(err || 'Fetch failed');
             return;
@@ -448,9 +448,9 @@ export default class DataCatalogEntry {
         }
       );
     } else {
-      this.optimizerMetaPromise = CancellablePromise.reject();
+      this.sqlAnalyzerMetaPromise = CancellablePromise.reject();
     }
-    return applyCancellable(this.optimizerMetaPromise, options);
+    return applyCancellable(this.sqlAnalyzerMetaPromise, options);
   }
 
   private reloadPartitions(options?: ReloadOptions): CancellablePromise<Partitions> {
@@ -812,14 +812,14 @@ export default class DataCatalogEntry {
   /**
    * Helper function used when loading navopt metdata for children
    */
-  applyOptimizerResponseToChildren(
-    response: OptimizerResponse,
+  applySqlAnalyzerResponseToChildren(
+    response: SqlAnalyzerResponse,
     options?: { silenceErrors?: boolean }
   ): CancellablePromise<DataCatalogEntry[]> {
     if (!this.definition) {
       this.definition = {};
     }
-    this.definition.optimizerLoaded = true;
+    this.definition.sqlAnalyzerLoaded = true;
     this.saveLater();
 
     return new CancellablePromise<DataCatalogEntry[]>(async (resolve, reject, onCancel) => {
@@ -843,16 +843,16 @@ export default class DataCatalogEntry {
             }
             const matchingChild = entriesByName[topTable.name.toLowerCase()];
             if (matchingChild) {
-              matchingChild.optimizerPopularity = topTable;
+              matchingChild.sqlAnalyzerPopularity = topTable;
               matchingChild.saveLater();
               updatedIndex[matchingChild.getQualifiedPath()] = matchingChild;
             }
           });
         } else if (this.isTableOrView() && response.values) {
-          const addOptimizerPopularity = (
-            columns: OptimizerResponsePopularity[] | undefined,
+          const addSqlAnalyzerPopularity = (
+            columns: SqlAnalyzerResponsePopularity[] | undefined,
             type: keyof Pick<
-              OptimizerPopularity,
+              SqlAnalyzerPopularity,
               'filterColumn' | 'groupByColumn' | 'joinColumn' | 'orderByColumn' | 'selectColumn'
             >
           ) => {
@@ -863,10 +863,10 @@ export default class DataCatalogEntry {
                 }
                 const matchingChild = entriesByName[column.columnName.toLowerCase()];
                 if (matchingChild) {
-                  if (!matchingChild.optimizerPopularity) {
-                    matchingChild.optimizerPopularity = { column_count: 0, columnCount: 0 };
+                  if (!matchingChild.sqlAnalyzerPopularity) {
+                    matchingChild.sqlAnalyzerPopularity = { column_count: 0, columnCount: 0 };
                   }
-                  matchingChild.optimizerPopularity[type] = column;
+                  matchingChild.sqlAnalyzerPopularity[type] = column;
                   matchingChild.saveLater();
                   updatedIndex[matchingChild.getQualifiedPath()] = matchingChild;
                 }
@@ -874,11 +874,11 @@ export default class DataCatalogEntry {
             }
           };
 
-          addOptimizerPopularity(response.values.filterColumns, 'filterColumn');
-          addOptimizerPopularity(response.values.groupbyColumns, 'groupByColumn');
-          addOptimizerPopularity(response.values.joinColumns, 'joinColumn');
-          addOptimizerPopularity(response.values.orderbyColumns, 'orderByColumn');
-          addOptimizerPopularity(response.values.selectColumns, 'selectColumn');
+          addSqlAnalyzerPopularity(response.values.filterColumns, 'filterColumn');
+          addSqlAnalyzerPopularity(response.values.groupbyColumns, 'groupByColumn');
+          addSqlAnalyzerPopularity(response.values.joinColumns, 'joinColumn');
+          addSqlAnalyzerPopularity(response.values.orderbyColumns, 'orderByColumn');
+          addSqlAnalyzerPopularity(response.values.selectColumns, 'selectColumn');
         }
         const popularEntries: DataCatalogEntry[] = [];
         Object.keys(updatedIndex).forEach(path => {
@@ -892,29 +892,29 @@ export default class DataCatalogEntry {
   }
 
   /**
-   * Loads nav opt popularity for the children of this entry.
+   * Loads SQL Analyzer popularity for the children of this entry.
    */
-  loadOptimizerPopularityForChildren(
+  loadSqlAnalyzerPopularityForChildren(
     options?: CatalogGetOptions
   ): CancellablePromise<DataCatalogEntry[]> {
     if (
-      this.optimizerPopularityForChildrenPromise &&
-      this.optimizerPopularityForChildrenPromise.cancelled
+      this.sqlAnalyzerPopularityForChildrenPromise &&
+      this.sqlAnalyzerPopularityForChildrenPromise.cancelled
     ) {
-      this.optimizerPopularityForChildrenPromise = undefined;
+      this.sqlAnalyzerPopularityForChildrenPromise = undefined;
     }
     options = forceSilencedErrors(options);
 
-    if (!this.dataCatalog.canHaveOptimizerMeta()) {
+    if (!this.dataCatalog.canHaveSqlAnalyzerMeta()) {
       return CancellablePromise.reject();
     }
 
-    if (this.optimizerPopularityForChildrenPromise && !shouldReload(options)) {
-      return applyCancellable(this.optimizerPopularityForChildrenPromise, options);
+    if (this.sqlAnalyzerPopularityForChildrenPromise && !shouldReload(options)) {
+      return applyCancellable(this.sqlAnalyzerPopularityForChildrenPromise, options);
     }
 
-    if (this.definition && this.definition.optimizerLoaded && !shouldReload(options)) {
-      this.optimizerPopularityForChildrenPromise = new CancellablePromise<DataCatalogEntry[]>(
+    if (this.definition && this.definition.sqlAnalyzerLoaded && !shouldReload(options)) {
+      this.sqlAnalyzerPopularityForChildrenPromise = new CancellablePromise<DataCatalogEntry[]>(
         async (resolve, reject, onCancel) => {
           const childPromise = this.getChildren(options);
           onCancel(() => {
@@ -922,30 +922,30 @@ export default class DataCatalogEntry {
           });
           try {
             const children = await childPromise;
-            resolve(children.filter(child => child.optimizerPopularity));
+            resolve(children.filter(child => child.sqlAnalyzerPopularity));
           } catch (err) {
             reject(err);
           }
         }
       );
     } else if (this.isDatabase() || this.isTableOrView()) {
-      this.optimizerPopularityForChildrenPromise = new CancellablePromise<DataCatalogEntry[]>(
+      this.sqlAnalyzerPopularityForChildrenPromise = new CancellablePromise<DataCatalogEntry[]>(
         async (resolve, reject, onCancel) => {
           const cancellablePromises: Cancellable[] = [];
           onCancel(() => {
             cancellablePromises.forEach(cancellable => cancellable.cancel());
           });
 
-          const optimizer = getOptimizer(this.dataCatalog.connector);
-          const popularityPromise = optimizer.fetchPopularity({
+          const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(this.dataCatalog.connector);
+          const popularityPromise = sqlAnalyzer.fetchPopularity({
             ...options,
             paths: [this.path]
           });
           cancellablePromises.push(popularityPromise);
 
           try {
-            const optimzerResponse = await popularityPromise;
-            const applyPromise = this.applyOptimizerResponseToChildren(optimzerResponse, options);
+            const analyzerResponse = await popularityPromise;
+            const applyPromise = this.applySqlAnalyzerResponseToChildren(analyzerResponse, options);
             cancellablePromises.push(applyPromise);
             const entries = await applyPromise;
             resolve(entries);
@@ -955,10 +955,10 @@ export default class DataCatalogEntry {
         }
       );
     } else {
-      this.optimizerPopularityForChildrenPromise = CancellablePromise.resolve([]);
+      this.sqlAnalyzerPopularityForChildrenPromise = CancellablePromise.resolve([]);
     }
 
-    return applyCancellable(this.optimizerPopularityForChildrenPromise);
+    return applyCancellable(this.sqlAnalyzerPopularityForChildrenPromise);
   }
 
   /**
@@ -1579,24 +1579,24 @@ export default class DataCatalogEntry {
   }
 
   /**
-   * Gets the Nav Opt metadata for the entry. It will fetch it if not cached or if the refresh option is set.
+   * Gets the SQL Analyzer metadata for the entry. It will fetch it if not cached or if the refresh option is set.
    */
-  getOptimizerMeta(options?: CatalogGetOptions): CancellablePromise<OptimizerMeta> {
-    if (this.optimizerMetaPromise && this.optimizerMetaPromise.cancelled) {
-      this.optimizerMetaPromise = undefined;
+  getSqlAnalyzerMeta(options?: CatalogGetOptions): CancellablePromise<SqlAnalyzerMeta> {
+    if (this.sqlAnalyzerMetaPromise && this.sqlAnalyzerMetaPromise.cancelled) {
+      this.sqlAnalyzerMetaPromise = undefined;
     }
     options = forceSilencedErrors(options);
 
-    if (!this.dataCatalog.canHaveOptimizerMeta() || !this.isTableOrView()) {
+    if (!this.dataCatalog.canHaveSqlAnalyzerMeta() || !this.isTableOrView()) {
       return CancellablePromise.reject();
     }
-    if (!this.optimizerMetaPromise && cachedOnly(options)) {
+    if (!this.sqlAnalyzerMetaPromise && cachedOnly(options)) {
       return CancellablePromise.reject();
     }
-    if (!this.optimizerMetaPromise || shouldReload(options)) {
-      return this.reloadOptimizerMeta(options);
+    if (!this.sqlAnalyzerMetaPromise || shouldReload(options)) {
+      return this.reloadSqlAnalyzerMeta(options);
     }
-    return applyCancellable(this.optimizerMetaPromise, options);
+    return applyCancellable(this.sqlAnalyzerMetaPromise, options);
   }
 
   /**

+ 24 - 23
desktop/core/src/desktop/js/catalog/MultiTableEntry.ts

@@ -17,10 +17,11 @@
 import { noop } from 'lodash';
 
 import DataCatalogEntry from 'catalog/DataCatalogEntry';
+import { PopularityOptions } from './analyzer/types';
 import { CatalogGetOptions, DataCatalog, TimestampedData } from './dataCatalog';
 import { CancellablePromise } from 'api/cancellablePromise';
 import { applyCancellable } from 'catalog/catalogUtils';
-import { getOptimizer, PopularityOptions } from 'catalog/optimizer/optimizer';
+import { sqlAnalyzerRepository } from 'catalog/analyzer/sqlAnalyzerRepository';
 import { UdfDetails } from 'sql/reference/types';
 import { Connector } from 'config/types';
 import { hueWindow } from 'types/types';
@@ -78,12 +79,12 @@ export interface TopColumns extends TimestampedData {
 }
 
 const fetchAndSave = <T>(
-  optimizerFunction: (option: PopularityOptions) => CancellablePromise<T>,
+  sqlAnalyzerFunction: (option: PopularityOptions) => CancellablePromise<T>,
   setFunction: (val: T) => void,
   entry: DataCatalogEntry | MultiTableEntry,
   apiOptions?: { silenceErrors?: boolean; refreshAnalysis?: boolean }
 ): CancellablePromise<T> => {
-  const promise = optimizerFunction({
+  const promise = sqlAnalyzerFunction({
     paths: (<MultiTableEntry>entry).paths, // Set for MultiTableEntry
     silenceErrors: apiOptions && apiOptions.silenceErrors
   });
@@ -97,22 +98,22 @@ const fetchAndSave = <T>(
 };
 
 /**
- * Helper function to reload a Optimizer multi table attribute, like topAggs or topFilters
+ * Helper function to reload a SQL Analyzer multi table attribute, like topAggs or topFilters
  */
-const genericOptimizerReload = <T>(
+const genericSqlAnalyzerReload = <T>(
   multiTableEntry: MultiTableEntry,
   options: { silenceErrors?: boolean } | undefined,
   promiseSetter: (promise?: CancellablePromise<T>) => void,
   dataAttributeSetter: (val: T) => void,
-  optimizerFunction: (option: PopularityOptions) => CancellablePromise<T>
+  sqlAnalyzerFunction: (option: PopularityOptions) => CancellablePromise<T>
 ): CancellablePromise<T> => {
   const promise = new CancellablePromise<T>((resolve, reject, onCancel) => {
-    if (!multiTableEntry.dataCatalog.canHaveOptimizerMeta()) {
+    if (!multiTableEntry.dataCatalog.canHaveSqlAnalyzerMeta()) {
       reject();
       return;
     }
     const fetchPromise = fetchAndSave(
-      optimizerFunction,
+      sqlAnalyzerFunction,
       dataAttributeSetter,
       multiTableEntry,
       options
@@ -136,9 +137,9 @@ const genericOptimizerReload = <T>(
 };
 
 /**
- * Helper function to get a Optimizer multi table attribute, like topAggs or topFilters
+ * Helper function to get a SQL Analyzer multi table attribute, like topAggs or topFilters
  */
-const genericOptimizerGet = <T>(
+const genericSqlAnalyzerGet = <T>(
   multiTableEntry: MultiTableEntry,
   options: CatalogGetOptions | undefined,
   promiseSetter: (promise?: CancellablePromise<T>) => void,
@@ -152,7 +153,7 @@ const genericOptimizerGet = <T>(
   }
 
   if (!promise || !DataCatalog.cacheEnabled() || (options && options.refreshCache)) {
-    promise = genericOptimizerReload<T>(
+    promise = genericSqlAnalyzerReload<T>(
       multiTableEntry,
       options,
       promiseSetter,
@@ -226,8 +227,8 @@ class MultiTableEntry {
    * Gets the top aggregate UDFs for the entry. It will fetch it if not cached or if the refresh option is set.
    */
   getTopAggs(options?: CatalogGetOptions): CancellablePromise<TopAggs> {
-    const optimizer = getOptimizer(this.dataCatalog.connector);
-    return genericOptimizerGet<TopAggs>(
+    const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(this.dataCatalog.connector);
+    return genericSqlAnalyzerGet<TopAggs>(
       this,
       options,
       promise => {
@@ -237,7 +238,7 @@ class MultiTableEntry {
       val => {
         this.topAggs = val;
       },
-      optimizer.fetchTopAggs.bind(optimizer)
+      sqlAnalyzer.fetchTopAggs.bind(sqlAnalyzer)
     );
   }
 
@@ -245,8 +246,8 @@ class MultiTableEntry {
    * Gets the top columns for the entry. It will fetch it if not cached or if the refresh option is set.
    */
   getTopColumns(options?: CatalogGetOptions): CancellablePromise<TopColumns> {
-    const optimizer = getOptimizer(this.dataCatalog.connector);
-    return genericOptimizerGet<TopColumns>(
+    const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(this.dataCatalog.connector);
+    return genericSqlAnalyzerGet<TopColumns>(
       this,
       options,
       promise => {
@@ -256,7 +257,7 @@ class MultiTableEntry {
       val => {
         this.topColumns = val;
       },
-      optimizer.fetchTopColumns.bind(optimizer)
+      sqlAnalyzer.fetchTopColumns.bind(sqlAnalyzer)
     );
   }
 
@@ -264,8 +265,8 @@ class MultiTableEntry {
    * Gets the top filters for the entry. It will fetch it if not cached or if the refresh option is set.
    */
   getTopFilters(options?: CatalogGetOptions): CancellablePromise<TopFilters> {
-    const optimizer = getOptimizer(this.dataCatalog.connector);
-    return genericOptimizerGet<TopFilters>(
+    const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(this.dataCatalog.connector);
+    return genericSqlAnalyzerGet<TopFilters>(
       this,
       options,
       promise => {
@@ -275,7 +276,7 @@ class MultiTableEntry {
       val => {
         this.topFilters = val;
       },
-      optimizer.fetchTopFilters.bind(optimizer)
+      sqlAnalyzer.fetchTopFilters.bind(sqlAnalyzer)
     );
   }
 
@@ -283,8 +284,8 @@ class MultiTableEntry {
    * Gets the top joins for the entry. It will fetch it if not cached or if the refresh option is set.
    */
   getTopJoins(options?: CatalogGetOptions): CancellablePromise<TopJoins> {
-    const optimizer = getOptimizer(this.dataCatalog.connector);
-    return genericOptimizerGet<TopJoins>(
+    const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(this.dataCatalog.connector);
+    return genericSqlAnalyzerGet<TopJoins>(
       this,
       options,
       promise => {
@@ -294,7 +295,7 @@ class MultiTableEntry {
       val => {
         this.topJoins = val;
       },
-      optimizer.fetchTopJoins.bind(optimizer)
+      sqlAnalyzer.fetchTopJoins.bind(sqlAnalyzer)
     );
   }
 }

+ 22 - 18
desktop/core/src/desktop/js/catalog/optimizer/ApiStrategy.ts → desktop/core/src/desktop/js/catalog/analyzer/ApiSqlAnalyzer.ts

@@ -16,26 +16,26 @@
 
 import { CancellablePromise } from 'api/cancellablePromise';
 import { extractErrorMessage, post, successResponseIsError } from 'api/utils';
-import { OptimizerResponse, TimestampedData } from 'catalog/dataCatalog';
-import { OptimizerMeta } from 'catalog/DataCatalogEntry';
+import { SqlAnalyzerResponse, TimestampedData } from 'catalog/dataCatalog';
+import { SqlAnalyzerMeta } from 'catalog/DataCatalogEntry';
 import { TopAggs, TopColumns, TopFilters, TopJoins } from 'catalog/MultiTableEntry';
 import {
   CompatibilityOptions,
   MetaOptions,
-  Optimizer,
-  OptimizerRisk,
+  SqlAnalyzer,
+  AnalyzerRisk,
   PopularityOptions,
   PredictOptions,
   PredictResponse,
   RiskOptions,
   SimilarityOptions
-} from 'catalog/optimizer/optimizer';
+} from 'catalog/analyzer/types';
 import { Connector } from 'config/types';
 
 /**
  * Fetches the popularity for various aspects of the given tables
  */
-const genericOptimizerMultiTableFetch = <T extends TimestampedData>(
+const genericSqlAnalyzerMultiTableFetch = <T extends TimestampedData>(
   { silenceErrors, paths, connector }: PopularityOptions & { connector: Connector },
   url: string
 ): CancellablePromise<T> => {
@@ -72,7 +72,7 @@ const TOP_JOINS_URL = '/metadata/api/optimizer/top_joins';
 const TOP_TABLES_URL = '/metadata/api/optimizer/top_tables';
 const TABLE_DETAILS_URL = '/metadata/api/optimizer/table_details';
 
-export default class ApiStrategy implements Optimizer {
+export default class ApiSqlAnalyzer implements SqlAnalyzer {
   connector: Connector;
 
   constructor(connector: Connector) {
@@ -103,8 +103,8 @@ export default class ApiStrategy implements Optimizer {
     notebookJson,
     snippetJson,
     silenceErrors
-  }: RiskOptions): CancellablePromise<OptimizerRisk> {
-    return post<OptimizerRisk>(
+  }: RiskOptions): CancellablePromise<AnalyzerRisk> {
+    return post<AnalyzerRisk>(
       RISK_URL,
       {
         connector: JSON.stringify(this.connector),
@@ -136,7 +136,7 @@ export default class ApiStrategy implements Optimizer {
   fetchPopularity({
     paths,
     silenceErrors
-  }: PopularityOptions): CancellablePromise<OptimizerResponse> {
+  }: PopularityOptions): CancellablePromise<SqlAnalyzerResponse> {
     let url, data;
 
     if (paths.length === 1 && paths[0].length === 1) {
@@ -153,7 +153,7 @@ export default class ApiStrategy implements Optimizer {
       };
     }
 
-    return post<OptimizerResponse>(url, data, {
+    return post<SqlAnalyzerResponse>(url, data, {
       silenceErrors,
       handleSuccess: (response, resolve, reject) => {
         if (successResponseIsError(response)) {
@@ -167,35 +167,35 @@ export default class ApiStrategy implements Optimizer {
   }
 
   fetchTopAggs(options: PopularityOptions): CancellablePromise<TopAggs> {
-    return genericOptimizerMultiTableFetch<TopAggs>(
+    return genericSqlAnalyzerMultiTableFetch<TopAggs>(
       { ...options, connector: this.connector },
       TOP_AGGS_URL
     );
   }
 
   fetchTopColumns(options: PopularityOptions): CancellablePromise<TopColumns> {
-    return genericOptimizerMultiTableFetch<TopColumns>(
+    return genericSqlAnalyzerMultiTableFetch<TopColumns>(
       { ...options, connector: this.connector },
       TOP_COLUMNS_URL
     );
   }
 
   fetchTopFilters(options: PopularityOptions): CancellablePromise<TopFilters> {
-    return genericOptimizerMultiTableFetch<TopFilters>(
+    return genericSqlAnalyzerMultiTableFetch<TopFilters>(
       { ...options, connector: this.connector },
       TOP_FILTERS_URL
     );
   }
 
   fetchTopJoins(options: PopularityOptions): CancellablePromise<TopJoins> {
-    return genericOptimizerMultiTableFetch<TopJoins>(
+    return genericSqlAnalyzerMultiTableFetch<TopJoins>(
       { ...options, connector: this.connector },
       TOP_JOINS_URL
     );
   }
 
-  fetchOptimizerMeta({ path, silenceErrors }: MetaOptions): CancellablePromise<OptimizerMeta> {
-    return post<OptimizerMeta>(
+  fetchSqlAnalyzerMeta({ path, silenceErrors }: MetaOptions): CancellablePromise<SqlAnalyzerMeta> {
+    return post<SqlAnalyzerMeta>(
       TABLE_DETAILS_URL,
       {
         connector: JSON.stringify(this.connector),
@@ -204,7 +204,11 @@ export default class ApiStrategy implements Optimizer {
       },
       {
         silenceErrors,
-        handleSuccess: (response: { status: number; details?: OptimizerMeta }, resolve, reject) => {
+        handleSuccess: (
+          response: { status: number; details?: SqlAnalyzerMeta },
+          resolve,
+          reject
+        ) => {
           if (response.status === 0 && response.details) {
             response.details.hueTimestamp = Date.now();
             resolve(response.details);

+ 6 - 6
desktop/core/src/desktop/js/catalog/optimizer/SqlAnalyser.test.ts → desktop/core/src/desktop/js/catalog/analyzer/MixedSqlAnalyser.test.ts

@@ -15,7 +15,7 @@
 // limitations under the License.
 
 import { Connector } from 'config/types';
-import SqlAnalyzer from './SqlAnalyzer';
+import MixedSqlAnalyzer from './MixedSqlAnalyzer';
 
 const connectorA: Connector = {
   buttonName: '',
@@ -29,7 +29,7 @@ const connectorA: Connector = {
 describe('SqlAnalyzer.ts', () => {
   describe('checkMissingLimit', () => {
     it('Should detect a missing LIMIT', async () => {
-      const isMissingLimit = await new SqlAnalyzer(connectorA).checkMissingLimit(
+      const isMissingLimit = await new MixedSqlAnalyzer(connectorA).checkMissingLimit(
         'SELECT * FROM employee',
         'hive'
       );
@@ -38,7 +38,7 @@ describe('SqlAnalyzer.ts', () => {
     });
 
     it('Should avoid warning from a missing LIMIT in SELECT without a table', async () => {
-      const isMissingLimit = await new SqlAnalyzer(connectorA).checkMissingLimit(
+      const isMissingLimit = await new MixedSqlAnalyzer(connectorA).checkMissingLimit(
         'SELECT 1',
         'hive'
       );
@@ -47,7 +47,7 @@ describe('SqlAnalyzer.ts', () => {
     });
 
     it('Should not warning from a missing LIMIT in CREATE', async () => {
-      const isMissingLimit = await new SqlAnalyzer(connectorA).checkMissingLimit(
+      const isMissingLimit = await new MixedSqlAnalyzer(connectorA).checkMissingLimit(
         'CREATE TABLE a (a int)',
         'hive'
       );
@@ -58,7 +58,7 @@ describe('SqlAnalyzer.ts', () => {
 
   describe('checkSelectStar', () => {
     it('Should detect a SELECT *', async () => {
-      const isSelectStar = await new SqlAnalyzer(connectorA).checkSelectStar(
+      const isSelectStar = await new MixedSqlAnalyzer(connectorA).checkSelectStar(
         'SELECT * FROM employee',
         'hive'
       );
@@ -66,7 +66,7 @@ describe('SqlAnalyzer.ts', () => {
       expect(isSelectStar).toBeTruthy();
     });
     it('Should not warning from a non SELECT *', async () => {
-      const isSelectStar = await new SqlAnalyzer(connectorA).checkSelectStar(
+      const isSelectStar = await new MixedSqlAnalyzer(connectorA).checkSelectStar(
         'SELECT name FROM employee',
         'hive'
       );

+ 33 - 33
desktop/core/src/desktop/js/catalog/optimizer/SqlAnalyzer.ts → desktop/core/src/desktop/js/catalog/analyzer/MixedSqlAnalyzer.ts

@@ -16,46 +16,46 @@
 
 import { CancellablePromise } from 'api/cancellablePromise';
 import { getNamespaces } from 'catalog/contextCatalog';
-import { OptimizerMeta, TableSourceMeta } from 'catalog/DataCatalogEntry';
+import { SqlAnalyzerMeta, TableSourceMeta } from 'catalog/DataCatalogEntry';
 import { TopAggs, TopColumns, TopFilters, TopJoins, TopJoinValue } from 'catalog/MultiTableEntry';
-import ApiStrategy from 'catalog/optimizer/ApiStrategy';
+import ApiSqlAnalyzer from './ApiSqlAnalyzer';
 import {
-  API_STRATEGY,
   CompatibilityOptions,
   MetaOptions,
-  Optimizer,
-  OptimizerRisk,
+  SqlAnalyzer,
+  AnalyzerRisk,
   PopularityOptions,
   PredictOptions,
   PredictResponse,
   RiskHint,
   RiskOptions,
-  SimilarityOptions
-} from 'catalog/optimizer/optimizer';
+  SimilarityOptions,
+  SqlAnalyzerMode
+} from 'catalog/analyzer/types';
 
-import dataCatalog, { OptimizerResponse } from 'catalog/dataCatalog';
+import dataCatalog, { SqlAnalyzerResponse } from 'catalog/dataCatalog';
 import sqlParserRepository from 'parse/sql/sqlParserRepository';
 import { Connector, Namespace } from 'config/types';
 import { hueWindow } from 'types/types';
 import I18n from 'utils/i18n';
 
-export default class SqlAnalyzer implements Optimizer {
-  apiStrategy: ApiStrategy;
+export default class MixedSqlAnalyzer implements SqlAnalyzer {
+  apiAnalyzer: ApiSqlAnalyzer;
   connector: Connector;
 
   constructor(connector: Connector) {
-    this.apiStrategy = new ApiStrategy(connector);
+    this.apiAnalyzer = new ApiSqlAnalyzer(connector);
     this.connector = connector;
   }
 
-  analyzeRisk(options: RiskOptions): CancellablePromise<OptimizerRisk> {
-    return new CancellablePromise<OptimizerRisk>(async (resolve, reject, onCancel) => {
+  analyzeRisk(options: RiskOptions): CancellablePromise<AnalyzerRisk> {
+    return new CancellablePromise<AnalyzerRisk>(async (resolve, reject, onCancel) => {
       if (!this.connector.dialect) {
         reject();
         return;
       }
 
-      const apiPromise = this.apiStrategy.analyzeRisk({ ...options, silenceErrors: true });
+      const apiPromise = this.apiAnalyzer.analyzeRisk({ ...options, silenceErrors: true });
 
       onCancel(() => {
         apiPromise.cancel();
@@ -147,7 +147,7 @@ export default class SqlAnalyzer implements Optimizer {
   }
 
   fetchTopJoins(options: PopularityOptions): CancellablePromise<TopJoins> {
-    const apiPromise = this.apiStrategy.fetchTopJoins(options);
+    const apiPromise = this.apiAnalyzer.fetchTopJoins(options);
 
     const path = options.paths[0].join('.');
 
@@ -200,55 +200,55 @@ export default class SqlAnalyzer implements Optimizer {
   }
 
   analyzeCompatibility(options: CompatibilityOptions): CancellablePromise<unknown> {
-    if ((<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY) {
-      return this.apiStrategy.analyzeCompatibility(options);
+    if ((<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api) {
+      return this.apiAnalyzer.analyzeCompatibility(options);
     }
     return CancellablePromise.reject('analyzeCompatibility is not Implemented');
   }
 
   analyzeSimilarity(options: SimilarityOptions): CancellablePromise<unknown> {
-    if ((<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY) {
-      return this.apiStrategy.analyzeSimilarity(options);
+    if ((<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api) {
+      return this.apiAnalyzer.analyzeSimilarity(options);
     }
     return CancellablePromise.reject('analyzeSimilarity is not Implemented');
   }
 
-  fetchOptimizerMeta(options: MetaOptions): CancellablePromise<OptimizerMeta> {
-    if ((<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY) {
-      return this.apiStrategy.fetchOptimizerMeta(options);
+  fetchSqlAnalyzerMeta(options: MetaOptions): CancellablePromise<SqlAnalyzerMeta> {
+    if ((<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api) {
+      return this.apiAnalyzer.fetchSqlAnalyzerMeta(options);
     }
-    return CancellablePromise.reject('fetchOptimizerMeta is not Implemented');
+    return CancellablePromise.reject('fetchSqlAnalyzerMeta is not Implemented');
   }
 
-  fetchPopularity(options: PopularityOptions): CancellablePromise<OptimizerResponse> {
-    if ((<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY) {
-      return this.apiStrategy.fetchPopularity(options);
+  fetchPopularity(options: PopularityOptions): CancellablePromise<SqlAnalyzerResponse> {
+    if ((<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api) {
+      return this.apiAnalyzer.fetchPopularity(options);
     }
     return CancellablePromise.reject('fetchPopularity is not Implemented');
   }
 
   fetchTopAggs(options: PopularityOptions): CancellablePromise<TopAggs> {
-    if ((<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY) {
-      return this.apiStrategy.fetchTopAggs(options);
+    if ((<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api) {
+      return this.apiAnalyzer.fetchTopAggs(options);
     }
     return CancellablePromise.reject('fetchTopAggs is not Implemented');
   }
 
   fetchTopColumns(options: PopularityOptions): CancellablePromise<TopColumns> {
-    if ((<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY) {
-      return this.apiStrategy.fetchTopColumns(options);
+    if ((<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api) {
+      return this.apiAnalyzer.fetchTopColumns(options);
     }
     return CancellablePromise.reject('fetchTopColumns is not Implemented');
   }
 
   fetchTopFilters(options: PopularityOptions): CancellablePromise<TopFilters> {
-    if ((<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY) {
-      return this.apiStrategy.fetchTopFilters(options);
+    if ((<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api) {
+      return this.apiAnalyzer.fetchTopFilters(options);
     }
     return CancellablePromise.reject('fetchTopFilters is not Implemented');
   }
 
   predict(options: PredictOptions): CancellablePromise<PredictResponse> {
-    return this.apiStrategy.predict(options);
+    return this.apiAnalyzer.predict(options);
   }
 }

+ 10 - 10
desktop/core/src/desktop/js/catalog/optimizer/NoopSqlAnalyzer.ts → desktop/core/src/desktop/js/catalog/analyzer/NoopSqlAnalyzer.ts

@@ -15,30 +15,30 @@
 // limitations under the License.
 
 import { CancellablePromise } from 'api/cancellablePromise';
-import { OptimizerMeta } from 'catalog/DataCatalogEntry';
+import { SqlAnalyzerMeta } from 'catalog/DataCatalogEntry';
 import { TopAggs, TopColumns, TopFilters, TopJoins } from 'catalog/MultiTableEntry';
 import {
   CompatibilityOptions,
   MetaOptions,
-  Optimizer,
-  OptimizerRisk,
+  SqlAnalyzer,
+  AnalyzerRisk,
   PopularityOptions,
   PredictOptions,
   PredictResponse,
   RiskOptions,
   SimilarityOptions
-} from 'catalog/optimizer/optimizer';
+} from 'catalog/analyzer/types';
 
-import { OptimizerResponse } from 'catalog/dataCatalog';
+import { SqlAnalyzerResponse } from 'catalog/dataCatalog';
 
-export default class NoopSqlAnalyzer implements Optimizer {
+export default class NoopSqlAnalyzer implements SqlAnalyzer {
   // eslint-disable-next-line @typescript-eslint/no-unused-vars
   analyzeCompatibility(options: CompatibilityOptions): CancellablePromise<unknown> {
     return CancellablePromise.reject('analyzeCompatibility is not Implemented');
   }
 
   // eslint-disable-next-line @typescript-eslint/no-unused-vars
-  analyzeRisk(options: RiskOptions): CancellablePromise<OptimizerRisk> {
+  analyzeRisk(options: RiskOptions): CancellablePromise<AnalyzerRisk> {
     return CancellablePromise.reject('analyzeRisk is not Implemented');
   }
 
@@ -48,12 +48,12 @@ export default class NoopSqlAnalyzer implements Optimizer {
   }
 
   // eslint-disable-next-line @typescript-eslint/no-unused-vars
-  fetchOptimizerMeta(options: MetaOptions): CancellablePromise<OptimizerMeta> {
-    return CancellablePromise.reject('fetchOptimizerMeta is not Implemented');
+  fetchSqlAnalyzerMeta(options: MetaOptions): CancellablePromise<SqlAnalyzerMeta> {
+    return CancellablePromise.reject('fetchSqlAnalyzerMeta is not Implemented');
   }
 
   // eslint-disable-next-line @typescript-eslint/no-unused-vars
-  fetchPopularity(options: PopularityOptions): CancellablePromise<OptimizerResponse> {
+  fetchPopularity(options: PopularityOptions): CancellablePromise<SqlAnalyzerResponse> {
     return CancellablePromise.reject('analyzeCompatibility is not Implemented');
   }
 

+ 45 - 0
desktop/core/src/desktop/js/catalog/analyzer/sqlAnalyzerRepository.ts

@@ -0,0 +1,45 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import NoopSqlAnalyzer from './NoopSqlAnalyzer';
+import MixedSqlAnalyzer from './MixedSqlAnalyzer';
+import { Connector } from 'config/types';
+import { hueWindow } from 'types/types';
+import { SqlAnalyzer, SqlAnalyzerProvider, SqlAnalyzerMode } from './types';
+
+const sqlAnalyzerInstances: { [connectorId: string]: SqlAnalyzer | undefined } = {};
+
+const createSqlAnalyzer = (connector: Connector): SqlAnalyzer => {
+  // TODO: Remove window.SQL_ANALYZER_MODE and hardcoded { optimizer: 'api' } when 'connector.optimizer_mode' works.
+  if (
+    (<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.local ||
+    (<hueWindow>window).SQL_ANALYZER_MODE === SqlAnalyzerMode.api
+  ) {
+    return new MixedSqlAnalyzer(connector);
+  }
+  return new NoopSqlAnalyzer();
+};
+
+export const sqlAnalyzerRepository: SqlAnalyzerProvider = {
+  getSqlAnalyzer: (connector: Connector): SqlAnalyzer => {
+    let sqlAnalyzer = sqlAnalyzerInstances[connector.id];
+    if (!sqlAnalyzer) {
+      sqlAnalyzer = createSqlAnalyzer(connector);
+      sqlAnalyzerInstances[connector.id] = sqlAnalyzer;
+    }
+    return sqlAnalyzer;
+  }
+};

+ 19 - 37
desktop/core/src/desktop/js/catalog/optimizer/optimizer.ts → desktop/core/src/desktop/js/catalog/analyzer/types.ts

@@ -14,14 +14,21 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import NoopSqlAnalyzer from './NoopSqlAnalyzer';
-import SqlAnalyzer from 'catalog/optimizer/SqlAnalyzer';
 import { CancellablePromise } from 'api/cancellablePromise';
-import { OptimizerResponse } from 'catalog/dataCatalog';
-import { OptimizerMeta } from 'catalog/DataCatalogEntry';
-import { TopAggs, TopColumns, TopFilters, TopJoins } from 'catalog/MultiTableEntry';
-import { Connector } from 'config/types';
-import { hueWindow } from 'types/types';
+import { Connector } from '../../config/types';
+import { SqlAnalyzerResponse } from '../dataCatalog';
+import { SqlAnalyzerMeta } from '../DataCatalogEntry';
+import { TopAggs, TopColumns, TopFilters, TopJoins } from '../MultiTableEntry';
+
+export enum SqlAnalyzerMode {
+  local = 'local',
+  api = 'api',
+  off = 'off'
+}
+
+export interface SqlAnalyzerProvider {
+  getSqlAnalyzer(connector: Connector): SqlAnalyzer;
+}
 
 export interface CompatibilityOptions {
   notebookJson: string;
@@ -45,7 +52,7 @@ export interface RiskHint {
   riskRecommendation: string;
 }
 
-export interface OptimizerRisk {
+export interface AnalyzerRisk {
   status: number;
   message: string;
   query_complexity: {
@@ -81,40 +88,15 @@ export interface PredictResponse {
   prediction?: string;
 }
 
-export interface Optimizer {
-  analyzeRisk(options: RiskOptions): CancellablePromise<OptimizerRisk>;
+export interface SqlAnalyzer {
+  analyzeRisk(options: RiskOptions): CancellablePromise<AnalyzerRisk>;
   analyzeSimilarity(options: SimilarityOptions): CancellablePromise<unknown>;
   analyzeCompatibility(options: CompatibilityOptions): CancellablePromise<unknown>;
-  fetchPopularity(options: PopularityOptions): CancellablePromise<OptimizerResponse>;
+  fetchPopularity(options: PopularityOptions): CancellablePromise<SqlAnalyzerResponse>;
   fetchTopAggs(options: PopularityOptions): CancellablePromise<TopAggs>;
   fetchTopColumns(options: PopularityOptions): CancellablePromise<TopColumns>;
   fetchTopFilters(options: PopularityOptions): CancellablePromise<TopFilters>;
   fetchTopJoins(options: PopularityOptions): CancellablePromise<TopJoins>;
-  fetchOptimizerMeta(options: MetaOptions): CancellablePromise<OptimizerMeta>;
+  fetchSqlAnalyzerMeta(options: MetaOptions): CancellablePromise<SqlAnalyzerMeta>;
   predict(options: PredictOptions): CancellablePromise<PredictResponse>;
 }
-
-const optimizerInstances: { [connectorId: string]: Optimizer | undefined } = {};
-
-export const LOCAL_STRATEGY = 'local';
-export const API_STRATEGY = 'api';
-
-const createOptimizer = (connector: Connector): Optimizer => {
-  // TODO: Remove window.OPTIMIZER_MODE and hardcoded { optimizer: 'api' } when 'connector.optimizer_mode' works.
-  if (
-    (<hueWindow>window).OPTIMIZER_MODE === LOCAL_STRATEGY ||
-    (<hueWindow>window).OPTIMIZER_MODE === API_STRATEGY
-  ) {
-    return new SqlAnalyzer(connector);
-  }
-  return new NoopSqlAnalyzer();
-};
-
-export const getOptimizer = (connector: Connector): Optimizer => {
-  let optimizer = optimizerInstances[connector.id];
-  if (!optimizer) {
-    optimizer = createOptimizer(connector);
-    optimizerInstances[connector.id] = optimizer;
-  }
-  return optimizer;
-};

+ 71 - 66
desktop/core/src/desktop/js/catalog/dataCatalog.ts

@@ -24,7 +24,7 @@ import DataCatalogEntry, {
   ExtendedColumn,
   FieldSample,
   NavigatorMeta,
-  OptimizerMeta,
+  SqlAnalyzerMeta,
   Partitions,
   Sample,
   SourceMeta,
@@ -37,9 +37,10 @@ import MultiTableEntry, {
   TopFilters,
   TopJoins
 } from 'catalog/MultiTableEntry';
-import { getOptimizer, LOCAL_STRATEGY } from 'catalog/optimizer/optimizer';
+import { sqlAnalyzerRepository } from 'catalog/analyzer/sqlAnalyzerRepository';
 import { Compute, Connector, Namespace } from 'config/types';
 import { hueWindow } from 'types/types';
+import { SqlAnalyzerMode } from './analyzer/types';
 
 export interface TimestampedData {
   hueTimestamp?: number;
@@ -84,8 +85,8 @@ interface StoreEntry {
   partitions?: Partitions;
   sample?: Sample;
   navigatorMeta?: NavigatorMeta;
-  optimizerMeta?: OptimizerMeta;
-  optimizerPopularity?: OptimizerPopularity;
+  sqlAnalyzerMeta?: SqlAnalyzerMeta;
+  sqlAnalyzerPopularity?: SqlAnalyzerPopularity;
 }
 
 interface StoreMultiTableEntry {
@@ -96,7 +97,7 @@ interface StoreMultiTableEntry {
   topFilters?: TopFilters;
 }
 
-export interface OptimizerResponsePopularity {
+export interface SqlAnalyzerResponsePopularity {
   name?: string;
   columnCount: number;
   dbName?: string;
@@ -104,31 +105,31 @@ export interface OptimizerResponsePopularity {
   columnName?: string;
 }
 
-export interface OptimizerResponseValues {
-  filterColumns?: OptimizerResponsePopularity[];
-  groupbyColumns?: OptimizerResponsePopularity[];
-  joinColumns?: OptimizerResponsePopularity[];
-  orderbyColumns?: OptimizerResponsePopularity[];
-  selectColumns?: OptimizerResponsePopularity[];
+export interface SqlAnalyzerResponseValues {
+  filterColumns?: SqlAnalyzerResponsePopularity[];
+  groupbyColumns?: SqlAnalyzerResponsePopularity[];
+  joinColumns?: SqlAnalyzerResponsePopularity[];
+  orderbyColumns?: SqlAnalyzerResponsePopularity[];
+  selectColumns?: SqlAnalyzerResponsePopularity[];
 }
 
-export interface OptimizerResponse extends TimestampedData {
-  top_tables?: OptimizerResponsePopularity[];
-  values?: OptimizerResponseValues;
+export interface SqlAnalyzerResponse extends TimestampedData {
+  top_tables?: SqlAnalyzerResponsePopularity[];
+  values?: SqlAnalyzerResponseValues;
 }
 
-export interface OptimizerPopularitySubType {
-  filterColumn?: OptimizerResponsePopularity;
-  groupByColumn?: OptimizerResponsePopularity;
-  joinColumn?: OptimizerResponsePopularity;
-  orderByColumn?: OptimizerResponsePopularity;
-  selectColumn?: OptimizerResponsePopularity;
+export interface SqlAnalyzerPopularitySubType {
+  filterColumn?: SqlAnalyzerResponsePopularity;
+  groupByColumn?: SqlAnalyzerResponsePopularity;
+  joinColumn?: SqlAnalyzerResponsePopularity;
+  orderByColumn?: SqlAnalyzerResponsePopularity;
+  selectColumn?: SqlAnalyzerResponsePopularity;
 }
 
-export interface OptimizerPopularity
+export interface SqlAnalyzerPopularity
   extends TimestampedData,
-    OptimizerResponsePopularity,
-    OptimizerPopularitySubType {
+    SqlAnalyzerResponsePopularity,
+    SqlAnalyzerPopularitySubType {
   column_count?: number;
   popularity?: number;
   relativePopularity?: number;
@@ -208,19 +209,19 @@ const mergeEntry = (dataCatalogEntry: DataCatalogEntry, storeEntry: StoreEntry):
       dataCatalogEntry.navigatorMeta
     );
   }
-  if (dataCatalogEntry.getConnector().optimizer !== LOCAL_STRATEGY) {
+  if (dataCatalogEntry.getConnector().optimizer !== SqlAnalyzerMode.local) {
     const confTtl = (<hueWindow>window).CACHEABLE_TTL || {};
-    if (storeEntry.optimizerMeta && isFresh(storeEntry.optimizerMeta, confTtl.optimizer)) {
-      dataCatalogEntry.optimizerMeta = storeEntry.optimizerMeta;
-      dataCatalogEntry.optimizerMetaPromise = CancellablePromise.resolve(
-        dataCatalogEntry.optimizerMeta
+    if (storeEntry.sqlAnalyzerMeta && isFresh(storeEntry.sqlAnalyzerMeta, confTtl.sqlAnalyzer)) {
+      dataCatalogEntry.sqlAnalyzerMeta = storeEntry.sqlAnalyzerMeta;
+      dataCatalogEntry.sqlAnalyzerMetaPromise = CancellablePromise.resolve(
+        dataCatalogEntry.sqlAnalyzerMeta
       );
     }
     if (
-      storeEntry.optimizerPopularity &&
-      isFresh(storeEntry.optimizerPopularity, confTtl.optimizer)
+      storeEntry.sqlAnalyzerPopularity &&
+      isFresh(storeEntry.sqlAnalyzerPopularity, confTtl.sqlAnalyzer)
     ) {
-      dataCatalogEntry.optimizerPopularity = storeEntry.optimizerPopularity;
+      dataCatalogEntry.sqlAnalyzerPopularity = storeEntry.sqlAnalyzerPopularity;
     }
   }
 };
@@ -233,25 +234,25 @@ const mergeMultiTableEntry = (
   storeEntry: StoreMultiTableEntry
 ): void => {
   if (
-    multiTableEntry.getConnector().optimizer === LOCAL_STRATEGY ||
+    multiTableEntry.getConnector().optimizer === SqlAnalyzerMode.local ||
     storeEntry.version !== DATA_CATALOG_VERSION
   ) {
     return;
   }
   const confTtl = (<hueWindow>window).CACHEABLE_TTL || {};
-  if (storeEntry.topAggs && isFresh(storeEntry.topAggs, confTtl.optimizer)) {
+  if (storeEntry.topAggs && isFresh(storeEntry.topAggs, confTtl.sqlAnalyzer)) {
     multiTableEntry.topAggs = storeEntry.topAggs;
     multiTableEntry.topAggsPromise = CancellablePromise.resolve(multiTableEntry.topAggs);
   }
-  if (storeEntry.topColumns && isFresh(storeEntry.topColumns, confTtl.optimizer)) {
+  if (storeEntry.topColumns && isFresh(storeEntry.topColumns, confTtl.sqlAnalyzer)) {
     multiTableEntry.topColumns = storeEntry.topColumns;
     multiTableEntry.topColumnsPromise = CancellablePromise.resolve(multiTableEntry.topColumns);
   }
-  if (storeEntry.topFilters && isFresh(storeEntry.topFilters, confTtl.optimizer)) {
+  if (storeEntry.topFilters && isFresh(storeEntry.topFilters, confTtl.sqlAnalyzer)) {
     multiTableEntry.topFilters = storeEntry.topFilters;
     multiTableEntry.topFiltersPromise = CancellablePromise.resolve(multiTableEntry.topFilters);
   }
-  if (storeEntry.topJoins && isFresh(storeEntry.topJoins, confTtl.optimizer)) {
+  if (storeEntry.topJoins && isFresh(storeEntry.topJoins, confTtl.sqlAnalyzer)) {
     multiTableEntry.topJoins = storeEntry.topJoins;
     multiTableEntry.topJoinsPromise = CancellablePromise.resolve(multiTableEntry.topJoins);
   }
@@ -300,14 +301,14 @@ export class DataCatalog {
   }
 
   /**
-   * Returns true if the catalog can have Optimizer metadata
+   * Returns true if the catalog can have SQL Analyzer metadata
    */
-  canHaveOptimizerMeta(): boolean {
+  canHaveSqlAnalyzerMeta(): boolean {
     return !!(
-      (<hueWindow>window).HAS_OPTIMIZER &&
+      (<hueWindow>window).HAS_SQL_ANALYZER &&
       this.connector &&
       this.connector.optimizer &&
-      this.connector.optimizer !== 'off'
+      this.connector.optimizer !== SqlAnalyzerMode.off
     );
   }
 
@@ -364,19 +365,21 @@ export class DataCatalog {
       partitions: dataCatalogEntry.partitions,
       sample: dataCatalogEntry.sample,
       navigatorMeta: dataCatalogEntry.navigatorMeta,
-      optimizerMeta:
-        this.connector.optimizer !== LOCAL_STRATEGY ? dataCatalogEntry.optimizerMeta : undefined,
-      optimizerPopularity:
-        this.connector.optimizer !== LOCAL_STRATEGY
-          ? dataCatalogEntry.optimizerPopularity
+      sqlAnalyzerMeta:
+        this.connector.optimizer !== SqlAnalyzerMode.local
+          ? dataCatalogEntry.sqlAnalyzerMeta
+          : undefined,
+      sqlAnalyzerPopularity:
+        this.connector.optimizer !== SqlAnalyzerMode.local
+          ? dataCatalogEntry.sqlAnalyzerPopularity
           : undefined
     });
   }
 
   /**
-   * Loads Navigator Optimizer popularity for multiple tables in one go.
+   * Loads SQL Analyzer popularity for multiple tables in one go.
    */
-  loadOptimizerPopularityForTables(options: {
+  loadSqlAnalyzerPopularityForTables(options: {
     namespace: Namespace;
     compute: Compute;
     paths: string[][];
@@ -396,15 +399,15 @@ export class DataCatalog {
             compute: options.compute,
             path: path
           });
-          if (tableEntry.optimizerPopularityForChildrenPromise) {
-            const existingPopularEntries = await tableEntry.optimizerPopularityForChildrenPromise;
+          if (tableEntry.sqlAnalyzerPopularityForChildrenPromise) {
+            const existingPopularEntries = await tableEntry.sqlAnalyzerPopularityForChildrenPromise;
             popularEntries.push(...existingPopularEntries);
-          } else if (tableEntry.definition && tableEntry.definition.optimizerLoaded) {
+          } else if (tableEntry.definition && tableEntry.definition.sqlAnalyzerLoaded) {
             const childPromise = tableEntry.getChildren({ ...options, silenceErrors: true });
             cancellablePromises.push(childPromise);
             const childEntries = await childPromise;
             childEntries.forEach(childEntry => {
-              if (childEntry.optimizerPopularity) {
+              if (childEntry.sqlAnalyzerPopularity) {
                 popularEntries.push(childEntry);
               }
             });
@@ -435,9 +438,9 @@ export class DataCatalog {
           return;
         }
 
-        const optimizer = getOptimizer(this.connector);
+        const sqlAnalyzer = sqlAnalyzerRepository.getSqlAnalyzer(this.connector);
 
-        const fetchPromise = optimizer.fetchPopularity({
+        const fetchPromise = sqlAnalyzer.fetchPopularity({
           silenceErrors: true,
           paths: pathsToLoad
         });
@@ -445,9 +448,11 @@ export class DataCatalog {
 
         try {
           const data = await fetchPromise;
-          const perTable: { [path: string]: OptimizerResponse } = {};
+          const perTable: { [path: string]: SqlAnalyzerResponse } = {};
 
-          const splitOptimizerValuesPerTable = (listName: keyof OptimizerResponseValues): void => {
+          const splitSqlAnalyzerValuesPerTable = (
+            listName: keyof SqlAnalyzerResponseValues
+          ): void => {
             const values = data.values && data.values[listName];
             if (values) {
               values.forEach(column => {
@@ -469,11 +474,11 @@ export class DataCatalog {
           };
 
           if (data.values) {
-            splitOptimizerValuesPerTable('filterColumns');
-            splitOptimizerValuesPerTable('groupbyColumns');
-            splitOptimizerValuesPerTable('joinColumns');
-            splitOptimizerValuesPerTable('orderbyColumns');
-            splitOptimizerValuesPerTable('selectColumns');
+            splitSqlAnalyzerValuesPerTable('filterColumns');
+            splitSqlAnalyzerValuesPerTable('groupbyColumns');
+            splitSqlAnalyzerValuesPerTable('joinColumns');
+            splitSqlAnalyzerValuesPerTable('orderbyColumns');
+            splitSqlAnalyzerValuesPerTable('selectColumns');
           }
 
           const tablePromises: Promise<void>[] = Object.keys(perTable).map(
@@ -485,7 +490,7 @@ export class DataCatalog {
                     compute: options.compute,
                     path: path
                   });
-                  const applyPromise = entry.applyOptimizerResponseToChildren(perTable[path], {
+                  const applyPromise = entry.applySqlAnalyzerResponseToChildren(perTable[path], {
                     ...options,
                     silenceErrors: true
                   });
@@ -547,7 +552,7 @@ export class DataCatalog {
         path: [],
         definition: {
           index: 0,
-          optimizerLoaded: true,
+          sqlAnalyzerLoaded: true,
           type: 'source'
         }
       });
@@ -574,7 +579,7 @@ export class DataCatalog {
           path: [database],
           definition: {
             index: 0,
-            optimizerLoaded: true,
+            sqlAnalyzerLoaded: true,
             type: 'database'
           }
         });
@@ -612,7 +617,7 @@ export class DataCatalog {
           comment: '',
           index: existingTemporaryTables.length,
           name: options.name,
-          optimizerLoaded: true,
+          sqlAnalyzerLoaded: true,
           type: 'table'
         }
       });
@@ -791,8 +796,8 @@ export class DataCatalog {
     if (
       !cacheEnabled ||
       (confTtl.default && confTtl.default <= 0) ||
-      (confTtl.optimizer && confTtl.optimizer <= 0) ||
-      multiTableEntry.getConnector().optimizer === LOCAL_STRATEGY
+      (confTtl.sqlAnalyzer && confTtl.sqlAnalyzer <= 0) ||
+      multiTableEntry.getConnector().optimizer === SqlAnalyzerMode.local
     ) {
       return;
     }

+ 1 - 1
desktop/core/src/desktop/js/jest/jest.init.js

@@ -41,7 +41,7 @@ const globalVars = {
   AUTOCOMPLETE_TIMEOUT: 1,
   CACHEABLE_TTL: 1,
   HAS_LINK_SHARING: true,
-  HAS_OPTIMIZER: false,
+  HAS_SQL_ANALYZER: false,
   HUE_I18n: {},
   HUE_BASE_URL: '',
   HUE_CHARTS: {

+ 2 - 1
desktop/core/src/desktop/js/ko/bindings/ko.sqlContextPopover.js

@@ -14,6 +14,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+import { SqlAnalyzerMode } from 'catalog/analyzer/types';
 import $ from 'jquery';
 import * as ko from 'knockout';
 
@@ -55,7 +56,7 @@ ko.bindingHandlers.sqlContextPopover = {
             (options.sourceType === 'hive' || options.sourceType === 'impala')
           ) {
             options.connector = {
-              optimizer: 'api',
+              optimizer: SqlAnalyzerMode.api,
               id: options.sourceType,
               dialect: options.sourceType
             };

+ 11 - 9
desktop/core/src/desktop/js/ko/components/assist/assistDbEntry.js

@@ -399,21 +399,23 @@ class AssistDbEntry {
 
     if (
       !self.navigationSettings.rightAssist &&
-      HAS_OPTIMIZER &&
+      window.HAS_SQL_ANALYZER &&
       (self.catalogEntry.isTable() || self.catalogEntry.isDatabase()) &&
       !self.assistDbNamespace.nonSqlType
     ) {
-      self.catalogEntry.loadOptimizerPopularityForChildren({ silenceErrors: true }).then(() => {
+      self.catalogEntry.loadSqlAnalyzerPopularityForChildren({ silenceErrors: true }).then(() => {
         loadEntriesDeferred.done(() => {
           if (!self.hasErrors()) {
             self.entries().forEach(entry => {
-              if (entry.catalogEntry.optimizerPopularity) {
-                if (entry.catalogEntry.optimizerPopularity.popularity) {
-                  entry.popularity(entry.catalogEntry.optimizerPopularity.popularity);
-                } else if (entry.catalogEntry.optimizerPopularity.column_count) {
-                  entry.popularity(entry.catalogEntry.optimizerPopularity.column_count);
-                } else if (entry.catalogEntry.optimizerPopularity.selectColumn) {
-                  entry.popularity(entry.catalogEntry.optimizerPopularity.selectColumn.columnCount);
+              if (entry.catalogEntry.sqlAnalyzerPopularity) {
+                if (entry.catalogEntry.sqlAnalyzerPopularity.popularity) {
+                  entry.popularity(entry.catalogEntry.sqlAnalyzerPopularity.popularity);
+                } else if (entry.catalogEntry.sqlAnalyzerPopularity.column_count) {
+                  entry.popularity(entry.catalogEntry.sqlAnalyzerPopularity.column_count);
+                } else if (entry.catalogEntry.sqlAnalyzerPopularity.selectColumn) {
+                  entry.popularity(
+                    entry.catalogEntry.sqlAnalyzerPopularity.selectColumn.columnCount
+                  );
                 }
               }
             });

+ 5 - 5
desktop/core/src/desktop/js/ko/components/assist/assistDbNamespace.js

@@ -117,15 +117,15 @@ class AssistDbNamespace {
         });
       }
 
-      if (window.HAS_OPTIMIZER && db && !db.popularityIndexSet && !self.nonSqlType) {
-        db.catalogEntry.loadOptimizerPopularityForChildren({ silenceErrors: true }).then(() => {
+      if (window.HAS_SQL_ANALYZER && db && !db.popularityIndexSet && !self.nonSqlType) {
+        db.catalogEntry.loadSqlAnalyzerPopularityForChildren({ silenceErrors: true }).then(() => {
           const applyPopularity = () => {
             db.entries().forEach(entry => {
               if (
-                entry.catalogEntry.optimizerPopularity &&
-                entry.catalogEntry.optimizerPopularity.popularity >= 5
+                entry.catalogEntry.sqlAnalyzerPopularity &&
+                entry.catalogEntry.sqlAnalyzerPopularity.popularity >= 5
               ) {
-                entry.popularity(entry.catalogEntry.optimizerPopularity.popularity);
+                entry.popularity(entry.catalogEntry.sqlAnalyzerPopularity.popularity);
               }
             });
           };

+ 3 - 3
desktop/core/src/desktop/js/ko/components/assist/ko.assistEditorContextPanel.js

@@ -117,7 +117,7 @@ const TEMPLATE =
             <div class="risk-list-title" data-bind="css: { 'risk-list-high' : risk === 'high', 'risk-list-normal':  risk !== 'high' }, tooltip: { title: risk + ' ' + riskTables }"><span data-bind="text: riskAnalysis"></span></div>
             <div class="risk-list-description" data-bind="text: riskRecommendation"></div>
             <div class="risk-quickfix" data-bind="visible: (riskId === 17 || riskId === 18 || riskId === 22) && $parent.activeEditor() && $parent.activeLocations()" style="display:none;">
-              <a href="javascript:void(0);" data-bind="click: function () { $parent.addFilter(riskId); hueAnalytics.convert('optimizer', 'addFilter/' + riskId); }">${I18n(
+              <a href="javascript:void(0);" data-bind="click: function () { $parent.addFilter(riskId); hueAnalytics.convert('sqlAnalyzer', 'addFilter/' + riskId); }">${I18n(
                 'Fix me'
               )}</a>
             </div>
@@ -203,7 +203,7 @@ class AssistEditorContextPanel {
     this.connector = params.connector;
 
     this.showRisks = ko.pureComputed(() => {
-      if (!window.HAS_OPTIMIZER || this.isSolr()) {
+      if (!window.HAS_SQL_ANALYZER || this.isSolr()) {
         return false;
       }
       if (this.connector().dialect_properties) {
@@ -240,7 +240,7 @@ class AssistEditorContextPanel {
 
     this.isMissingStats = ko.pureComputed(
       () =>
-        window.AUTO_UPLOAD_OPTIMIZER_STATS &&
+        window.AUTO_UPLOAD_SQL_ANALYZER_STATS &&
         this.activeRisks().noStats &&
         this.activeRisks().noStats.length > 0
     );

+ 6 - 6
desktop/core/src/desktop/js/ko/components/ko.catalogEntriesList.js

@@ -518,7 +518,7 @@ class CatalogEntriesList {
       self.cancellablePromises.push(
         self
           .catalogEntry()
-          .loadOptimizerPopularityForChildren({ silenceErrors: true, cancellable: true })
+          .loadSqlAnalyzerPopularityForChildren({ silenceErrors: true, cancellable: true })
           .then(popularEntries => {
             if (popularEntries.length) {
               childPromise
@@ -533,15 +533,15 @@ class CatalogEntriesList {
                   popularEntries.forEach(popularEntry => {
                     if (
                       entryIndex[popularEntry.name] &&
-                      popularEntry.optimizerPopularity &&
-                      popularEntry.optimizerPopularity.selectColumn &&
-                      popularEntry.optimizerPopularity.selectColumn.columnCount > 0
+                      popularEntry.sqlAnalyzerPopularity &&
+                      popularEntry.sqlAnalyzerPopularity.selectColumn &&
+                      popularEntry.sqlAnalyzerPopularity.selectColumn.columnCount > 0
                     ) {
-                      totalCount += popularEntry.optimizerPopularity.selectColumn.columnCount;
+                      totalCount += popularEntry.sqlAnalyzerPopularity.selectColumn.columnCount;
                       popularityToApply.push(() => {
                         entryIndex[popularEntry.name].popularity(
                           Math.round(
-                            (100 * popularEntry.optimizerPopularity.selectColumn.columnCount) /
+                            (100 * popularEntry.sqlAnalyzerPopularity.selectColumn.columnCount) /
                               totalCount
                           )
                         );

+ 1 - 1
desktop/core/src/desktop/js/ko/components/ko.fieldSamples.test.js

@@ -32,7 +32,7 @@ describe('ko.fieldSamples.js', () => {
         getChildren: () => CancellablePromise.resolve([]),
         getSample: () => CancellablePromise.reject(),
         loadNavigatorMetaForChildren: () => CancellablePromise.reject(),
-        loadOptimizerPopularityForChildren: () => CancellablePromise.reject(),
+        loadSqlAnalyzerPopularityForChildren: () => CancellablePromise.reject(),
         isTableOrView: () => false,
         getDialect: () => 'impala'
       }

+ 1 - 1
desktop/core/src/desktop/js/ko/components/ko.navProperties.test.js

@@ -29,7 +29,7 @@ describe('ko.navProperties.js', () => {
         getChildren: () => CancellablePromise.resolve([]),
         getSample: () => CancellablePromise.reject(),
         loadNavigatorMetaForChildren: () => CancellablePromise.reject(),
-        loadOptimizerPopularityForChildren: () => CancellablePromise.reject(),
+        loadSqlAnalyzerPopularityForChildren: () => CancellablePromise.reject(),
         isTableOrView: () => false,
         getDialect: () => 'impala',
         getNavigatorMeta: () =>

+ 1 - 1
desktop/core/src/desktop/js/ko/components/ko.navTags.test.js

@@ -31,7 +31,7 @@ describe('ko.navTags.js', () => {
         getChildren: () => CancellablePromise.resolve([]),
         getSample: () => CancellablePromise.reject(),
         loadNavigatorMetaForChildren: () => CancellablePromise.reject(),
-        loadOptimizerPopularityForChildren: () => CancellablePromise.reject(),
+        loadSqlAnalyzerPopularityForChildren: () => CancellablePromise.reject(),
         isTableOrView: () => false,
         getDialect: () => 'impala',
         getNavigatorMeta: () =>

+ 53 - 45
desktop/core/src/desktop/js/sql/autocompleteResults.js

@@ -1478,7 +1478,7 @@ class AutocompleteResults {
 
   async handleJoins() {
     const suggestJoins = this.parseResult.suggestJoins;
-    if (!window.HAS_OPTIMIZER || !suggestJoins) {
+    if (!window.HAS_SQL_ANALYZER || !suggestJoins) {
       return [];
     }
     this.loadingJoins(true);
@@ -1537,7 +1537,7 @@ class AutocompleteResults {
             const tableParts = table.split('.');
             if (!existingTables[tableParts[tableParts.length - 1]]) {
               tablesAdded = true;
-              const identifier = this.convertOptimizerQualifiedIdentifier(
+              const identifier = this.convertSqlAnalyzerQualifiedIdentifier(
                 table,
                 suggestJoins.tables
               );
@@ -1561,13 +1561,13 @@ class AutocompleteResults {
                 suggestionString += this.parseResult.lowerCase ? ' and ' : ' AND ';
               }
               suggestionString +=
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[0],
                   suggestJoins.tables,
                   this.dialect()
                 ) +
                 ' = ' +
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[1],
                   suggestJoins.tables,
                   this.dialect()
@@ -1602,7 +1602,7 @@ class AutocompleteResults {
 
   async handleJoinConditions() {
     const suggestJoinConditions = this.parseResult.suggestJoinConditions;
-    if (!window.HAS_OPTIMIZER || !suggestJoinConditions) {
+    if (!window.HAS_SQL_ANALYZER || !suggestJoinConditions) {
       return [];
     }
     this.loadingJoinConditions(true);
@@ -1654,12 +1654,12 @@ class AutocompleteResults {
                 suggestionString += this.parseResult.lowerCase ? ' and ' : ' AND ';
               }
               suggestionString +=
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[0],
                   suggestJoinConditions.tables
                 ) +
                 ' = ' +
-                this.convertOptimizerQualifiedIdentifier(
+                this.convertSqlAnalyzerQualifiedIdentifier(
                   joinColPair.columns[1],
                   suggestJoinConditions.tables
                 );
@@ -1692,7 +1692,7 @@ class AutocompleteResults {
   async handleAggregateFunctions() {
     const suggestAggregateFunctions = this.parseResult.suggestAggregateFunctions;
     if (
-      !window.HAS_OPTIMIZER ||
+      !window.HAS_SQL_ANALYZER ||
       !suggestAggregateFunctions ||
       !suggestAggregateFunctions.tables.length
     ) {
@@ -1821,7 +1821,7 @@ class AutocompleteResults {
     return aggregateFunctionsSuggestions;
   }
 
-  async handlePopularGroupByOrOrderBy(optimizerAttribute, suggestSpec, columnsPromise) {
+  async handlePopularGroupByOrOrderBy(sqlAnalyzerAttribute, suggestSpec, columnsPromise) {
     const paths = [];
     suggestSpec.tables.forEach(table => {
       if (table.identifierChain) {
@@ -1842,7 +1842,7 @@ class AutocompleteResults {
         this.onCancelFunctions.push(reject);
         const popularityPromise = dataCatalog
           .getCatalog(this.snippet.connector())
-          .loadOptimizerPopularityForTables({
+          .loadSqlAnalyzerPopularityForTables({
             namespace: this.snippet.namespace(),
             compute: this.snippet.compute(),
             paths: paths,
@@ -1860,8 +1860,8 @@ class AutocompleteResults {
         : '';
 
       entries.forEach(entry => {
-        if (entry.optimizerPopularity[optimizerAttribute]) {
-          totalColumnCount += entry.optimizerPopularity[optimizerAttribute].columnCount;
+        if (entry.sqlAnalyzerPopularity[sqlAnalyzerAttribute]) {
+          totalColumnCount += entry.sqlAnalyzerPopularity[sqlAnalyzerAttribute].columnCount;
           matchedEntries.push(entry);
         }
       });
@@ -1869,20 +1869,21 @@ class AutocompleteResults {
       if (totalColumnCount > 0) {
         const suggestions = [];
         matchedEntries.forEach(entry => {
-          const filterValue = this.createOptimizerIdentifierForColumn(
-            entry.optimizerPopularity[optimizerAttribute],
+          const filterValue = this.createSqlAnalyzerIdentifierForColumn(
+            entry.sqlAnalyzerPopularity[sqlAnalyzerAttribute],
             suggestSpec.tables
           );
           suggestions.push({
             value: prefix + filterValue,
             filterValue: filterValue,
-            meta: optimizerAttribute === 'groupByColumn' ? META_I18n.groupBy : META_I18n.orderBy,
+            meta: sqlAnalyzerAttribute === 'groupByColumn' ? META_I18n.groupBy : META_I18n.orderBy,
             category:
-              optimizerAttribute === 'groupByColumn'
+              sqlAnalyzerAttribute === 'groupByColumn'
                 ? CATEGORIES.POPULAR_GROUP_BY
                 : CATEGORIES.POPULAR_ORDER_BY,
             weightAdjust: Math.round(
-              (100 * entry.optimizerPopularity[optimizerAttribute].columnCount) / totalColumnCount
+              (100 * entry.sqlAnalyzerPopularity[sqlAnalyzerAttribute].columnCount) /
+                totalColumnCount
             ),
             popular: ko.observable(true),
             hasCatalogEntry: false,
@@ -1911,7 +1912,7 @@ class AutocompleteResults {
 
   async handleGroupBys(columnsPromise) {
     const suggestGroupBys = this.parseResult.suggestGroupBys;
-    if (!window.HAS_OPTIMIZER || !suggestGroupBys) {
+    if (!window.HAS_SQL_ANALYZER || !suggestGroupBys) {
       return [];
     }
     this.loadingGroupBys(true);
@@ -1926,7 +1927,7 @@ class AutocompleteResults {
 
   async handleOrderBys(columnsDeferred) {
     const suggestOrderBys = this.parseResult.suggestOrderBys;
-    if (!window.HAS_OPTIMIZER || !suggestOrderBys) {
+    if (!window.HAS_SQL_ANALYZER || !suggestOrderBys) {
       return [];
     }
     this.loadingOrderBys(true);
@@ -1941,7 +1942,7 @@ class AutocompleteResults {
 
   async handleFilters() {
     const suggestFilters = this.parseResult.suggestFilters;
-    if (!window.HAS_OPTIMIZER || !suggestFilters) {
+    if (!window.HAS_SQL_ANALYZER || !suggestFilters) {
       return [];
     }
     this.loadingFilters(true);
@@ -1990,7 +1991,7 @@ class AutocompleteResults {
                         ? suggestFilters.prefix.toLowerCase()
                         : suggestFilters.prefix) + ' '
                     : '';
-                  compVal += this.createOptimizerIdentifier(
+                  compVal += this.createSqlAnalyzerIdentifier(
                     value.tableName,
                     grp.columnName,
                     suggestFilters.tables
@@ -2032,7 +2033,7 @@ class AutocompleteResults {
 
   async handlePopularTables(tablesPromise) {
     const suggestTables = this.parseResult.suggestTables;
-    if (!window.HAS_OPTIMIZER || !suggestTables) {
+    if (!window.HAS_SQL_ANALYZER || !suggestTables) {
       return [];
     }
 
@@ -2062,7 +2063,7 @@ class AutocompleteResults {
 
       const childEntries = await new Promise((resolve, reject) => {
         this.onCancelFunctions.push(reject);
-        const popularityPromise = entry.loadOptimizerPopularityForChildren({
+        const popularityPromise = entry.loadSqlAnalyzerPopularityForChildren({
           silenceErrors: true,
           cancellable: true
         });
@@ -2074,9 +2075,9 @@ class AutocompleteResults {
       const popularityIndex = {};
 
       childEntries.forEach(childEntry => {
-        if (childEntry.optimizerPopularity && childEntry.optimizerPopularity.popularity) {
+        if (childEntry.sqlAnalyzerPopularity && childEntry.sqlAnalyzerPopularity.popularity) {
           popularityIndex[childEntry.name] = true;
-          totalPopularity += childEntry.optimizerPopularity.popularity;
+          totalPopularity += childEntry.sqlAnalyzerPopularity.popularity;
         }
       });
 
@@ -2085,7 +2086,7 @@ class AutocompleteResults {
         tableSuggestions.forEach(suggestion => {
           if (popularityIndex[suggestion.details.name]) {
             suggestion.relativePopularity = Math.round(
-              (100 * suggestion.details.optimizerPopularity.popularity) / totalPopularity
+              (100 * suggestion.details.sqlAnalyzerPopularity.popularity) / totalPopularity
             );
             if (suggestion.relativePopularity >= 5) {
               suggestion.popular(true);
@@ -2103,7 +2104,7 @@ class AutocompleteResults {
   async handlePopularColumns(columnsPromise) {
     const suggestColumns = this.parseResult.suggestColumns;
 
-    if (!window.HAS_OPTIMIZER || !suggestColumns || !suggestColumns.source) {
+    if (!window.HAS_SQL_ANALYZER || !suggestColumns || !suggestColumns.source) {
       return [];
     }
 
@@ -2139,7 +2140,7 @@ class AutocompleteResults {
         this.onCancelFunctions.push(reject);
         const popularityPromise = dataCatalog
           .getCatalog(this.snippet.connector())
-          .loadOptimizerPopularityForTables({
+          .loadSqlAnalyzerPopularityForTables({
             namespace: this.snippet.namespace(),
             compute: this.snippet.compute(),
             paths: paths,
@@ -2165,7 +2166,10 @@ class AutocompleteResults {
       const popularityIndex = {};
 
       popularEntries.forEach(popularEntry => {
-        if (popularEntry.optimizerPopularity && popularEntry.optimizerPopularity[valueAttribute]) {
+        if (
+          popularEntry.sqlAnalyzerPopularity &&
+          popularEntry.sqlAnalyzerPopularity[valueAttribute]
+        ) {
           popularityIndex[popularEntry.getQualifiedPath()] = true;
         }
       });
@@ -2179,13 +2183,13 @@ class AutocompleteResults {
       columnSuggestions.forEach(suggestion => {
         if (suggestion.hasCatalogEntry && popularityIndex[suggestion.details.getQualifiedPath()]) {
           matchedSuggestions.push(suggestion);
-          totalColumnCount += suggestion.details.optimizerPopularity[valueAttribute].columnCount;
+          totalColumnCount += suggestion.details.sqlAnalyzerPopularity[valueAttribute].columnCount;
         }
       });
       if (totalColumnCount > 0) {
         matchedSuggestions.forEach(matchedSuggestion => {
           matchedSuggestion.relativePopularity = Math.round(
-            (100 * matchedSuggestion.details.optimizerPopularity[valueAttribute].columnCount) /
+            (100 * matchedSuggestion.details.sqlAnalyzerPopularity[valueAttribute].columnCount) /
               totalColumnCount
           );
           if (matchedSuggestion.relativePopularity >= 5) {
@@ -2200,8 +2204,8 @@ class AutocompleteResults {
     return [];
   }
 
-  createOptimizerIdentifier(optimizerTableName, optimizerColumnName, tables) {
-    let path = optimizerTableName + '.' + optimizerColumnName.split('.').pop();
+  createSqlAnalyzerIdentifier(sqlAnalyzerTableName, sqlAnalyzerColumnName, tables) {
+    let path = sqlAnalyzerTableName + '.' + sqlAnalyzerColumnName.split('.').pop();
     for (let i = 0; i < tables.length; i++) {
       let tablePath = '';
       if (tables[i].identifierChain.length === 2) {
@@ -2224,39 +2228,43 @@ class AutocompleteResults {
     return path;
   }
 
-  createOptimizerIdentifierForColumn(optimizerColumn, tables) {
+  createSqlAnalyzerIdentifierForColumn(sqlAnalyzerColumn, tables) {
     for (let i = 0; i < tables.length; i++) {
       if (
-        optimizerColumn.dbName &&
-        (optimizerColumn.dbName !== this.activeDatabase ||
-          optimizerColumn.dbName !== tables[i].identifierChain[0].name)
+        sqlAnalyzerColumn.dbName &&
+        (sqlAnalyzerColumn.dbName !== this.activeDatabase ||
+          sqlAnalyzerColumn.dbName !== tables[i].identifierChain[0].name)
       ) {
         continue;
       }
       if (
-        optimizerColumn.tableName &&
+        sqlAnalyzerColumn.tableName &&
         hueUtils.equalIgnoreCase(
-          optimizerColumn.tableName,
+          sqlAnalyzerColumn.tableName,
           tables[i].identifierChain[tables[i].identifierChain.length - 1].name
         ) &&
         tables[i].alias
       ) {
-        return tables[i].alias + '.' + optimizerColumn.columnName;
+        return tables[i].alias + '.' + sqlAnalyzerColumn.columnName;
       }
     }
 
-    if (optimizerColumn.dbName && optimizerColumn.dbName !== this.activeDatabase) {
+    if (sqlAnalyzerColumn.dbName && sqlAnalyzerColumn.dbName !== this.activeDatabase) {
       return (
-        optimizerColumn.dbName + '.' + optimizerColumn.tableName + '.' + optimizerColumn.columnName
+        sqlAnalyzerColumn.dbName +
+        '.' +
+        sqlAnalyzerColumn.tableName +
+        '.' +
+        sqlAnalyzerColumn.columnName
       );
     }
     if (tables.length > 1) {
-      return optimizerColumn.tableName + '.' + optimizerColumn.columnName;
+      return sqlAnalyzerColumn.tableName + '.' + sqlAnalyzerColumn.columnName;
     }
-    return optimizerColumn.columnName;
+    return sqlAnalyzerColumn.columnName;
   }
 
-  convertOptimizerQualifiedIdentifier(qualifiedIdentifier, tables, type) {
+  convertSqlAnalyzerQualifiedIdentifier(qualifiedIdentifier, tables, type) {
     const aliases = [];
     let tablesHasDefaultDatabase = false;
     tables.forEach(table => {

+ 3 - 3
desktop/core/src/desktop/js/types/types.ts

@@ -44,18 +44,18 @@ declare global {
 }
 
 export interface hueWindow {
-  CACHEABLE_TTL?: { default?: number; optimizer?: number };
+  CACHEABLE_TTL?: { default?: number; sqlAnalyzer?: number };
   CLOSE_SESSIONS?: { [dialect: string]: boolean };
   CUSTOM_DASHBOARD_URL?: string;
   ENABLE_PREDICT?: boolean;
   HAS_CATALOG?: boolean;
   HAS_CONNECTORS?: boolean;
-  HAS_OPTIMIZER?: boolean;
+  HAS_SQL_ANALYZER?: boolean;
   AUTOCOMPLETE_TIMEOUT?: number;
   ENABLE_SQL_SYNTAX_CHECK?: boolean;
   HUE_BASE_URL?: string;
   LOGGED_USERNAME?: string;
-  OPTIMIZER_MODE?: string;
+  SQL_ANALYZER_MODE?: string;
   SHOW_ADD_MORE_EDITORS?: boolean;
   USER_IS_ADMIN?: boolean;
   USER_IS_HUE_ADMIN?: boolean;

+ 2 - 2
desktop/core/src/desktop/templates/common_header_m.mako

@@ -81,11 +81,11 @@ if USE_NEW_EDITOR.get():
   <script type="text/javascript">
     var LOGGED_USERNAME = '${ user.username }';
     var IS_S3_ENABLED = '${ is_s3_enabled }' === 'True';
-    var HAS_OPTIMIZER = '${ has_optimizer() }' === 'True';
+    var HAS_SQL_ANALYZER = '${ has_optimizer() }' === 'True';
 
     var CACHEABLE_TTL = {
       default: ${ conf.CUSTOM.CACHEABLE_TTL.get() },
-      optimizer: ${ OPTIMIZER.CACHEABLE_TTL.get() }
+      sqlAnalyzer: ${ OPTIMIZER.CACHEABLE_TTL.get() }
     };
 
     var AUTOCOMPLETE_TIMEOUT = ${ conf.EDITOR_AUTOCOMPLETE_TIMEOUT.get() };

+ 5 - 6
desktop/core/src/desktop/templates/global_js_constants.mako

@@ -56,7 +56,7 @@
 
   window.CACHEABLE_TTL = {
     default: ${ conf.CUSTOM.CACHEABLE_TTL.get() },
-    optimizer: ${ OPTIMIZER.CACHEABLE_TTL.get() or 0 }
+    sqlAnalyzer: ${ OPTIMIZER.CACHEABLE_TTL.get() or 0 }
   };
 
   window.DEV = '${ conf.DEV.get() }' === 'True';
@@ -115,10 +115,9 @@
   window.CATALOG_URL = '${ get_catalog_url() or "" }'
   window.HAS_READ_ONLY_CATALOG = '${ has_readonly_catalog(request.user) }' === 'True' || '${ has_write_access(request.user) }' === 'False';
 
-  window.HAS_OPTIMIZER = '${ has_optimizer() }' === 'True';
-  window.OPTIMIZER_MODE = '${ get_optimizer_mode() }';
-  window.OPTIMIZER_URL = '${ get_optimizer_url() }'
-  window.AUTO_UPLOAD_OPTIMIZER_STATS = '${ OPTIMIZER.AUTO_UPLOAD_STATS.get() }' === 'True';
+  window.HAS_SQL_ANALYZER = '${ has_optimizer() }' === 'True';
+  window.SQL_ANALYZER_MODE = '${ get_optimizer_mode() }';
+  window.AUTO_UPLOAD_SQL_ANALYZER_STATS = '${ OPTIMIZER.AUTO_UPLOAD_STATS.get() }' === 'True';
 
   window.HAS_GIST = '${ ENABLE_GIST.get() }' === 'True';
   window.SHARE_TO_SLACK = '${ conf.SLACK.SHARE_FROM_EDITOR.get() }' === 'True';
@@ -602,7 +601,7 @@
     'Updated: ': '${ _('Updated: ') }',
     'Upload a file': '${_('Upload a file')}',
     'Upload file': '${_('Upload file')}',
-    'Upload optimizer history': '${ _('Upload optimizer history') }',
+    'Upload SQL Analyzer history': '${ _('Upload SQL Analyzer history') }',
     'uploaded successfully': '${ _('uploaded successfully') }',
     'USA': '${ _('USA') }',
     'used by': '${ _('used by') }',

+ 2 - 2
desktop/core/src/desktop/templates/hue_ace_autocompleter.mako

@@ -752,8 +752,8 @@ else:
           }, COMMENT_LOAD_DELAY);
         }
 
-        if (self.catalogEntry.optimizerPopularity && self.catalogEntry.optimizerPopularity.relativePopularity) {
-          self.popularity(self.catalogEntry.optimizerPopularity.relativePopularity);
+        if (self.catalogEntry.sqlAnalyzerPopularity && self.catalogEntry.sqlAnalyzerPopularity.relativePopularity) {
+          self.popularity(self.catalogEntry.sqlAnalyzerPopularity.relativePopularity);
         }
       }
 

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
desktop/libs/notebook/src/notebook/static/notebook/css/editor2.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
desktop/libs/notebook/src/notebook/static/notebook/css/notebook.css


+ 4 - 4
desktop/libs/notebook/src/notebook/static/notebook/less/editor2.less

@@ -1430,12 +1430,12 @@
     color: @state-warning-text;
   }
 
-  .optimizer-container {
+  .sql-analyzer-container {
     margin-top: -11px;
     font-size: 15px;
   }
 
-  .optimizer-icon {
+  .sql-analyzer-icon {
     display: inline-block;
     width: 16px;
     height: 16px;
@@ -1466,7 +1466,7 @@
     }
   }
 
-  .active .optimizer-icon {
+  .active .sql-analyzer-icon {
     opacity: 1;
   }
 
@@ -1487,7 +1487,7 @@
     padding-left: 4px;
   }
 
-  .optimizer-explanation {
+  .sql-analyzer-explanation {
     margin-left: 4px;
   }
 

+ 4 - 4
desktop/libs/notebook/src/notebook/static/notebook/less/notebook.less

@@ -1190,12 +1190,12 @@
     color: @state-warning-text;
   }
 
-  .optimizer-container {
+  .sql-analyzer-container {
     margin-top: -11px;
     font-size: 15px;
   }
 
-  .optimizer-icon {
+  .sql-analyzer-icon {
     display: inline-block;
     width: 16px;
     height: 16px;
@@ -1226,7 +1226,7 @@
     }
   }
 
-  .active .optimizer-icon {
+  .active .sql-analyzer-icon {
     opacity: 1;
   }
 
@@ -1247,7 +1247,7 @@
     padding-left: 4px;
   }
 
-  .optimizer-explanation {
+  .sql-analyzer-explanation {
     margin-left: 4px;
   }
 

+ 24 - 24
desktop/libs/notebook/src/notebook/templates/editor2.mako

@@ -222,37 +222,37 @@
   </div>
 </script>
 
-<script type="text/html" id="editor-optimizer-alerts">
-  <!-- ko if: window.HAS_OPTIMIZER && (dialect() == 'impala' || dialect() == 'hive') && ! $root.isPresentationMode() -->
-  <div class="optimizer-container" data-bind="css: { 'active': showOptimizer }">
+<script type="text/html" id="editor-sql-analyzer-alerts">
+  <!-- ko if: window.HAS_SQL_ANALYZER && (dialect() == 'impala' || dialect() == 'hive') && ! $root.isPresentationMode() -->
+  <div class="sql-analyzer-container" data-bind="css: { 'active': showSqlAnalyzer }">
     <!-- ko if: hasSuggestion() -->
     <!-- ko with: suggestion() -->
     <!-- ko if: parseError -->
     <!-- ko if: $parent.compatibilityTargetPlatform().value === $parent.dialect() && $parent.compatibilitySourcePlatform().value === $parent.dialect() -->
-    <div class="optimizer-icon error" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+    <div class="sql-analyzer-icon error" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
       <i class="fa fa-exclamation"></i>
     </div>
-    <!-- ko if: $parent.showOptimizer -->
-    <span class="optimizer-explanation alert-error alert-neutral">${ _('The query has a parse error.') }</span>
+    <!-- ko if: $parent.showSqlAnalyzer -->
+    <span class="sql-analyzer-explanation alert-error alert-neutral">${ _('The query has a parse error.') }</span>
     <!-- /ko -->
     <!-- /ko -->
     ## Oracle, MySQL compatibility... as they return a parseError and not encounteredString.
           <!-- ko if: $parent.compatibilityTargetPlatform().value !== $parent.dialect() || $parent.dialect() !== $parent.compatibilitySourcePlatform().value -->
-    <div class="optimizer-icon warning" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+    <div class="sql-analyzer-icon warning" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
       <i class="fa fa-exclamation"></i>
     </div>
-    <!-- ko if: $parent.showOptimizer -->
-    <span class="optimizer-explanation alert-warning alert-neutral">${ _('This ') } <span data-bind="text: $parent.compatibilitySourcePlatform().name"></span> ${ _(' query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
+    <!-- ko if: $parent.showSqlAnalyzer -->
+    <span class="sql-analyzer-explanation alert-warning alert-neutral">${ _('This ') } <span data-bind="text: $parent.compatibilitySourcePlatform().name"></span> ${ _(' query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
     <!-- /ko -->
     <!-- /ko -->
     <!-- /ko -->
     <!-- ko if: !parseError() && ($parent.compatibilityTargetPlatform().value !== $parent.dialect() || $parent.compatibilitySourcePlatform().value !== $parent.dialect()) -->
     <!-- ko if: queryError.encounteredString().length == 0 -->
-    <div class="optimizer-icon success" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+    <div class="sql-analyzer-icon success" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
       <i class="fa fa-check"></i>
     </div>
-    <!-- ko if: $parent.showOptimizer -->
-    <span class="optimizer-explanation alert-success alert-neutral">
+    <!-- ko if: $parent.showSqlAnalyzer -->
+    <span class="sql-analyzer-explanation alert-success alert-neutral">
               ${ _('The ') } <div data-bind="component: { name: 'hue-drop-down', params: { value: $parent.compatibilitySourcePlatform, entries: $parent.compatibilitySourcePlatforms, labelAttribute: 'name' } }" style="display: inline-block"></div>
       <!-- ko if: $parent.compatibilitySourcePlatform().value === $parent.dialect() -->
       ${ _(' query is compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.
@@ -265,11 +265,11 @@
     <!-- /ko -->
     <!-- /ko -->
     <!-- ko ifnot: queryError.encounteredString().length == 0 -->
-    <div class="optimizer-icon warning" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+    <div class="sql-analyzer-icon warning" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
       <i class="fa fa-exclamation"></i>
     </div>
-    <!-- ko if: $parent.showOptimizer -->
-    <span class="optimizer-explanation alert-warning alert-neutral">${ _('This query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
+    <!-- ko if: $parent.showSqlAnalyzer -->
+    <span class="sql-analyzer-explanation alert-warning alert-neutral">${ _('This query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
     <!-- /ko -->
     <!-- /ko -->
     <!-- /ko -->
@@ -277,23 +277,23 @@
     <!-- /ko -->
     <!-- ko if: ! hasSuggestion() && topRisk() -->
     <!-- ko if: topRisk().risk === 'low' -->
-    <div class="optimizer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some low risks were detected, see the assistant for details.') }">
+    <div class="sql-analyzer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some low risks were detected, see the assistant for details.') }">
       <i class="fa fa-check"></i>
     </div>
     <!-- /ko -->
     <!-- ko if: topRisk().risk == 'medium' -->
-    <div class="optimizer-icon warning" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some medium risks were detected, see the assistant for details.') }">
+    <div class="sql-analyzer-icon warning" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some medium risks were detected, see the assistant for details.') }">
       <i class="fa fa-exclamation"></i>
     </div>
     <!-- /ko -->
     <!-- ko if: topRisk().risk == 'high' -->
-    <div class="optimizer-icon error" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some high risks were detected, see the assistant for details.') }">
+    <div class="sql-analyzer-icon error" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some high risks were detected, see the assistant for details.') }">
       <i class="fa fa-exclamation"></i>
     </div>
     <!-- /ko -->
     <!-- /ko -->
     <!-- ko if: hasSuggestion() == '' && ! topRisk() -->
-    <div class="optimizer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Query validated, no issues found.') }">
+    <div class="sql-analyzer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Query validated, no issues found.') }">
       <i class="fa fa-check"></i>
     </div>
     <!-- /ko -->
@@ -551,7 +551,7 @@
           },
           css: {'blue': $data.showLogs}
         " title="${ _('Toggle Logs') }"><i class="fa fa-fw" data-bind="css: { 'fa-caret-right': !$data.showLogs(), 'fa-caret-down': $data.showLogs() }"></i></a>
-    <div class="snippet-progress-container" data-bind="visible: status() != 'canceled' && status() != 'with-optimizer-report'">
+    <div class="snippet-progress-container" data-bind="visible: status() != 'canceled' && status() != 'with-sql-analyzer-report'">
       <!-- ko component: { name: 'executable-progress-bar', params: { activeExecutable: activeExecutable } } --><!-- /ko -->
     </div>
     <div class="snippet-error-container alert alert-error" style="margin-bottom: 0" data-bind="visible: errors().length > 0">
@@ -882,7 +882,7 @@
         <div class="editor-settings-drawer">
           <!-- ko template: 'editor-snippet-settings' --><!-- /ko -->
         </div>
-  ##      <!-- ko template: { name: 'editor-optimizer-alerts' } --><!-- /ko -->
+  ##      <!-- ko template: { name: 'editor-sql-analyzer-alerts' } --><!-- /ko -->
         <div class="editor-code-editor">
           <!-- ko template: { name: 'editor-code-editor' } --><!-- /ko -->
         </div>
@@ -1262,9 +1262,9 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
 
   window.NOTEBOOKS_JSON = ${ notebooks_json | n,unicode };
 
-  window.OPTIMIZER_AUTO_UPLOAD_QUERIES = '${ OPTIMIZER.AUTO_UPLOAD_QUERIES.get() }' === 'True';
+  window.SQL_ANALYZER_AUTO_UPLOAD_QUERIES = '${ OPTIMIZER.AUTO_UPLOAD_QUERIES.get() }' === 'True';
 
-  window.OPTIMIZER_AUTO_UPLOAD_DDL = '${ OPTIMIZER.AUTO_UPLOAD_DDL.get() }' === 'True';
+  window.SQL_ANALYZER_AUTO_UPLOAD_DDL = '${ OPTIMIZER.AUTO_UPLOAD_DDL.get() }' === 'True';
 
-  window.OPTIMIZER_QUERY_HISTORY_UPLOAD_LIMIT = ${ OPTIMIZER.QUERY_HISTORY_UPLOAD_LIMIT.get() };
+  window.SQL_ANALYZER_QUERY_HISTORY_UPLOAD_LIMIT = ${ OPTIMIZER.QUERY_HISTORY_UPLOAD_LIMIT.get() };
 </script>

+ 23 - 23
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -983,36 +983,36 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
 </script>
 
 <script type="text/html" id="code-editor-snippet-body${ suffix }">
-  <!-- ko if: HAS_OPTIMIZER && (type() == 'impala' || type() == 'hive') && ! $root.isPresentationMode() && ! $root.isResultFullScreenMode() -->
-  <div class="optimizer-container" data-bind="css: { 'active': showOptimizer }">
+  <!-- ko if: HAS_SQL_ANALYZER && (type() == 'impala' || type() == 'hive') && ! $root.isPresentationMode() && ! $root.isResultFullScreenMode() -->
+  <div class="sql-analyzer-container" data-bind="css: { 'active': showSqlAnalyzer }">
     <!-- ko if: hasSuggestion() -->
       <!-- ko with: suggestion() -->
         <!-- ko if: parseError -->
           <!-- ko if: $parent.compatibilityTargetPlatform().value === $parent.type() && $parent.compatibilitySourcePlatform().value === $parent.type() -->
-            <div class="optimizer-icon error" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+            <div class="sql-analyzer-icon error" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
               <i class="fa fa-exclamation"></i>
             </div>
-            <!-- ko if: $parent.showOptimizer -->
-              <span class="optimizer-explanation alert-error alert-neutral">${ _('The query has a parse error.') }</span>
+            <!-- ko if: $parent.showSqlAnalyzer -->
+              <span class="sql-analyzer-explanation alert-error alert-neutral">${ _('The query has a parse error.') }</span>
             <!-- /ko -->
           <!-- /ko -->
           ## Oracle, MySQL compatibility... as they return a parseError and not encounteredString.
           <!-- ko if: $parent.compatibilityTargetPlatform().value !== $parent.type() || $parent.type() !== $parent.compatibilitySourcePlatform().value -->
-            <div class="optimizer-icon warning" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+            <div class="sql-analyzer-icon warning" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
               <i class="fa fa-exclamation"></i>
             </div>
-            <!-- ko if: $parent.showOptimizer -->
-              <span class="optimizer-explanation alert-warning alert-neutral">${ _('This ') } <span data-bind="text: $parent.compatibilitySourcePlatform().name"></span> ${ _(' query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
+            <!-- ko if: $parent.showSqlAnalyzer -->
+              <span class="sql-analyzer-explanation alert-warning alert-neutral">${ _('This ') } <span data-bind="text: $parent.compatibilitySourcePlatform().name"></span> ${ _(' query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
             <!-- /ko -->
           <!-- /ko -->
         <!-- /ko -->
         <!-- ko if: !parseError() && ($parent.compatibilityTargetPlatform().value !== $parent.type() || $parent.compatibilitySourcePlatform().value !== $parent.type()) -->
           <!-- ko if: queryError.encounteredString().length == 0 -->
-            <div class="optimizer-icon success" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+            <div class="sql-analyzer-icon success" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
               <i class="fa fa-check"></i>
             </div>
-            <!-- ko if: $parent.showOptimizer -->
-            <span class="optimizer-explanation alert-success alert-neutral">
+            <!-- ko if: $parent.showSqlAnalyzer -->
+            <span class="sql-analyzer-explanation alert-success alert-neutral">
               ${ _('The ') } <div data-bind="component: { name: 'hue-drop-down', params: { value: $parent.compatibilitySourcePlatform, entries: $parent.compatibilitySourcePlatforms, labelAttribute: 'name' } }" style="display: inline-block"></div>
               <!-- ko if: $parent.compatibilitySourcePlatform().value === $parent.type() -->
                 ${ _(' query is compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.
@@ -1025,11 +1025,11 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
           <!-- /ko -->
         <!-- /ko -->
         <!-- ko ifnot: queryError.encounteredString().length == 0 -->
-          <div class="optimizer-icon warning" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
+          <div class="sql-analyzer-icon warning" data-bind="click: function(){ $parent.showSqlAnalyzer(! $parent.showSqlAnalyzer()) }, attr: { 'title': $parent.showSqlAnalyzer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
             <i class="fa fa-exclamation"></i>
           </div>
-          <!-- ko if: $parent.showOptimizer -->
-            <span class="optimizer-explanation alert-warning alert-neutral">${ _('This query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
+          <!-- ko if: $parent.showSqlAnalyzer -->
+            <span class="sql-analyzer-explanation alert-warning alert-neutral">${ _('This query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
           <!-- /ko -->
         <!-- /ko -->
       <!-- /ko -->
@@ -1037,23 +1037,23 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
     <!-- /ko -->
     <!-- ko if: ! hasSuggestion() && topRisk() -->
       <!-- ko if: topRisk().risk === 'low' -->
-        <div class="optimizer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some low risks were detected, see the assistant for details.') }">
+        <div class="sql-analyzer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some low risks were detected, see the assistant for details.') }">
           <i class="fa fa-check"></i>
         </div>
       <!-- /ko -->
       <!-- ko if: topRisk().risk == 'medium' -->
-        <div class="optimizer-icon warning" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some medium risks were detected, see the assistant for details.') }">
+        <div class="sql-analyzer-icon warning" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some medium risks were detected, see the assistant for details.') }">
           <i class="fa fa-exclamation"></i>
         </div>
       <!-- /ko -->
       <!-- ko if: topRisk().risk == 'high' -->
-        <div class="optimizer-icon error" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some high risks were detected, see the assistant for details.') }">
+        <div class="sql-analyzer-icon error" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some high risks were detected, see the assistant for details.') }">
           <i class="fa fa-exclamation"></i>
         </div>
       <!-- /ko -->
     <!-- /ko -->
     <!-- ko if: hasSuggestion() == '' && ! topRisk() -->
-      <div class="optimizer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Query validated, no issues found.') }">
+      <div class="sql-analyzer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Query validated, no issues found.') }">
         <i class="fa fa-check"></i>
       </div>
     <!-- /ko -->
@@ -1648,7 +1648,7 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
 <script type="text/html" id="snippet-execution-status${ suffix }">
   <div class="snippet-execution-status" data-bind="clickForAceFocus: ace">
     <a class="inactive-action pull-left snippet-logs-btn" href="javascript:void(0)" data-bind="visible: status() === 'running' && errors().length == 0, click: function() { hideFixedHeaders(); $data.showLogs(!$data.showLogs());}, css: {'blue': $data.showLogs}" title="${ _('Toggle Logs') }"><i class="fa fa-fw" data-bind="css: { 'fa-caret-right': !$data.showLogs(), 'fa-caret-down': $data.showLogs() }"></i></a>
-    <div class="snippet-progress-container" data-bind="visible: status() != 'canceled' && status() != 'with-optimizer-report'">
+    <div class="snippet-progress-container" data-bind="visible: status() != 'canceled' && status() != 'with-sql-analyzer-report'">
       <div class="progress-snippet progress" data-bind="css: {
         'progress-starting': progress() == 0 && (status() == 'running' || status() == 'starting'),
         'progress-warning': progress() > 0 && progress() < 100,
@@ -1798,7 +1798,7 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
             <i class="fa fa-fw fa-eraser"></i> ${_('Clear')}
           </a>
         </li>
-        <!-- ko if: HAS_OPTIMIZER -->
+        <!-- ko if: HAS_SQL_ANALYZER -->
         <li class="divider"></li>
         <li>
           <a href="javascript:void(0)" data-bind="click: checkCompatibility, visible: type() == 'hive' || type() == 'impala'" title="${ _('Get hints on how to port SQL from other databases') }">
@@ -2248,11 +2248,11 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
 
   window.NOTEBOOKS_JSON = ${ notebooks_json | n,unicode };
 
-  window.OPTIMIZER_AUTO_UPLOAD_QUERIES = '${ OPTIMIZER.AUTO_UPLOAD_QUERIES.get() }' === 'True';
+  window.SQL_ANALYZER_AUTO_UPLOAD_QUERIES = '${ OPTIMIZER.AUTO_UPLOAD_QUERIES.get() }' === 'True';
 
-  window.OPTIMIZER_AUTO_UPLOAD_DDL = '${ OPTIMIZER.AUTO_UPLOAD_DDL.get() }' === 'True';
+  window.SQL_ANALYZER_AUTO_UPLOAD_DDL = '${ OPTIMIZER.AUTO_UPLOAD_DDL.get() }' === 'True';
 
-  window.OPTIMIZER_QUERY_HISTORY_UPLOAD_LIMIT = ${ OPTIMIZER.QUERY_HISTORY_UPLOAD_LIMIT.get() };
+  window.SQL_ANALYZER_QUERY_HISTORY_UPLOAD_LIMIT = ${ OPTIMIZER.QUERY_HISTORY_UPLOAD_LIMIT.get() };
 </script>
 
 </%def>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio