(feature)(semantic) add materialization optimizer (#239)

Co-authored-by: jipengli <jipengli@tencent.com>
This commit is contained in:
jipeli
2023-10-16 22:07:45 +08:00
committed by GitHub
parent 5b8fde70ca
commit 40ba179703
126 changed files with 9172 additions and 91 deletions

View File

@@ -0,0 +1,8 @@
package com.tencent.supersonic.semantic.api.materialization.enums;
public enum ElementFrequencyEnum {
UNKNOWN,
HIGH,
LOW
}

View File

@@ -0,0 +1,11 @@
package com.tencent.supersonic.semantic.api.materialization.enums;
public enum ElementTypeEnum {
VARCHAR,
DOUBLE,
BIGINT,
INT,
DATE,
ARRAY
}

View File

@@ -0,0 +1,7 @@
package com.tencent.supersonic.semantic.api.materialization.enums;
public enum MaterializedTypeEnum {
FULL,
PARTITION,
ZIPPER
}

View File

@@ -0,0 +1,8 @@
package com.tencent.supersonic.semantic.api.materialization.enums;
public enum UpdateCycleEnum {
DAY,
WEEK,
MONTH
}

View File

@@ -0,0 +1,17 @@
package com.tencent.supersonic.semantic.api.materialization.pojo;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class MaterializationConfFilter extends MaterializationFilter {
private Long id;
private Boolean containElements = false;
private TypeEnums type;
private Long materializationId;
private Long elementId;
}

View File

@@ -0,0 +1,16 @@
package com.tencent.supersonic.semantic.api.materialization.pojo;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
public class MaterializationDateFilter {
private Long modelId;
private List<String> dimensions;
private List<String> metrics;
private Date createdAt;
}

View File

@@ -0,0 +1,25 @@
package com.tencent.supersonic.semantic.api.materialization.pojo;
import com.tencent.supersonic.semantic.api.materialization.enums.MaterializedTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.UpdateCycleEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MaterializationFilter {
private Long materializationId;
private String name;
private MaterializedTypeEnum materializedType;
private UpdateCycleEnum updateCycle;
private Long modelId;
private Long databaseId;
private Integer level;
private String createdBy;
private String destinationTable;
}

View File

@@ -0,0 +1,28 @@
package com.tencent.supersonic.semantic.api.materialization.pojo;
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import java.util.List;
import lombok.Builder;
import lombok.Data;
import java.util.Date;
@Data
@Builder
public class MaterializationRecordFilter {
private Long id;
private Long materializationId;
private TypeEnums elementType;
private Long elementId;
private String elementName;
private List<TaskStatusEnum> taskStatus;
private String taskId;
private String createdBy;
private Date createdAt;
private String startDataTime;
private String endDataTime;
private List<Long> materializationIds;
}

View File

@@ -0,0 +1,25 @@
package com.tencent.supersonic.semantic.api.materialization.request;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementFrequencyEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementTypeEnum;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class MaterializationElementReq extends RecordInfo {
private Long id;
private TypeEnums type;
private Long materializationId;
private String depends;
private ElementTypeEnum elementType;
private String defaultValue;
private String outlier;
private ElementFrequencyEnum frequency;
private String description;
private StatusEnum status;
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.semantic.api.materialization.request;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import lombok.Data;
@Data
public class MaterializationRecordReq extends RecordInfo {
private Long id;
private Long materializationId;
private TypeEnums elementType;
private Long elementId;
private String elementName;
private String dataTime;
private TaskStatusEnum taskStatus;
private String taskId;
private Long retryCount;
private Long sourceCount;
private Long sinkCount;
private String message;
}

View File

@@ -0,0 +1,26 @@
package com.tencent.supersonic.semantic.api.materialization.request;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.MaterializedTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.UpdateCycleEnum;
import lombok.Data;
import java.util.List;
@Data
public class MaterializationReq extends RecordInfo {
private Long id;
private String name;
private MaterializedTypeEnum materializedType;
private UpdateCycleEnum updateCycle;
private Long modelId;
private Long databaseId;
private Integer level;
private String destinationTable;
private String dateInfo;
private String entities;
private List<String> principals;
private String description;
private StatusEnum status;
}

View File

@@ -0,0 +1,12 @@
package com.tencent.supersonic.semantic.api.materialization.request;
import lombok.Data;
@Data
public class MaterializationSourceReq {
private Long materializationId = 0L;
private Long dataSourceId = 0L;
private String dataTime;
}

View File

@@ -0,0 +1,20 @@
package com.tencent.supersonic.semantic.api.materialization.response;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class MaterializationDateResp {
private Long modelId;
private TypeEnums elementType;
private Long elementId;
private String elementName;
private String dateFormat;
private String startDate;
private String endDate;
private List<String> unavailableDateList = new ArrayList<>();
}

View File

@@ -0,0 +1,18 @@
package com.tencent.supersonic.semantic.api.materialization.response;
import com.google.common.collect.Lists;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
import java.util.List;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class MaterializationElementModelResp {
private Long id;
private TypeEnums type;
private String bizName;
private String expr;
private List<Measure> measures = Lists.newArrayList();
}

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.semantic.api.materialization.response;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementFrequencyEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementTypeEnum;
import lombok.Data;
@Data
public class MaterializationElementResp extends RecordInfo {
private Long id;
private TypeEnums type;
private Long materializationId;
private String depends;
private ElementTypeEnum elementType;
private String defaultValue;
private String outlier;
private ElementFrequencyEnum frequency;
private String description;
private String bizName;
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.semantic.api.materialization.response;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import lombok.Data;
@Data
public class MaterializationRecordResp extends RecordInfo {
private Long id;
private Long materializationId;
private TypeEnums elementType;
private Long elementId;
private String elementName;
private String dataTime;
private TaskStatusEnum taskStatus;
private String taskId;
private Integer retryCount;
private Long sourceCount;
private Long sinkCount;
private String message;
}

View File

@@ -0,0 +1,25 @@
package com.tencent.supersonic.semantic.api.materialization.response;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.semantic.api.materialization.enums.MaterializedTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.UpdateCycleEnum;
import lombok.Data;
import java.util.List;
@Data
public class MaterializationResp extends RecordInfo {
private Long id;
private String name;
private MaterializedTypeEnum materializedType;
private UpdateCycleEnum updateCycle;
private Long modelId;
private Long databaseId;
private Integer level;
private String destinationTable;
private String dateInfo;
private String entities;
private List<String> principals;
private String description;
private List<MaterializationElementResp> materializationElementRespList;
}

View File

@@ -0,0 +1,35 @@
package com.tencent.supersonic.semantic.api.materialization.response;
import com.tencent.supersonic.semantic.api.materialization.enums.MaterializedTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.UpdateCycleEnum;
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MaterializationSourceResp {
private Long materializationId;
private Long dataSourceId;
private Long modelId;
private String sql;
private List<String> fields;
private String sourceDb;
private String sourceTable;
private String dateInfo;
private String entities;
private MaterializedTypeEnum materializedType;
private UpdateCycleEnum updateCycle;
private DatabaseResp databaseResp;
private String depends;
private Map<Long, String> dimensions;
private Map<Long, String> metrics;
}

View File

@@ -0,0 +1,8 @@
package com.tencent.supersonic.semantic.api.model.enums;
public enum QueryOptMode {
NONE,
MATERIALIZATION
}

View File

@@ -25,6 +25,8 @@ public class Dim {
private String bizName;
private String description;
public Dim(String name, String bizName, String type, Integer isCreateDimension) {
this.name = name;
this.type = type;
@@ -32,6 +34,17 @@ public class Dim {
this.bizName = bizName;
}
public Dim(String name, String type, String expr, String dateFormat, DimensionTimeTypeParams typeParams,
Integer isCreateDimension, String bizName) {
this.name = name;
this.type = type;
this.expr = expr;
this.dateFormat = dateFormat;
this.typeParams = typeParams;
this.isCreateDimension = isCreateDimension;
this.bizName = bizName;
}
public static Dim getDefault() {
return new Dim("日期", "time", "2023-05-28",
Constants.DAY_FORMAT,

View File

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Objects;
import lombok.Data;
import lombok.ToString;
@@ -48,6 +49,13 @@ public class QueryStat {
private Boolean useSqlCache;
private String sqlCacheKey;
private String resultCacheKey;
private String queryOptMode;
public QueryStat setQueryOptMode(String queryOptMode) {
this.queryOptMode = queryOptMode;
return this;
}
public QueryStat setQuerySqlCmdMd5(String querySqlCmdMd5) {
this.querySqlCmdMd5 = querySqlCmdMd5;

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.semantic.api.model.request;
import com.tencent.supersonic.common.pojo.enums.DataTypeEnums;
import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap;
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
@@ -30,4 +31,6 @@ public class DimensionReq extends SchemaItem {
private List<String> defaultValues;
private List<DimValueMap> dimValueMaps;
private DataTypeEnums dataType;
}

View File

@@ -13,6 +13,8 @@ public class DatasourceResp extends SchemaItem {
private DatasourceDetail datasourceDetail;
private String depends;
}

View File

@@ -1,6 +1,7 @@
package com.tencent.supersonic.semantic.api.model.response;
import com.tencent.supersonic.common.pojo.enums.DataTypeEnums;
import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap;
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
@@ -36,4 +37,6 @@ public class DimensionResp extends SchemaItem {
private List<DimValueMap> dimValueMaps;
private DataTypeEnums dataType;
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>semantic</artifactId>
<groupId>com.tencent.supersonic</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>semantic-materialization</artifactId>
<dependencies>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>semantic-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>semantic-model</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,490 @@
package com.tencent.supersonic.semantic.materialization.application;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.common.util.JsonUtil;
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementFrequencyEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationConfFilter;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationFilter;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationElementReq;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementModelResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationSourceResp;
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
import com.tencent.supersonic.semantic.api.model.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
import com.tencent.supersonic.semantic.api.model.response.MetricSchemaResp;
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
import com.tencent.supersonic.semantic.materialization.domain.MaterializationConfService;
import com.tencent.supersonic.semantic.materialization.domain.pojo.Materialization;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationElement;
import com.tencent.supersonic.semantic.materialization.domain.repository.MaterializationElementRepository;
import com.tencent.supersonic.semantic.materialization.domain.repository.MaterializationRepository;
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationConverter;
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationUtils;
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationZipperUtils;
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
import com.tencent.supersonic.semantic.model.domain.ModelService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@Slf4j
@Service
public class MaterializationConfServiceImpl implements MaterializationConfService {
private final MaterializationRepository materializationRepository;
private final MaterializationElementRepository materializationElementRepository;
private final ModelService modelService;
private final DatasourceService datasourceService;
private String typeAndIdSplit = "_";
public MaterializationConfServiceImpl(MaterializationRepository materializationRepository,
MaterializationElementRepository materializationElementRepository,
ModelService modelService, DatasourceService datasourceService) {
this.materializationRepository = materializationRepository;
this.materializationElementRepository = materializationElementRepository;
this.modelService = modelService;
this.datasourceService = datasourceService;
}
@Override
public Boolean addMaterializationConf(MaterializationReq materializationReq, User user) {
log.info("materializationReq:{}, user:{}", JsonUtil.toString(materializationReq), JsonUtil.toString(user));
Materialization materialization = MaterializationConverter.materializationReq2Bean(materializationReq);
RecordInfo recordInfo = new RecordInfo().createdBy(user.getName());
BeanUtils.copyProperties(recordInfo, materialization);
return materializationRepository.insert(materialization);
}
@Override
public Boolean updateMaterializationConf(MaterializationReq materializationReq, User user) {
Materialization materialization = MaterializationConverter.materializationReq2Bean(materializationReq);
RecordInfo recordInfo = new RecordInfo().updatedBy(user.getName());
BeanUtils.copyProperties(recordInfo, materialization);
return materializationRepository.update(materialization);
}
@Override
public List<MaterializationResp> getMaterializationResp(MaterializationFilter filter, User user) {
return materializationRepository.getMaterializationResp(filter);
}
public MaterializationResp getMaterializationRespById(Long materializationId, User user) {
MaterializationResp materializationResp = new MaterializationResp();
MaterializationConfFilter filter = new MaterializationConfFilter();
filter.setMaterializationId(materializationId);
filter.setContainElements(true);
List<MaterializationResp> materializationRespList = queryMaterializationConf(filter, user);
if (CollectionUtils.isEmpty(materializationRespList)) {
return materializationResp;
}
return materializationRespList.get(0);
}
@Override
public Boolean addMaterializationElementConf(MaterializationElementReq materializationElementReq, User user) {
log.info("materializationElementReq:{}, user:{}", JsonUtil.toString(materializationElementReq),
JsonUtil.toString(user));
MaterializationElement materializationElement = MaterializationConverter
.materializationElementReq2Bean(materializationElementReq);
RecordInfo recordInfo = new RecordInfo().createdBy(user.getName());
BeanUtils.copyProperties(recordInfo, materializationElement);
return materializationElementRepository.insert(materializationElement);
}
@Override
public Boolean updateMaterializationElementConf(MaterializationElementReq materializationElementReq, User user) {
MaterializationElement materializationElement = MaterializationConverter
.materializationElementReq2Bean(materializationElementReq);
RecordInfo recordInfo = new RecordInfo().updatedBy(user.getName());
BeanUtils.copyProperties(recordInfo, materializationElement);
return materializationElementRepository.update(materializationElement);
}
@Override
public List<MaterializationResp> queryMaterializationConf(MaterializationConfFilter filter, User user) {
MaterializationFilter materializationFilter = MaterializationFilter.builder().build();
BeanUtils.copyProperties(filter, materializationFilter);
List<MaterializationResp> materializationRespList = getMaterializationResp(materializationFilter, user);
if (!CollectionUtils.isEmpty(materializationRespList) && filter.getContainElements()) {
Map<String, SchemaItem> keyAndSchemaItemPair = generateSchemaItem(filter, user);
materializationRespList.stream().forEach(materializationResp -> {
filter.setMaterializationId(materializationResp.getId());
List<MaterializationElementResp> materializationElementRespList = materializationElementRepository
.getMaterializationElementResp(filter);
fillElementInfo(materializationElementRespList, keyAndSchemaItemPair);
materializationResp.setMaterializationElementRespList(materializationElementRespList);
});
}
return materializationRespList;
}
private void fillElementInfo(List<MaterializationElementResp> materializationElementRespList,
Map<String, SchemaItem> keyAndSchemaItemPair) {
if (CollectionUtils.isEmpty(materializationElementRespList) || Objects.isNull(keyAndSchemaItemPair)) {
return;
}
materializationElementRespList.stream().forEach(materializationElementResp -> {
String key = materializationElementResp.getType() + typeAndIdSplit + materializationElementResp.getId();
SchemaItem schemaItem = keyAndSchemaItemPair.getOrDefault(key, null);
if (Objects.nonNull(schemaItem)) {
materializationElementResp.setBizName(schemaItem.getBizName());
}
});
}
private Map<String, SchemaItem> generateSchemaItem(MaterializationConfFilter filter, User user) {
return generateSchemaItem(filter);
}
private Map<String, SchemaItem> generateSchemaItem(MaterializationConfFilter filter) {
Map<String, SchemaItem> keyAndSchemaItemPair = new HashMap<>();
ModelSchemaFilterReq modelFilter = new ModelSchemaFilterReq();
List<Long> modelIds = new ArrayList<>();
if (Objects.nonNull(filter.getModelId())) {
modelIds.add(filter.getModelId());
}
List<ModelSchemaResp> modelSchemaRespList = modelService.fetchModelSchema(modelFilter);
if (!CollectionUtils.isEmpty(modelSchemaRespList)) {
modelSchemaRespList.stream().forEach(modelSchemaResp -> {
List<DimSchemaResp> dimensions = modelSchemaResp.getDimensions();
List<MetricSchemaResp> metrics = modelSchemaResp.getMetrics();
if (!CollectionUtils.isEmpty(dimensions)) {
dimensions.stream().forEach(dimSchemaResp -> {
SchemaItem schemaItem = new SchemaItem();
BeanUtils.copyProperties(dimSchemaResp, schemaItem);
String key = TypeEnums.DIMENSION.name() + typeAndIdSplit + dimSchemaResp.getId();
keyAndSchemaItemPair.put(key, schemaItem);
});
}
if (!CollectionUtils.isEmpty(metrics)) {
metrics.stream().forEach(metricSchemaResp -> {
SchemaItem schemaItem = new SchemaItem();
BeanUtils.copyProperties(metricSchemaResp, schemaItem);
String key = TypeEnums.METRIC.name() + typeAndIdSplit + metricSchemaResp.getId();
keyAndSchemaItemPair.put(key, schemaItem);
});
}
});
}
return keyAndSchemaItemPair;
}
@Override
public List<MaterializationResp> getMaterializationByModel(Long modelId) {
MaterializationFilter filter = new MaterializationConfFilter();
filter.setModelId(modelId);
List<MaterializationResp> materializationRespList = materializationRepository.getMaterializationResp(filter);
MaterializationConfFilter materializationConfFilter = new MaterializationConfFilter();
if (!CollectionUtils.isEmpty(materializationRespList)) {
materializationRespList.stream().forEach(materializationResp -> {
materializationConfFilter.setMaterializationId(materializationResp.getId());
List<MaterializationElementResp> materializationElementRespList = materializationElementRepository
.getMaterializationElementResp(materializationConfFilter);
materializationResp.setMaterializationElementRespList(materializationElementRespList);
});
}
return materializationRespList;
}
@Override
public List<Long> getMaterializationByTable(Long databaseId, String destinationTable) {
MaterializationFilter filter = new MaterializationConfFilter();
filter.setDestinationTable(destinationTable);
filter.setDatabaseId(databaseId);
List<MaterializationResp> materializationRespList = materializationRepository.getMaterializationResp(filter);
if (!CollectionUtils.isEmpty(materializationRespList)) {
return materializationRespList.stream().map(m -> m.getId()).collect(Collectors.toList());
}
return new ArrayList<>();
}
@Override
public String generateCreateSql(Long materializationId, User user) {
MaterializationConfFilter filter = new MaterializationConfFilter();
filter.setMaterializationId(materializationId);
filter.setContainElements(true);
List<MaterializationResp> materializationRespList = queryMaterializationConf(filter, user);
if (CollectionUtils.isEmpty(materializationRespList)) {
log.warn("materializationRespList is empty, materializationId:{}", materializationId);
return "";
}
// 获取db 连接信息
MaterializationResp materializationResp = materializationRespList.get(0);
return generateCreateSql(materializationResp);
}
private String generateCreateSql(MaterializationResp materializationResp) {
MaterializationUtils materializationUtils = new MaterializationZipperUtils();
return materializationUtils.generateCreateSql(materializationResp);
}
@Override
public Boolean initMaterializationElementConf(MaterializationConfFilter filter, User user) {
Long materializationId = filter.getMaterializationId();
MaterializationResp materializationResp = getMaterializationRespById(materializationId, user);
Long modelId = materializationResp.getModelId();
ModelSchemaResp modelSchemaResp = modelService.fetchSingleModelSchema(modelId);
doDimensionMaterializationLogic(modelSchemaResp.getDimensions(), materializationResp, user);
return true;
}
private void doDimensionMaterializationLogic(List<DimSchemaResp> dimensions,
MaterializationResp materializationResp, User user) {
if (CollectionUtils.isEmpty(dimensions)) {
return;
}
Long materializationId = materializationResp.getId();
cleanMaterializationElement(materializationId, user);
for (DimSchemaResp dimSchemaResp : dimensions) {
MaterializationElementReq materializationElementReq = MaterializationElementReq.builder()
.id(dimSchemaResp.getId())
.type(TypeEnums.DIMENSION)
.materializationId(materializationId)
.elementType(ElementTypeEnum.VARCHAR)
.frequency(ElementFrequencyEnum.LOW)
.status(StatusEnum.ONLINE)
.description(dimSchemaResp.getDescription())
.build();
addMaterializationElementConf(materializationElementReq, user);
}
MaterializationConfFilter filter = new MaterializationConfFilter();
filter.setMaterializationId(materializationId);
MaterializationResp materializationRespNew = getMaterializationRespById(materializationId, user);
String createSql = generateCreateSql(materializationRespNew);
log.info("createSql:{}", createSql);
}
private Boolean cleanMaterializationElement(Long materializationId, User user) {
log.info("cleanMaterializationElement materializationId:{}", materializationId);
return materializationElementRepository.cleanMaterializationElement(materializationId);
}
@Override
public List<MaterializationElementModelResp> getMaterializationElementModels(Long materializationId, User user) {
MaterializationResp materializationResp = materializationRepository.getMaterialization(materializationId);
MaterializationConfFilter filter = new MaterializationConfFilter();
filter.setMaterializationId(materializationId);
List<MaterializationElementResp> materializationElementRespList = materializationElementRepository
.getMaterializationElementResp(filter);
List<MaterializationElementModelResp> materializationElementModelRespList = new ArrayList<>();
if (!CollectionUtils.isEmpty(materializationElementRespList)) {
ModelSchemaFilterReq modelFilter = new ModelSchemaFilterReq();
modelFilter.setModelIds(Arrays.asList(materializationResp.getModelId()));
List<ModelSchemaResp> modelSchemaRespList = modelService.fetchModelSchema(modelFilter);
List<MeasureResp> measureRespList = datasourceService.getMeasureListOfModel(
materializationResp.getModelId());
Map<String, DimSchemaResp> dimSchemaRespMap = new HashMap<>();
Map<String, MetricSchemaResp> metricSchemaRespHashMap = new HashMap<>();
if (!CollectionUtils.isEmpty(modelSchemaRespList)) {
modelSchemaRespList.stream().forEach(modelSchemaResp -> {
List<DimSchemaResp> dimensions = modelSchemaResp.getDimensions();
List<MetricSchemaResp> metrics = modelSchemaResp.getMetrics();
if (!CollectionUtils.isEmpty(dimensions)) {
dimensions.stream().forEach(dimSchemaResp -> {
String key = TypeEnums.DIMENSION.name() + typeAndIdSplit + dimSchemaResp.getId();
dimSchemaRespMap.put(key, dimSchemaResp);
});
}
if (!CollectionUtils.isEmpty(metrics)) {
metrics.stream().forEach(metricSchemaResp -> {
String key = TypeEnums.METRIC.name() + typeAndIdSplit + metricSchemaResp.getId();
metricSchemaRespHashMap.put(key, metricSchemaResp);
});
}
});
}
materializationElementRespList.stream().forEach(materializationElementResp -> {
String key = materializationElementResp.getType() + typeAndIdSplit + materializationElementResp.getId();
DimSchemaResp schemaItem = dimSchemaRespMap.getOrDefault(key, null);
MaterializationElementModelResp materializationElementModelResp = MaterializationElementModelResp
.builder()
.type(materializationElementResp.getType())
.id(materializationElementResp.getId())
.build();
if (Objects.nonNull(schemaItem)) {
materializationElementModelResp.setBizName(schemaItem.getBizName());
materializationElementModelResp.setExpr(schemaItem.getExpr());
materializationElementModelRespList.add(materializationElementModelResp);
} else {
MetricSchemaResp metricSchemaResp = metricSchemaRespHashMap.getOrDefault(key, null);
if (Objects.nonNull(metricSchemaResp)) {
materializationElementModelResp.setBizName(metricSchemaResp.getBizName());
materializationElementModelResp.setExpr(metricSchemaResp.getTypeParams().getExpr());
materializationElementModelResp.setMeasures(metricSchemaResp.getTypeParams().getMeasures());
materializationElementModelResp.getMeasures().forEach(m -> {
m.setExpr(getDataSourceMeasure(measureRespList, m.getBizName()));
});
materializationElementModelRespList.add(materializationElementModelResp);
}
}
});
}
return materializationElementModelRespList;
}
@Override
public List<MaterializationSourceResp> getMaterializationSourceResp(
Long materializationId) {
MaterializationResp materializationResp = materializationRepository.getMaterialization(
materializationId);
Long modelId = materializationResp.getModelId();
List<DatasourceResp> modelDataSources = datasourceService.getDatasourceList(modelId);
Set<Long> dataSourceIds = new HashSet<>();
Map<Long, Map<Long, String>> dataSourceDimensions = new HashMap<>();
Map<Long, Map<Long, String>> dataSourceMetrics = new HashMap<>();
MaterializationConfFilter materializationConfFilter = new MaterializationConfFilter();
materializationConfFilter.setMaterializationId(materializationId);
List<MaterializationElementResp> materializationElementRespList = materializationElementRepository
.getMaterializationElementResp(materializationConfFilter);
if (!CollectionUtils.isEmpty(materializationElementRespList)) {
ModelSchemaFilterReq modelSchemaFilterReq = new ModelSchemaFilterReq();
modelSchemaFilterReq.setModelIds(Arrays.asList(modelId));
List<ModelSchemaResp> modelSchemaRespList = modelService.fetchModelSchema(modelSchemaFilterReq);
List<MeasureResp> measureRespList = datasourceService.getMeasureListOfModel(modelId);
Set<Long> dimensionIds = new HashSet<>();
Set<Long> metricIds = new HashSet<>();
materializationElementRespList.stream().forEach(e -> {
if (e.getType().equals(TypeEnums.DIMENSION)) {
dimensionIds.add(e.getId());
}
if (e.getType().equals(TypeEnums.METRIC)) {
metricIds.add(e.getId());
}
});
modelSchemaRespList.stream().forEach(m -> {
m.getDimensions().stream().filter(mm -> dimensionIds.contains(mm.getId())).forEach(mm -> {
if (!dataSourceDimensions.containsKey(mm.getDatasourceId())) {
dataSourceDimensions.put(mm.getDatasourceId(), new HashMap<>());
}
dataSourceDimensions.get(mm.getDatasourceId()).put(mm.getId(), mm.getBizName());
dataSourceIds.add(mm.getDatasourceId());
});
m.getMetrics().stream().filter(mm -> metricIds.contains(mm.getId())).forEach(mm -> {
Long sourceId = 0L;
for (Measure measure : mm.getTypeParams().getMeasures()) {
sourceId = getSourceIdByMeasure(measureRespList, measure.getBizName());
if (sourceId > 0) {
break;
}
}
if (sourceId > 0) {
if (!dataSourceMetrics.containsKey(sourceId)) {
dataSourceMetrics.put(sourceId, new HashMap<>());
}
dataSourceMetrics.get(sourceId).put(mm.getId(), mm.getBizName());
dataSourceIds.add(sourceId);
}
});
});
}
List<MaterializationSourceResp> materializationSourceResps = new ArrayList<>();
for (Long sourceId : dataSourceIds) {
Optional<DatasourceResp> datasourceResp = modelDataSources.stream().filter(d -> d.getId().equals(sourceId))
.findFirst();
if (datasourceResp.isPresent()) {
MaterializationSourceResp materializationSourceResp = MaterializationSourceResp.builder()
.dataSourceId(sourceId)
.materializationId(materializationId)
.modelId(modelId)
.depends(datasourceResp.get().getDepends())
.materializedType(materializationResp.getMaterializedType())
.entities(materializationResp.getEntities())
.dateInfo(materializationResp.getDateInfo())
.updateCycle(materializationResp.getUpdateCycle())
.build();
setDataSourceDb(datasourceResp.get(), materializationSourceResp);
materializationSourceResp.setMetrics(
dataSourceMetrics.containsKey(sourceId) ? dataSourceMetrics.get(sourceId)
: new HashMap<>());
materializationSourceResp.setDimensions(
dataSourceDimensions.containsKey(sourceId) ? dataSourceDimensions.get(sourceId)
: new HashMap<>());
materializationSourceResps.add(materializationSourceResp);
}
}
return materializationSourceResps;
}
public Long getSourceIdByMeasure(List<MeasureResp> measureRespList, String bizName) {
if (!CollectionUtils.isEmpty(measureRespList)) {
Optional<MeasureResp> measure = measureRespList.stream()
.filter(m -> m.getBizName().equalsIgnoreCase(bizName)).findFirst();
if (measure.isPresent()) {
return measure.get().getDatasourceId();
}
}
return 0L;
}
private void setDataSourceDb(DatasourceResp datasourceResp, MaterializationSourceResp materializationSourceResp) {
if (Objects.nonNull(datasourceResp.getDatasourceDetail())) {
String dbTable = "";
if (Objects.nonNull(datasourceResp.getDatasourceDetail().getTableQuery())
&& !datasourceResp.getDatasourceDetail().getTableQuery().isEmpty()) {
dbTable = datasourceResp.getDatasourceDetail().getTableQuery();
}
if (Objects.nonNull(datasourceResp.getDatasourceDetail().getSqlQuery())
&& !datasourceResp.getDatasourceDetail().getSqlQuery().isEmpty()) {
dbTable = SqlParserSelectHelper.getDbTableName(datasourceResp.getDatasourceDetail().getSqlQuery());
}
if (!dbTable.isEmpty()) {
String[] db = dbTable.split("\\.");
if (db.length > 1) {
materializationSourceResp.setSourceDb(db[0]);
materializationSourceResp.setSourceTable(db[1]);
}
}
}
}
private String getDataSourceMeasure(List<MeasureResp> measureRespList, String bizName) {
if (!CollectionUtils.isEmpty(measureRespList)) {
Optional<MeasureResp> measure = measureRespList.stream()
.filter(m -> m.getBizName().equalsIgnoreCase(bizName)).findFirst();
if (measure.isPresent()) {
return measure.get().getExpr();
}
}
return "";
}
}

View File

@@ -0,0 +1,80 @@
package com.tencent.supersonic.semantic.materialization.application;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
import com.tencent.supersonic.common.util.JsonUtil;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationDateFilter;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationRecordFilter;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationRecordReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationDateResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationRecordResp;
import com.tencent.supersonic.semantic.materialization.domain.MaterializationRecordService;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationRecord;
import com.tencent.supersonic.semantic.materialization.domain.repository.MaterializationRecordRepository;
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationRecordConverter;
import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class MaterializationRecordServiceImpl implements MaterializationRecordService {
private final MaterializationRecordRepository repository;
public MaterializationRecordServiceImpl(MaterializationRecordRepository materializationRecordRepository) {
this.repository = materializationRecordRepository;
}
@Override
public Boolean addMaterializationRecord(MaterializationRecordReq materializationRecordReq, User user) {
log.info("materializationRecordReq:{}, user:{}", JsonUtil.toString(materializationRecordReq),
JsonUtil.toString(user));
MaterializationRecord materializationRecord = MaterializationRecordConverter.req2Bean(materializationRecordReq);
RecordInfo recordInfo = new RecordInfo().createdBy(user.getName());
BeanUtils.copyProperties(recordInfo, materializationRecord);
return repository.insertMaterializationRecord(materializationRecord);
}
@Override
public Boolean updateMaterializationRecord(MaterializationRecordReq materializationRecordReq, User user) {
log.info("materializationRecordReq:{}, user:{}", JsonUtil.toString(materializationRecordReq),
JsonUtil.toString(user));
MaterializationRecord materializationRecord = MaterializationRecordConverter.req2Bean(materializationRecordReq);
RecordInfo recordInfo = new RecordInfo().updatedBy(user.getName());
BeanUtils.copyProperties(recordInfo, materializationRecord);
return repository.updateMaterializationRecord(materializationRecord);
}
@Override
public List<MaterializationRecordResp> getMaterializationRecordList(MaterializationRecordFilter filter, User user) {
return repository.getMaterializationRecordList(filter);
}
@Override
public Long getMaterializationRecordCount(MaterializationRecordFilter filter, User user) {
return repository.getCount(filter);
}
@Override
public List<MaterializationDateResp> fetchMaterializationDate(MaterializationDateFilter filter, User user) {
return null;
}
@Override
public List<MaterializationRecordResp> fetchMaterializationDate(List<Long> materializationIds, String elementName,
String startTime, String endTime) {
MaterializationRecordFilter materializationRecordFilter = MaterializationRecordFilter.builder()
.taskStatus(Arrays.asList(TaskStatusEnum.SUCCESS))
.elementName(elementName)
.materializationIds(materializationIds)
.startDataTime(startTime)
.endDataTime(endTime).build();
return repository.getMaterializationRecordList(materializationRecordFilter);
}
}

View File

@@ -0,0 +1,44 @@
package com.tencent.supersonic.semantic.materialization.domain;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationConfFilter;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationFilter;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationElementReq;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementModelResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationSourceResp;
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
import java.util.List;
public interface MaterializationConfService {
Boolean addMaterializationConf(MaterializationReq materializationReq, User user);
Boolean updateMaterializationConf(MaterializationReq materializationReq, User user);
List<MaterializationResp> getMaterializationResp(MaterializationFilter filter, User user);
Boolean addMaterializationElementConf(MaterializationElementReq materializationElementReq, User user);
Boolean updateMaterializationElementConf(MaterializationElementReq materializationElementReq, User user);
List<MaterializationResp> queryMaterializationConf(MaterializationConfFilter filter, User user);
List<MaterializationResp> getMaterializationByModel(Long modelId);
List<Long> getMaterializationByTable(Long databaseId, String destinationTable);
String generateCreateSql(Long materializationId, User user);
Boolean initMaterializationElementConf(MaterializationConfFilter filter, User user);
List<MaterializationElementModelResp> getMaterializationElementModels(Long materializationId, User user);
List<MaterializationSourceResp> getMaterializationSourceResp(Long materializationId);
Long getSourceIdByMeasure(List<MeasureResp> measureRespList, String bizName);
}

View File

@@ -0,0 +1,27 @@
package com.tencent.supersonic.semantic.materialization.domain;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationDateFilter;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationRecordFilter;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationRecordReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationDateResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationRecordResp;
import java.util.List;
public interface MaterializationRecordService {
Boolean addMaterializationRecord(MaterializationRecordReq materializationRecord, User user);
Boolean updateMaterializationRecord(MaterializationRecordReq materializationRecord, User user);
List<MaterializationRecordResp> getMaterializationRecordList(MaterializationRecordFilter filter, User user);
Long getMaterializationRecordCount(MaterializationRecordFilter filter, User user);
List<MaterializationDateResp> fetchMaterializationDate(MaterializationDateFilter filter, User user);
List<MaterializationRecordResp> fetchMaterializationDate(List<Long> materializationIds, String elementName,
String startTime, String endTime);
}

View File

@@ -0,0 +1,145 @@
package com.tencent.supersonic.semantic.materialization.domain.dataobject;
import java.util.Date;
public class MaterializationDO {
private Long id;
private String name;
private String materializedType;
private String updateCycle;
private Long modelId;
private Long databaseId;
private Integer level;
private Integer status;
private String destinationTable;
private String principals;
private Date createdAt;
private String createdBy;
private Date updatedAt;
private String updatedBy;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public String getMaterializedType() {
return materializedType;
}
public void setMaterializedType(String materializedType) {
this.materializedType = materializedType == null ? null : materializedType.trim();
}
public String getUpdateCycle() {
return updateCycle;
}
public void setUpdateCycle(String updateCycle) {
this.updateCycle = updateCycle == null ? null : updateCycle.trim();
}
public Long getModelId() {
return modelId;
}
public void setModelId(Long modelId) {
this.modelId = modelId;
}
public Long getDatabaseId() {
return databaseId;
}
public void setDatabaseId(Long databaseId) {
this.databaseId = databaseId;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getDestinationTable() {
return destinationTable;
}
public void setDestinationTable(String destinationTable) {
this.destinationTable = destinationTable == null ? null : destinationTable.trim();
}
public String getPrincipals() {
return principals;
}
public void setPrincipals(String principals) {
this.principals = principals == null ? null : principals.trim();
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy == null ? null : createdBy.trim();
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
}
}

View File

@@ -0,0 +1,33 @@
package com.tencent.supersonic.semantic.materialization.domain.dataobject;
public class MaterializationDOWithBLOBs extends MaterializationDO {
private String dateInfo;
private String entities;
private String description;
public String getDateInfo() {
return dateInfo;
}
public void setDateInfo(String dateInfo) {
this.dateInfo = dateInfo == null ? null : dateInfo.trim();
}
public String getEntities() {
return entities;
}
public void setEntities(String entities) {
this.entities = entities == null ? null : entities.trim();
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description == null ? null : description.trim();
}
}

View File

@@ -0,0 +1,95 @@
package com.tencent.supersonic.semantic.materialization.domain.dataobject;
import java.util.Date;
public class MaterializationElementDO extends MaterializationElementDOKey {
private String elementType;
private String defaultValue;
private String outlier;
private String frequency;
private Date createdAt;
private String createdBy;
private Date updatedAt;
private String updatedBy;
private Integer status;
public String getElementType() {
return elementType;
}
public void setElementType(String elementType) {
this.elementType = elementType == null ? null : elementType.trim();
}
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue == null ? null : defaultValue.trim();
}
public String getOutlier() {
return outlier;
}
public void setOutlier(String outlier) {
this.outlier = outlier == null ? null : outlier.trim();
}
public String getFrequency() {
return frequency;
}
public void setFrequency(String frequency) {
this.frequency = frequency == null ? null : frequency.trim();
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy == null ? null : createdBy.trim();
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@@ -0,0 +1,992 @@
package com.tencent.supersonic.semantic.materialization.domain.dataobject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class MaterializationElementDOExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public MaterializationElementDOExample() {
oredCriteria = new ArrayList<>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Long value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Long value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Long value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Long value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Long value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Long value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Long> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Long> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Long value1, Long value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Long value1, Long value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andTypeIsNull() {
addCriterion("type is null");
return (Criteria) this;
}
public Criteria andTypeIsNotNull() {
addCriterion("type is not null");
return (Criteria) this;
}
public Criteria andTypeEqualTo(String value) {
addCriterion("type =", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotEqualTo(String value) {
addCriterion("type <>", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThan(String value) {
addCriterion("type >", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThanOrEqualTo(String value) {
addCriterion("type >=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThan(String value) {
addCriterion("type <", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThanOrEqualTo(String value) {
addCriterion("type <=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLike(String value) {
addCriterion("type like", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotLike(String value) {
addCriterion("type not like", value, "type");
return (Criteria) this;
}
public Criteria andTypeIn(List<String> values) {
addCriterion("type in", values, "type");
return (Criteria) this;
}
public Criteria andTypeNotIn(List<String> values) {
addCriterion("type not in", values, "type");
return (Criteria) this;
}
public Criteria andTypeBetween(String value1, String value2) {
addCriterion("type between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andTypeNotBetween(String value1, String value2) {
addCriterion("type not between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andMaterializationIdIsNull() {
addCriterion("materialization_id is null");
return (Criteria) this;
}
public Criteria andMaterializationIdIsNotNull() {
addCriterion("materialization_id is not null");
return (Criteria) this;
}
public Criteria andMaterializationIdEqualTo(Long value) {
addCriterion("materialization_id =", value, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdNotEqualTo(Long value) {
addCriterion("materialization_id <>", value, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdGreaterThan(Long value) {
addCriterion("materialization_id >", value, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdGreaterThanOrEqualTo(Long value) {
addCriterion("materialization_id >=", value, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdLessThan(Long value) {
addCriterion("materialization_id <", value, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdLessThanOrEqualTo(Long value) {
addCriterion("materialization_id <=", value, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdIn(List<Long> values) {
addCriterion("materialization_id in", values, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdNotIn(List<Long> values) {
addCriterion("materialization_id not in", values, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdBetween(Long value1, Long value2) {
addCriterion("materialization_id between", value1, value2, "materializationId");
return (Criteria) this;
}
public Criteria andMaterializationIdNotBetween(Long value1, Long value2) {
addCriterion("materialization_id not between", value1, value2, "materializationId");
return (Criteria) this;
}
public Criteria andElementTypeIsNull() {
addCriterion("element_type is null");
return (Criteria) this;
}
public Criteria andElementTypeIsNotNull() {
addCriterion("element_type is not null");
return (Criteria) this;
}
public Criteria andElementTypeEqualTo(String value) {
addCriterion("element_type =", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeNotEqualTo(String value) {
addCriterion("element_type <>", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeGreaterThan(String value) {
addCriterion("element_type >", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeGreaterThanOrEqualTo(String value) {
addCriterion("element_type >=", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeLessThan(String value) {
addCriterion("element_type <", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeLessThanOrEqualTo(String value) {
addCriterion("element_type <=", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeLike(String value) {
addCriterion("element_type like", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeNotLike(String value) {
addCriterion("element_type not like", value, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeIn(List<String> values) {
addCriterion("element_type in", values, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeNotIn(List<String> values) {
addCriterion("element_type not in", values, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeBetween(String value1, String value2) {
addCriterion("element_type between", value1, value2, "elementType");
return (Criteria) this;
}
public Criteria andElementTypeNotBetween(String value1, String value2) {
addCriterion("element_type not between", value1, value2, "elementType");
return (Criteria) this;
}
public Criteria andDefaultValueIsNull() {
addCriterion("default_value is null");
return (Criteria) this;
}
public Criteria andDefaultValueIsNotNull() {
addCriterion("default_value is not null");
return (Criteria) this;
}
public Criteria andDefaultValueEqualTo(String value) {
addCriterion("default_value =", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueNotEqualTo(String value) {
addCriterion("default_value <>", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueGreaterThan(String value) {
addCriterion("default_value >", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueGreaterThanOrEqualTo(String value) {
addCriterion("default_value >=", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueLessThan(String value) {
addCriterion("default_value <", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueLessThanOrEqualTo(String value) {
addCriterion("default_value <=", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueLike(String value) {
addCriterion("default_value like", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueNotLike(String value) {
addCriterion("default_value not like", value, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueIn(List<String> values) {
addCriterion("default_value in", values, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueNotIn(List<String> values) {
addCriterion("default_value not in", values, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueBetween(String value1, String value2) {
addCriterion("default_value between", value1, value2, "defaultValue");
return (Criteria) this;
}
public Criteria andDefaultValueNotBetween(String value1, String value2) {
addCriterion("default_value not between", value1, value2, "defaultValue");
return (Criteria) this;
}
public Criteria andOutlierIsNull() {
addCriterion("outlier is null");
return (Criteria) this;
}
public Criteria andOutlierIsNotNull() {
addCriterion("outlier is not null");
return (Criteria) this;
}
public Criteria andOutlierEqualTo(String value) {
addCriterion("outlier =", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierNotEqualTo(String value) {
addCriterion("outlier <>", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierGreaterThan(String value) {
addCriterion("outlier >", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierGreaterThanOrEqualTo(String value) {
addCriterion("outlier >=", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierLessThan(String value) {
addCriterion("outlier <", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierLessThanOrEqualTo(String value) {
addCriterion("outlier <=", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierLike(String value) {
addCriterion("outlier like", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierNotLike(String value) {
addCriterion("outlier not like", value, "outlier");
return (Criteria) this;
}
public Criteria andOutlierIn(List<String> values) {
addCriterion("outlier in", values, "outlier");
return (Criteria) this;
}
public Criteria andOutlierNotIn(List<String> values) {
addCriterion("outlier not in", values, "outlier");
return (Criteria) this;
}
public Criteria andOutlierBetween(String value1, String value2) {
addCriterion("outlier between", value1, value2, "outlier");
return (Criteria) this;
}
public Criteria andOutlierNotBetween(String value1, String value2) {
addCriterion("outlier not between", value1, value2, "outlier");
return (Criteria) this;
}
public Criteria andFrequencyIsNull() {
addCriterion("frequency is null");
return (Criteria) this;
}
public Criteria andFrequencyIsNotNull() {
addCriterion("frequency is not null");
return (Criteria) this;
}
public Criteria andFrequencyEqualTo(String value) {
addCriterion("frequency =", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyNotEqualTo(String value) {
addCriterion("frequency <>", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyGreaterThan(String value) {
addCriterion("frequency >", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyGreaterThanOrEqualTo(String value) {
addCriterion("frequency >=", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyLessThan(String value) {
addCriterion("frequency <", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyLessThanOrEqualTo(String value) {
addCriterion("frequency <=", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyLike(String value) {
addCriterion("frequency like", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyNotLike(String value) {
addCriterion("frequency not like", value, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyIn(List<String> values) {
addCriterion("frequency in", values, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyNotIn(List<String> values) {
addCriterion("frequency not in", values, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyBetween(String value1, String value2) {
addCriterion("frequency between", value1, value2, "frequency");
return (Criteria) this;
}
public Criteria andFrequencyNotBetween(String value1, String value2) {
addCriterion("frequency not between", value1, value2, "frequency");
return (Criteria) this;
}
public Criteria andCreatedAtIsNull() {
addCriterion("created_at is null");
return (Criteria) this;
}
public Criteria andCreatedAtIsNotNull() {
addCriterion("created_at is not null");
return (Criteria) this;
}
public Criteria andCreatedAtEqualTo(Date value) {
addCriterion("created_at =", value, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtNotEqualTo(Date value) {
addCriterion("created_at <>", value, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtGreaterThan(Date value) {
addCriterion("created_at >", value, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtGreaterThanOrEqualTo(Date value) {
addCriterion("created_at >=", value, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtLessThan(Date value) {
addCriterion("created_at <", value, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtLessThanOrEqualTo(Date value) {
addCriterion("created_at <=", value, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtIn(List<Date> values) {
addCriterion("created_at in", values, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtNotIn(List<Date> values) {
addCriterion("created_at not in", values, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtBetween(Date value1, Date value2) {
addCriterion("created_at between", value1, value2, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedAtNotBetween(Date value1, Date value2) {
addCriterion("created_at not between", value1, value2, "createdAt");
return (Criteria) this;
}
public Criteria andCreatedByIsNull() {
addCriterion("created_by is null");
return (Criteria) this;
}
public Criteria andCreatedByIsNotNull() {
addCriterion("created_by is not null");
return (Criteria) this;
}
public Criteria andCreatedByEqualTo(String value) {
addCriterion("created_by =", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByNotEqualTo(String value) {
addCriterion("created_by <>", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByGreaterThan(String value) {
addCriterion("created_by >", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByGreaterThanOrEqualTo(String value) {
addCriterion("created_by >=", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByLessThan(String value) {
addCriterion("created_by <", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByLessThanOrEqualTo(String value) {
addCriterion("created_by <=", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByLike(String value) {
addCriterion("created_by like", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByNotLike(String value) {
addCriterion("created_by not like", value, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByIn(List<String> values) {
addCriterion("created_by in", values, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByNotIn(List<String> values) {
addCriterion("created_by not in", values, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByBetween(String value1, String value2) {
addCriterion("created_by between", value1, value2, "createdBy");
return (Criteria) this;
}
public Criteria andCreatedByNotBetween(String value1, String value2) {
addCriterion("created_by not between", value1, value2, "createdBy");
return (Criteria) this;
}
public Criteria andUpdatedAtIsNull() {
addCriterion("updated_at is null");
return (Criteria) this;
}
public Criteria andUpdatedAtIsNotNull() {
addCriterion("updated_at is not null");
return (Criteria) this;
}
public Criteria andUpdatedAtEqualTo(Date value) {
addCriterion("updated_at =", value, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtNotEqualTo(Date value) {
addCriterion("updated_at <>", value, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtGreaterThan(Date value) {
addCriterion("updated_at >", value, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtGreaterThanOrEqualTo(Date value) {
addCriterion("updated_at >=", value, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtLessThan(Date value) {
addCriterion("updated_at <", value, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtLessThanOrEqualTo(Date value) {
addCriterion("updated_at <=", value, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtIn(List<Date> values) {
addCriterion("updated_at in", values, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtNotIn(List<Date> values) {
addCriterion("updated_at not in", values, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtBetween(Date value1, Date value2) {
addCriterion("updated_at between", value1, value2, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedAtNotBetween(Date value1, Date value2) {
addCriterion("updated_at not between", value1, value2, "updatedAt");
return (Criteria) this;
}
public Criteria andUpdatedByIsNull() {
addCriterion("updated_by is null");
return (Criteria) this;
}
public Criteria andUpdatedByIsNotNull() {
addCriterion("updated_by is not null");
return (Criteria) this;
}
public Criteria andUpdatedByEqualTo(String value) {
addCriterion("updated_by =", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByNotEqualTo(String value) {
addCriterion("updated_by <>", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByGreaterThan(String value) {
addCriterion("updated_by >", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByGreaterThanOrEqualTo(String value) {
addCriterion("updated_by >=", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByLessThan(String value) {
addCriterion("updated_by <", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByLessThanOrEqualTo(String value) {
addCriterion("updated_by <=", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByLike(String value) {
addCriterion("updated_by like", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByNotLike(String value) {
addCriterion("updated_by not like", value, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByIn(List<String> values) {
addCriterion("updated_by in", values, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByNotIn(List<String> values) {
addCriterion("updated_by not in", values, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByBetween(String value1, String value2) {
addCriterion("updated_by between", value1, value2, "updatedBy");
return (Criteria) this;
}
public Criteria andUpdatedByNotBetween(String value1, String value2) {
addCriterion("updated_by not between", value1, value2, "updatedBy");
return (Criteria) this;
}
public Criteria andStatusIsNull() {
addCriterion("status is null");
return (Criteria) this;
}
public Criteria andStatusIsNotNull() {
addCriterion("status is not null");
return (Criteria) this;
}
public Criteria andStatusEqualTo(Integer value) {
addCriterion("status =", value, "status");
return (Criteria) this;
}
public Criteria andStatusNotEqualTo(Integer value) {
addCriterion("status <>", value, "status");
return (Criteria) this;
}
public Criteria andStatusGreaterThan(Integer value) {
addCriterion("status >", value, "status");
return (Criteria) this;
}
public Criteria andStatusGreaterThanOrEqualTo(Integer value) {
addCriterion("status >=", value, "status");
return (Criteria) this;
}
public Criteria andStatusLessThan(Integer value) {
addCriterion("status <", value, "status");
return (Criteria) this;
}
public Criteria andStatusLessThanOrEqualTo(Integer value) {
addCriterion("status <=", value, "status");
return (Criteria) this;
}
public Criteria andStatusIn(List<Integer> values) {
addCriterion("status in", values, "status");
return (Criteria) this;
}
public Criteria andStatusNotIn(List<Integer> values) {
addCriterion("status not in", values, "status");
return (Criteria) this;
}
public Criteria andStatusBetween(Integer value1, Integer value2) {
addCriterion("status between", value1, value2, "status");
return (Criteria) this;
}
public Criteria andStatusNotBetween(Integer value1, Integer value2) {
addCriterion("status not between", value1, value2, "status");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
}
}

View File

@@ -0,0 +1,33 @@
package com.tencent.supersonic.semantic.materialization.domain.dataobject;
public class MaterializationElementDOKey {
private Long id;
private String type;
private Long materializationId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type == null ? null : type.trim();
}
public Long getMaterializationId() {
return materializationId;
}
public void setMaterializationId(Long materializationId) {
this.materializationId = materializationId;
}
}

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.semantic.materialization.domain.dataobject;
public class MaterializationElementDOWithBLOBs extends MaterializationElementDO {
private String depends;
private String description;
public String getDepends() {
return depends;
}
public void setDepends(String depends) {
this.depends = depends == null ? null : depends.trim();
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description == null ? null : description.trim();
}
}

View File

@@ -0,0 +1,168 @@
package com.tencent.supersonic.semantic.materialization.domain.dataobject;
import lombok.Data;
import java.util.Date;
@Data
public class MaterializationRecordDO {
private Long id;
private Long materializationId;
private String elementType;
private Long elementId;
private String elementName;
private String dataTime;
private String state;
private String taskId;
private Date createdAt;
private Date updatedAt;
private String createdBy;
private String updatedBy;
private Long retryCount;
private Long sourceCount;
private Long sinkCount;
private String message;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getMaterializationId() {
return materializationId;
}
public void setMaterializationId(Long materializationId) {
this.materializationId = materializationId;
}
public String getElementType() {
return elementType;
}
public void setElementType(String elementType) {
this.elementType = elementType == null ? null : elementType.trim();
}
public Long getElementId() {
return elementId;
}
public void setElementId(Long elementId) {
this.elementId = elementId;
}
public String getElementName() {
return elementName;
}
public void setElementName(String elementName) {
this.elementName = elementName == null ? null : elementName.trim();
}
public String getDataTime() {
return dataTime;
}
public void setDataTime(String dataTime) {
this.dataTime = dataTime == null ? null : dataTime.trim();
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state == null ? null : state.trim();
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId == null ? null : taskId.trim();
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy == null ? null : createdBy.trim();
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
}
public Long getRetryCount() {
return retryCount;
}
public void setRetryCount(Long retryCount) {
this.retryCount = retryCount;
}
public Long getSourceCount() {
return sourceCount;
}
public void setSourceCount(Long sourceCount) {
this.sourceCount = sourceCount;
}
public Long getSinkCount() {
return sinkCount;
}
public void setSinkCount(Long sinkCount) {
this.sinkCount = sinkCount;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message == null ? null : message.trim();
}
}

View File

@@ -0,0 +1,28 @@
package com.tencent.supersonic.semantic.materialization.domain.pojo;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.MaterializedTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.UpdateCycleEnum;
import lombok.Data;
import java.util.List;
@Data
public class Materialization extends RecordInfo {
private Long id;
private String name;
private MaterializedTypeEnum materializedType;
private UpdateCycleEnum updateCycle;
private Long modelId;
private Long databaseId;
private Integer level;
private String destinationTable;
private String dateInfo;
private String entities;
private List<String> principals;
private String description;
private StatusEnum status = StatusEnum.ONLINE;
}

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.semantic.materialization.domain.pojo;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementFrequencyEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementTypeEnum;
import lombok.Data;
@Data
public class MaterializationElement extends RecordInfo {
private Long id;
private TypeEnums type;
private Long materializationId;
private String depends;
private ElementTypeEnum elementType;
private String defaultValue;
private String outlier;
private ElementFrequencyEnum frequency;
private String description;
private StatusEnum status;
}

View File

@@ -0,0 +1,23 @@
package com.tencent.supersonic.semantic.materialization.domain.pojo;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import lombok.Data;
@Data
public class MaterializationRecord extends RecordInfo {
private Long id;
private Long materializationId;
private TypeEnums elementType;
private Long elementId;
private String elementName;
private String dataTime;
private TaskStatusEnum taskStatus;
private String taskId;
private Long retryCount;
private Long sourceCount;
private Long sinkCount;
private String message;
}

View File

@@ -0,0 +1,17 @@
package com.tencent.supersonic.semantic.materialization.domain.repository;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationConfFilter;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementResp;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationElement;
import java.util.List;
public interface MaterializationElementRepository {
Boolean insert(MaterializationElement materializationElement);
Boolean update(MaterializationElement materializationElement);
List<MaterializationElementResp> getMaterializationElementResp(MaterializationConfFilter filter);
Boolean cleanMaterializationElement(Long materializationId);
}

View File

@@ -0,0 +1,18 @@
package com.tencent.supersonic.semantic.materialization.domain.repository;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationRecordFilter;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationRecordResp;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationRecord;
import java.util.List;
public interface MaterializationRecordRepository {
Boolean insertMaterializationRecord(MaterializationRecord materializationRecord);
Boolean updateMaterializationRecord(MaterializationRecord materializationRecord);
List<MaterializationRecordResp> getMaterializationRecordList(MaterializationRecordFilter filter);
long getCount(MaterializationRecordFilter filter);
}

View File

@@ -0,0 +1,17 @@
package com.tencent.supersonic.semantic.materialization.domain.repository;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationFilter;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import com.tencent.supersonic.semantic.materialization.domain.pojo.Materialization;
import java.util.List;
public interface MaterializationRepository {
Boolean insert(Materialization materialization);
Boolean update(Materialization materialization);
List<MaterializationResp> getMaterializationResp(MaterializationFilter filter);
MaterializationResp getMaterialization(Long id);
}

View File

@@ -0,0 +1,146 @@
package com.tencent.supersonic.semantic.materialization.domain.utils;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.common.util.BeanMapper;
import com.tencent.supersonic.common.util.JsonUtil;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementFrequencyEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.MaterializedTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.UpdateCycleEnum;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationElementReq;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs;
import com.tencent.supersonic.semantic.materialization.domain.pojo.Materialization;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationElement;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Objects;
@Component
public class MaterializationConverter {
public static Materialization materializationReq2Bean(MaterializationReq materializationReq) {
Materialization materialization = new Materialization();
BeanUtils.copyProperties(materializationReq, materialization);
return materialization;
}
public static MaterializationDOWithBLOBs materialization2DO(Materialization materialization) {
MaterializationDOWithBLOBs materializationDOWithBLOBs = new MaterializationDOWithBLOBs();
BeanUtils.copyProperties(materialization, materializationDOWithBLOBs);
if (Objects.nonNull(materialization.getMaterializedType())) {
materializationDOWithBLOBs.setMaterializedType(materialization.getMaterializedType().name());
}
if (Objects.nonNull(materialization.getUpdateCycle())) {
materializationDOWithBLOBs.setUpdateCycle(materialization.getUpdateCycle().name());
}
if (Objects.nonNull(materialization.getStatus())) {
materializationDOWithBLOBs.setStatus(materialization.getStatus().getCode());
}
if (!CollectionUtils.isEmpty(materialization.getPrincipals())) {
materializationDOWithBLOBs.setPrincipals(JsonUtil.toString(materialization.getPrincipals()));
}
return materializationDOWithBLOBs;
}
public static MaterializationElementDOWithBLOBs materialization2DO(MaterializationElement materializationElement) {
MaterializationElementDOWithBLOBs materializationElementDO = new MaterializationElementDOWithBLOBs();
BeanUtils.copyProperties(materializationElement, materializationElementDO);
if (Objects.nonNull(materializationElement.getElementType())) {
materializationElementDO.setElementType(materializationElement.getElementType().name());
}
if (Objects.nonNull(materializationElement.getType())) {
materializationElementDO.setType(materializationElement.getType().getName());
}
if (Objects.nonNull(materializationElement.getStatus())) {
materializationElementDO.setStatus(materializationElement.getStatus().getCode());
}
if (Objects.nonNull(materializationElement.getFrequency())) {
materializationElementDO.setFrequency(materializationElement.getFrequency().name());
}
return materializationElementDO;
}
public static MaterializationDOWithBLOBs convert(MaterializationDOWithBLOBs materializationDO,
Materialization materialization) {
BeanMapper.mapper(materialization, materializationDO);
if (Objects.nonNull(materialization.getMaterializedType())) {
materializationDO.setMaterializedType(materialization.getMaterializedType().name());
}
if (Objects.nonNull(materialization.getUpdateCycle())) {
materializationDO.setUpdateCycle(materialization.getUpdateCycle().name());
}
if (Objects.nonNull(materialization.getStatus())) {
materializationDO.setStatus(materialization.getStatus().getCode());
}
if (!CollectionUtils.isEmpty(materialization.getPrincipals())) {
materializationDO.setPrincipals(JsonUtil.toString(materialization.getPrincipals()));
}
return materializationDO;
}
public static MaterializationElementDOWithBLOBs convert(MaterializationElementDOWithBLOBs materializationElementDO,
MaterializationElement materializationElement) {
BeanMapper.mapper(materializationElement, materializationElementDO);
if (Objects.nonNull(materializationElement.getType())) {
materializationElementDO.setType(materializationElement.getType().name());
}
if (Objects.nonNull(materializationElement.getElementType())) {
materializationElementDO.setElementType(materializationElement.getElementType().name());
}
if (Objects.nonNull(materializationElement.getFrequency())) {
materializationElementDO.setFrequency(materializationElement.getFrequency().name());
}
if (Objects.nonNull(materializationElement.getStatus())) {
materializationElementDO.setStatus(materializationElement.getStatus().getCode());
}
return materializationElementDO;
}
public static MaterializationElement materializationElementReq2Bean(MaterializationElementReq elementReq) {
MaterializationElement materializationElement = new MaterializationElement();
BeanUtils.copyProperties(elementReq, materializationElement);
return materializationElement;
}
public static MaterializationResp convert2Resp(MaterializationDOWithBLOBs materializationDO) {
MaterializationResp materializationResp = new MaterializationResp();
BeanUtils.copyProperties(materializationDO, materializationResp);
if (Strings.isNotEmpty(materializationDO.getMaterializedType())) {
materializationResp.setMaterializedType(Enum.valueOf(MaterializedTypeEnum.class,
materializationDO.getMaterializedType()));
}
if (Strings.isNotEmpty(materializationDO.getUpdateCycle())) {
materializationResp.setUpdateCycle(Enum.valueOf(UpdateCycleEnum.class, materializationDO.getUpdateCycle()));
}
if (Strings.isNotEmpty(materializationDO.getPrincipals())) {
materializationResp.setPrincipals(JsonUtil.toList(materializationDO.getPrincipals(), String.class));
}
return materializationResp;
}
public static MaterializationElementResp elementDO2Resp(MaterializationElementDOWithBLOBs elementDO) {
MaterializationElementResp materializationElementResp = new MaterializationElementResp();
BeanUtils.copyProperties(elementDO, materializationElementResp);
if (Strings.isNotEmpty(elementDO.getType())) {
materializationElementResp.setType(TypeEnums.of(elementDO.getType()));
}
if (Strings.isNotEmpty(elementDO.getElementType())) {
materializationElementResp.setElementType(Enum.valueOf(ElementTypeEnum.class,
elementDO.getElementType()));
}
if (Strings.isNotEmpty(elementDO.getFrequency())) {
materializationElementResp.setFrequency(Enum.valueOf(ElementFrequencyEnum.class,
elementDO.getFrequency()));
}
return materializationElementResp;
}
}

View File

@@ -0,0 +1,78 @@
package com.tencent.supersonic.semantic.materialization.domain.utils;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementFrequencyEnum;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import org.apache.logging.log4j.util.Strings;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.StringJoiner;
public class MaterializationPartitionHelper implements MaterializationUtils {
private String split = "_";
private String createPatter = "CREATE TABLE `#{tableName}` (\n"
+ " `dayno` date NOT NULL COMMENT '日期',\n"
+ " `id` int(11) NOT NULL COMMENT 'id',\n"
+ " #{columnInfo}\n"
+ " ) ENGINE=OLAP\n"
+ "UNIQUE KEY(`dayno`, `id`)\n"
+ "COMMENT 'OLAP'\n"
+ "PARTITION BY RANGE(`dayno`)\n"
+ "(PARTITION p20230820 VALUES [('2023-08-20'), ('2023-08-21')),\n"
+ "PARTITION p20230821 VALUES [('2023-08-21'), ('2023-08-22')),\n"
+ "PARTITION p20230827 VALUES [('2023-08-27'), ('2023-08-28')))\n"
+ "DISTRIBUTED BY HASH(`id`) BUCKETS 36\n"
+ "PROPERTIES (\n"
+ "\"replication_allocation\" = \"tag.location.default: 1\",\n"
+ "\"is_being_synced\" = \"false\",\n"
+ "\"colocate_with\" = \"#{colocateGroup}\",\n"
+ "\"storage_format\" = \"V2\",\n"
+ "\"enable_unique_key_merge_on_write\" = \"true\",\n"
+ "\"light_schema_change\" = \"true\",\n"
+ "\"disable_auto_compaction\" = \"false\",\n"
+ "\"enable_single_replica_compaction\" = \"false\"\n"
+ ")";
@Override
public String generateCreateSql(MaterializationResp materializationResp) {
List<MaterializationElementResp> materializationElementRespList = materializationResp
.getMaterializationElementRespList();
if (CollectionUtils.isEmpty(materializationElementRespList)) {
return "";
}
StringJoiner joiner = new StringJoiner(",");
materializationElementRespList.stream()
.filter(element -> !ElementFrequencyEnum.LOW.equals(element.getFrequency()))
.forEach(element -> {
String type = "double";
if (TypeEnums.DIMENSION.equals(element.getType())) {
type = "varchar(10000)";
}
String description = element.getDescription().replace("'", "").replace("\"", "");
joiner.add(
String.format(" %s %s COMMENT '%s'", element.getBizName(), type, description));
}
);
if (Strings.isEmpty(joiner.toString())) {
return "";
}
String colocateGroup = generateColocateGroup(materializationResp);
return createPatter.replace("#{tableName}", materializationResp.getDestinationTable())
.replace("#{columnInfo}", joiner.toString())
.replace("#{colocateGroup}", colocateGroup);
}
private String generateColocateGroup(MaterializationResp materializationResp) {
String name = materializationResp.getName();
if (Strings.isNotEmpty(name) && name.contains(split)) {
return name.split(split)[0];
}
return "";
}
}

View File

@@ -0,0 +1,57 @@
package com.tencent.supersonic.semantic.materialization.domain.utils;
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.common.util.BeanMapper;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationRecordReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationRecordResp;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationRecord;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import java.util.Objects;
public class MaterializationRecordConverter {
public static MaterializationRecord req2Bean(MaterializationRecordReq materializationRecordReq) {
MaterializationRecord materializationRecord = new MaterializationRecord();
BeanUtils.copyProperties(materializationRecordReq, materializationRecord);
return materializationRecord;
}
public static MaterializationRecordDO materializationRecord2DO(MaterializationRecord materializationRecord) {
MaterializationRecordDO materializationRecordDO = new MaterializationRecordDO();
BeanUtils.copyProperties(materializationRecord, materializationRecordDO);
if (Objects.nonNull(materializationRecord.getElementType())) {
materializationRecordDO.setElementType(materializationRecord.getElementType().name());
}
if (Objects.nonNull(materializationRecord.getTaskStatus())) {
materializationRecordDO.setState(materializationRecord.getTaskStatus().name());
}
return materializationRecordDO;
}
public static MaterializationRecordDO convert(MaterializationRecordDO materializationRecordDO,
MaterializationRecord materializationRecord) {
BeanMapper.mapper(materializationRecord, materializationRecordDO);
if (Objects.nonNull(materializationRecord.getElementType())) {
materializationRecordDO.setElementType(materializationRecord.getElementType().name());
}
if (Objects.nonNull(materializationRecord.getTaskStatus())) {
materializationRecordDO.setState(materializationRecord.getTaskStatus().name());
}
return materializationRecordDO;
}
public static MaterializationRecordResp materializationRecordDO2Resp(MaterializationRecordDO recordDO) {
MaterializationRecordResp materializationRecordResp = new MaterializationRecordResp();
BeanUtils.copyProperties(recordDO, materializationRecordResp);
if (Strings.isNotEmpty(recordDO.getElementType())) {
materializationRecordResp.setElementType(TypeEnums.of(recordDO.getElementType()));
}
if (Strings.isNotEmpty(recordDO.getState())) {
materializationRecordResp.setTaskStatus(TaskStatusEnum.of(recordDO.getState()));
}
return materializationRecordResp;
}
}

View File

@@ -0,0 +1,8 @@
package com.tencent.supersonic.semantic.materialization.domain.utils;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
public interface MaterializationUtils {
String generateCreateSql(MaterializationResp materializationResp);
}

View File

@@ -0,0 +1,85 @@
package com.tencent.supersonic.semantic.materialization.domain.utils;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementFrequencyEnum;
import com.tencent.supersonic.semantic.api.materialization.enums.ElementTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
@Component
public class MaterializationZipperUtils implements MaterializationUtils {
private String split = "_";
private String createPatter = "CREATE TABLE IF NOT EXISTS `#{tableName}` (\n"
+ " `end_date` date NOT NULL COMMENT '日期',\n"
+ " `id` int(11) NOT NULL COMMENT 'id',\n"
+ " `start_date` date NULL,\n"
+ " #{columnInfo}\n"
+ " ) ENGINE=OLAP\n"
+ "UNIQUE KEY(`end_date`, `id`)\n"
+ "COMMENT 'OLAP'\n"
+ "PARTITION BY RANGE(`end_date`)\n"
+ "(PARTITION p99991230 VALUES [('9999-12-30'), ('9999-12-31')))\n"
+ "DISTRIBUTED BY HASH(`id`) BUCKETS 9\n"
+ "PROPERTIES (\n"
+ "\"replication_allocation\" = \"tag.location.default: 1\",\n"
+ "\"is_being_synced\" = \"false\",\n"
+ "\"colocate_with\" = \"#{colocateGroup}\",\n"
+ "\"storage_format\" = \"V2\",\n"
+ "\"enable_unique_key_merge_on_write\" = \"true\",\n"
+ "\"light_schema_change\" = \"true\",\n"
+ "\"disable_auto_compaction\" = \"false\",\n"
+ "\"enable_single_replica_compaction\" = \"false\"\n"
+ ");";
@Override
public String generateCreateSql(MaterializationResp materializationResp) {
List<MaterializationElementResp> materializationElementRespList = materializationResp
.getMaterializationElementRespList();
if (CollectionUtils.isEmpty(materializationElementRespList)) {
return "";
}
StringJoiner joiner = new StringJoiner(",");
materializationElementRespList.stream()
.filter(element -> TypeEnums.DIMENSION.equals(element.getType()) && ElementFrequencyEnum.LOW.equals(
element.getFrequency()))
.forEach(element -> {
String type = "varchar(10000)";
if (Objects.nonNull(element.getElementType()) && ElementTypeEnum.DATE.equals(
element.getElementType())) {
type = "date";
}
String description = element.getDescription().replace("'", "").replace("\"", "");
joiner.add(
String.format(" %s %s COMMENT '%s'",
element.getBizName(), type, description));
}
);
if (Strings.isEmpty(joiner.toString())) {
return "";
}
String colocateGroup = generateColocateGroup(materializationResp);
return createPatter.replace("#{tableName}", materializationResp.getDestinationTable())
.replace("#{columnInfo}", joiner.toString())
.replace("#{colocateGroup}", colocateGroup);
}
private String generateColocateGroup(MaterializationResp materializationResp) {
String name = materializationResp.getName();
if (Strings.isNotEmpty(name) && name.contains(split)) {
return name.split(split)[0];
}
return "";
}
}

View File

@@ -0,0 +1,13 @@
package com.tencent.supersonic.semantic.materialization.infrastructure.mapper;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationFilter;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface MaterializationDOCustomMapper {
List<MaterializationDOWithBLOBs> getMaterializationResp(MaterializationFilter filter);
}

View File

@@ -0,0 +1,31 @@
package com.tencent.supersonic.semantic.materialization.infrastructure.mapper;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDO;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOExample;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface MaterializationDOMapper {
long countByExample(MaterializationDOExample example);
int deleteByPrimaryKey(Long id);
int insert(MaterializationDOWithBLOBs record);
int insertSelective(MaterializationDOWithBLOBs record);
List<MaterializationDOWithBLOBs> selectByExampleWithBLOBs(MaterializationDOExample example);
List<MaterializationDO> selectByExample(MaterializationDOExample example);
MaterializationDOWithBLOBs selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(MaterializationDOWithBLOBs record);
int updateByPrimaryKeyWithBLOBs(MaterializationDOWithBLOBs record);
int updateByPrimaryKey(MaterializationDO record);
}

View File

@@ -0,0 +1,35 @@
package com.tencent.supersonic.semantic.materialization.infrastructure.mapper;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDO;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOExample;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOKey;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface MaterializationElementDOMapper {
long countByExample(MaterializationElementDOExample example);
int deleteByPrimaryKey(MaterializationElementDOKey key);
int insert(MaterializationElementDOWithBLOBs record);
int insertSelective(MaterializationElementDOWithBLOBs record);
List<MaterializationElementDOWithBLOBs> selectByExampleWithBLOBs(MaterializationElementDOExample example);
List<MaterializationElementDO> selectByExample(MaterializationElementDOExample example);
MaterializationElementDOWithBLOBs selectByPrimaryKey(MaterializationElementDOKey key);
int updateByPrimaryKeySelective(MaterializationElementDOWithBLOBs record);
int updateByPrimaryKeyWithBLOBs(MaterializationElementDOWithBLOBs record);
int updateByPrimaryKey(MaterializationElementDO record);
Boolean cleanMaterializationElement(Long materializationId);
}

View File

@@ -0,0 +1,33 @@
package com.tencent.supersonic.semantic.materialization.infrastructure.mapper;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDOExample;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface MaterializationRecordDOMapper {
long countByExample(MaterializationRecordDOExample example);
int deleteByPrimaryKey(Long id);
int insert(MaterializationRecordDO record);
int insertSelective(MaterializationRecordDO record);
List<MaterializationRecordDO> selectByExampleWithBLOBs(MaterializationRecordDOExample example);
List<MaterializationRecordDO> selectByExample(MaterializationRecordDOExample example);
MaterializationRecordDO selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(MaterializationRecordDO record);
int updateByPrimaryKeyWithBLOBs(MaterializationRecordDO record);
int updateByBizName(MaterializationRecordDO record);
int updateByPrimaryKey(MaterializationRecordDO record);
}

View File

@@ -0,0 +1,82 @@
package com.tencent.supersonic.semantic.materialization.infrastructure.repository;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationConfFilter;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationElementResp;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOExample;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOKey;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationElement;
import com.tencent.supersonic.semantic.materialization.domain.repository.MaterializationElementRepository;
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationConverter;
import com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationElementDOMapper;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Component
public class MaterializationElementRepositoryImpl implements MaterializationElementRepository {
private final MaterializationElementDOMapper materializationElementDOMapper;
public MaterializationElementRepositoryImpl(MaterializationElementDOMapper materializationElementDOMapper) {
this.materializationElementDOMapper = materializationElementDOMapper;
}
@Override
public Boolean insert(MaterializationElement materializationElement) {
MaterializationElementDOWithBLOBs materializationElementDOWithBLOBs = MaterializationConverter
.materialization2DO(materializationElement);
materializationElementDOMapper.insert(materializationElementDOWithBLOBs);
return true;
}
@Override
public Boolean update(MaterializationElement materializationElement) {
MaterializationElementDOKey key = new MaterializationElementDOKey();
key.setId(materializationElement.getId());
if (Objects.nonNull(materializationElement.getType())) {
key.setType(materializationElement.getType().getName());
}
if (Objects.nonNull(materializationElement.getMaterializationId())) {
key.setMaterializationId(materializationElement.getMaterializationId());
}
MaterializationElementDOWithBLOBs materializationElementDO = materializationElementDOMapper
.selectByPrimaryKey(key);
MaterializationConverter.convert(materializationElementDO, materializationElement);
materializationElementDOMapper.updateByPrimaryKeyWithBLOBs(MaterializationConverter
.convert(materializationElementDO, materializationElement));
return true;
}
@Override
public List<MaterializationElementResp> getMaterializationElementResp(MaterializationConfFilter filter) {
List<MaterializationElementResp> materializationElementRespList = new ArrayList<>();
MaterializationElementDOExample example = new MaterializationElementDOExample();
MaterializationElementDOExample.Criteria criteria = example.createCriteria();
if (Objects.nonNull(filter.getType())) {
criteria.andTypeEqualTo(filter.getType().getName());
}
if (Objects.nonNull(filter.getMaterializationId())) {
criteria.andMaterializationIdEqualTo(filter.getMaterializationId());
}
if (Objects.nonNull(filter.getElementId())) {
criteria.andIdEqualTo(filter.getElementId());
}
List<MaterializationElementDOWithBLOBs> materializationElementDOs = materializationElementDOMapper
.selectByExampleWithBLOBs(example);
if (!CollectionUtils.isEmpty(materializationElementDOs)) {
materializationElementDOs.stream().forEach(materializationElementDO -> {
materializationElementRespList.add(MaterializationConverter.elementDO2Resp(materializationElementDO));
});
}
return materializationElementRespList;
}
@Override
public Boolean cleanMaterializationElement(Long materializationId) {
return materializationElementDOMapper.cleanMaterializationElement(materializationId);
}
}

View File

@@ -0,0 +1,113 @@
package com.tencent.supersonic.semantic.materialization.infrastructure.repository;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationRecordFilter;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationRecordResp;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDOExample;
import com.tencent.supersonic.semantic.materialization.domain.pojo.MaterializationRecord;
import com.tencent.supersonic.semantic.materialization.domain.repository.MaterializationRecordRepository;
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationRecordConverter;
import com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationRecordDOMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Component
public class MaterializationRecordRepositoryImpl implements MaterializationRecordRepository {
private final MaterializationRecordDOMapper mapper;
public MaterializationRecordRepositoryImpl(MaterializationRecordDOMapper mapper) {
this.mapper = mapper;
}
@Override
public Boolean insertMaterializationRecord(MaterializationRecord materializationRecord) {
MaterializationRecordDO materializationRecordDO = MaterializationRecordConverter
.materializationRecord2DO(materializationRecord);
mapper.insert(materializationRecordDO);
return true;
}
@Override
public Boolean updateMaterializationRecord(MaterializationRecord materializationRecord) {
MaterializationRecordDO materializationRecordDO = mapper.selectByPrimaryKey(materializationRecord.getId());
if (Objects.nonNull(materializationRecordDO)) {
MaterializationRecordConverter.convert(materializationRecordDO, materializationRecord);
} else {
materializationRecordDO = MaterializationRecordConverter.materializationRecord2DO(materializationRecord);
}
if (Objects.isNull(materializationRecord.getId())) {
mapper.updateByBizName(materializationRecordDO);
} else {
mapper.updateByPrimaryKey(materializationRecordDO);
}
return true;
}
@Override
public List<MaterializationRecordResp> getMaterializationRecordList(MaterializationRecordFilter filter) {
List<MaterializationRecordResp> materializationRecordRespList = new ArrayList<>();
MaterializationRecordDOExample example = getExample(filter);
List<MaterializationRecordDO> materializationRecordDOS = mapper.selectByExampleWithBLOBs(example);
if (!CollectionUtils.isEmpty(materializationRecordDOS)) {
materializationRecordDOS.stream().forEach(recordDO -> materializationRecordRespList.add(
MaterializationRecordConverter.materializationRecordDO2Resp(recordDO)));
}
return materializationRecordRespList;
}
@Override
public long getCount(MaterializationRecordFilter filter) {
MaterializationRecordDOExample example = getExample(filter);
return mapper.countByExample(example);
}
private MaterializationRecordDOExample getExample(MaterializationRecordFilter filter) {
MaterializationRecordDOExample example = new MaterializationRecordDOExample();
MaterializationRecordDOExample.Criteria criteria = example.createCriteria();
if (Objects.nonNull(filter.getId())) {
criteria.andIdEqualTo(filter.getId());
}
if (Objects.nonNull(filter.getMaterializationId())) {
criteria.andMaterializationIdEqualTo(filter.getMaterializationId());
}
if (!CollectionUtils.isEmpty(filter.getMaterializationIds())) {
criteria.andMaterializationIdIn(filter.getMaterializationIds());
}
if (Objects.nonNull(filter.getElementType())) {
criteria.andElementTypeEqualTo(filter.getElementType().getName());
}
if (Objects.nonNull(filter.getElementId())) {
criteria.andElementIdEqualTo(filter.getElementId());
}
if (Objects.nonNull(filter.getElementName())) {
criteria.andElementNameEqualTo(filter.getElementName());
}
if (Objects.nonNull(filter.getTaskStatus())) {
criteria.andStateIn(filter.getTaskStatus().stream().map(s -> s.getStatus()).collect(Collectors.toList()));
}
if (Objects.nonNull(filter.getTaskId())) {
criteria.andTaskIdEqualTo(filter.getTaskId());
}
if (Objects.nonNull(filter.getCreatedBy())) {
criteria.andCreatedByEqualTo(filter.getCreatedBy());
}
if (Objects.nonNull(filter.getCreatedAt())) {
criteria.andCreatedAtGreaterThanOrEqualTo(filter.getCreatedAt());
}
if (Objects.nonNull(filter.getStartDataTime())) {
criteria.andDataTimeGreaterThanOrEqualTo(filter.getStartDataTime());
}
if (Objects.nonNull(filter.getEndDataTime())) {
criteria.andDataTimeLessThanOrEqualTo(filter.getEndDataTime());
}
return example;
}
}

View File

@@ -0,0 +1,63 @@
package com.tencent.supersonic.semantic.materialization.infrastructure.repository;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationFilter;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs;
import com.tencent.supersonic.semantic.materialization.domain.pojo.Materialization;
import com.tencent.supersonic.semantic.materialization.domain.repository.MaterializationRepository;
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationConverter;
import com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationDOCustomMapper;
import com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationDOMapper;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
@Component
public class MaterializationRepositoryImpl implements MaterializationRepository {
private final MaterializationDOMapper materializationDOMapper;
private final MaterializationDOCustomMapper materializationDOCustomMapper;
public MaterializationRepositoryImpl(MaterializationDOMapper materializationDOMapper,
MaterializationDOCustomMapper materializationDOCustomMapper) {
this.materializationDOMapper = materializationDOMapper;
this.materializationDOCustomMapper = materializationDOCustomMapper;
}
@Override
public Boolean insert(Materialization materialization) {
MaterializationDOWithBLOBs materializationDOWithBLOBs = MaterializationConverter
.materialization2DO(materialization);
materializationDOMapper.insert(materializationDOWithBLOBs);
return true;
}
@Override
public Boolean update(Materialization materialization) {
MaterializationDOWithBLOBs materializationDOWithBLOBs = materializationDOMapper
.selectByPrimaryKey(materialization.getId());
materializationDOMapper.updateByPrimaryKeyWithBLOBs(MaterializationConverter
.convert(materializationDOWithBLOBs, materialization));
return true;
}
@Override
public List<MaterializationResp> getMaterializationResp(MaterializationFilter filter) {
List<MaterializationResp> materializationRespList = new ArrayList<>();
List<MaterializationDOWithBLOBs> materializationDOWithBLOBsList = materializationDOCustomMapper
.getMaterializationResp(filter);
if (!CollectionUtils.isEmpty(materializationDOWithBLOBsList)) {
materializationDOWithBLOBsList.stream().forEach(materializationDO -> {
materializationRespList.add(MaterializationConverter.convert2Resp(materializationDO));
});
}
return materializationRespList;
}
@Override
public MaterializationResp getMaterialization(Long id) {
return MaterializationConverter.convert2Resp(materializationDOMapper.selectByPrimaryKey(id));
}
}

View File

@@ -0,0 +1,111 @@
package com.tencent.supersonic.semantic.materialization.rest;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationConfFilter;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationFilter;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationElementReq;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationSourceResp;
import com.tencent.supersonic.semantic.materialization.domain.MaterializationConfService;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/semantic/materialization/conf")
public class MaterializationConfController {
private final MaterializationConfService confService;
public MaterializationConfController(MaterializationConfService confService) {
this.confService = confService;
}
@PostMapping
public Boolean addMaterializationConf(@RequestBody MaterializationReq materializationReq,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.addMaterializationConf(materializationReq, user);
}
@PutMapping
public Boolean updateMaterializationConf(@RequestBody MaterializationReq materializationReq,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.updateMaterializationConf(materializationReq, user);
}
@PostMapping("/info")
List<MaterializationResp> getMaterializationResp(@RequestBody MaterializationFilter filter,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.getMaterializationResp(filter, user);
}
@PostMapping("/element")
public Boolean addMaterializationElementConf(@RequestBody MaterializationElementReq materializationElementReq,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.addMaterializationElementConf(materializationElementReq, user);
}
@PutMapping("/element")
public Boolean updateMaterializationElementConf(@RequestBody MaterializationElementReq materializationElementReq,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.updateMaterializationElementConf(materializationElementReq, user);
}
@PutMapping("/element/init")
public Boolean initMaterializationElementConf(@RequestBody MaterializationConfFilter filter,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.initMaterializationElementConf(filter, user);
}
@PostMapping("/element/info")
List<MaterializationResp> queryMaterializationConf(@RequestBody MaterializationConfFilter filter,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.queryMaterializationConf(filter, user);
}
@GetMapping("/table/sql")
String generateCreateSql(@RequestParam(value = "materializationId") Long materializationId,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return confService.generateCreateSql(materializationId, user);
}
@PostMapping("/source")
List<MaterializationSourceResp> queryElementModel(@RequestBody MaterializationFilter filter,
HttpServletRequest request,
HttpServletResponse response) {
//User user = UserHolder.findUser(request, response);
return confService.getMaterializationSourceResp(filter.getMaterializationId());
}
}

View File

@@ -0,0 +1,76 @@
package com.tencent.supersonic.semantic.materialization.rest;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationDateFilter;
import com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationRecordFilter;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationRecordReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationDateResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationRecordResp;
import com.tencent.supersonic.semantic.materialization.domain.MaterializationRecordService;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PutMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@RestController
@RequestMapping("/api/semantic/materialization/record")
public class MaterializationRecordController {
private final MaterializationRecordService recordService;
public MaterializationRecordController(MaterializationRecordService recordService) {
this.recordService = recordService;
}
@PostMapping
public Boolean addMaterializationRecord(@RequestBody MaterializationRecordReq materializationRecord,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return recordService.addMaterializationRecord(materializationRecord, user);
}
@PutMapping
public Boolean updateMaterializationRecord(@RequestBody MaterializationRecordReq materializationRecord,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return recordService.updateMaterializationRecord(materializationRecord, user);
}
@PostMapping("/info")
List<MaterializationRecordResp> getMaterializationRecordList(@RequestBody MaterializationRecordFilter filter,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return recordService.getMaterializationRecordList(filter, user);
}
@PostMapping("/count")
Long getMaterializationRecordCount(@RequestBody MaterializationRecordFilter filter,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return recordService.getMaterializationRecordCount(filter, user);
}
@PostMapping("/info/date")
List<MaterializationDateResp> fetchMaterializationDate(@RequestBody MaterializationDateFilter filter,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return recordService.fetchMaterializationDate(filter, user);
}
}

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationDOCustomMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="materialized_type" jdbcType="VARCHAR" property="materializedType" />
<result column="update_cycle" jdbcType="VARCHAR" property="updateCycle" />
<result column="model_id" jdbcType="BIGINT" property="modelId" />
<result column="database_id" jdbcType="BIGINT" property="databaseId" />
<result column="level" jdbcType="INTEGER" property="level" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="destination_table" jdbcType="VARCHAR" property="destinationTable" />
<result column="principals" jdbcType="VARCHAR" property="principals" />
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs">
<result column="date_info" jdbcType="LONGVARCHAR" property="dateInfo" />
<result column="entities" jdbcType="LONGVARCHAR" property="entities" />
<result column="description" jdbcType="LONGVARCHAR" property="description" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, name, materialized_type, update_cycle, model_id, database_id, level, status,
destination_table, principals, created_at, created_by, updated_at, updated_by
</sql>
<sql id="Blob_Column_List">
date_info, entities, description
</sql>
<select id="getMaterializationResp" parameterType="com.tencent.supersonic.semantic.api.materialization.pojo.MaterializationFilter" resultMap="ResultMapWithBLOBs">
select *
from s2_materialization
<where>
<if test="materializationId != null">
and `id` = #{materializationId}
</if>
<if test="name != null and name != ''">
and `name` = #{name}
</if>
<if test="materializedType != null">
and `materialized_type` = #{materializedType.name()}
</if>
<if test="updateCycle != null">
and update_cycle = #{updateCycle.name()}
</if>
<if test="modelId != null and modelId !=''">
and model_id = #{modelId}
</if>
<if test="databaseId != null and databaseId !=''">
and database_id= #{databaseId}
</if>
<if test="level != null and level !=''">
and level= #{level}
</if>
<if test="createdBy != null and createdBy !=''">
and created_by = #{createdBy}
</if>
<if test="destinationTable != null and destinationTable !=''">
and destination_table = #{destinationTable}
</if>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,324 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationDOMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="materialized_type" jdbcType="VARCHAR" property="materializedType" />
<result column="update_cycle" jdbcType="VARCHAR" property="updateCycle" />
<result column="model_id" jdbcType="BIGINT" property="modelId" />
<result column="database_id" jdbcType="BIGINT" property="databaseId" />
<result column="level" jdbcType="INTEGER" property="level" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="destination_table" jdbcType="VARCHAR" property="destinationTable" />
<result column="principals" jdbcType="VARCHAR" property="principals" />
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs">
<result column="date_info" jdbcType="LONGVARCHAR" property="dateInfo" />
<result column="entities" jdbcType="LONGVARCHAR" property="entities" />
<result column="description" jdbcType="LONGVARCHAR" property="description" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, name, materialized_type, update_cycle, model_id, database_id, level, status,
destination_table, principals, created_at, created_by, updated_at, updated_by
</sql>
<sql id="Blob_Column_List">
date_info, entities, description
</sql>
<select id="selectByExampleWithBLOBs" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOExample" resultMap="ResultMapWithBLOBs">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from s2_materialization
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByExample" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from s2_materialization
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from s2_materialization
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from s2_materialization
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs">
insert into s2_materialization (id, name, materialized_type,
update_cycle, model_id, database_id,
level, status, destination_table,
principals, created_at, created_by,
updated_at, updated_by, date_info,
entities, description)
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{materializedType,jdbcType=VARCHAR},
#{updateCycle,jdbcType=VARCHAR}, #{modelId,jdbcType=BIGINT}, #{databaseId,jdbcType=BIGINT},
#{level,jdbcType=INTEGER}, #{status,jdbcType=INTEGER}, #{destinationTable,jdbcType=VARCHAR},
#{principals,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{createdBy,jdbcType=VARCHAR},
#{updatedAt,jdbcType=TIMESTAMP}, #{updatedBy,jdbcType=VARCHAR}, #{dateInfo,jdbcType=LONGVARCHAR},
#{entities,jdbcType=LONGVARCHAR}, #{description,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs">
insert into s2_materialization
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
<if test="materializedType != null">
materialized_type,
</if>
<if test="updateCycle != null">
update_cycle,
</if>
<if test="modelId != null">
model_id,
</if>
<if test="databaseId != null">
database_id,
</if>
<if test="level != null">
level,
</if>
<if test="status != null">
status,
</if>
<if test="destinationTable != null">
destination_table,
</if>
<if test="principals != null">
principals,
</if>
<if test="createdAt != null">
created_at,
</if>
<if test="createdBy != null">
created_by,
</if>
<if test="updatedAt != null">
updated_at,
</if>
<if test="updatedBy != null">
updated_by,
</if>
<if test="dateInfo != null">
date_info,
</if>
<if test="entities != null">
entities,
</if>
<if test="description != null">
description,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="materializedType != null">
#{materializedType,jdbcType=VARCHAR},
</if>
<if test="updateCycle != null">
#{updateCycle,jdbcType=VARCHAR},
</if>
<if test="modelId != null">
#{modelId,jdbcType=BIGINT},
</if>
<if test="databaseId != null">
#{databaseId,jdbcType=BIGINT},
</if>
<if test="level != null">
#{level,jdbcType=INTEGER},
</if>
<if test="status != null">
#{status,jdbcType=INTEGER},
</if>
<if test="destinationTable != null">
#{destinationTable,jdbcType=VARCHAR},
</if>
<if test="principals != null">
#{principals,jdbcType=VARCHAR},
</if>
<if test="createdAt != null">
#{createdAt,jdbcType=TIMESTAMP},
</if>
<if test="createdBy != null">
#{createdBy,jdbcType=VARCHAR},
</if>
<if test="updatedAt != null">
#{updatedAt,jdbcType=TIMESTAMP},
</if>
<if test="updatedBy != null">
#{updatedBy,jdbcType=VARCHAR},
</if>
<if test="dateInfo != null">
#{dateInfo,jdbcType=LONGVARCHAR},
</if>
<if test="entities != null">
#{entities,jdbcType=LONGVARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOExample" resultType="java.lang.Long">
select count(*) from s2_materialization
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs">
update s2_materialization
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="materializedType != null">
materialized_type = #{materializedType,jdbcType=VARCHAR},
</if>
<if test="updateCycle != null">
update_cycle = #{updateCycle,jdbcType=VARCHAR},
</if>
<if test="modelId != null">
model_id = #{modelId,jdbcType=BIGINT},
</if>
<if test="databaseId != null">
database_id = #{databaseId,jdbcType=BIGINT},
</if>
<if test="level != null">
level = #{level,jdbcType=INTEGER},
</if>
<if test="status != null">
status = #{status,jdbcType=INTEGER},
</if>
<if test="destinationTable != null">
destination_table = #{destinationTable,jdbcType=VARCHAR},
</if>
<if test="principals != null">
principals = #{principals,jdbcType=VARCHAR},
</if>
<if test="createdAt != null">
created_at = #{createdAt,jdbcType=TIMESTAMP},
</if>
<if test="createdBy != null">
created_by = #{createdBy,jdbcType=VARCHAR},
</if>
<if test="updatedAt != null">
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
</if>
<if test="updatedBy != null">
updated_by = #{updatedBy,jdbcType=VARCHAR},
</if>
<if test="dateInfo != null">
date_info = #{dateInfo,jdbcType=LONGVARCHAR},
</if>
<if test="entities != null">
entities = #{entities,jdbcType=LONGVARCHAR},
</if>
<if test="description != null">
description = #{description,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDOWithBLOBs">
update s2_materialization
set name = #{name,jdbcType=VARCHAR},
materialized_type = #{materializedType,jdbcType=VARCHAR},
update_cycle = #{updateCycle,jdbcType=VARCHAR},
model_id = #{modelId,jdbcType=BIGINT},
database_id = #{databaseId,jdbcType=BIGINT},
level = #{level,jdbcType=INTEGER},
status = #{status,jdbcType=INTEGER},
destination_table = #{destinationTable,jdbcType=VARCHAR},
principals = #{principals,jdbcType=VARCHAR},
created_at = #{createdAt,jdbcType=TIMESTAMP},
created_by = #{createdBy,jdbcType=VARCHAR},
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
updated_by = #{updatedBy,jdbcType=VARCHAR},
date_info = #{dateInfo,jdbcType=LONGVARCHAR},
entities = #{entities,jdbcType=LONGVARCHAR},
description = #{description,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationDO">
update s2_materialization
set name = #{name,jdbcType=VARCHAR},
materialized_type = #{materializedType,jdbcType=VARCHAR},
update_cycle = #{updateCycle,jdbcType=VARCHAR},
model_id = #{modelId,jdbcType=BIGINT},
database_id = #{databaseId,jdbcType=BIGINT},
level = #{level,jdbcType=INTEGER},
status = #{status,jdbcType=INTEGER},
destination_table = #{destinationTable,jdbcType=VARCHAR},
principals = #{principals,jdbcType=VARCHAR},
created_at = #{createdAt,jdbcType=TIMESTAMP},
created_by = #{createdBy,jdbcType=VARCHAR},
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
updated_by = #{updatedBy,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>

View File

@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationElementDOMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDO">
<id column="id" jdbcType="BIGINT" property="id" />
<id column="type" jdbcType="VARCHAR" property="type" />
<id column="materialization_id" jdbcType="BIGINT" property="materializationId" />
<result column="element_type" jdbcType="VARCHAR" property="elementType" />
<result column="default_value" jdbcType="VARCHAR" property="defaultValue" />
<result column="outlier" jdbcType="VARCHAR" property="outlier" />
<result column="frequency" jdbcType="VARCHAR" property="frequency" />
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
<result column="status" jdbcType="INTEGER" property="status" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs">
<result column="depends" jdbcType="LONGVARCHAR" property="depends" />
<result column="description" jdbcType="LONGVARCHAR" property="description" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, type, materialization_id, element_type, default_value, outlier, frequency, created_at,
created_by, updated_at, updated_by, status
</sql>
<sql id="Blob_Column_List">
depends, description
</sql>
<select id="selectByExampleWithBLOBs" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOExample" resultMap="ResultMapWithBLOBs">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from s2_materialization_element
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByExample" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from s2_materialization_element
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOKey" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from s2_materialization_element
where id = #{id,jdbcType=BIGINT}
and type = #{type,jdbcType=VARCHAR}
and materialization_id = #{materializationId,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOKey">
delete from s2_materialization_element
where id = #{id,jdbcType=BIGINT}
and type = #{type,jdbcType=VARCHAR}
and materialization_id = #{materializationId,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs">
insert into s2_materialization_element (id, type, materialization_id,
element_type, default_value, outlier,
frequency, created_at, created_by,
updated_at, updated_by, status,
depends, description)
values (#{id,jdbcType=BIGINT}, #{type,jdbcType=VARCHAR}, #{materializationId,jdbcType=BIGINT},
#{elementType,jdbcType=VARCHAR}, #{defaultValue,jdbcType=VARCHAR}, #{outlier,jdbcType=VARCHAR},
#{frequency,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{createdBy,jdbcType=VARCHAR},
#{updatedAt,jdbcType=TIMESTAMP}, #{updatedBy,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER},
#{depends,jdbcType=LONGVARCHAR}, #{description,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs">
insert into s2_materialization_element
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="type != null">
type,
</if>
<if test="materializationId != null">
materialization_id,
</if>
<if test="elementType != null">
element_type,
</if>
<if test="defaultValue != null">
default_value,
</if>
<if test="outlier != null">
outlier,
</if>
<if test="frequency != null">
frequency,
</if>
<if test="createdAt != null">
created_at,
</if>
<if test="createdBy != null">
created_by,
</if>
<if test="updatedAt != null">
updated_at,
</if>
<if test="updatedBy != null">
updated_by,
</if>
<if test="status != null">
status,
</if>
<if test="depends != null">
depends,
</if>
<if test="description != null">
description,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="type != null">
#{type,jdbcType=VARCHAR},
</if>
<if test="materializationId != null">
#{materializationId,jdbcType=BIGINT},
</if>
<if test="elementType != null">
#{elementType,jdbcType=VARCHAR},
</if>
<if test="defaultValue != null">
#{defaultValue,jdbcType=VARCHAR},
</if>
<if test="outlier != null">
#{outlier,jdbcType=VARCHAR},
</if>
<if test="frequency != null">
#{frequency,jdbcType=VARCHAR},
</if>
<if test="createdAt != null">
#{createdAt,jdbcType=TIMESTAMP},
</if>
<if test="createdBy != null">
#{createdBy,jdbcType=VARCHAR},
</if>
<if test="updatedAt != null">
#{updatedAt,jdbcType=TIMESTAMP},
</if>
<if test="updatedBy != null">
#{updatedBy,jdbcType=VARCHAR},
</if>
<if test="status != null">
#{status,jdbcType=INTEGER},
</if>
<if test="depends != null">
#{depends,jdbcType=LONGVARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOExample" resultType="java.lang.Long">
select count(*) from s2_materialization_element
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs">
update s2_materialization_element
<set>
<if test="elementType != null">
element_type = #{elementType,jdbcType=VARCHAR},
</if>
<if test="defaultValue != null">
default_value = #{defaultValue,jdbcType=VARCHAR},
</if>
<if test="outlier != null">
outlier = #{outlier,jdbcType=VARCHAR},
</if>
<if test="frequency != null">
frequency = #{frequency,jdbcType=VARCHAR},
</if>
<if test="createdAt != null">
created_at = #{createdAt,jdbcType=TIMESTAMP},
</if>
<if test="createdBy != null">
created_by = #{createdBy,jdbcType=VARCHAR},
</if>
<if test="updatedAt != null">
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
</if>
<if test="updatedBy != null">
updated_by = #{updatedBy,jdbcType=VARCHAR},
</if>
<if test="status != null">
status = #{status,jdbcType=INTEGER},
</if>
<if test="depends != null">
depends = #{depends,jdbcType=LONGVARCHAR},
</if>
<if test="description != null">
description = #{description,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
and type = #{type,jdbcType=VARCHAR}
and materialization_id = #{materializationId,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDOWithBLOBs">
update s2_materialization_element
set element_type = #{elementType,jdbcType=VARCHAR},
default_value = #{defaultValue,jdbcType=VARCHAR},
outlier = #{outlier,jdbcType=VARCHAR},
frequency = #{frequency,jdbcType=VARCHAR},
created_at = #{createdAt,jdbcType=TIMESTAMP},
created_by = #{createdBy,jdbcType=VARCHAR},
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
updated_by = #{updatedBy,jdbcType=VARCHAR},
status = #{status,jdbcType=INTEGER},
depends = #{depends,jdbcType=LONGVARCHAR},
description = #{description,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=BIGINT}
and type = #{type,jdbcType=VARCHAR}
and materialization_id = #{materializationId,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationElementDO">
update s2_materialization_element
set element_type = #{elementType,jdbcType=VARCHAR},
default_value = #{defaultValue,jdbcType=VARCHAR},
outlier = #{outlier,jdbcType=VARCHAR},
frequency = #{frequency,jdbcType=VARCHAR},
created_at = #{createdAt,jdbcType=TIMESTAMP},
created_by = #{createdBy,jdbcType=VARCHAR},
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
updated_by = #{updatedBy,jdbcType=VARCHAR},
status = #{status,jdbcType=INTEGER}
where id = #{id,jdbcType=BIGINT}
and type = #{type,jdbcType=VARCHAR}
and materialization_id = #{materializationId,jdbcType=BIGINT}
</update>
<update id="cleanMaterializationElement">
delete from s2_materialization_element
where materialization_id = #{materializationId}
</update>
</mapper>

View File

@@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tencent.supersonic.semantic.materialization.infrastructure.mapper.MaterializationRecordDOMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="materialization_id" jdbcType="BIGINT" property="materializationId" />
<result column="element_type" jdbcType="VARCHAR" property="elementType" />
<result column="element_id" jdbcType="BIGINT" property="elementId" />
<result column="element_name" jdbcType="VARCHAR" property="elementName" />
<result column="data_time" jdbcType="VARCHAR" property="dataTime" />
<result column="state" jdbcType="VARCHAR" property="state" />
<result column="task_id" jdbcType="VARCHAR" property="taskId" />
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
<result column="retry_count" jdbcType="BIGINT" property="retryCount" />
<result column="source_count" jdbcType="BIGINT" property="sourceCount" />
<result column="sink_count" jdbcType="BIGINT" property="sinkCount" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
<result column="message" jdbcType="LONGVARCHAR" property="message" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, materialization_id, element_type, element_id, element_name, data_time, state,
task_id, created_at, updated_at, created_by, updated_by, retry_count, source_count,
sink_count
</sql>
<sql id="Blob_Column_List">
message
</sql>
<select id="selectByExampleWithBLOBs" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDOExample" resultMap="ResultMapWithBLOBs">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from s2_materialization_record
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByExample" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDOExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from s2_materialization_record
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from s2_materialization_record
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from s2_materialization_record
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
insert into s2_materialization_record (id, materialization_id, element_type,
element_id, element_name, data_time,
state, task_id, created_at,
updated_at, created_by, updated_by,
retry_count, source_count, sink_count,
message)
values (#{id,jdbcType=BIGINT}, #{materializationId,jdbcType=BIGINT}, #{elementType,jdbcType=VARCHAR},
#{elementId,jdbcType=BIGINT}, #{elementName,jdbcType=VARCHAR}, #{dataTime,jdbcType=VARCHAR},
#{state,jdbcType=VARCHAR}, #{taskId,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP},
#{updatedAt,jdbcType=TIMESTAMP}, #{createdBy,jdbcType=VARCHAR}, #{updatedBy,jdbcType=VARCHAR},
#{retryCount,jdbcType=BIGINT}, #{sourceCount,jdbcType=BIGINT}, #{sinkCount,jdbcType=BIGINT},
#{message,jdbcType=LONGVARCHAR})
ON DUPLICATE KEY UPDATE
updated_at = #{updatedAt}, retry_count = retry_count + 1
</insert>
<insert id="insertSelective" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
insert into s2_materialization_record
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="materializationId != null">
materialization_id,
</if>
<if test="elementType != null">
element_type,
</if>
<if test="elementId != null">
element_id,
</if>
<if test="elementName != null">
element_name,
</if>
<if test="dataTime != null">
data_time,
</if>
<if test="state != null">
state,
</if>
<if test="taskId != null">
task_id,
</if>
<if test="createdAt != null">
created_at,
</if>
<if test="updatedAt != null">
updated_at,
</if>
<if test="createdBy != null">
created_by,
</if>
<if test="updatedBy != null">
updated_by,
</if>
<if test="retryCount != null">
retry_count,
</if>
<if test="sourceCount != null">
source_count,
</if>
<if test="sinkCount != null">
sink_count,
</if>
<if test="message != null">
message,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="materializationId != null">
#{materializationId,jdbcType=BIGINT},
</if>
<if test="elementType != null">
#{elementType,jdbcType=VARCHAR},
</if>
<if test="elementId != null">
#{elementId,jdbcType=BIGINT},
</if>
<if test="elementName != null">
#{elementName,jdbcType=VARCHAR},
</if>
<if test="dataTime != null">
#{dataTime,jdbcType=VARCHAR},
</if>
<if test="state != null">
#{state,jdbcType=VARCHAR},
</if>
<if test="taskId != null">
#{taskId,jdbcType=VARCHAR},
</if>
<if test="createdAt != null">
#{createdAt,jdbcType=TIMESTAMP},
</if>
<if test="updatedAt != null">
#{updatedAt,jdbcType=TIMESTAMP},
</if>
<if test="createdBy != null">
#{createdBy,jdbcType=VARCHAR},
</if>
<if test="updatedBy != null">
#{updatedBy,jdbcType=VARCHAR},
</if>
<if test="retryCount != null">
#{retryCount,jdbcType=BIGINT},
</if>
<if test="sourceCount != null">
#{sourceCount,jdbcType=BIGINT},
</if>
<if test="sinkCount != null">
#{sinkCount,jdbcType=BIGINT},
</if>
<if test="message != null">
#{message,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDOExample" resultType="java.lang.Long">
select count(*) from s2_materialization_record
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
update s2_materialization_record
<set>
<if test="materializationId != null">
materialization_id = #{materializationId,jdbcType=BIGINT},
</if>
<if test="elementType != null">
element_type = #{elementType,jdbcType=VARCHAR},
</if>
<if test="elementId != null">
element_id = #{elementId,jdbcType=BIGINT},
</if>
<if test="elementName != null">
element_name = #{elementName,jdbcType=VARCHAR},
</if>
<if test="dataTime != null">
data_time = #{dataTime,jdbcType=VARCHAR},
</if>
<if test="state != null">
state = #{state,jdbcType=VARCHAR},
</if>
<if test="taskId != null">
task_id = #{taskId,jdbcType=VARCHAR},
</if>
<if test="createdAt != null">
created_at = #{createdAt,jdbcType=TIMESTAMP},
</if>
<if test="updatedAt != null">
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
</if>
<if test="createdBy != null">
created_by = #{createdBy,jdbcType=VARCHAR},
</if>
<if test="updatedBy != null">
updated_by = #{updatedBy,jdbcType=VARCHAR},
</if>
<if test="retryCount != null">
retry_count = #{retryCount,jdbcType=BIGINT},
</if>
<if test="sourceCount != null">
source_count = #{sourceCount,jdbcType=BIGINT},
</if>
<if test="sinkCount != null">
sink_count = #{sinkCount,jdbcType=BIGINT},
</if>
<if test="message != null">
message = #{message,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
update s2_materialization_record
set materialization_id = #{materializationId,jdbcType=BIGINT},
element_type = #{elementType,jdbcType=VARCHAR},
element_id = #{elementId,jdbcType=BIGINT},
element_name = #{elementName,jdbcType=VARCHAR},
data_time = #{dataTime,jdbcType=VARCHAR},
state = #{state,jdbcType=VARCHAR},
task_id = #{taskId,jdbcType=VARCHAR},
created_at = #{createdAt,jdbcType=TIMESTAMP},
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
created_by = #{createdBy,jdbcType=VARCHAR},
updated_by = #{updatedBy,jdbcType=VARCHAR},
retry_count = #{retryCount,jdbcType=BIGINT},
source_count = #{sourceCount,jdbcType=BIGINT},
sink_count = #{sinkCount,jdbcType=BIGINT},
message = #{message,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByBizName" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
update s2_materialization_record
set
element_id = #{elementId,jdbcType=BIGINT},
state = #{state,jdbcType=VARCHAR},
task_id = #{taskId,jdbcType=VARCHAR},
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
updated_by = #{updatedBy,jdbcType=VARCHAR},
retry_count = #{retryCount,jdbcType=BIGINT},
source_count = #{sourceCount,jdbcType=BIGINT},
sink_count = #{sinkCount,jdbcType=BIGINT},
message = #{message,jdbcType=LONGVARCHAR}
where
materialization_id = #{materializationId}
AND element_type = #{elementType}
AND element_name = #{elementName}
AND data_time = #{dataTime}
</update>
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.semantic.materialization.domain.dataobject.MaterializationRecordDO">
update s2_materialization_record
set materialization_id = #{materializationId,jdbcType=BIGINT},
element_type = #{elementType,jdbcType=VARCHAR},
element_id = #{elementId,jdbcType=BIGINT},
element_name = #{elementName,jdbcType=VARCHAR},
data_time = #{dataTime,jdbcType=VARCHAR},
state = #{state,jdbcType=VARCHAR},
task_id = #{taskId,jdbcType=VARCHAR},
created_at = #{createdAt,jdbcType=TIMESTAMP},
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
created_by = #{createdBy,jdbcType=VARCHAR},
updated_by = #{updatedBy,jdbcType=VARCHAR},
retry_count = #{retryCount,jdbcType=BIGINT},
source_count = #{sourceCount,jdbcType=BIGINT},
sink_count = #{sinkCount,jdbcType=BIGINT}
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>

View File

@@ -228,8 +228,9 @@ public class ModelServiceImpl implements ModelService {
@Override
public Map<Long, String> getModelFullPathMap() {
return getModelList().stream().filter(Objects::nonNull).collect(Collectors.toMap(ModelResp::getId,
ModelResp::getFullPath, (k1, k2) -> k1));
return getModelList().stream().filter(m -> m != null && m.getFullPath() != null)
.collect(Collectors.toMap(ModelResp::getId,
ModelResp::getFullPath, (k1, k2) -> k1));
}
@Override

View File

@@ -58,6 +58,8 @@ public class DatasourceDO {
*/
private String datasourceDetail;
private String depends;
/**
* @return id
@@ -253,5 +255,11 @@ public class DatasourceDO {
this.datasourceDetail = datasourceDetail == null ? null : datasourceDetail.trim();
}
public void setDepends(String depends) {
this.depends = depends;
}
public String getDepends() {
return depends;
}
}

View File

@@ -98,6 +98,11 @@ public class DimensionDO {
*/
private String expr;
/**
* 数据类型
*/
private String dataType;
/**
* 维度ID
*
@@ -431,4 +436,12 @@ public class DimensionDO {
public void setExpr(String expr) {
this.expr = expr == null ? null : expr.trim();
}
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
}

View File

@@ -1,9 +1,11 @@
package com.tencent.supersonic.semantic.model.domain.pojo;
import com.tencent.supersonic.common.pojo.enums.DataTypeEnums;
import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap;
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
import lombok.Data;
import java.util.List;
@Data
@@ -26,4 +28,6 @@ public class Dimension extends SchemaItem {
private List<DimValueMap> dimValueMaps;
private DataTypeEnums dataType;
}

View File

@@ -3,6 +3,8 @@ package com.tencent.supersonic.semantic.model.domain.utils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.common.util.BeanMapper;
import com.tencent.supersonic.semantic.api.model.enums.MetricTypeEnum;
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
@@ -15,13 +17,12 @@ import com.tencent.supersonic.semantic.api.model.request.MetricReq;
import com.tencent.supersonic.semantic.api.model.response.DatasourceRelaResp;
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.common.util.BeanMapper;
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO;
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceRelaDO;
import com.tencent.supersonic.semantic.model.domain.pojo.Datasource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -108,6 +109,7 @@ public class DatasourceConverter {
dimensionReq.setModelId(datasource.getModelId());
dimensionReq.setExpr(dim.getBizName());
dimensionReq.setType("categorical");
dimensionReq.setDescription(Objects.isNull(dim.getDescription()) ? "" : dim.getDescription());
return dimensionReq;
}

View File

@@ -1,6 +1,7 @@
package com.tencent.supersonic.semantic.model.domain.utils;
import com.alibaba.fastjson.JSONObject;
import com.tencent.supersonic.common.pojo.enums.DataTypeEnums;
import com.tencent.supersonic.common.util.JsonUtil;
import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap;
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
@@ -14,6 +15,7 @@ import com.tencent.supersonic.semantic.model.domain.pojo.Dimension;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
@@ -35,6 +37,9 @@ public class DimensionConverter {
} else {
dimensionDO.setDimValueMaps(JSONObject.toJSONString(new ArrayList<>()));
}
if (Objects.nonNull(dimension.getDataType())) {
dimensionDO.setDataType(dimension.getDataType().getType());
}
return dimensionDO;
}
@@ -43,6 +48,9 @@ public class DimensionConverter {
BeanUtils.copyProperties(dimension, dimensionDO);
dimensionDO.setDefaultValues(JSONObject.toJSONString(dimension.getDefaultValues()));
dimensionDO.setDimValueMaps(JSONObject.toJSONString(dimension.getDimValueMaps()));
if (Objects.nonNull(dimension.getDataType())) {
dimensionDO.setDataType(dimension.getDataType().getType());
}
return dimensionDO;
}
@@ -65,6 +73,9 @@ public class DimensionConverter {
if (Strings.isNotEmpty(dimensionDO.getDimValueMaps())) {
dimensionResp.setDimValueMaps(JsonUtil.toList(dimensionDO.getDimValueMaps(), DimValueMap.class));
}
if (Strings.isNotEmpty(dimensionDO.getDataType())) {
dimensionResp.setDataType(DataTypeEnums.of(dimensionDO.getDataType()));
}
return dimensionResp;
}

View File

@@ -77,7 +77,12 @@ public class MetricConverter {
RelateDimension.class));
return metricResp;
}
public static Metric convert2Metric(MetricDO metricDO) {
Metric metric = new Metric();
BeanUtils.copyProperties(metricDO, metric);
metric.setTypeParams(JSONObject.parseObject(metricDO.getTypeParams(), MetricTypeParams.class));
return metric;
}
public static MetricYamlTpl convert2MetricYamlTpl(Metric metric) {
MetricYamlTpl metricYamlTpl = new MetricYamlTpl();

View File

@@ -12,6 +12,7 @@
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
<result column="depends" jdbcType="VARCHAR" property="depends" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO">
<result column="datasource_detail" jdbcType="LONGVARCHAR" property="datasourceDetail" />
@@ -47,7 +48,7 @@
</sql>
<sql id="Base_Column_List">
id, model_id, name, biz_name, description, database_id, created_at, created_by, updated_at,
updated_by
updated_by,depends
</sql>
<sql id="Blob_Column_List">
datasource_detail

View File

@@ -19,6 +19,7 @@
<result column="alias" jdbcType="VARCHAR" property="alias" />
<result column="default_values" jdbcType="VARCHAR" property="defaultValues" />
<result column="dim_value_maps" jdbcType="VARCHAR" property="dimValueMaps" />
<result column="data_type" jdbcType="VARCHAR" property="dataType"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.semantic.model.domain.dataobject.DimensionDO">
<result column="type_params" jdbcType="LONGVARCHAR" property="typeParams" />
@@ -56,7 +57,7 @@
<sql id="Base_Column_List">
id, model_id, datasource_id, name, biz_name, description, status, sensitive_level,
type, created_at, created_by, updated_at, updated_by, semantic_type, alias, default_values,
dim_value_maps
dim_value_maps, data_type
</sql>
<sql id="Blob_Column_List">
type_params, expr
@@ -113,14 +114,14 @@
created_at, created_by, updated_at,
updated_by, semantic_type, alias,
default_values, dim_value_maps, type_params,
expr)
expr, data_type)
values (#{id,jdbcType=BIGINT}, #{modelId,jdbcType=BIGINT}, #{datasourceId,jdbcType=BIGINT},
#{name,jdbcType=VARCHAR}, #{bizName,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
#{status,jdbcType=INTEGER}, #{sensitiveLevel,jdbcType=INTEGER}, #{type,jdbcType=VARCHAR},
#{createdAt,jdbcType=TIMESTAMP}, #{createdBy,jdbcType=VARCHAR}, #{updatedAt,jdbcType=TIMESTAMP},
#{updatedBy,jdbcType=VARCHAR}, #{semanticType,jdbcType=VARCHAR}, #{alias,jdbcType=VARCHAR},
#{defaultValues,jdbcType=VARCHAR}, #{dimValueMaps,jdbcType=VARCHAR}, #{typeParams,jdbcType=LONGVARCHAR},
#{expr,jdbcType=LONGVARCHAR})
#{defaultValues,jdbcType=VARCHAR}, #{dimValueMaps,jdbcType=VARCHAR}, #{typeParams,jdbcType=LONGVARCHAR},
#{expr,jdbcType=LONGVARCHAR}, #{dataType,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.DimensionDO">
insert into s2_dimension
@@ -182,6 +183,9 @@
<if test="expr != null">
expr,
</if>
<if test="data_type != null">
data_type,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@@ -241,6 +245,9 @@
<if test="expr != null">
#{expr,jdbcType=LONGVARCHAR},
</if>
<if test="dataType != null">
#{dataType,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.DimensionDOExample" resultType="java.lang.Long">
@@ -306,6 +313,9 @@
<if test="expr != null">
expr = #{expr,jdbcType=LONGVARCHAR},
</if>
<if test="dataType != null">
data_type = #{dataType,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
@@ -328,7 +338,8 @@
default_values = #{defaultValues,jdbcType=VARCHAR},
dim_value_maps = #{dimValueMaps,jdbcType=VARCHAR},
type_params = #{typeParams,jdbcType=LONGVARCHAR},
expr = #{expr,jdbcType=LONGVARCHAR}
expr = #{expr,jdbcType=LONGVARCHAR},
data_type = #{dataType,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.DimensionDO">
@@ -348,7 +359,8 @@
semantic_type = #{semanticType,jdbcType=VARCHAR},
alias = #{alias,jdbcType=VARCHAR},
default_values = #{defaultValues,jdbcType=VARCHAR},
dim_value_maps = #{dimValueMaps,jdbcType=VARCHAR}
dim_value_maps = #{dimValueMaps,jdbcType=VARCHAR},
data_type = #{dataType,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>

View File

@@ -16,6 +16,7 @@
<module>api</module>
<module>model</module>
<module>query</module>
<module>materialization</module>
</modules>
</project>

View File

@@ -70,6 +70,12 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>semantic-materialization</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.calcite.avatica</groupId>
<artifactId>avatica-core</artifactId>

View File

@@ -19,16 +19,16 @@ public class DetailQuery implements QueryOptimizer {
if (Strings.isNullOrEmpty(sqlRaw)) {
throw new RuntimeException("sql is empty or null");
}
log.info("before handleNoMetric, sql:{}", sqlRaw);
log.debug("before handleNoMetric, sql:{}", sqlRaw);
if (isDetailQuery(queryStructCmd)) {
if (queryStructCmd.getMetrics().size() == 0) {
if (queryStructCmd.getMetrics().size() == 0 && !CollectionUtils.isEmpty(queryStructCmd.getGroups())) {
String sqlForm = "select %s from ( %s ) src_no_metric";
String sql = String.format(sqlForm, queryStructCmd.getGroups().stream().collect(
Collectors.joining(",")), sqlRaw);
queryStatement.setSql(sql);
}
}
log.info("after handleNoMetric, sql:{}", queryStatement.getSql());
log.debug("after handleNoMetric, sql:{}", queryStatement.getSql());
}
public boolean isDetailQuery(QueryStructReq queryStructCmd) {

View File

@@ -0,0 +1,349 @@
package com.tencent.supersonic.semantic.query.optimizer;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.common.util.StringUtil;
import com.tencent.supersonic.common.util.calcite.SqlParseUtils;
import com.tencent.supersonic.semantic.api.materialization.enums.MaterializedTypeEnum;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationRecordResp;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationResp;
import com.tencent.supersonic.semantic.api.model.enums.QueryOptMode;
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.pojo.MetricTable;
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq;
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
import com.tencent.supersonic.semantic.materialization.domain.MaterializationConfService;
import com.tencent.supersonic.semantic.materialization.domain.MaterializationRecordService;
import com.tencent.supersonic.semantic.model.domain.Catalog;
import com.tencent.supersonic.semantic.query.parser.calcite.SemanticSchemaManager;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.DataSource;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Materialization;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Materialization.TimePartType;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.MaterializationElement;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Metric;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.SemanticModel;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.TimeRange;
import com.tencent.supersonic.semantic.query.parser.calcite.planner.AggPlanner;
import com.tencent.supersonic.semantic.query.parser.calcite.planner.MaterializationPlanner;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSchema;
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
import com.tencent.supersonic.semantic.query.utils.QueryStructUtils;
import com.tencent.supersonic.semantic.query.utils.StatUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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("MaterializationQuery")
public class MaterializationQuery implements QueryOptimizer {
protected final MaterializationConfService materializationConfService;
protected final MaterializationRecordService materializationRecordService;
protected final Catalog catalog;
protected final QueryStructUtils queryStructUtils;
protected final SemanticSchemaManager semanticSchemaManager;
protected final StatUtils statUtils;
@Value("${materialization.query.enable:false}")
private boolean enabled;
public MaterializationQuery(
MaterializationConfService materializationConfService,
MaterializationRecordService materializationRecordService,
Catalog catalog, QueryStructUtils queryStructUtils,
SemanticSchemaManager semanticSchemaManager,
StatUtils statUtils) {
this.materializationConfService = materializationConfService;
this.materializationRecordService = materializationRecordService;
this.catalog = catalog;
this.queryStructUtils = queryStructUtils;
this.semanticSchemaManager = semanticSchemaManager;
this.statUtils = statUtils;
}
@Override
public void rewrite(QueryStructReq queryStructCmd, QueryStatement queryStatement) {
if (!enabled) {
return;
}
try {
if (Objects.isNull(queryStructCmd) || Objects.isNull(queryStatement) || Objects.isNull(
queryStructCmd.getModelId()) || Objects.isNull(
queryStructCmd.getDateInfo())) {
return;
}
if (Objects.nonNull(queryStatement.getParseSqlReq())) {
rewriteSqlReq(queryStructCmd, queryStatement);
return;
}
List<Materialization> materializationList = getMaterializationSchema(queryStructCmd,
queryStatement.getMetricReq());
if (!CollectionUtils.isEmpty(materializationList)) {
if (replan(materializationList, queryStructCmd, queryStatement)) {
statUtils.updateQueryOptMode(QueryOptMode.MATERIALIZATION.name());
}
}
} catch (Exception e) {
log.error("MaterializationQuery error {}", e);
}
}
protected void rewriteSqlReq(QueryStructReq queryStructCmd, QueryStatement queryStatement) throws Exception {
ParseSqlReq parseSqlReq = queryStatement.getParseSqlReq();
String sourceId = queryStatement.getSourceId();
String sql = queryStatement.getSql();
String parseSql = parseSqlReq.getSql();
String msg = queryStatement.getErrMsg();
String materializationSourceId = "";
String materializationSql = "";
String parseSqlReqMaterialization = "";
if (!CollectionUtils.isEmpty(parseSqlReq.getTables())) {
List<String[]> tables = new ArrayList<>();
for (MetricTable metricTable : parseSqlReq.getTables()) {
MetricReq metricReq = new MetricReq();
metricReq.setMetrics(metricTable.getMetrics());
metricReq.setDimensions(metricTable.getDimensions());
metricReq.setWhere(StringUtil.formatSqlQuota(metricTable.getWhere()));
metricReq.setRootPath(parseSqlReq.getRootPath());
List<Materialization> materializationList = getMaterializationSchema(queryStructCmd,
metricReq);
if (!CollectionUtils.isEmpty(materializationList)) {
queryStatement.setMetricReq(metricReq);
boolean ok = replan(materializationList, queryStructCmd, queryStatement);
if (!ok) {
log.info("MaterializationQuery rewriteSqlReq not match {}", metricTable.getAlias());
queryStatement.setSql(sql);
queryStatement.setSourceId(sourceId);
queryStatement.setErrMsg(msg);
queryStatement.setMetricReq(null);
return;
}
tables.add(new String[]{metricTable.getAlias(), queryStatement.getSql()});
materializationSourceId = queryStatement.getSourceId();
parseSqlReqMaterialization = queryStatement.getParseSqlReq().getSql();
}
}
if (!CollectionUtils.isEmpty(tables)) {
if (parseSqlReq.isSupportWith()) {
materializationSql = "with " + String.join(",",
tables.stream().map(t -> String.format("%s as (%s)", t[0], t[1])).collect(
Collectors.toList())) + "\n" + parseSqlReqMaterialization;
} else {
materializationSql = parseSqlReqMaterialization;
for (String[] tb : tables) {
materializationSql = StringUtils.replace(materializationSql, tb[0],
"(" + tb[1] + ") " + (parseSqlReq.isWithAlias() ? "" : tb[0]), -1);
}
}
queryStatement.setSql(materializationSql);
queryStatement.setSourceId(materializationSourceId);
log.info("rewriteSqlReq before[{}] after[{}]", sql, materializationSql);
statUtils.updateQueryOptMode(QueryOptMode.MATERIALIZATION.name());
}
parseSqlReq.setSql(parseSql);
}
}
public List<Materialization> getMaterializationSchema(QueryStructReq queryStructReq, MetricReq metricReq)
throws Exception {
List<Materialization> materializationList = new ArrayList<>();
if (Objects.isNull(metricReq)) {
return materializationList;
}
ImmutablePair<String, String> timeRange = queryStructUtils.getBeginEndTime(queryStructReq);
String start = timeRange.left;
String end = timeRange.right;
Long modelId = queryStructReq.getModelId();
List<MaterializationResp> materializationResps = materializationConfService.getMaterializationByModel(modelId);
List<DimensionResp> dimensionResps = catalog.getDimensions(modelId);
List<MetricResp> metrics = catalog.getMetrics(modelId);
Set<String> fields = new HashSet<>();
if (Objects.nonNull(metricReq.getWhere()) && !metricReq.getWhere().isEmpty()) {
fields.addAll(SqlParseUtils.getFilterField(metricReq.getWhere()));
}
if (!CollectionUtils.isEmpty(metricReq.getMetrics())) {
fields.addAll(metricReq.getMetrics());
}
if (!CollectionUtils.isEmpty(metricReq.getDimensions())) {
fields.addAll(metricReq.getDimensions());
}
materializationResps.forEach(materializationResp -> {
Materialization materialization =
Materialization.builder().dateInfo(materializationResp.getDateInfo())
.materializationId(materializationResp.getId())
.level(materializationResp.getLevel())
.timePartType(TimePartType.of(materializationResp.getMaterializedType().name()))
.dimensions(new ArrayList<>())
.metrics(new ArrayList<>())
.entities(materializationResp.getEntities())
.destinationTable(materializationResp.getDestinationTable()).modelId(modelId)
.dataBase(materializationResp.getDatabaseId()).build();
List<Long> sameTableMaterialization = materializationConfService.getMaterializationByTable(
materializationResp.getDatabaseId(), materializationResp.getDestinationTable());
Set<Long> metricIds = materializationResp.getMaterializationElementRespList().stream()
.filter(e -> e.getType().equals(
TypeEnums.METRIC)).map(e -> e.getId()).collect(Collectors.toSet());
Set<Long> dimensionIds = materializationResp.getMaterializationElementRespList().stream()
.filter(e -> e.getType().equals(
TypeEnums.DIMENSION)).map(e -> e.getId()).collect(Collectors.toSet());
dimensionResps.stream().filter(d -> dimensionIds.contains(d.getId()))
.filter(d -> fields.contains(d.getBizName())).forEach(d -> {
List<MaterializationRecordResp> materializationRecordResps = materializationRecordService
.fetchMaterializationDate(sameTableMaterialization, d.getBizName(), start, end);
if (!CollectionUtils.isEmpty(materializationRecordResps)) {
List<TimeRange> timeRangeList = new ArrayList<>();
materializationRecordResps.stream().forEach(t -> timeRangeList.add(
TimeRange.builder().start(t.getDataTime()).end(t.getDataTime()).build()));
materialization.getDimensions().add(
MaterializationElement.builder()
.name(d.getBizName())
.timeRangeList(timeRangeList)
.build()
);
} else if (MaterializedTypeEnum.FULL.equals(materializationResp.getMaterializedType())) {
materialization.getDimensions().add(
MaterializationElement.builder()
.name(d.getBizName())
.timeRangeList(
Arrays.asList(TimeRange.builder().start(start).end(end).build()))
.build()
);
}
});
metrics.stream().filter(m -> metricIds.contains(m.getId())).filter(m -> fields.contains(m.getBizName()))
.forEach(m -> {
List<MaterializationRecordResp> materializationRecordResps = materializationRecordService
.fetchMaterializationDate(sameTableMaterialization, m.getBizName(), start, end);
if (!CollectionUtils.isEmpty(materializationRecordResps)) {
List<TimeRange> timeRangeList = new ArrayList<>();
materializationRecordResps.stream().forEach(t -> timeRangeList.add(
TimeRange.builder().start(t.getDataTime()).end(t.getDataTime()).build()));
materialization.getMetrics().add(MaterializationElement.builder().name(m.getBizName())
.timeRangeList(timeRangeList).build());
} else if (MaterializedTypeEnum.FULL.equals(materializationResp.getMaterializedType())) {
materialization.getMetrics().add(
MaterializationElement.builder()
.name(m.getBizName())
.timeRangeList(
Arrays.asList(TimeRange.builder().start(start).end(end).build()))
.build()
);
}
});
materializationList.add(materialization);
});
return materializationList;
}
protected boolean replan(List<Materialization> materializationList, QueryStructReq queryStructReq,
QueryStatement queryStatement)
throws Exception {
log.info("{}", materializationList);
SemanticSchema schema = SemanticSchema.newBuilder(queryStatement.getMetricReq().getRootPath()).build();
schema.setMaterializationList(materializationList);
getTimeRanges(queryStructReq, queryStatement);
removeDefaultMetric(queryStructReq, queryStatement.getMetricReq());
MaterializationPlanner materializationPlanner = new MaterializationPlanner(schema);
materializationPlanner.explain(queryStatement, AggOption.getAggregation(queryStructReq.getNativeQuery()));
log.info("optimize {}", materializationPlanner.findBest().getDatasource());
SemanticSchema semanticSchema = materializationPlanner.findBest();
if (!CollectionUtils.isEmpty(semanticSchema.getDatasource())) {
semanticSchema.getSemanticModel().setRootPath(semanticSchema.getRootPath());
semanticSchema.setSemanticModel(transform(queryStatement, semanticSchema.getSemanticModel()));
int materCnt = semanticSchema.getDatasource().size();
if (materCnt == semanticSchema.getDatasource().entrySet().stream()
.filter(d -> d.getValue().getTimePartType().equals(TimePartType.ZIPPER)).count()) {
doSingleZipperSource(queryStructReq, queryStatement);
}
AggPlanner aggBuilder = new AggPlanner(semanticSchema);
aggBuilder.explain(queryStatement, AggOption.getAggregation(queryStructReq.getNativeQuery()));
log.debug("optimize before {} sql {}", queryStatement.getSourceId(), queryStatement.getSql());
log.debug("optimize after {} sql {}", aggBuilder.getSourceId(), aggBuilder.getSql());
queryStatement.setSourceId(aggBuilder.getSourceId());
queryStatement.setSql(aggBuilder.getSql());
queryStatement.setStatus(queryStatement.getStatus() + 1);
return true;
}
return false;
}
protected SemanticModel transform(QueryStatement queryStatement, SemanticModel semanticModel) throws Exception {
for (DataSource dataSource : semanticModel.getDatasourceMap().values()) {
if (!CollectionUtils.isEmpty(dataSource.getMeasures())) {
dataSource.getMeasures().stream().forEach(m -> {
m.setExpr(getMetricExpr(semanticModel.getRootPath(), m.getName()));
});
}
}
return semanticModel;
}
protected String getMetricExpr(String rootPath, String bizName) {
try {
SemanticModel oriSemanticModel = semanticSchemaManager.get(rootPath);
if (Objects.nonNull(oriSemanticModel)) {
Optional<Metric> metric = oriSemanticModel.getMetrics()
.stream().filter(m -> m.getName().equalsIgnoreCase(bizName)).findFirst();
if (metric.isPresent() && metric.get().getMetricTypeParams().getExpr().contains(getVariablePrefix())) {
return metric.get().getMetricTypeParams().getExpr();
}
}
} catch (Exception e) {
log.error("getMetricExpr {}", e);
}
return bizName;
}
protected void removeDefaultMetric(QueryStructReq queryStructReq, MetricReq metricReq) {
// due to default metrics have no materialization
if (CollectionUtils.isEmpty(queryStructReq.getAggregators()) && Objects.nonNull(metricReq)) {
metricReq.setMetrics(new ArrayList<>());
}
}
protected void doSingleZipperSource(QueryStructReq queryStructReq, QueryStatement queryStatement) {
// time field rewrite to start_ end_
log.info("doSingleZipperSource {}", queryStatement);
if (CollectionUtils.isEmpty(queryStructReq.getAggregators()) && CollectionUtils.isEmpty(
queryStructReq.getGroups()) && Objects.nonNull(queryStatement.getParseSqlReq())) {
String sqlNew = queryStructUtils.generateZipperWhere(queryStatement, queryStructReq);
log.info("doSingleZipperSource before[{}] after[{}]", queryStatement.getParseSqlReq().getSql(), sqlNew);
queryStatement.getParseSqlReq().setSql(sqlNew);
return;
}
MetricReq metricReq = queryStatement.getMetricReq();
String where = queryStructUtils.generateZipperWhere(queryStructReq);
if (!where.isEmpty() && Objects.nonNull(metricReq)) {
log.info("doSingleZipperSource before[{}] after[{}]", metricReq.getWhere(), where);
metricReq.setWhere(where);
}
}
protected void getTimeRanges(QueryStructReq queryStructReq, QueryStatement queryStatement) {
queryStatement.setTimeRanges(queryStructUtils.getTimeRanges(queryStructReq));
}
protected String getVariablePrefix() {
return queryStructUtils.getVariablePrefix();
}
}

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.semantic.query.parser;
import com.tencent.supersonic.common.util.StringUtil;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.pojo.MetricTable;
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
@@ -59,7 +60,8 @@ public class QueryParser {
MetricReq metricReq = new MetricReq();
metricReq.setMetrics(metricTable.getMetrics());
metricReq.setDimensions(metricTable.getDimensions());
metricReq.setWhere(formatWhere(metricTable.getWhere()));
metricReq.setWhere(StringUtil.formatSqlQuota(metricTable.getWhere()));
metricReq.setNativeQuery(!AggOption.isAgg(metricTable.getAggOption()));
metricReq.setRootPath(sqlCommend.getRootPath());
QueryStatement tableSql = parser(metricReq, metricTable.getAggOption());
if (!tableSql.isOk()) {
@@ -86,6 +88,7 @@ public class QueryParser {
}
queryStatement.setSql(sql);
queryStatement.setSourceId(sourceId);
queryStatement.setParseSqlReq(sqlCommend);
return queryStatement;
}
}
@@ -118,10 +121,4 @@ public class QueryParser {
}
private String formatWhere(String where) {
if (StringUtils.isEmpty(where)) {
return where;
}
return where.replace("\"", "\\\\\"");
}
}

View File

@@ -27,9 +27,10 @@ public class CalciteSqlParser implements SqlParser {
queryStatement.setErrMsg("semanticSchema not found");
return queryStatement;
}
queryStatement.setMetricReq(metricReq);
SemanticSchema semanticSchema = getSemanticSchema(semanticModel);
AggPlanner aggBuilder = new AggPlanner(semanticSchema);
aggBuilder.explain(metricReq, isAgg);
aggBuilder.explain(queryStatement, isAgg);
queryStatement.setSql(aggBuilder.getSql());
queryStatement.setSourceId(aggBuilder.getSourceId());
return queryStatement;

View File

@@ -1,8 +1,11 @@
package com.tencent.supersonic.semantic.query.parser.calcite;
import com.tencent.supersonic.semantic.query.parser.calcite.sql.DSLSqlValidatorImpl;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSqlDialect;
import com.tencent.supersonic.semantic.query.parser.calcite.sql.DSLSqlValidatorImpl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.apache.calcite.avatica.util.Casing;
import org.apache.calcite.avatica.util.Quoting;
@@ -10,6 +13,10 @@ import org.apache.calcite.config.CalciteConnectionConfig;
import org.apache.calcite.config.CalciteConnectionConfigImpl;
import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.config.Lex;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.prepare.CalciteCatalogReader;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.rel.hint.HintStrategyTable;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.sql.SqlOperatorTable;
@@ -17,8 +24,11 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.impl.SqlParserImpl;
import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
import org.apache.calcite.sql.validate.SqlConformanceEnum;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorUtil;
import org.apache.calcite.sql2rel.SqlToRelConverter;
public class Configuration {
@@ -58,4 +68,33 @@ public class Configuration {
return parserConfig.build();
}
public static SqlValidator getSqlValidator(CalciteSchema rootSchema) {
List<SqlOperatorTable> tables = new ArrayList<>();
tables.add(SqlStdOperatorTable.instance());
SqlOperatorTable operatorTable = new ChainedSqlOperatorTable(tables); //.of(SqlStdOperatorTable.instance());
//operatorTable.
SqlValidator.Config validatorConfig = SqlValidator.Config.DEFAULT
.withLenientOperatorLookup(config.lenientOperatorLookup())
.withConformance(SemanticSqlDialect.DEFAULT.getConformance())
.withDefaultNullCollation(config.defaultNullCollation())
.withIdentifierExpansion(true);
Prepare.CatalogReader catalogReader = new CalciteCatalogReader(
rootSchema,
Collections.singletonList(rootSchema.getName()),
typeFactory,
config
);
SqlValidator validator = SqlValidatorUtil.newValidator(operatorTable, catalogReader, typeFactory,
validatorConfig);
return validator;
}
public static SqlToRelConverter.Config getConverterConfig() {
HintStrategyTable strategies = HintStrategyTable.builder().build();
return SqlToRelConverter.config()
.withHintStrategyTable(strategies)
.withTrimUnusedFields(true)
.withExpand(true);
}
}

View File

@@ -107,15 +107,9 @@ public class SemanticSchemaManager {
public static DataSource getDatasource(final DatasourceYamlTpl d) {
DataSource datasource = new DataSource();
datasource.setSqlQuery(d.getSqlQuery());
datasource.setName(d.getName());
datasource.setSourceId(d.getSourceId());
datasource.setTableQuery(d.getTableQuery());
datasource.setIdentifiers(getIdentify(d.getIdentifiers()));
datasource.setDimensions(getDimensions(d.getDimensions()));
datasource.setMeasures(getMeasures(d.getMeasures()));
DataSource datasource = DataSource.builder().sourceId(d.getSourceId()).sqlQuery(d.getSqlQuery())
.name(d.getName()).tableQuery(d.getTableQuery()).identifiers(getIdentify(d.getIdentifiers()))
.measures(getMeasures(d.getMeasures())).dimensions(getDimensions(d.getDimensions())).build();
datasource.setAggTime(getDataSourceAggTime(datasource.getDimensions()));
return datasource;
}
@@ -167,7 +161,7 @@ public class SemanticSchemaManager {
private static List<Dimension> getDimension(List<DimensionYamlTpl> dimensionYamlTpls) {
List<Dimension> dimensions = new ArrayList<>();
for (DimensionYamlTpl dimensionYamlTpl : dimensionYamlTpls) {
Dimension dimension = new Dimension();
Dimension dimension = Dimension.builder().build();
dimension.setType(dimensionYamlTpl.getType());
dimension.setExpr(dimensionYamlTpl.getExpr());
dimension.setName(dimensionYamlTpl.getName());

View File

@@ -11,6 +11,8 @@ public class Constants {
public static final String JOIN_TABLE_LEFT_PREFIX = "src12_";
public static final String DIMENSION_TYPE_TIME_GRANULARITY_NONE = "none";
public static final String DIMENSION_TYPE_TIME = "time";
public static final String MATERIALIZATION_ZIPPER_START = "start_";
public static final String MATERIALIZATION_ZIPPER_END = "end_";
}

View File

@@ -1,10 +1,13 @@
package com.tencent.supersonic.semantic.query.parser.calcite.dsl;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Materialization.TimePartType;
import java.util.List;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class DataSource {
private String name;
@@ -22,4 +25,6 @@ public class DataSource {
private List<Measure> measures;
private String aggTime;
private TimePartType timePartType = TimePartType.None;
}

View File

@@ -2,10 +2,12 @@ package com.tencent.supersonic.semantic.query.parser.calcite.dsl;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticItem;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Dimension implements SemanticItem {
String name;

View File

@@ -0,0 +1,51 @@
package com.tencent.supersonic.semantic.query.parser.calcite.dsl;
import java.util.ArrayList;
import java.util.List;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Materialization {
public enum TimePartType {
/**
* partition time type
* 1 - FULL, not use partition
* 2 - PARTITION , use time list
* 3 - ZIPPER, use [startDate, endDate] range time
*/
FULL("FULL"),
PARTITION("PARTITION"),
ZIPPER("ZIPPER"),
None("");
private String name;
TimePartType(String name) {
this.name = name;
}
public static TimePartType of(String name) {
for (TimePartType typeEnum : TimePartType.values()) {
if (typeEnum.name.equalsIgnoreCase(name)) {
return typeEnum;
}
}
return TimePartType.None;
}
}
private TimePartType timePartType;
private String destinationTable;
private String dateInfo;
private String entities;
private Long modelId;
private Long dataBase;
private Long materializationId;
private Integer level;
private List<MaterializationElement> dimensions = new ArrayList<>();
private List<MaterializationElement> metrics = new ArrayList<>();
}

View File

@@ -0,0 +1,12 @@
package com.tencent.supersonic.semantic.query.parser.calcite.dsl;
import java.util.List;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class MaterializationElement {
private List<TimeRange> timeRangeList;
private String name;
}

View File

@@ -1,6 +1,7 @@
package com.tencent.supersonic.semantic.query.parser.calcite.dsl;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -8,6 +9,7 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Measure {
private String name;

View File

@@ -13,4 +13,5 @@ public class SemanticModel {
private List<Metric> metrics = new ArrayList<>();
private Map<String, DataSource> datasourceMap = new HashMap<>();
private Map<String, List<Dimension>> dimensionMap = new HashMap<>();
private List<Materialization> materializationList = new ArrayList<>();
}

View File

@@ -0,0 +1,11 @@
package com.tencent.supersonic.semantic.query.parser.calcite.dsl;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class TimeRange {
private String start;
private String end;
}

View File

@@ -14,6 +14,7 @@ import com.tencent.supersonic.semantic.query.parser.calcite.sql.node.SemanticNod
import com.tencent.supersonic.semantic.query.parser.calcite.sql.render.FilterRender;
import com.tencent.supersonic.semantic.query.parser.calcite.sql.render.OutputRender;
import com.tencent.supersonic.semantic.query.parser.calcite.sql.render.SourceRender;
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -84,15 +85,17 @@ public class AggPlanner implements Planner {
// default by dataSource time aggregation
if (Objects.nonNull(dataSource.getAggTime()) && !dataSource.getAggTime().equalsIgnoreCase(
Constants.DIMENSION_TYPE_TIME_GRANULARITY_NONE)) {
return true;
if (!metricCommand.isNativeQuery()) {
return true;
}
}
return isAgg;
}
@Override
public void explain(MetricReq metricCommand, AggOption aggOption) throws Exception {
this.metricCommand = metricCommand;
public void explain(QueryStatement queryStatement, AggOption aggOption) throws Exception {
this.metricCommand = queryStatement.getMetricReq();
if (metricCommand.getMetrics() == null) {
metricCommand.setMetrics(new ArrayList<>());
}
@@ -117,4 +120,9 @@ public class AggPlanner implements Planner {
public String getSourceId() {
return sourceId;
}
@Override
public SemanticSchema findBest() {
return schema;
}
}

View File

@@ -0,0 +1,340 @@
package com.tencent.supersonic.semantic.query.parser.calcite.planner;
import com.tencent.supersonic.common.util.calcite.SqlParseUtils;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.query.parser.calcite.Configuration;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Constants;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.DataSource;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Dimension;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Identify;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Materialization;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Materialization.TimePartType;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.MaterializationElement;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Measure;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.TimeRange;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SchemaBuilder;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSchema;
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.adapter.enumerable.EnumerableRules;
import org.apache.calcite.config.CalciteConnectionConfigImpl;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.plan.ConventionTraitDef;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptMaterialization;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.hep.HepPlanner;
import org.apache.calcite.plan.hep.HepProgramBuilder;
import org.apache.calcite.prepare.CalciteCatalogReader;
import org.apache.calcite.rel.RelDistributionTraitDef;
import org.apache.calcite.rel.RelHomogeneousShuttle;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelShuttle;
import org.apache.calcite.rel.core.RelFactories;
import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.rules.materialize.MaterializedViewRules;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.tools.RelBuilder;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.springframework.util.CollectionUtils;
@Slf4j
public class MaterializationPlanner implements Planner {
protected SemanticSchema schema;
protected CalciteSchema viewSchema;
protected HepProgramBuilder hepProgramBuilder;
protected RelOptPlanner relOptPlanner;
protected RelBuilder relBuilder;
protected CalciteCatalogReader calciteCatalogReader;
protected Comparator materializationSort = new Comparator<Entry<Long, Set<String>>>() {
@Override
public int compare(Entry<Long, Set<String>> o1, Entry<Long, Set<String>> o2) {
if (o1.getValue().size() == o2.getValue().size()) {
Optional<Materialization> o1Lever = schema.getMaterializationList().stream()
.filter(m -> m.getMaterializationId().equals(o1.getKey())).findFirst();
Optional<Materialization> o2Lever = schema.getMaterializationList().stream()
.filter(m -> m.getMaterializationId().equals(o2.getKey())).findFirst();
if (o1Lever.isPresent() && o2Lever.isPresent()) {
return o2Lever.get().getLevel() - o1Lever.get().getLevel();
}
return 0;
}
return o2.getValue().size() - o1.getValue().size();
}
};
public MaterializationPlanner(SemanticSchema schema) {
this.schema = schema;
init();
}
@Override
public void explain(QueryStatement queryStatement, AggOption isAgg) throws Exception {
// findMatchMaterialization
// checkValid field + time
if (CollectionUtils.isEmpty(queryStatement.getTimeRanges())) {
//has no matchMaterialization time info
return;
}
Set<String> fields = new HashSet<>();
MetricReq metricCommand = queryStatement.getMetricReq();
if (!Objects.isNull(metricCommand.getWhere()) && !metricCommand.getWhere().isEmpty()) {
fields.addAll(SqlParseUtils.getFilterField(metricCommand.getWhere()));
}
if (!CollectionUtils.isEmpty(metricCommand.getMetrics())) {
fields.addAll(metricCommand.getMetrics());
}
if (!CollectionUtils.isEmpty(metricCommand.getDimensions())) {
fields.addAll(metricCommand.getDimensions());
}
Map<Long, Set<String>> matchMaterialization = new HashMap<>();
Map<Long, Long> materializationDataBase = schema.getMaterializationList().stream()
.collect(Collectors.toMap(Materialization::getMaterializationId, Materialization::getDataBase));
for (String elem : fields) {
boolean checkOk = false;
for (Materialization materialization : schema.getMaterializationList()) {
if (check(metricCommand, materialization, elem, queryStatement.getTimeRanges())) {
if (!matchMaterialization.containsKey(materialization.getMaterializationId())) {
matchMaterialization.put(materialization.getMaterializationId(), new HashSet<>());
}
matchMaterialization.get(materialization.getMaterializationId()).add(elem);
checkOk = true;
}
}
if (!checkOk) {
log.info("check fail [{}]", elem);
}
}
if (!CollectionUtils.isEmpty(matchMaterialization)) {
List<Entry<Long, Set<String>>> sortedMaterialization = new ArrayList<>(matchMaterialization.entrySet());
sortedMaterialization.stream().collect(Collectors.toList()).sort(materializationSort);
for (Entry<Long, Set<String>> m : sortedMaterialization) {
Optional<Materialization> materialization = schema.getMaterializationList().stream()
.filter(mz -> mz.getMaterializationId().equals(m.getKey())).findFirst();
if (!materialization.isPresent()) {
continue;
}
Set<String> viewField = new HashSet<>(m.getValue());
viewField.add(materialization.get().getEntities());
viewField.add(materialization.get().getDateInfo());
if (materialization.get().getTimePartType().equals(TimePartType.ZIPPER)) {
viewField.add(Constants.MATERIALIZATION_ZIPPER_START + materialization.get().getDateInfo());
viewField.add(Constants.MATERIALIZATION_ZIPPER_END + materialization.get().getDateInfo());
}
if (viewField.containsAll(fields)) {
addDataSource(materialization.get());
break;
}
List<Entry<Long, Set<String>>> linkMaterialization = new ArrayList<>();
for (Entry<Long, Set<String>> mm : sortedMaterialization) {
if (mm.getKey().equals(m.getKey())) {
continue;
}
if (materializationDataBase.get(mm.getKey()).equals(materializationDataBase.get(m.getKey()))) {
linkMaterialization.add(mm);
}
}
if (!CollectionUtils.isEmpty(linkMaterialization)) {
linkMaterialization.sort(materializationSort);
for (Entry<Long, Set<String>> mm : linkMaterialization) {
Set<String> linkField = new HashSet<>(mm.getValue());
linkField.addAll(viewField);
if (linkField.containsAll(fields)) {
Optional<Materialization> linkMaterial = schema.getMaterializationList().stream()
.filter(mz -> mz.getMaterializationId().equals(mm.getKey())).findFirst();
if (linkMaterial.isPresent()) {
addDataSource(materialization.get());
addDataSource(linkMaterial.get());
break;
}
}
}
}
}
}
}
private void addDataSource(Materialization materialization) {
Identify identify = new Identify();
identify.setName(materialization.getEntities());
List<Measure> metrics = materialization.getMetrics().stream()
.map(m -> Measure.builder().name(m.getName()).expr(m.getName()).build()).collect(
Collectors.toList());
List<Dimension> dimensions = materialization.getDimensions().stream()
.map(d -> Dimension.builder().name(d.getName()).expr(d.getName()).build()).collect(
Collectors.toList());
if (materialization.getTimePartType().equals(TimePartType.ZIPPER)) {
dimensions.add(
Dimension.builder().name(Constants.MATERIALIZATION_ZIPPER_START + materialization.getDateInfo())
.type(Constants.DIMENSION_TYPE_TIME)
.expr(Constants.MATERIALIZATION_ZIPPER_START + materialization.getDateInfo()).build());
dimensions.add(
Dimension.builder().name(Constants.MATERIALIZATION_ZIPPER_END + materialization.getDateInfo())
.type(Constants.DIMENSION_TYPE_TIME)
.expr(Constants.MATERIALIZATION_ZIPPER_END + materialization.getDateInfo()).build());
} else {
dimensions.add(Dimension.builder().name(materialization.getDateInfo()).expr(materialization.getDateInfo())
.type(Constants.DIMENSION_TYPE_TIME)
.build());
}
DataSource dataSource = DataSource.builder().sourceId(materialization.getDataBase())
.tableQuery(materialization.getDestinationTable())
.timePartType(materialization.getTimePartType())
.name("v_" + String.valueOf(materialization.getMaterializationId()))
.identifiers(Arrays.asList(identify))
.measures(metrics)
.dimensions(dimensions)
.build();
schema.getDatasource().put(dataSource.getName(), dataSource);
}
@Override
public String getSql() {
return null;
}
@Override
public String getSourceId() {
return null;
}
@Override
public SemanticSchema findBest() {
return schema;
}
private void init() {
viewSchema = SchemaBuilder.getMaterializationSchema();
hepProgramBuilder = new HepProgramBuilder();
hepProgramBuilder.addRuleInstance(MaterializedViewRules.PROJECT_FILTER);
relOptPlanner = new HepPlanner(hepProgramBuilder.build());
calciteCatalogReader = new CalciteCatalogReader(
CalciteSchema.from(viewSchema.plus()),
CalciteSchema.from(viewSchema.plus()).path(null),
Configuration.typeFactory,
new CalciteConnectionConfigImpl(new Properties()));
relOptPlanner.addRelTraitDef(ConventionTraitDef.INSTANCE);
relOptPlanner.addRelTraitDef(RelDistributionTraitDef.INSTANCE);
EnumerableRules.rules().forEach(relOptPlanner::addRule);
RexBuilder rexBuilder = new RexBuilder(Configuration.typeFactory);
RelOptCluster relOptCluster = RelOptCluster.create(relOptPlanner, rexBuilder);
relBuilder = RelFactories.LOGICAL_BUILDER.create(relOptCluster, calciteCatalogReader);
}
private RexNode getRexNode(List<ImmutablePair<String, String>> timeRanges, String viewField) {
RexNode rexNode = null;
for (ImmutablePair<String, String> timeRange : timeRanges) {
if (rexNode == null) {
rexNode = getRexNodeByTimeRange(TimeRange.builder().start(timeRange.left).end(timeRange.right).build(),
viewField);
continue;
}
rexNode = relBuilder.call(SqlStdOperatorTable.OR, rexNode,
getRexNodeByTimeRange(TimeRange.builder().start(timeRange.left).end(timeRange.right).build(),
viewField));
}
return rexNode;
}
private RexNode getRexNode(Materialization materialization, String elem, String viewField) {
Optional<MaterializationElement> dim = materialization.getDimensions()
.stream().filter(d -> d.getName().equalsIgnoreCase(elem)).findFirst();
if (!dim.isPresent()) {
dim = materialization.getMetrics().stream().filter(m -> m.getName().equalsIgnoreCase(elem)).findFirst();
}
RexNode rexNode = null;
if (dim.isPresent()) {
for (TimeRange timeRange : dim.get().getTimeRangeList()) {
if (rexNode == null) {
rexNode = getRexNodeByTimeRange(timeRange, viewField);
continue;
}
rexNode = relBuilder.call(SqlStdOperatorTable.OR, rexNode, getRexNodeByTimeRange(timeRange, viewField));
}
}
return rexNode;
}
private RexNode getRexNodeByTimeRange(TimeRange timeRange, String field) {
return relBuilder.call(SqlStdOperatorTable.AND,
relBuilder.call(SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, relBuilder.field(field),
relBuilder.literal(timeRange.getStart())),
relBuilder.call(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, relBuilder.field(field),
relBuilder.literal(timeRange.getEnd())));
}
public boolean check(MetricReq metricCommand, Materialization materialization, String elem,
List<ImmutablePair<String, String>> timeRanges)
throws SqlParseException {
boolean isMatch = false;
try {
relBuilder.clear();
if (!CollectionUtils.isEmpty(relOptPlanner.getMaterializations())) {
relOptPlanner.clear();
}
String db = SchemaBuilder.MATERIALIZATION_SYS_DB;
RelBuilder viewBuilder = relBuilder.scan(Arrays.asList(db, SchemaBuilder.MATERIALIZATION_SYS_SOURCE));
RexNode viewFilter = getRexNode(materialization, elem, SchemaBuilder.MATERIALIZATION_SYS_FIELD_DATE);
if (viewFilter == null) {
return false;
}
RelNode viewRel = viewBuilder.filter(viewFilter).project(relBuilder.fields()).build();
log.debug("view {}", viewRel.explain());
List<String> view = Arrays.asList(db, SchemaBuilder.MATERIALIZATION_SYS_VIEW);
RelNode replacement = relBuilder.scan(view).build();
RelOptMaterialization relOptMaterialization = new RelOptMaterialization(replacement, viewRel, null, view);
relOptPlanner.addMaterialization(relOptMaterialization);
RelNode checkRel = relBuilder.scan(Arrays.asList(db, SchemaBuilder.MATERIALIZATION_SYS_SOURCE))
.filter(getRexNode(timeRanges, SchemaBuilder.MATERIALIZATION_SYS_FIELD_DATE))
.project(relBuilder.field(SchemaBuilder.MATERIALIZATION_SYS_FIELD_DATE)).build();
relOptPlanner.setRoot(checkRel);
RelNode optRel = relOptPlanner.findBestExp();
log.debug("findBestExp {}", optRel.explain());
isMatch = !extractTableNames(optRel).contains(SchemaBuilder.MATERIALIZATION_SYS_SOURCE);
} catch (Exception e) {
log.error("check error {}", e);
}
return isMatch;
}
public static Set<String> extractTableNames(RelNode relNode) {
Set<String> tableNames = new HashSet<>();
RelShuttle shuttle = new RelHomogeneousShuttle() {
public RelNode visit(TableScan scan) {
RelOptTable table = scan.getTable();
tableNames.addAll(table.getQualifiedName());
return scan;
}
};
relNode.accept(shuttle);
return tableNames;
}
}

View File

@@ -2,13 +2,16 @@ package com.tencent.supersonic.semantic.query.parser.calcite.planner;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSchema;
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
public interface Planner {
public void explain(MetricReq metricCommand, AggOption aggOption) throws Exception;
public void explain(QueryStatement queryStatement, AggOption aggOption) throws Exception;
public String getSql();
public String getSourceId();
public SemanticSchema findBest();
}

View File

@@ -10,11 +10,21 @@ import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.prepare.CalciteCatalogReader;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.validate.ParameterScope;
import org.apache.calcite.sql.validate.SqlValidatorScope;
public class SchemaBuilder {
public static final String MATERIALIZATION_SYS_DB = "SYS";
public static final String MATERIALIZATION_SYS_SOURCE = "SYS_SOURCE";
public static final String MATERIALIZATION_SYS_VIEW = "SYS_VIEW";
public static final String MATERIALIZATION_SYS_FIELD_DATE = "C1";
public static final String MATERIALIZATION_SYS_FIELD_DATA = "C2";
public static SqlValidatorScope getScope(SemanticSchema schema) throws Exception {
Map<String, RelDataType> nameToTypeMap = new HashMap<>();
CalciteSchema rootSchema = CalciteSchema.createRootSchema(true, false);
@@ -29,4 +39,22 @@ public class SchemaBuilder {
Configuration.typeFactory, Configuration.validatorConfig);
return new ParameterScope(dslSqlValidator, nameToTypeMap);
}
public static CalciteSchema getMaterializationSchema() {
CalciteSchema rootSchema = CalciteSchema.createRootSchema(true, false);
SchemaPlus schema = rootSchema.plus().add(MATERIALIZATION_SYS_DB, new AbstractSchema());
DataSourceTable srcTable = DataSourceTable.newBuilder(MATERIALIZATION_SYS_SOURCE)
.addField(MATERIALIZATION_SYS_FIELD_DATE, SqlTypeName.DATE)
.addField(MATERIALIZATION_SYS_FIELD_DATA, SqlTypeName.BIGINT)
.withRowCount(1)
.build();
schema.add(MATERIALIZATION_SYS_SOURCE, srcTable);
DataSourceTable viewTable = DataSourceTable.newBuilder(MATERIALIZATION_SYS_VIEW)
.addField(MATERIALIZATION_SYS_FIELD_DATE, SqlTypeName.DATE)
.addField(MATERIALIZATION_SYS_FIELD_DATA, SqlTypeName.BIGINT)
.withRowCount(1)
.build();
schema.add(MATERIALIZATION_SYS_VIEW, viewTable);
return rootSchema;
}
}

View File

@@ -3,6 +3,7 @@ package com.tencent.supersonic.semantic.query.parser.calcite.schema;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.DataSource;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Dimension;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Materialization;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Metric;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.SemanticModel;
import java.util.HashMap;
@@ -34,6 +35,14 @@ public class SemanticSchema extends AbstractSchema {
return rootPath;
}
public void setSemanticModel(SemanticModel semanticModel) {
this.semanticModel = semanticModel;
}
public SemanticModel getSemanticModel() {
return semanticModel;
}
@Override
public Map<String, Table> getTableMap() {
return tableMap;
@@ -68,6 +77,13 @@ public class SemanticSchema extends AbstractSchema {
semanticModel.setMetrics(metric);
}
public void setMaterializationList(List<Materialization> materializationList) {
semanticModel.setMaterializationList(materializationList);
}
public List<Materialization> getMaterializationList() {
return semanticModel.getMaterializationList();
}
public static final class Builder {

View File

@@ -25,7 +25,6 @@ public class TableView {
private String alias;
private List<String> primary;
private DataSource dataSource;
public SqlNode build() {

View File

@@ -142,7 +142,7 @@ public class DataSourceNode extends SemanticNode {
String.format("not find the match datasource : dimension[%s],measure[%s]", queryDimension,
measures));
}
log.info("linkDataSources {}", linkDataSources);
log.debug("linkDataSources {}", linkDataSources);
dataSources.addAll(linkDataSources);
}

View File

@@ -2,8 +2,8 @@ package com.tencent.supersonic.semantic.query.parser.calcite.sql.node;
import com.tencent.supersonic.semantic.query.parser.calcite.Configuration;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSqlDialect;
import com.tencent.supersonic.semantic.query.parser.calcite.sql.Optimization;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSqlDialect;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -11,6 +11,8 @@ import java.util.List;
import java.util.Set;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.sql.SqlAsOperator;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlIdentifier;
@@ -18,10 +20,13 @@ import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.SqlWriterConfig;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.pretty.SqlPrettyWriter;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.calcite.sql2rel.SqlToRelConverter;
import org.apache.commons.lang3.StringUtils;
public abstract class SemanticNode {
@@ -118,6 +123,13 @@ public abstract class SemanticNode {
return sqlNode;
}
public static RelNode getRelNode(CalciteSchema rootSchema, SqlToRelConverter sqlToRelConverter, String sql)
throws SqlParseException {
SqlValidator sqlValidator = Configuration.getSqlValidator(rootSchema);
return sqlToRelConverter.convertQuery(
sqlValidator.validate(SqlParser.create(sql, SqlParser.Config.DEFAULT).parseStmt()), false, true).rel;
}
public void accept(Optimization optimization) {
optimization.visit(this);
}

View File

@@ -5,7 +5,10 @@ import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Constants;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.DataSource;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Dimension;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Identify;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Identify.Type;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Materialization.TimePartType;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Metric;
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSchema;
import com.tencent.supersonic.semantic.query.parser.calcite.sql.Renderer;
@@ -97,7 +100,9 @@ public class JoinRender extends Renderer {
fieldWhere.add(identify.getName());
}
}
TableView tableView = SourceRender.renderOne("", fieldWhere, queryMetrics, queryDimension,
List<String> dataSourceWhere = new ArrayList<>(fieldWhere);
addZipperField(dataSource, dataSourceWhere);
TableView tableView = SourceRender.renderOne("", dataSourceWhere, queryMetrics, queryDimension,
metricCommand.getWhere(), dataSources.get(i), scope, schema, true);
log.info("tableView {}", tableView.getTable().toString());
String alias = Constants.JOIN_TABLE_PREFIX + dataSource.getName();
@@ -255,7 +260,10 @@ public class JoinRender extends Renderer {
private SqlNode getCondition(TableView left, TableView right, DataSource dataSource, SemanticSchema schema,
SqlValidatorScope scope) throws Exception {
if (TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) || TimePartType.ZIPPER.equals(
right.getDataSource().getTimePartType())) {
return getZipperCondition(left, right, dataSource, schema, scope);
}
Set<String> selectLeft = SemanticNode.getSelect(left.getTable());
Set<String> selectRight = SemanticNode.getSelect(right.getTable());
selectLeft.retainAll(selectRight);
@@ -376,4 +384,95 @@ public class JoinRender extends Renderer {
orders.poll();
visited.put(id, false);
}
private void addZipperField(DataSource dataSource, List<String> fields) {
if (TimePartType.ZIPPER.equals(dataSource.getTimePartType())) {
dataSource.getDimensions().stream()
.filter(d -> Constants.DIMENSION_TYPE_TIME.equalsIgnoreCase(d.getType())).forEach(t -> {
if (t.getName().startsWith(Constants.MATERIALIZATION_ZIPPER_END)
&& !fields.contains(t.getName())
) {
fields.add(t.getName());
}
if (t.getName().startsWith(Constants.MATERIALIZATION_ZIPPER_START)
&& !fields.contains(t.getName())
) {
fields.add(t.getName());
}
});
}
}
private SqlNode getZipperCondition(TableView left, TableView right, DataSource dataSource, SemanticSchema schema,
SqlValidatorScope scope) throws Exception {
if (TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) && TimePartType.ZIPPER.equals(
right.getDataSource().getTimePartType())) {
throw new Exception("not support two zipper table");
}
SqlNode condition = null;
Optional<Dimension> leftTime = left.getDataSource().getDimensions().stream()
.filter(d -> Constants.DIMENSION_TYPE_TIME.equalsIgnoreCase(d.getType())).findFirst();
Optional<Dimension> rightTime = right.getDataSource().getDimensions().stream()
.filter(d -> Constants.DIMENSION_TYPE_TIME.equalsIgnoreCase(d.getType())).findFirst();
if (leftTime.isPresent() && rightTime.isPresent()) {
String startTime = "";
String endTime = "";
String dateTime = "";
List<String> primaryZipper = new ArrayList<>();
List<String> primaryPartition = new ArrayList<>();
Optional<Dimension> startTimeOp = (TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) ? left
: right).getDataSource().getDimensions().stream()
.filter(d -> Constants.DIMENSION_TYPE_TIME.equalsIgnoreCase(d.getType()))
.filter(d -> d.getName().startsWith(Constants.MATERIALIZATION_ZIPPER_START)).findFirst();
Optional<Dimension> endTimeOp = (TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) ? left
: right).getDataSource().getDimensions().stream()
.filter(d -> Constants.DIMENSION_TYPE_TIME.equalsIgnoreCase(d.getType()))
.filter(d -> d.getName().startsWith(Constants.MATERIALIZATION_ZIPPER_END)).findFirst();
if (startTimeOp.isPresent() && endTimeOp.isPresent()) {
TableView zipper = TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) ? left : right;
TableView partMetric =
TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) ? right : left;
Optional<Dimension> partTime =
TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) ? rightTime : leftTime;
startTime = zipper.getAlias() + "." + startTimeOp.get().getName();
endTime = zipper.getAlias() + "." + endTimeOp.get().getName();
dateTime = partMetric.getAlias() + "." + partTime.get().getName();
primaryZipper = zipper.getDataSource().getIdentifiers().stream().map(i -> i.getName()).collect(
Collectors.toList());
primaryPartition = partMetric.getDataSource().getIdentifiers().stream().map(i -> i.getName()).collect(
Collectors.toList());
}
primaryZipper.retainAll(primaryPartition);
condition =
new SqlBasicCall(
SqlStdOperatorTable.AND,
new ArrayList<SqlNode>(Arrays.asList(new SqlBasicCall(
SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
new ArrayList<SqlNode>(Arrays.asList(SemanticNode.parse(startTime, scope),
SemanticNode.parse(dateTime, scope))),
SqlParserPos.ZERO, null), new SqlBasicCall(
SqlStdOperatorTable.GREATER_THAN,
new ArrayList<SqlNode>(Arrays.asList(SemanticNode.parse(endTime, scope),
SemanticNode.parse(dateTime, scope))),
SqlParserPos.ZERO, null))),
SqlParserPos.ZERO, null);
for (String p : primaryZipper) {
List<SqlNode> ons = new ArrayList<>();
ons.add(SemanticNode.parse(left.getAlias() + "." + p, scope));
ons.add(SemanticNode.parse(right.getAlias() + "." + p, scope));
SqlNode addCondition = new SqlBasicCall(
SqlStdOperatorTable.EQUALS,
ons,
SqlParserPos.ZERO, null);
condition = new SqlBasicCall(
SqlStdOperatorTable.AND,
new ArrayList<>(Arrays.asList(condition, addCondition)),
SqlParserPos.ZERO, null);
}
}
return condition;
}
}

View File

@@ -1,5 +1,8 @@
package com.tencent.supersonic.semantic.query.parser.convert;
import com.tencent.supersonic.common.pojo.Aggregator;
import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum;
import com.tencent.supersonic.common.util.DateUtils;
import com.tencent.supersonic.common.util.jsqlparser.SqlParserReplaceHelper;
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectFunctionHelper;
@@ -13,6 +16,7 @@ import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.pojo.MetricTable;
import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq;
import com.tencent.supersonic.semantic.api.query.request.QueryDslReq;
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
import com.tencent.supersonic.semantic.model.domain.Catalog;
import com.tencent.supersonic.semantic.model.domain.ModelService;
import com.tencent.supersonic.semantic.model.domain.adaptor.engineadapter.EngineAdaptor;
@@ -51,6 +55,7 @@ public class QueryReqConverter {
private Catalog catalog;
public QueryStatement convert(QueryDslReq databaseReq, ModelSchemaResp modelSchemaResp) throws Exception {
if (Objects.isNull(modelSchemaResp)) {
return new QueryStatement();
}
@@ -68,6 +73,7 @@ public class QueryReqConverter {
//4.build MetricTables
List<String> allFields = SqlParserSelectHelper.getAllFields(databaseReq.getSql());
List<String> metrics = getMetrics(modelSchemaResp, allFields);
QueryStructReq queryStructCmd = new QueryStructReq();
MetricTable metricTable = new MetricTable();
metricTable.setMetrics(metrics);
@@ -81,8 +87,13 @@ public class QueryReqConverter {
metricTable.setMetrics(new ArrayList<>(Arrays.asList(
queryStructUtils.generateInternalMetricName(databaseReq.getModelId(),
metricTable.getDimensions()))));
} else {
queryStructCmd.setAggregators(
metricTable.getMetrics().stream().map(m -> new Aggregator(m, AggOperatorEnum.UNKNOWN)).collect(
Collectors.toList()));
}
metricTable.setAggOption(getAggOption(databaseReq));
AggOption aggOption = getAggOption(databaseReq);
metricTable.setAggOption(aggOption);
List<MetricTable> tables = new ArrayList<>();
tables.add(metricTable);
//4.build ParseSqlReq
@@ -97,7 +108,11 @@ public class QueryReqConverter {
result.setWithAlias(false);
}
//5.physicalSql by ParseSqlReq
QueryStatement queryStatement = parserService.physicalSql(result);
queryStructCmd.setDateInfo(queryStructUtils.getDateConfBySql(databaseReq.getSql()));
queryStructCmd.setModelId(databaseReq.getModelId());
queryStructCmd.setNativeQuery(!AggOption.isAgg(aggOption));
log.info("QueryReqConverter queryStructCmd[{}]", queryStructCmd);
QueryStatement queryStatement = parserService.physicalSql(queryStructCmd, result);
queryStatement.setSql(String.format(SqlExecuteReq.LIMIT_WRAPPER, queryStatement.getSql()));
return queryStatement;
}

View File

@@ -1,14 +1,24 @@
package com.tencent.supersonic.semantic.query.persistence.pojo;
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq;
import java.util.List;
import lombok.Data;
import org.apache.commons.lang3.tuple.ImmutablePair;
@Data
public class QueryStatement {
private Long modelId = 0L;
private String sql = "";
private String sourceId = "";
private String errMsg = "";
private Boolean ok;
private MetricReq metricReq;
private ParseSqlReq parseSqlReq;
private Integer status = 0;
private List<ImmutablePair<String, String>> timeRanges;
public boolean isOk() {
this.ok = "".equals(errMsg) && !"".equals(sql);

View File

@@ -68,7 +68,8 @@ public class QueryController {
public SqlParserResp parseByStruct(@RequestBody ParseSqlReq parseSqlReq,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
QueryStatement queryStatement = semanticQueryEngine.physicalSql(parseSqlReq);
QueryStructReq queryStructCmd = new QueryStructReq();
QueryStatement queryStatement = semanticQueryEngine.physicalSql(queryStructCmd, parseSqlReq);
SqlParserResp sqlParserResp = new SqlParserResp();
BeanUtils.copyProperties(queryStatement, sqlParserResp);
return sqlParserResp;

View File

@@ -4,6 +4,8 @@ import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.common.pojo.enums.AuthType;
import com.tencent.supersonic.semantic.api.materialization.request.MaterializationSourceReq;
import com.tencent.supersonic.semantic.api.materialization.response.MaterializationSourceResp;
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
import com.tencent.supersonic.semantic.api.model.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
@@ -12,6 +14,7 @@ import com.tencent.supersonic.semantic.api.model.response.DomainResp;
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
import com.tencent.supersonic.semantic.query.service.MaterializationService;
import com.tencent.supersonic.semantic.query.service.SchemaService;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@@ -30,6 +33,8 @@ public class SchemaController {
@Autowired
private SchemaService schemaService;
@Autowired
private MaterializationService materializationService;
@PostMapping
public List<ModelSchemaResp> fetchModelSchema(@RequestBody ModelSchemaFilterReq filter,
@@ -71,4 +76,16 @@ public class SchemaController {
return schemaService.queryMetric(pageMetricCmd, user);
}
/**
* task api
*/
@PostMapping("/materialization/source")
MaterializationSourceResp queryDataSource(@RequestBody MaterializationSourceReq materializationSourceReq,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
User user = UserHolder.findUser(request, response);
return materializationService.getMaterializationDataSource(materializationSourceReq, user);
}
}

Some files were not shown because too many files have changed in this diff Show More