mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-14 22:25:19 +00:00
[improvement][headless]Introduce new time mode CURRENT. #1692
This commit is contained in:
@@ -1,95 +1,65 @@
|
||||
package com.tencent.supersonic.headless.chat.corrector;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.enums.DatePeriodEnum;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeMode;
|
||||
import com.tencent.supersonic.common.util.DateUtils;
|
||||
import com.tencent.supersonic.headless.api.pojo.DataSetSchema;
|
||||
import com.tencent.supersonic.headless.api.pojo.TimeDefaultConfig;
|
||||
import com.tencent.supersonic.headless.chat.ChatQueryContext;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
public class S2SqlDateHelper {
|
||||
|
||||
public static String getReferenceDate(ChatQueryContext chatQueryContext, Long dataSetId) {
|
||||
String defaultDate = DateUtils.getBeforeDate(0);
|
||||
if (Objects.isNull(dataSetId)) {
|
||||
return defaultDate;
|
||||
}
|
||||
DataSetSchema dataSetSchema =
|
||||
chatQueryContext.getSemanticSchema().getDataSetSchemaMap().get(dataSetId);
|
||||
if (dataSetSchema == null || dataSetSchema.getTagTypeTimeDefaultConfig() == null) {
|
||||
return defaultDate;
|
||||
}
|
||||
TimeDefaultConfig tagTypeTimeDefaultConfig = dataSetSchema.getTagTypeTimeDefaultConfig();
|
||||
String partitionTimeFormat = dataSetSchema.getPartitionTimeFormat();
|
||||
return getDefaultDate(defaultDate, tagTypeTimeDefaultConfig, partitionTimeFormat).getLeft();
|
||||
public static Pair<String, String> calculateDateRange(
|
||||
TimeDefaultConfig timeConfig, String timeFormat) {
|
||||
return calculateDateRange(DateUtils.getBeforeDate(0), timeConfig, timeFormat);
|
||||
}
|
||||
|
||||
public static Pair<String, String> getStartEndDate(
|
||||
ChatQueryContext chatQueryContext, Long dataSetId, QueryType queryType) {
|
||||
String defaultDate = DateUtils.getBeforeDate(0);
|
||||
if (Objects.isNull(dataSetId)) {
|
||||
return Pair.of(defaultDate, defaultDate);
|
||||
}
|
||||
DataSetSchema dataSetSchema =
|
||||
chatQueryContext.getSemanticSchema().getDataSetSchemaMap().get(dataSetId);
|
||||
if (Objects.isNull(dataSetSchema)) {
|
||||
return Pair.of(defaultDate, defaultDate);
|
||||
}
|
||||
TimeDefaultConfig defaultConfig = dataSetSchema.getMetricTypeTimeDefaultConfig();
|
||||
if (QueryType.DETAIL.equals(queryType) && defaultConfig.getUnit() >= 0) {
|
||||
defaultConfig = dataSetSchema.getTagTypeTimeDefaultConfig();
|
||||
}
|
||||
String partitionTimeFormat = dataSetSchema.getPartitionTimeFormat();
|
||||
return getDefaultDate(defaultDate, defaultConfig, partitionTimeFormat);
|
||||
}
|
||||
|
||||
private static Pair<String, String> getDefaultDate(
|
||||
String defaultDate, TimeDefaultConfig defaultConfig, String partitionTimeFormat) {
|
||||
if (defaultConfig == null) {
|
||||
return Pair.of(null, null);
|
||||
}
|
||||
Integer unit = defaultConfig.getUnit();
|
||||
if (unit == null) {
|
||||
return Pair.of(defaultDate, defaultDate);
|
||||
}
|
||||
|
||||
// If the unit is set to less than 0, then do not add relative date.
|
||||
if (unit < 0) {
|
||||
public static Pair<String, String> calculateDateRange(
|
||||
String currentDate, TimeDefaultConfig timeConfig, String timeFormat) {
|
||||
Integer unit = timeConfig.getUnit();
|
||||
if (timeConfig == null || unit == null || unit < 0) {
|
||||
return Pair.of(null, null);
|
||||
}
|
||||
|
||||
String period = defaultConfig.getPeriod();
|
||||
TimeMode timeMode = defaultConfig.getTimeMode();
|
||||
DatePeriodEnum datePeriodEnum = DatePeriodEnum.get(period);
|
||||
|
||||
String startDate = DateUtils.getBeforeDate(unit, datePeriodEnum);
|
||||
String endDate = DateUtils.getBeforeDate(0, DatePeriodEnum.DAY);
|
||||
|
||||
if (unit == 0 || TimeMode.LAST.equals(timeMode)) {
|
||||
endDate = startDate;
|
||||
TimeMode timeMode = timeConfig.getTimeMode();
|
||||
DatePeriodEnum datePeriod = DatePeriodEnum.get(timeConfig.getPeriod());
|
||||
String startDate;
|
||||
String endDate;
|
||||
switch (timeMode) {
|
||||
case CURRENT:
|
||||
startDate = DateUtils.getBeforeDate(currentDate, datePeriod);
|
||||
endDate = currentDate;
|
||||
break;
|
||||
case RECENT:
|
||||
startDate = DateUtils.getBeforeDate(currentDate, unit, datePeriod);
|
||||
endDate = currentDate;
|
||||
break;
|
||||
case LAST:
|
||||
default:
|
||||
startDate = DateUtils.getBeforeDate(currentDate, unit, datePeriod);
|
||||
endDate = DateUtils.getBeforeDate(currentDate, unit, datePeriod);
|
||||
break;
|
||||
}
|
||||
if (StringUtils.isNotBlank(partitionTimeFormat)) {
|
||||
startDate = formatDate(startDate, partitionTimeFormat);
|
||||
endDate = formatDate(endDate, partitionTimeFormat);
|
||||
|
||||
if (StringUtils.isNotBlank(timeFormat)) {
|
||||
startDate = reformatDate(startDate, timeFormat);
|
||||
endDate = reformatDate(endDate, timeFormat);
|
||||
}
|
||||
return Pair.of(startDate, endDate);
|
||||
}
|
||||
|
||||
private static String formatDate(String dateStr, String format) {
|
||||
private static String reformatDate(String dateStr, String format) {
|
||||
try {
|
||||
// Assuming the input date format is "yyyy-MM-dd"
|
||||
SimpleDateFormat inputFormat = new SimpleDateFormat(DateUtils.DATE_FORMAT);
|
||||
Date date = inputFormat.parse(dateStr);
|
||||
SimpleDateFormat outputFormat = new SimpleDateFormat(format);
|
||||
return outputFormat.format(date);
|
||||
} catch (Exception e) {
|
||||
} catch (ParseException e) {
|
||||
// Handle the exception, maybe log it and return the original dateStr
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,12 @@ import com.tencent.supersonic.common.jsqlparser.DateVisitor.DateBoundInfo;
|
||||
import com.tencent.supersonic.common.jsqlparser.SqlAddHelper;
|
||||
import com.tencent.supersonic.common.jsqlparser.SqlDateSelectHelper;
|
||||
import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||
import com.tencent.supersonic.headless.api.pojo.DataSetSchema;
|
||||
import com.tencent.supersonic.headless.api.pojo.QueryConfig;
|
||||
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.headless.api.pojo.TimeDefaultConfig;
|
||||
import com.tencent.supersonic.headless.chat.ChatQueryContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
@@ -27,10 +30,10 @@ public class TimeCorrector extends BaseSemanticCorrector {
|
||||
public void doCorrect(ChatQueryContext chatQueryContext, SemanticParseInfo semanticParseInfo) {
|
||||
if (containsPartitionDimensions(chatQueryContext, semanticParseInfo)) {
|
||||
addDateIfNotExist(chatQueryContext, semanticParseInfo);
|
||||
addLowerBoundDate(semanticParseInfo);
|
||||
} else {
|
||||
removeDateIfExist(chatQueryContext, semanticParseInfo);
|
||||
}
|
||||
addLowerBoundDate(semanticParseInfo);
|
||||
}
|
||||
|
||||
private void addDateIfNotExist(
|
||||
@@ -48,15 +51,21 @@ public class TimeCorrector extends BaseSemanticCorrector {
|
||||
}
|
||||
String partitionDimension = dataSetSchema.getPartitionDimension().getName();
|
||||
if (CollectionUtils.isEmpty(whereFields) || !whereFields.contains(partitionDimension)) {
|
||||
Pair<String, String> startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(
|
||||
chatQueryContext, dataSetId, semanticParseInfo.getQueryType());
|
||||
TimeDefaultConfig timeConfig;
|
||||
QueryConfig queryConfig = dataSetSchema.getQueryConfig();
|
||||
if (QueryType.METRIC.equals(semanticParseInfo.getQueryType())) {
|
||||
timeConfig = queryConfig.getMetricTypeDefaultConfig().getTimeDefaultConfig();
|
||||
} else {
|
||||
timeConfig = queryConfig.getTagTypeDefaultConfig().getTimeDefaultConfig();
|
||||
}
|
||||
|
||||
if (isValidDateRange(startEndDate)) {
|
||||
String timeFormat = dataSetSchema.getPartitionTimeFormat();
|
||||
Pair<String, String> dateRange =
|
||||
S2SqlDateHelper.calculateDateRange(timeConfig, timeFormat);
|
||||
if (isValidDateRange(dateRange)) {
|
||||
correctS2SQL = SqlAddHelper.addParenthesisToWhere(correctS2SQL);
|
||||
String startDateLeft = startEndDate.getLeft();
|
||||
String endDateRight = startEndDate.getRight();
|
||||
|
||||
String startDateLeft = dateRange.getLeft();
|
||||
String endDateRight = dateRange.getRight();
|
||||
String condExpr =
|
||||
String.format(
|
||||
" ( %s >= '%s' and %s <= '%s' )",
|
||||
|
||||
@@ -1,134 +1,79 @@
|
||||
package com.tencent.supersonic.headless.chat.utils;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeMode;
|
||||
import com.tencent.supersonic.common.util.DateUtils;
|
||||
import com.tencent.supersonic.headless.api.pojo.DataSetSchema;
|
||||
import com.tencent.supersonic.headless.api.pojo.QueryConfig;
|
||||
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.headless.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.headless.api.pojo.TimeDefaultConfig;
|
||||
import com.tencent.supersonic.headless.chat.ChatQueryContext;
|
||||
import com.tencent.supersonic.headless.chat.corrector.S2SqlDateHelper;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Disabled
|
||||
class S2SqlDateHelperTest {
|
||||
|
||||
@Test
|
||||
void getReferenceDate() {
|
||||
Long dataSetId = 1L;
|
||||
ChatQueryContext chatQueryContext = buildQueryContext(dataSetId);
|
||||
|
||||
String referenceDate = S2SqlDateHelper.getReferenceDate(chatQueryContext, null);
|
||||
Assert.assertEquals(referenceDate, DateUtils.getBeforeDate(0));
|
||||
|
||||
referenceDate = S2SqlDateHelper.getReferenceDate(chatQueryContext, dataSetId);
|
||||
Assert.assertEquals(referenceDate, DateUtils.getBeforeDate(0));
|
||||
|
||||
DataSetSchema dataSetSchema =
|
||||
chatQueryContext.getSemanticSchema().getDataSetSchemaMap().get(dataSetId);
|
||||
QueryConfig queryConfig = dataSetSchema.getQueryConfig();
|
||||
void testCurrentTimeMode() {
|
||||
TimeDefaultConfig timeDefaultConfig = new TimeDefaultConfig();
|
||||
timeDefaultConfig.setTimeMode(TimeMode.LAST);
|
||||
timeDefaultConfig.setPeriod(Constants.DAY);
|
||||
timeDefaultConfig.setUnit(20);
|
||||
queryConfig.getTagTypeDefaultConfig().setTimeDefaultConfig(timeDefaultConfig);
|
||||
timeDefaultConfig.setTimeMode(TimeMode.CURRENT);
|
||||
timeDefaultConfig.setPeriod(Constants.MONTH);
|
||||
|
||||
referenceDate = S2SqlDateHelper.getReferenceDate(chatQueryContext, dataSetId);
|
||||
Assert.assertEquals(referenceDate, DateUtils.getBeforeDate(20));
|
||||
Pair<String, String> dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2024-09-01");
|
||||
assert dateRange.getRight().equals("2024-09-21");
|
||||
|
||||
timeDefaultConfig.setUnit(1);
|
||||
referenceDate = S2SqlDateHelper.getReferenceDate(chatQueryContext, dataSetId);
|
||||
Assert.assertEquals(referenceDate, DateUtils.getBeforeDate(1));
|
||||
|
||||
timeDefaultConfig.setUnit(-1);
|
||||
referenceDate = S2SqlDateHelper.getReferenceDate(chatQueryContext, dataSetId);
|
||||
Assert.assertNull(referenceDate);
|
||||
timeDefaultConfig.setPeriod(Constants.YEAR);
|
||||
dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2024-01-01");
|
||||
assert dateRange.getRight().equals("2024-09-21");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getStartEndDate() {
|
||||
Long dataSetId = 1L;
|
||||
ChatQueryContext chatQueryContext = buildQueryContext(dataSetId);
|
||||
void testRecentTimeMode() {
|
||||
TimeDefaultConfig timeDefaultConfig = new TimeDefaultConfig();
|
||||
timeDefaultConfig.setTimeMode(TimeMode.RECENT);
|
||||
timeDefaultConfig.setUnit(3);
|
||||
timeDefaultConfig.setPeriod(Constants.DAY);
|
||||
|
||||
Pair<String, String> startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, null, QueryType.DETAIL);
|
||||
Assert.assertEquals(startEndDate.getLeft(), DateUtils.getBeforeDate(0));
|
||||
Assert.assertEquals(startEndDate.getRight(), DateUtils.getBeforeDate(0));
|
||||
Pair<String, String> dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2024-09-18");
|
||||
assert dateRange.getRight().equals("2024-09-21");
|
||||
|
||||
startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, dataSetId, QueryType.DETAIL);
|
||||
Assert.assertNotNull(startEndDate.getLeft());
|
||||
Assert.assertNotNull(startEndDate.getRight());
|
||||
timeDefaultConfig.setPeriod(Constants.MONTH);
|
||||
dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2024-06-21");
|
||||
assert dateRange.getRight().equals("2024-09-21");
|
||||
|
||||
DataSetSchema dataSetSchema =
|
||||
chatQueryContext.getSemanticSchema().getDataSetSchemaMap().get(dataSetId);
|
||||
QueryConfig queryConfig = dataSetSchema.getQueryConfig();
|
||||
timeDefaultConfig.setPeriod(Constants.YEAR);
|
||||
dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2021-09-21");
|
||||
assert dateRange.getRight().equals("2024-09-21");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLastTimeMode() {
|
||||
TimeDefaultConfig timeDefaultConfig = new TimeDefaultConfig();
|
||||
timeDefaultConfig.setTimeMode(TimeMode.LAST);
|
||||
timeDefaultConfig.setUnit(3);
|
||||
timeDefaultConfig.setPeriod(Constants.DAY);
|
||||
timeDefaultConfig.setUnit(20);
|
||||
queryConfig.getTagTypeDefaultConfig().setTimeDefaultConfig(timeDefaultConfig);
|
||||
queryConfig.getMetricTypeDefaultConfig().setTimeDefaultConfig(timeDefaultConfig);
|
||||
|
||||
startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, dataSetId, QueryType.DETAIL);
|
||||
Assert.assertEquals(startEndDate.getLeft(), DateUtils.getBeforeDate(20));
|
||||
Assert.assertEquals(startEndDate.getRight(), DateUtils.getBeforeDate(20));
|
||||
Pair<String, String> dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2024-09-18");
|
||||
assert dateRange.getRight().equals("2024-09-18");
|
||||
|
||||
startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, dataSetId, QueryType.METRIC);
|
||||
Assert.assertEquals(startEndDate.getLeft(), DateUtils.getBeforeDate(20));
|
||||
Assert.assertEquals(startEndDate.getRight(), DateUtils.getBeforeDate(20));
|
||||
timeDefaultConfig.setPeriod(Constants.MONTH);
|
||||
dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2024-06-21");
|
||||
assert dateRange.getRight().equals("2024-06-21");
|
||||
|
||||
timeDefaultConfig.setUnit(2);
|
||||
timeDefaultConfig.setTimeMode(TimeMode.RECENT);
|
||||
startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, dataSetId, QueryType.METRIC);
|
||||
Assert.assertEquals(startEndDate.getLeft(), DateUtils.getBeforeDate(2));
|
||||
Assert.assertEquals(startEndDate.getRight(), DateUtils.getBeforeDate(1));
|
||||
|
||||
startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, dataSetId, QueryType.DETAIL);
|
||||
Assert.assertEquals(startEndDate.getLeft(), DateUtils.getBeforeDate(2));
|
||||
Assert.assertEquals(startEndDate.getRight(), DateUtils.getBeforeDate(1));
|
||||
|
||||
timeDefaultConfig.setUnit(-1);
|
||||
startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, dataSetId, QueryType.METRIC);
|
||||
Assert.assertNull(startEndDate.getLeft());
|
||||
Assert.assertNull(startEndDate.getRight());
|
||||
|
||||
timeDefaultConfig.setTimeMode(TimeMode.LAST);
|
||||
timeDefaultConfig.setPeriod(Constants.DAY);
|
||||
timeDefaultConfig.setUnit(5);
|
||||
startEndDate =
|
||||
S2SqlDateHelper.getStartEndDate(chatQueryContext, dataSetId, QueryType.METRIC);
|
||||
Assert.assertEquals(startEndDate.getLeft(), DateUtils.getBeforeDate(5));
|
||||
Assert.assertEquals(startEndDate.getRight(), DateUtils.getBeforeDate(5));
|
||||
}
|
||||
|
||||
private ChatQueryContext buildQueryContext(Long dataSetId) {
|
||||
ChatQueryContext chatQueryContext = new ChatQueryContext();
|
||||
List<DataSetSchema> dataSetSchemaList = new ArrayList<>();
|
||||
DataSetSchema dataSetSchema = new DataSetSchema();
|
||||
QueryConfig queryConfig = new QueryConfig();
|
||||
dataSetSchema.setQueryConfig(queryConfig);
|
||||
SchemaElement schemaElement = new SchemaElement();
|
||||
schemaElement.setDataSetId(dataSetId);
|
||||
dataSetSchema.setDataSet(schemaElement);
|
||||
dataSetSchemaList.add(dataSetSchema);
|
||||
|
||||
SemanticSchema semanticSchema = new SemanticSchema(dataSetSchemaList);
|
||||
chatQueryContext.setSemanticSchema(semanticSchema);
|
||||
return chatQueryContext;
|
||||
timeDefaultConfig.setPeriod(Constants.YEAR);
|
||||
dateRange =
|
||||
S2SqlDateHelper.calculateDateRange("2024-09-21", timeDefaultConfig, "yyyy-MM-dd");
|
||||
assert dateRange.getLeft().equals("2021-09-21");
|
||||
assert dateRange.getRight().equals("2021-09-21");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user