4 Commits

Author SHA1 Message Date
beat4ocean
fb71ed3dc1 Merge 738093bc88 into f764236657 2025-03-05 16:50:12 +08:00
jerryjzhang
f764236657 (improvement)(headless)Optimize compatibility and robustness in ontology query translation.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-03-05 16:48:40 +08:00
beat4ocean
738093bc88 [fix][chat]Fix dashboard display issue when categoryColumnName and dateColumnName are identical. 2025-03-05 15:01:11 +08:00
beat4ocean
b6d1525daa [Fix][Chat]Fix time granularity bug in model editing and dashboard display. 2025-03-05 15:01:11 +08:00
4 changed files with 42 additions and 34 deletions

View File

@@ -78,7 +78,8 @@ public abstract class SemanticNode {
scope.getValidator().getCatalogReader().getRootSchema(), engineType); scope.getValidator().getCatalogReader().getRootSchema(), engineType);
if (Configuration.getSqlAdvisor(sqlValidatorWithHints, engineType).getReservedAndKeyWords() if (Configuration.getSqlAdvisor(sqlValidatorWithHints, engineType).getReservedAndKeyWords()
.contains(expression.toUpperCase())) { .contains(expression.toUpperCase())) {
if (engineType == EngineType.HANADB || engineType == EngineType.PRESTO || engineType == EngineType.TRINO) { if (engineType == EngineType.HANADB || engineType == EngineType.PRESTO
|| engineType == EngineType.TRINO) {
expression = String.format("\"%s\"", expression); expression = String.format("\"%s\"", expression);
} else { } else {
expression = String.format("`%s`", expression); expression = String.format("`%s`", expression);
@@ -166,9 +167,9 @@ public abstract class SemanticNode {
if (sqlNode instanceof SqlBasicCall) { if (sqlNode instanceof SqlBasicCall) {
SqlBasicCall sqlBasicCall = (SqlBasicCall) sqlNode; SqlBasicCall sqlBasicCall = (SqlBasicCall) sqlNode;
if (sqlBasicCall.getOperator().getKind().equals(SqlKind.AS)) { if (sqlBasicCall.getOperator().getKind().equals(SqlKind.AS)) {
if (sqlBasicCall.getOperandList().get(0) instanceof SqlSelect) { SqlNode innerQuery = sqlBasicCall.getOperandList().get(0);
SqlSelect table = (SqlSelect) sqlBasicCall.getOperandList().get(0); if (innerQuery instanceof SqlCall) {
return table; return innerQuery;
} }
} }
} }

View File

@@ -69,7 +69,13 @@ public class SqlBuilder {
SqlNode parserNode = tableView.build(); SqlNode parserNode = tableView.build();
DatabaseResp database = queryStatement.getOntology().getDatabase(); DatabaseResp database = queryStatement.getOntology().getDatabase();
EngineType engineType = EngineType.fromString(database.getType()); EngineType engineType = EngineType.fromString(database.getType());
parserNode = optimizeParseNode(parserNode, engineType); try {
parserNode = optimizeParseNode(parserNode, engineType);
} catch (Exception e) {
// failure in optimization phase doesn't affect the query result,
// just ignore it
log.error("optimizeParseNode error", e);
}
return SemanticNode.getSql(parserNode, engineType); return SemanticNode.getSql(parserNode, engineType);
} }

View File

@@ -48,12 +48,13 @@ const MetricTrend: React.FC<Props> = ({
const { queryColumns, queryResults, aggregateInfo, entityInfo, chatContext } = data; const { queryColumns, queryResults, aggregateInfo, entityInfo, chatContext } = data;
const [chartType, setChartType] = useState('line'); const [chartType, setChartType] = useState('line');
const dateField: any = queryColumns?.find( const dateField = queryColumns?.find(
(column: any) => column.showType === 'DATE' || column.type === 'DATE' (column: any) => column.showType === 'DATE' || column.type === 'DATE'
); );
const dateColumnName = dateField?.bizName || ''; const dateColumnName = dateField?.bizName || '';
const categoryColumnName = let categoryColumnName =
queryColumns?.find((column: any) => column.showType === 'CATEGORY')?.bizName || ''; queryColumns?.find((column: any) => column.showType === 'CATEGORY')?.bizName || '';
categoryColumnName = categoryColumnName === dateColumnName ? '' : categoryColumnName;
const metricFields = queryColumns?.filter((column: any) => column.showType === 'NUMBER'); const metricFields = queryColumns?.filter((column: any) => column.showType === 'NUMBER');
const currentMetricField = queryColumns?.find((column: any) => column.showType === 'NUMBER'); const currentMetricField = queryColumns?.find((column: any) => column.showType === 'NUMBER');
@@ -80,11 +81,11 @@ const MetricTrend: React.FC<Props> = ({
<MetricInfo aggregateInfo={aggregateInfo} currentMetricField={currentMetricField} /> <MetricInfo aggregateInfo={aggregateInfo} currentMetricField={currentMetricField} />
)} )}
<div className={`${prefixCls}-select-options`}> <div className={`${prefixCls}-select-options`}>
<DateOptions {/*<DateOptions*/}
chatContext={chatContext} {/* chatContext={chatContext}*/}
currentDateOption={currentDateOption} {/* currentDateOption={currentDateOption}*/}
onSelectDateOption={onSelectDateOption} {/* onSelectDateOption={onSelectDateOption}*/}
/> {/*/>*/}
<div> <div>
<Select <Select
defaultValue="line" defaultValue="line"

View File

@@ -8,7 +8,7 @@ import { ISemantic } from '../../data';
import { import {
AGG_OPTIONS, AGG_OPTIONS,
DATE_FORMATTER, DATE_FORMATTER,
DATE_OPTIONS, // DATE_OPTIONS,
DIM_OPTIONS, DIM_OPTIONS,
EnumDataSourceType, EnumDataSourceType,
EnumModelDataType, EnumModelDataType,
@@ -275,7 +275,7 @@ const ModelFieldForm: React.FC<Props> = ({
} }
} }
if ([EnumDataSourceType.TIME, EnumDataSourceType.PARTITION_TIME].includes(type)) { if ([EnumDataSourceType.TIME, EnumDataSourceType.PARTITION_TIME].includes(type)) {
const { dateFormat, timeGranularity } = record; const { dateFormat } = record;
const dateFormatterOptions = const dateFormatterOptions =
type === EnumDataSourceType.PARTITION_TIME ? PARTITION_TIME_FORMATTER : DATE_FORMATTER; type === EnumDataSourceType.PARTITION_TIME ? PARTITION_TIME_FORMATTER : DATE_FORMATTER;
@@ -302,25 +302,25 @@ const ModelFieldForm: React.FC<Props> = ({
<ExclamationCircleOutlined /> <ExclamationCircleOutlined />
</Tooltip> </Tooltip>
</Space> </Space>
<Space> {/*<Space>*/}
<span>:</span> {/* <span>时间粒度:</span>*/}
<Select {/* <Select*/}
placeholder="时间粒度" {/* placeholder="时间粒度"*/}
value={timeGranularity === '' ? undefined : timeGranularity} {/* value={timeGranularity === '' ? undefined : timeGranularity}*/}
onChange={(value) => { {/* onChange={(value) => {*/}
handleFieldChange(record, 'timeGranularity', value); {/* handleFieldChange(record, 'timeGranularity', value);*/}
}} {/* }}*/}
defaultValue={timeGranularity === '' ? undefined : DATE_OPTIONS[0]} {/* defaultValue={timeGranularity === '' ? undefined : DATE_OPTIONS[0]}*/}
style={{ minWidth: 180 }} {/* style={{ minWidth: 180 }}*/}
allowClear {/* allowClear*/}
> {/* >*/}
{DATE_OPTIONS.map((item) => ( {/* {DATE_OPTIONS.map((item) => (*/}
<Option key={item} value={item}> {/* <Option key={item} value={item}>*/}
{item} {/* {item}*/}
</Option> {/* </Option>*/}
))} {/* ))}*/}
</Select> {/* </Select>*/}
</Space> {/*</Space>*/}
</Space> </Space>
); );
} }