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>
),
}),
),
}),