mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 12:07:42 +00:00
(improvement)(project) The Corrector is integrated into the Semantic module as an intermediate step for translating S2QL into SQL (#306)
This commit is contained in:
@@ -64,4 +64,6 @@ public class Constants {
|
||||
|
||||
public static final Long DEFAULT_FREQUENCY = 100000L;
|
||||
|
||||
public static final String TABLE_PREFIX = "t_";
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.tencent.supersonic.common.pojo;
|
||||
|
||||
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Criterion {
|
||||
|
||||
private String column;
|
||||
|
||||
private FilterOperatorEnum operator;
|
||||
|
||||
private Object value;
|
||||
|
||||
private List<Object> values;
|
||||
|
||||
private String dataType;
|
||||
|
||||
public Criterion(String column, FilterOperatorEnum operator, Object value, String dataType) {
|
||||
super();
|
||||
this.column = column;
|
||||
this.operator = operator;
|
||||
this.value = value;
|
||||
this.dataType = dataType;
|
||||
|
||||
if (FilterOperatorEnum.BETWEEN.name().equals(operator) || FilterOperatorEnum.IN.name().equals(operator)
|
||||
|| FilterOperatorEnum.NOT_IN.name().equals(operator)) {
|
||||
this.values = (List) value;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNeedApostrophe() {
|
||||
return Arrays.stream(StringDataType.values())
|
||||
.filter(value -> this.dataType.equalsIgnoreCase(value.getType())).findFirst()
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
|
||||
public enum NumericDataType {
|
||||
TINYINT("TINYINT"),
|
||||
SMALLINT("SMALLINT"),
|
||||
MEDIUMINT("MEDIUMINT"),
|
||||
INT("INT"),
|
||||
INTEGER("INTEGER"),
|
||||
BIGINT("BIGINT"),
|
||||
FLOAT("FLOAT"),
|
||||
DOUBLE("DOUBLE"),
|
||||
DECIMAL("DECIMAL"),
|
||||
NUMERIC("NUMERIC"),
|
||||
;
|
||||
private String type;
|
||||
|
||||
NumericDataType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum StringDataType {
|
||||
VARCHAR("VARCHAR"),
|
||||
STRING("STRING"),
|
||||
;
|
||||
private String type;
|
||||
|
||||
StringDataType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.tencent.supersonic.common.pojo;
|
||||
|
||||
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Filter {
|
||||
|
||||
private Relation relation = Relation.FILTER;
|
||||
private String bizName;
|
||||
private String name;
|
||||
private FilterOperatorEnum operator;
|
||||
private Object value;
|
||||
private List<Filter> children;
|
||||
|
||||
public Filter(String bizName, FilterOperatorEnum operator, Object value) {
|
||||
this.bizName = bizName;
|
||||
this.operator = operator;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Filter(Relation relation, String bizName, FilterOperatorEnum operator, Object value) {
|
||||
this.relation = relation;
|
||||
this.bizName = bizName;
|
||||
this.operator = operator;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"relation\":")
|
||||
.append(relation);
|
||||
sb.append(",\"bizName\":\"")
|
||||
.append(bizName).append('\"');
|
||||
sb.append(",\"name\":\"")
|
||||
.append(name).append('\"');
|
||||
sb.append(",\"operator\":")
|
||||
.append(operator);
|
||||
sb.append(",\"value\":")
|
||||
.append(value);
|
||||
sb.append(",\"children\":")
|
||||
.append(children);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public enum Relation {
|
||||
FILTER, OR, AND
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.supersonic.common.pojo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* @author: kanedai
|
||||
* @date: 2023/3/29
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class ItemDateResp {
|
||||
|
||||
private String dateFormat;
|
||||
private String startDate;
|
||||
private String endDate;
|
||||
private String datePeriod;
|
||||
private List<String> unavailableDateList = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.tencent.supersonic.common.pojo.enums;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum FilterOperatorEnum {
|
||||
IN("IN"),
|
||||
NOT_IN("NOT_IN"),
|
||||
EQUALS("="),
|
||||
BETWEEN("BETWEEN"),
|
||||
GREATER_THAN(">"),
|
||||
GREATER_THAN_EQUALS(">="),
|
||||
IS_NULL("IS_NULL"),
|
||||
IS_NOT_NULL("IS_NOT_NULL"),
|
||||
LIKE("LIKE"),
|
||||
MINOR_THAN("<"),
|
||||
MINOR_THAN_EQUALS("<="),
|
||||
NOT_EQUALS("!="),
|
||||
SQL_PART("SQL_PART"),
|
||||
EXISTS("EXISTS");
|
||||
|
||||
private String value;
|
||||
|
||||
FilterOperatorEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static FilterOperatorEnum getSqlOperator(String type) {
|
||||
for (FilterOperatorEnum operatorEnum : FilterOperatorEnum.values()) {
|
||||
if (operatorEnum.value.equalsIgnoreCase(type) || operatorEnum.name().equalsIgnoreCase(type)) {
|
||||
return operatorEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,415 @@
|
||||
package com.tencent.supersonic.common.util;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.APOSTROPHE;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.COMMA;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.DAY;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.DAY_FORMAT;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MONTH;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MONTH_FORMAT;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.WEEK;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@Data
|
||||
public class DateModeUtils {
|
||||
|
||||
@Value("${query.parameter.sys.date:sys_imp_date}")
|
||||
private String sysDateCol;
|
||||
@Value("${query.parameter.sys.month:sys_imp_month}")
|
||||
private String sysDateMonthCol;
|
||||
@Value("${query.parameter.sys.month:sys_imp_week}")
|
||||
private String sysDateWeekCol;
|
||||
|
||||
@Value("${query.parameter.sys.zipper.begin:start_}")
|
||||
private String sysZipperDateColBegin;
|
||||
@Value("${query.parameter.sys.zipper.end:end_}")
|
||||
private String sysZipperDateColEnd;
|
||||
|
||||
public Boolean recentMode(DateConf dateInfo) {
|
||||
if (Objects.nonNull(dateInfo) && DateConf.DateMode.RECENT == dateInfo.getDateMode()
|
||||
&& DAY.equalsIgnoreCase(dateInfo.getPeriod()) && Objects.nonNull(dateInfo.getUnit())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasAvailableDataMode(DateConf dateInfo) {
|
||||
if (Objects.nonNull(dateInfo) && DateConf.DateMode.AVAILABLE == dateInfo.getDateMode()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dateMode = 4, advance time until data is available
|
||||
*
|
||||
* @param dateDate
|
||||
* @param dateInfo
|
||||
* @return
|
||||
*/
|
||||
public String hasDataModeStr(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
if (Objects.isNull(dateDate)
|
||||
|| Strings.isNullOrEmpty(dateDate.getStartDate())
|
||||
|| Strings.isNullOrEmpty(dateDate.getStartDate())
|
||||
) {
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateCol, dateInfo.getStartDate(), sysDateCol,
|
||||
dateInfo.getEndDate());
|
||||
} else {
|
||||
log.info("dateDate:{}", dateDate);
|
||||
}
|
||||
String dateFormatStr = dateDate.getDateFormat();
|
||||
if (Strings.isNullOrEmpty(dateFormatStr)) {
|
||||
dateFormatStr = DAY_FORMAT;
|
||||
}
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormatStr);
|
||||
LocalDate endData = LocalDate.parse(dateDate.getEndDate(), formatter);
|
||||
LocalDate endReq = LocalDate.parse(dateInfo.getEndDate(), formatter);
|
||||
|
||||
if (endReq.isAfter(endData)) {
|
||||
if (DAY.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
Long unit = getInterval(dateInfo.getStartDate(), dateInfo.getEndDate(), dateFormatStr, ChronoUnit.DAYS);
|
||||
LocalDate dateMax = endData;
|
||||
LocalDate dateMin = dateMax.minusDays(unit - 1);
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateCol, dateMin, sysDateCol, dateMax);
|
||||
}
|
||||
|
||||
if (MONTH.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
Long unit = getInterval(dateInfo.getStartDate(), dateInfo.getEndDate(), dateFormatStr,
|
||||
ChronoUnit.MONTHS);
|
||||
return generateMonthSql(endData, unit, dateFormatStr);
|
||||
}
|
||||
|
||||
}
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateCol, dateInfo.getStartDate(), sysDateCol,
|
||||
dateInfo.getEndDate());
|
||||
}
|
||||
|
||||
|
||||
public String generateMonthSql(LocalDate endData, Long unit, String dateFormatStr) {
|
||||
LocalDate dateMax = endData;
|
||||
List<String> months = generateMonthStr(dateMax, unit, dateFormatStr);
|
||||
if (!CollectionUtils.isEmpty(months)) {
|
||||
StringJoiner joiner = new StringJoiner(",");
|
||||
months.stream().forEach(month -> joiner.add("'" + month + "'"));
|
||||
return String.format("(%s in (%s))", sysDateCol, joiner.toString());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private List<String> generateMonthStr(LocalDate dateMax, Long unit, String formatStr) {
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern(formatStr);
|
||||
List<String> months = new ArrayList<>();
|
||||
for (int i = unit.intValue() - 1; i >= 0; i--) {
|
||||
LocalDate tmp = dateMax.minusMonths(i);
|
||||
months.add(tmp.with(TemporalAdjusters.firstDayOfMonth()).format(format));
|
||||
}
|
||||
return months;
|
||||
}
|
||||
|
||||
public String recentDayStr(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
ImmutablePair<String, String> dayRange = recentDay(dateDate, dateInfo);
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateCol, dayRange.left, sysDateCol, dayRange.right);
|
||||
}
|
||||
|
||||
public ImmutablePair<String, String> recentDay(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
String dateFormatStr = dateDate.getDateFormat();
|
||||
if (Strings.isNullOrEmpty(dateFormatStr)) {
|
||||
dateFormatStr = DAY_FORMAT;
|
||||
}
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormatStr);
|
||||
LocalDate end = LocalDate.parse(dateDate.getEndDate(), formatter);
|
||||
// todo unavailableDateList logic
|
||||
|
||||
Integer unit = dateInfo.getUnit() - 1;
|
||||
String start = end.minusDays(unit).format(formatter);
|
||||
return ImmutablePair.of(start, dateDate.getEndDate());
|
||||
}
|
||||
|
||||
public String recentMonthStr(LocalDate endData, Long unit, String dateFormatStr) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormatStr);
|
||||
String endStr = endData.format(formatter);
|
||||
String start = endData.minusMonths(unit).format(formatter);
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateMonthCol, start, sysDateMonthCol, endStr);
|
||||
}
|
||||
|
||||
public String recentMonthStr(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
List<ImmutablePair<String, String>> range = recentMonth(dateDate, dateInfo);
|
||||
if (range.size() == 1) {
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateMonthCol, range.get(0).left, sysDateMonthCol,
|
||||
range.get(0).right);
|
||||
}
|
||||
if (range.size() > 0) {
|
||||
StringJoiner joiner = new StringJoiner(",");
|
||||
range.stream().forEach(month -> joiner.add("'" + month.left + "'"));
|
||||
return String.format("(%s in (%s))", sysDateCol, joiner.toString());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public List<ImmutablePair<String, String>> recentMonth(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
LocalDate endData = LocalDate.parse(dateDate.getEndDate(),
|
||||
DateTimeFormatter.ofPattern(dateDate.getDateFormat()));
|
||||
List<ImmutablePair<String, String>> ret = new ArrayList<>();
|
||||
if (dateDate.getDatePeriod() != null && MONTH.equalsIgnoreCase(dateDate.getDatePeriod())) {
|
||||
Long unit = getInterval(dateInfo.getStartDate(), dateInfo.getEndDate(), dateDate.getDateFormat(),
|
||||
ChronoUnit.MONTHS);
|
||||
LocalDate dateMax = endData;
|
||||
List<String> months = generateMonthStr(dateMax, unit, dateDate.getDateFormat());
|
||||
if (!CollectionUtils.isEmpty(months)) {
|
||||
months.stream().forEach(m -> ret.add(ImmutablePair.of(m, m)));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
String dateFormatStr = MONTH_FORMAT;
|
||||
Integer unit = dateInfo.getUnit() - 1;
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormatStr);
|
||||
String endStr = endData.format(formatter);
|
||||
String start = endData.minusMonths(unit).format(formatter);
|
||||
ret.add(ImmutablePair.of(start, endStr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String recentWeekStr(LocalDate endData, Long unit) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DAY_FORMAT);
|
||||
String start = endData.minusDays(unit * 7).format(formatter);
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateWeekCol, start, sysDateWeekCol,
|
||||
endData.format(formatter));
|
||||
}
|
||||
|
||||
public String recentWeekStr(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
ImmutablePair<String, String> dayRange = recentWeek(dateDate, dateInfo);
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateWeekCol, dayRange.left, sysDateWeekCol,
|
||||
dayRange.right);
|
||||
}
|
||||
|
||||
public ImmutablePair<String, String> recentWeek(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
String dateFormatStr = dateDate.getDateFormat();
|
||||
if (Strings.isNullOrEmpty(dateFormatStr)) {
|
||||
dateFormatStr = DAY_FORMAT;
|
||||
}
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormatStr);
|
||||
LocalDate end = LocalDate.parse(dateDate.getEndDate(), formatter);
|
||||
Integer unit = dateInfo.getUnit() - 1;
|
||||
String start = end.minusDays(unit * 7).format(formatter);
|
||||
return ImmutablePair.of(start, end.format(formatter));
|
||||
}
|
||||
|
||||
private Long getInterval(String startDate, String endDate, String dateFormat, ChronoUnit chronoUnit) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
|
||||
try {
|
||||
LocalDate start = LocalDate.parse(startDate, formatter);
|
||||
LocalDate end = LocalDate.parse(endDate, formatter);
|
||||
return start.until(end, chronoUnit) + 1;
|
||||
} catch (Exception e) {
|
||||
log.warn("e:{}", e);
|
||||
}
|
||||
return -1L;
|
||||
}
|
||||
|
||||
|
||||
public String recentDateStr(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
if (Objects.isNull(dateDate)) {
|
||||
return "";
|
||||
}
|
||||
if (DAY.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
return recentDayStr(dateDate, dateInfo);
|
||||
}
|
||||
if (MONTH.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
return recentMonthStr(dateDate, dateInfo);
|
||||
}
|
||||
if (WEEK.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
return recentWeekStr(dateDate, dateInfo);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* dateMode = 1; between, continuous value
|
||||
*
|
||||
* @param dateInfo
|
||||
* @return
|
||||
*/
|
||||
public String betweenDateStr(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
if (MONTH.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
LocalDate endData = LocalDate.parse(dateInfo.getEndDate(),
|
||||
DateTimeFormatter.ofPattern(DAY_FORMAT));
|
||||
LocalDate startData = LocalDate.parse(dateInfo.getStartDate(),
|
||||
DateTimeFormatter.ofPattern(DAY_FORMAT));
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(MONTH_FORMAT);
|
||||
return String.format("%s >= '%s' and %s <= '%s'",
|
||||
sysDateMonthCol, startData.format(formatter), sysDateMonthCol, endData.format(formatter));
|
||||
}
|
||||
if (WEEK.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
return String.format("%s >= '%s' and %s <= '%s'",
|
||||
sysDateWeekCol, dateInfo.getStartDate(), sysDateWeekCol, dateInfo.getEndDate());
|
||||
}
|
||||
return String.format("%s >= '%s' and %s <= '%s'",
|
||||
sysDateCol, dateInfo.getStartDate(), sysDateCol, dateInfo.getEndDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* dateMode = 2; list discrete value
|
||||
*
|
||||
* @param dateInfo
|
||||
* @return
|
||||
*/
|
||||
public String listDateStr(ItemDateResp dateDate, DateConf dateInfo) {
|
||||
StringJoiner joiner = new StringJoiner(COMMA);
|
||||
dateInfo.getDateList().stream().forEach(date -> joiner.add(APOSTROPHE + date + APOSTROPHE));
|
||||
String dateCol = sysDateCol;
|
||||
if (MONTH.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
dateCol = sysDateMonthCol;
|
||||
}
|
||||
if (WEEK.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
dateCol = sysDateWeekCol;
|
||||
}
|
||||
return String.format("(%s in (%s))", dateCol, joiner.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* dateMode = 3; - recent time units
|
||||
*
|
||||
* @param dateInfo
|
||||
* @return
|
||||
*/
|
||||
public String defaultRecentDateInfo(DateConf dateInfo) {
|
||||
if (Objects.isNull(dateInfo)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Integer unit = dateInfo.getUnit();
|
||||
|
||||
if (DAY.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
LocalDate dateMax = LocalDate.now().minusDays(1);
|
||||
LocalDate dateMin = dateMax.minusDays(unit - 1);
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateCol, dateMin, sysDateCol, dateMax);
|
||||
}
|
||||
|
||||
if (MONTH.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
LocalDate dateMax = LocalDate.now().minusDays(1);
|
||||
//return generateMonthSql(dateMax, unit.longValue(), DAY_FORMAT);
|
||||
return recentMonthStr(dateMax, unit.longValue(), MONTH_FORMAT);
|
||||
}
|
||||
if (WEEK.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
LocalDate dateMax = LocalDate.now().minusDays(1);
|
||||
return recentWeekStr(dateMax, unit.longValue());
|
||||
}
|
||||
|
||||
return String.format("(%s >= '%s' and %s <= '%s')", sysDateCol, LocalDate.now().minusDays(2), sysDateCol,
|
||||
LocalDate.now().minusDays(1));
|
||||
}
|
||||
|
||||
public String getDateWhereStr(DateConf dateInfo) {
|
||||
ItemDateResp dateDate = null;
|
||||
return getDateWhereStr(dateInfo, dateDate);
|
||||
}
|
||||
|
||||
public String getDateWhereStr(DateConf dateInfo, ItemDateResp dateDate) {
|
||||
String dateStr = "";
|
||||
switch (dateInfo.getDateMode()) {
|
||||
case BETWEEN:
|
||||
dateStr = betweenDateStr(dateDate, dateInfo);
|
||||
break;
|
||||
case LIST:
|
||||
dateStr = listDateStr(dateDate, dateInfo);
|
||||
break;
|
||||
case RECENT:
|
||||
dateStr = recentDateStr(dateDate, dateInfo);
|
||||
break;
|
||||
case AVAILABLE:
|
||||
dateStr = hasDataModeStr(dateDate, dateInfo);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
public String getDateWhereStr(DateConf dateConf, ImmutablePair<String, String> range) {
|
||||
if (DAY.equalsIgnoreCase(dateConf.getPeriod()) || WEEK.equalsIgnoreCase(dateConf.getPeriod())) {
|
||||
if (range.left.equals(range.right)) {
|
||||
return String.format("(%s <= '%s' and %s > '%s')", sysZipperDateColBegin + sysDateCol, range.left,
|
||||
sysZipperDateColEnd + sysDateCol, range.left);
|
||||
}
|
||||
return String.format("( '%s' <= %s and '%s' >= %s)", range.left, sysZipperDateColEnd + sysDateCol,
|
||||
range.right, sysZipperDateColBegin + sysDateCol);
|
||||
}
|
||||
|
||||
if (MONTH.equalsIgnoreCase(dateConf.getPeriod())) {
|
||||
if (range.left.equals(range.right)) {
|
||||
return String.format("(%s <= '%s' and %s > '%s')", sysZipperDateColBegin + sysDateMonthCol, range.left,
|
||||
sysZipperDateColEnd + sysDateMonthCol, range.left);
|
||||
}
|
||||
return String.format("( '%s' <= %s and '%s' >= %s)", range.left, sysZipperDateColEnd + sysDateMonthCol,
|
||||
range.right, sysZipperDateColBegin + sysDateMonthCol);
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getSysDateCol(DateConf dateInfo) {
|
||||
if (DAY.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
return sysDateCol;
|
||||
}
|
||||
if (WEEK.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
return sysDateWeekCol;
|
||||
}
|
||||
if (MONTH.equalsIgnoreCase(dateInfo.getPeriod())) {
|
||||
return sysDateMonthCol;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean isDateStr(String date) {
|
||||
return Pattern.matches("[\\d\\s-:]+", date);
|
||||
}
|
||||
|
||||
public String getPeriodByCol(String col) {
|
||||
if (sysDateCol.equalsIgnoreCase(col)) {
|
||||
return DAY;
|
||||
}
|
||||
if (sysDateWeekCol.equalsIgnoreCase(col)) {
|
||||
return WEEK;
|
||||
}
|
||||
if (sysDateMonthCol.equalsIgnoreCase(col)) {
|
||||
return MONTH;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getDateColBegin(DateConf dateInfo) {
|
||||
return sysZipperDateColBegin + getSysDateCol(dateInfo);
|
||||
}
|
||||
|
||||
public String getDateColEnd(DateConf dateInfo) {
|
||||
return sysZipperDateColEnd + getSysDateCol(dateInfo);
|
||||
}
|
||||
|
||||
public List<String> getDateCol() {
|
||||
return Arrays.asList(sysDateCol, sysDateMonthCol, sysDateWeekCol);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
package com.tencent.supersonic.common.util;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.PARENTHESES_END;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.PARENTHESES_START;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.SPACE;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.SYS_VAR;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.Criterion;
|
||||
import com.tencent.supersonic.common.pojo.Filter;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SqlFilterUtils {
|
||||
|
||||
private static String pattern = "^'.*?'$";
|
||||
private static String numericPattern = "^[0-9]+$";
|
||||
|
||||
public List<String> getFiltersCol(List<Filter> filters) {
|
||||
List<String> filterCols = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(filters)) {
|
||||
return filterCols;
|
||||
}
|
||||
for (Filter filter : filters) {
|
||||
filterCols.addAll(getFilterCol(filter));
|
||||
}
|
||||
return filterCols;
|
||||
}
|
||||
|
||||
private List<String> getFilterCol(Filter filter) {
|
||||
List<String> filterCols = new ArrayList<>();
|
||||
if (Filter.Relation.FILTER.equals(filter.getRelation())) {
|
||||
if (Strings.isNotEmpty(filter.getBizName())) {
|
||||
filterCols.add(filter.getBizName());
|
||||
}
|
||||
}
|
||||
|
||||
List<Filter> children = filter.getChildren();
|
||||
if (!CollectionUtils.isEmpty(children)) {
|
||||
for (Filter child : children) {
|
||||
filterCols.addAll(getFilterCol(child));
|
||||
}
|
||||
}
|
||||
return filterCols;
|
||||
}
|
||||
|
||||
|
||||
public String getWhereClause(List<Filter> filters) {
|
||||
StringJoiner joiner = new StringJoiner(Constants.AND_UPPER);
|
||||
|
||||
if (!CollectionUtils.isEmpty(filters)) {
|
||||
filters.stream()
|
||||
.forEach(filter -> {
|
||||
if (Strings.isNotEmpty(dealFilter(filter))) {
|
||||
joiner.add(SPACE + dealFilter(filter) + SPACE);
|
||||
}
|
||||
});
|
||||
log.info("getWhereClause, where sql : {}", joiner.toString());
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String dealFilter(Filter filter) {
|
||||
if (Objects.isNull(filter)) {
|
||||
return "";
|
||||
}
|
||||
if (Strings.isNotEmpty(filter.getBizName()) && filter.getBizName().endsWith(SYS_VAR)) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder condition = new StringBuilder();
|
||||
if (Filter.Relation.FILTER.equals(filter.getRelation())) {
|
||||
return dealSingleFilter(filter);
|
||||
}
|
||||
|
||||
List<Filter> children = filter.getChildren();
|
||||
condition.append(PARENTHESES_START);
|
||||
StringJoiner joiner = new StringJoiner(SPACE + filter.getRelation().name() + SPACE);
|
||||
for (Filter child : children) {
|
||||
joiner.add(dealFilter(child));
|
||||
}
|
||||
condition.append(joiner.toString());
|
||||
condition.append(PARENTHESES_END);
|
||||
return condition.toString();
|
||||
}
|
||||
|
||||
// todo deal metric filter
|
||||
private String dealSingleFilter(Filter filter) {
|
||||
String name = filter.getBizName();
|
||||
Object value = filter.getValue();
|
||||
FilterOperatorEnum operator = filter.getOperator();
|
||||
|
||||
String dataType = Criterion.StringDataType.STRING.name();
|
||||
|
||||
Criterion criterion = new Criterion(name, operator, value, dataType);
|
||||
return generator(criterion);
|
||||
}
|
||||
|
||||
private String generator(Criterion criterion) {
|
||||
log.info("criterion :{}", criterion);
|
||||
String sqlPart;
|
||||
switch (criterion.getOperator()) {
|
||||
case SQL_PART:
|
||||
sqlPart = sqlPartLogic(criterion);
|
||||
break;
|
||||
|
||||
case IS_NULL:
|
||||
case IS_NOT_NULL:
|
||||
sqlPart = judgeNullLogic(criterion);
|
||||
break;
|
||||
|
||||
case EQUALS:
|
||||
case NOT_EQUALS:
|
||||
case GREATER_THAN:
|
||||
case GREATER_THAN_EQUALS:
|
||||
case MINOR_THAN:
|
||||
case MINOR_THAN_EQUALS:
|
||||
sqlPart = singleValueLogic(criterion);
|
||||
break;
|
||||
|
||||
case BETWEEN:
|
||||
sqlPart = betweenLogic(criterion);
|
||||
break;
|
||||
|
||||
case IN:
|
||||
case NOT_IN:
|
||||
sqlPart = inLogic(criterion);
|
||||
break;
|
||||
case LIKE:
|
||||
sqlPart = likeLogic(criterion);
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + criterion.getOperator());
|
||||
}
|
||||
return sqlPart;
|
||||
}
|
||||
|
||||
private String likeLogic(Criterion criterion) {
|
||||
if (Objects.isNull(criterion) || Objects.isNull(criterion.getValue())) {
|
||||
throw new RuntimeException("criterion.getValue() can not be null");
|
||||
}
|
||||
StringBuilder whereClause = new StringBuilder();
|
||||
whereClause.append(criterion.getColumn() + SPACE + criterion.getOperator().getValue() + SPACE);
|
||||
String value = criterion.getValue().toString();
|
||||
if (criterion.isNeedApostrophe() && !Pattern.matches(pattern, value)) {
|
||||
// like click => 'like%'
|
||||
whereClause.append(Constants.APOSTROPHE + value + Constants.PERCENT_SIGN + Constants.APOSTROPHE);
|
||||
|
||||
} else {
|
||||
// like 'click' => 'like%'
|
||||
whereClause.append(Constants.APOSTROPHE + value.replaceAll(Constants.APOSTROPHE, Constants.PERCENT_SIGN)
|
||||
+ Constants.APOSTROPHE);
|
||||
}
|
||||
return whereClause.toString();
|
||||
}
|
||||
|
||||
private String inLogic(Criterion criterion) {
|
||||
if (Objects.isNull(criterion) || Objects.isNull(criterion.getValue())) {
|
||||
throw new RuntimeException("criterion.getValue() can not be null");
|
||||
}
|
||||
|
||||
StringBuilder whereClause = new StringBuilder();
|
||||
whereClause.append(criterion.getColumn() + SPACE + criterion.getOperator().getValue() + SPACE);
|
||||
List values = (List) criterion.getValue();
|
||||
whereClause.append(PARENTHESES_START);
|
||||
StringJoiner joiner = new StringJoiner(",");
|
||||
if (criterion.isNeedApostrophe()) {
|
||||
values.stream().forEach(value -> joiner.add(valueApostropheLogic(value.toString())));
|
||||
} else {
|
||||
values.stream().forEach(value -> joiner.add(value.toString()));
|
||||
}
|
||||
whereClause.append(joiner);
|
||||
whereClause.append(PARENTHESES_END);
|
||||
return whereClause.toString();
|
||||
}
|
||||
|
||||
private String betweenLogic(Criterion criterion) {
|
||||
if (Objects.isNull(criterion) || Objects.isNull(criterion.getValue())) {
|
||||
throw new RuntimeException("criterion.getValue() can not be null");
|
||||
}
|
||||
List values = (List) criterion.getValue();
|
||||
if (values.size() != 2) {
|
||||
throw new RuntimeException("between value size should be 2");
|
||||
}
|
||||
|
||||
if (criterion.isNeedApostrophe()) {
|
||||
return String.format("(%s >= %s and %s <= %s)", criterion.getColumn(),
|
||||
valueApostropheLogic(values.get(0).toString()),
|
||||
criterion.getColumn(), valueApostropheLogic(values.get(1).toString()));
|
||||
}
|
||||
return String.format("(%s >= %s and %s <= %s)", criterion.getColumn(), values.get(0).toString(),
|
||||
criterion.getColumn(), values.get(1).toString());
|
||||
}
|
||||
|
||||
private String singleValueLogic(Criterion criterion) {
|
||||
if (Objects.isNull(criterion) || Objects.isNull(criterion.getValue())) {
|
||||
throw new RuntimeException("criterion.getValue() can not be null");
|
||||
}
|
||||
StringBuilder whereClause = new StringBuilder();
|
||||
whereClause.append(criterion.getColumn() + SPACE + criterion.getOperator().getValue() + SPACE);
|
||||
String value = criterion.getValue().toString();
|
||||
if (criterion.isNeedApostrophe()) {
|
||||
value = valueApostropheLogic(value);
|
||||
}
|
||||
whereClause.append(value);
|
||||
return whereClause.toString();
|
||||
}
|
||||
|
||||
private String valueApostropheLogic(String value) {
|
||||
if (Pattern.matches(pattern, value) || Pattern.matches(numericPattern, value)) {
|
||||
return value;
|
||||
}
|
||||
return Constants.APOSTROPHE + value + Constants.APOSTROPHE;
|
||||
}
|
||||
|
||||
private String judgeNullLogic(Criterion criterion) {
|
||||
|
||||
if (Objects.isNull(criterion) || Objects.isNull(criterion.getColumn())) {
|
||||
throw new RuntimeException("criterion.getColumn() can not be null");
|
||||
}
|
||||
return String.format("( %s %s)", criterion.getColumn(), criterion.getOperator().getValue());
|
||||
}
|
||||
|
||||
private String sqlPartLogic(Criterion criterion) {
|
||||
if (Objects.isNull(criterion) || Objects.isNull(criterion.getValue())) {
|
||||
throw new RuntimeException("criterion.getValue() can not be null");
|
||||
}
|
||||
return PARENTHESES_START + SPACE + criterion.getValue().toString() + SPACE + PARENTHESES_END;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user