childNodes: groupBy()

in web-console/src/views/workbench-view/column-tree/column-tree.tsx [233:559]


          childNodes: groupBy(
            isSearching
              ? metadata.filter(
                  r =>
                    (searchMode === 'tables-and-columns' &&
                      (r.TABLE_NAME.toLowerCase().includes(lowerSearchString) ||
                        r.COLUMN_NAME.toLowerCase().includes(lowerSearchString))) ||
                    (searchMode === 'tables-only' &&
                      r.TABLE_NAME.toLowerCase().includes(lowerSearchString)) ||
                    (searchMode === 'columns-only' &&
                      r.COLUMN_NAME.toLowerCase().includes(lowerSearchString)),
                )
              : metadata,
            r => r.TABLE_NAME,
            (metadata, tableName): TreeNodeInfo => ({
              id: tableName,
              icon: IconNames.TH,
              className: tableName === highlightTable ? 'highlight' : undefined,
              isExpanded:
                expandedTables.has(tableName) ||
                (isSearching &&
                  (searchMode === 'columns-only' ||
                    !tableName.toLowerCase().includes(lowerSearchString))),
              label: (
                <Popover
                  position={Position.RIGHT}
                  content={
                    <Deferred
                      content={() => {
                        const parsedQuery = props.getParsedQuery();
                        const tableRef = T(tableName);
                        const prettyTableRef = prettyPrintSql(tableRef);
                        const countExpression = getCountExpression(
                          metadata.map(child => child.COLUMN_NAME),
                        );

                        const getQueryOnTable = () => {
                          return SqlQuery.create(
                            SqlTable.create(
                              tableName,
                              schemaName === 'druid' ? undefined : schemaName,
                            ),
                          );
                        };

                        const getWhere = (defaultToAllTime = false) => {
                          if (parsedQuery && parsedQuery.getFirstTableName() === tableName) {
                            return parsedQuery.getWhereExpression();
                          } else if (schemaName === 'druid') {
                            return defaultToAllTime ? undefined : defaultWhere;
                          } else {
                            return;
                          }
                        };

                        return (
                          <Menu>
                            <MenuItem
                              icon={IconNames.FULLSCREEN}
                              text={`SELECT ...columns... FROM ${tableName}`}
                              onClick={() => {
                                onQueryChange(
                                  getQueryOnTable()
                                    .changeSelectExpressions(
                                      metadata
                                        .map(child => child.COLUMN_NAME)
                                        .map(columnName => C(columnName)),
                                    )
                                    .changeWhereExpression(getWhere()),
                                  true,
                                );
                              }}
                            />
                            <MenuItem
                              icon={IconNames.FULLSCREEN}
                              text={`SELECT * FROM ${tableName}`}
                              onClick={() => {
                                onQueryChange(
                                  getQueryOnTable().changeWhereExpression(getWhere()),
                                  true,
                                );
                              }}
                            />
                            <MenuItem
                              icon={IconNames.FULLSCREEN}
                              text={`SELECT ${countExpression} FROM ${tableName}`}
                              onClick={() => {
                                onQueryChange(
                                  getQueryOnTable()
                                    .changeSelect(0, countExpression)
                                    .changeGroupByExpressions([])
                                    .changeWhereExpression(getWhere(true)),
                                  true,
                                );
                              }}
                            />
                            <MenuItem
                              icon={IconNames.FULLSCREEN}
                              text={`SELECT MIN(__time), MAX(__time) FROM ${tableName}`}
                              onClick={() => {
                                onQueryChange(
                                  getQueryOnTable()
                                    .changeSelectExpressions([
                                      F.min(C('__time')).as('min_time'),
                                      F.max(C('__time')).as('max_time'),
                                    ])
                                    .changeGroupByExpressions([])
                                    .changeWhereExpression(getWhere(true))
                                    .removeColumnFromWhere('__time'),
                                  true,
                                );
                              }}
                            />
                            {parsedQuery && parsedQuery.getFirstTableName() !== tableName && (
                              <MenuItem
                                icon={IconNames.EXCHANGE}
                                text={`Replace FROM with: ${prettyTableRef}`}
                                onClick={() => {
                                  onQueryChange(
                                    parsedQuery.changeFromExpressions([tableRef]),
                                    true,
                                  );
                                }}
                              />
                            )}
                            {parsedQuery && schemaName === 'lookup' && (
                              <MenuItem
                                popoverProps={{ openOnTargetFocus: false }}
                                icon={IconNames.JOIN_TABLE}
                                text={parsedQuery.hasJoin() ? `Replace join` : `Join`}
                              >
                                <MenuItem
                                  icon={IconNames.LEFT_JOIN}
                                  text="Left join"
                                  onClick={() => {
                                    const { lookupColumn, originalTableColumn } = getJoinColumns(
                                      parsedQuery,
                                      tableName,
                                    );
                                    onQueryChange(
                                      parsedQuery
                                        .removeAllJoins()
                                        .addJoin(
                                          SqlJoinPart.create(
                                            'LEFT',
                                            N(schemaName).table(tableName),
                                            N('lookup')
                                              .table(tableName)
                                              .column(lookupColumn)
                                              .equal(
                                                SqlColumn.create(
                                                  originalTableColumn,
                                                  parsedQuery.getFirstTableName(),
                                                ),
                                              ),
                                          ),
                                        ),
                                      false,
                                    );
                                  }}
                                />
                                <MenuItem
                                  icon={IconNames.INNER_JOIN}
                                  text="Inner join"
                                  onClick={() => {
                                    const { lookupColumn, originalTableColumn } = getJoinColumns(
                                      parsedQuery,
                                      tableName,
                                    );
                                    onQueryChange(
                                      parsedQuery.addJoin(
                                        SqlJoinPart.create(
                                          'INNER',
                                          N(schemaName).table(tableName),
                                          N('lookup')
                                            .table(tableName)
                                            .column(lookupColumn)
                                            .equal(
                                              SqlColumn.create(
                                                originalTableColumn,
                                                parsedQuery.getFirstTableName(),
                                              ),
                                            ),
                                        ),
                                      ),
                                      false,
                                    );
                                  }}
                                />
                              </MenuItem>
                            )}
                            {parsedQuery &&
                              parsedQuery.hasJoin() &&
                              parsedQuery.getJoins()[0].table.toString() === tableName && (
                                <MenuItem
                                  icon={IconNames.EXCHANGE}
                                  text="Remove join"
                                  onClick={() => onQueryChange(parsedQuery.removeAllJoins())}
                                />
                              )}
                            {parsedQuery &&
                              parsedQuery.hasGroupBy() &&
                              parsedQuery.getFirstTableName() === tableName && (
                                <MenuItem
                                  icon={IconNames.FUNCTION}
                                  text="Aggregate COUNT(*)"
                                  onClick={() =>
                                    onQueryChange(parsedQuery.addSelect(COUNT_STAR), true)
                                  }
                                />
                              )}
                            <MenuItem
                              icon={IconNames.CLIPBOARD}
                              text={`Copy: ${prettyTableRef}`}
                              onClick={() => {
                                copyAndAlert(
                                  tableRef.toString(),
                                  `${prettyTableRef} query copied to clipboard`,
                                );
                              }}
                            />
                          </Menu>
                        );
                      }}
                    />
                  }
                >
                  {tableName}
                </Popover>
              ),
              childNodes: metadata.map(
                (columnData): TreeNodeInfo => ({
                  id: columnData.COLUMN_NAME,
                  icon: (
                    <Icon
                      className={Classes.TREE_NODE_ICON}
                      icon={dataTypeToIcon(columnData.DATA_TYPE)}
                      aria-hidden
                      tabIndex={-1}
                      data-tooltip={columnData.DATA_TYPE}
                    />
                  ),
                  label: (
                    <Popover
                      position={Position.RIGHT}
                      autoFocus={false}
                      content={
                        <Deferred
                          content={() => {
                            const parsedQuery = props.getParsedQuery();
                            return (
                              <Menu>
                                <MenuItem
                                  icon={IconNames.FULLSCREEN}
                                  text={`Show: ${columnData.COLUMN_NAME}`}
                                  onClick={() => {
                                    handleColumnShow({
                                      columnSchema: schemaName,
                                      columnTable: tableName,
                                      columnName: columnData.COLUMN_NAME,
                                      columnType: columnData.DATA_TYPE,
                                      parsedQuery,
                                      defaultWhere,
                                      onQueryChange: onQueryChange,
                                    });
                                  }}
                                />
                                {parsedQuery &&
                                  oneOf(columnData.DATA_TYPE, 'BIGINT', 'FLOAT', 'DOUBLE') && (
                                    <NumberMenuItems
                                      table={tableName}
                                      schema={schemaName}
                                      columnName={columnData.COLUMN_NAME}
                                      parsedQuery={parsedQuery}
                                      onQueryChange={onQueryChange}
                                    />
                                  )}
                                {parsedQuery && columnData.DATA_TYPE === 'VARCHAR' && (
                                  <StringMenuItems
                                    table={tableName}
                                    schema={schemaName}
                                    columnName={columnData.COLUMN_NAME}
                                    parsedQuery={parsedQuery}
                                    onQueryChange={onQueryChange}
                                  />
                                )}
                                {parsedQuery && columnData.DATA_TYPE === 'TIMESTAMP' && (
                                  <TimeMenuItems
                                    table={tableName}
                                    schema={schemaName}
                                    columnName={columnData.COLUMN_NAME}
                                    parsedQuery={parsedQuery}
                                    onQueryChange={onQueryChange}
                                  />
                                )}
                                {parsedQuery && columnData.DATA_TYPE.startsWith('COMPLEX<') && (
                                  <ComplexMenuItems
                                    table={tableName}
                                    schema={schemaName}
                                    columnName={columnData.COLUMN_NAME}
                                    columnType={columnData.DATA_TYPE}
                                    parsedQuery={parsedQuery}
                                    onQueryChange={onQueryChange}
                                  />
                                )}
                                <MenuItem
                                  icon={IconNames.CLIPBOARD}
                                  text={`Copy: ${columnData.COLUMN_NAME}`}
                                  onClick={() => {
                                    copyAndAlert(
                                      columnData.COLUMN_NAME,
                                      `${columnData.COLUMN_NAME} query copied to clipboard`,
                                    );
                                  }}
                                />
                              </Menu>
                            );
                          }}
                        />
                      }
                    >
                      {columnData.COLUMN_NAME}
                    </Popover>
                  ),
                }),
              ),
            }),