10 Commits

Author SHA1 Message Date
zyclove
36b2b4c4db Merge 668f872743 into a3293e6788 2025-03-09 17:35:30 +08:00
zyclove
a3293e6788 fix:java.lang.NullPointerException: Cannot invoke "com.tencent.supersonic.common.pojo.DateConf.getDateField()" because "dateConf" is null (#2142)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-03-09 13:44:07 +08:00
jerryjzhang
a99f5985f5 (improvement)(headless)Set fields of model detail when restoring model.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-03-09 10:58:49 +08:00
jerryjzhang
91243005bc (fix)(launcher)Change join_condition to type text to avoid "value too long for column". 2025-03-09 09:18:29 +08:00
jerryjzhang
a76b5a4300 (improvement)(headless)Add unit to measure. 2025-03-09 09:15:13 +08:00
jerryjzhang
c1f9df963c (improvement)(headless)Add expr to semantic column. 2025-03-09 08:31:48 +08:00
Shaofeng Shi
954aa4eea5 fix: https://github.com/tencentmusic/supersonic/issues/2132 for Trino syntax (#2144)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-03-08 21:41:35 +08:00
jerryjzhang
33bd0de604 (improvement)(headless)Set fields of model detail when creating model. 2025-03-08 21:16:10 +08:00
zhaoyingchao
668f872743 Merge remote-tracking branch 'origin/master' into jsqlparser-fix 2025-03-05 10:01:57 +08:00
zhaoyingchao
acb9cef64e feat:upgrade jsqlparser 4.9 and add timeout 2025-02-27 17:30:48 +08:00
19 changed files with 66 additions and 62 deletions

View File

@@ -225,7 +225,7 @@ public class SqlSelectHelper {
public static Select getSelect(String sql) {
Statement statement = null;
try {
statement = CCJSqlParserUtil.parse(sql);
statement = CCJSqlParserUtil.parse(sql, parser -> parser.withTimeOut(20000));
} catch (JSQLParserException e) {
log.error("parse error, sql:{}", sql, e);
throw new RuntimeException(e);

View File

@@ -23,12 +23,16 @@ public class Measure {
private String alias;
public Measure(String name, String bizName, String expr, String agg, Integer isCreateMetric) {
private String unit;
public Measure(String name, String bizName, String expr, String agg, String unit,
Integer isCreateMetric) {
this.name = name;
this.agg = agg;
this.isCreateMetric = isCreateMetric;
this.bizName = bizName;
this.expr = expr;
this.unit = unit;
}
public Measure(String name, String bizName, String agg, Integer isCreateMetric) {

View File

@@ -49,27 +49,4 @@ public class ModelDetail {
.collect(Collectors.toList());
}
public List<Field> getFields() {
if (!CollectionUtils.isEmpty(fields)) {
return fields;
}
List<Field> fieldList = Lists.newArrayList();
// Compatible with older versions
if (!CollectionUtils.isEmpty(identifiers)) {
fieldList.addAll(identifiers.stream()
.map(identify -> Field.builder().fieldName(identify.getFieldName()).build())
.collect(Collectors.toSet()));
}
if (!CollectionUtils.isEmpty(dimensions)) {
fieldList.addAll(dimensions.stream()
.map(dim -> Field.builder().fieldName(dim.getFieldName()).build())
.collect(Collectors.toSet()));
}
if (!CollectionUtils.isEmpty(measures)) {
fieldList.addAll(measures.stream()
.map(measure -> Field.builder().fieldName(measure.getFieldName()).build())
.collect(Collectors.toSet()));
}
return fieldList;
}
}

View File

@@ -14,11 +14,11 @@ public class ModelSchema {
private String description;
private List<ColumnSchema> columnSchemas;
private List<SemanticColumn> semanticColumns;
@JsonIgnore
public ColumnSchema getColumnByName(String columnName) {
for (ColumnSchema fieldSchema : columnSchemas) {
public SemanticColumn getColumnByName(String columnName) {
for (SemanticColumn fieldSchema : semanticColumns) {
if (fieldSchema.getColumnName().equalsIgnoreCase(columnName)) {
return fieldSchema;
}

View File

@@ -5,7 +5,7 @@ import com.tencent.supersonic.headless.api.pojo.enums.FieldType;
import lombok.Data;
@Data
public class ColumnSchema {
public class SemanticColumn {
private String columnName;
@@ -19,4 +19,8 @@ public class ColumnSchema {
private String name;
private String expr;
private String unit;
}

View File

@@ -83,6 +83,7 @@ public class PrestoAdaptor extends BaseDbAdaptor {
@Override
public String rewriteSql(String sql) {
sql = sql.replaceAll("`", "\"");
return sql;
}
}

View File

@@ -100,6 +100,7 @@ public class SemanticSchemaManager {
modelDetail.getIdentifiers().addAll(getIdentify(d.getIdentifiers()));
modelDetail.getMeasures().addAll(getMeasureParams(d.getMeasures()));
modelDetail.getDimensions().addAll(getDimensions(d.getDimensions()));
modelDetail.getFields().addAll(d.getFields());
return dataModel;
}

View File

@@ -75,6 +75,7 @@ public class LLMSemanticModeller implements SemanticModeller {
if (!chatApp.isPresent() || !chatApp.get().isEnable()) {
return;
}
List<DbSchema> otherDbSchema = getOtherDbSchema(dbSchema, dbSchemas);
ModelSchemaExtractor extractor =
AiServices.create(ModelSchemaExtractor.class, getChatModel(modelBuildReq));

View File

@@ -1,9 +1,9 @@
package com.tencent.supersonic.headless.server.modeller;
import com.tencent.supersonic.headless.api.pojo.ColumnSchema;
import com.tencent.supersonic.headless.api.pojo.DBColumn;
import com.tencent.supersonic.headless.api.pojo.DbSchema;
import com.tencent.supersonic.headless.api.pojo.ModelSchema;
import com.tencent.supersonic.headless.api.pojo.SemanticColumn;
import com.tencent.supersonic.headless.api.pojo.request.ModelBuildReq;
import lombok.extern.slf4j.Slf4j;
@@ -16,19 +16,20 @@ public class RuleSemanticModeller implements SemanticModeller {
@Override
public void build(DbSchema dbSchema, List<DbSchema> dbSchemas, ModelSchema modelSchema,
ModelBuildReq modelBuildReq) {
List<ColumnSchema> columnSchemas =
List<SemanticColumn> semanticColumns =
dbSchema.getDbColumns().stream().map(this::convert).collect(Collectors.toList());
modelSchema.setColumnSchemas(columnSchemas);
modelSchema.setSemanticColumns(semanticColumns);
}
private ColumnSchema convert(DBColumn dbColumn) {
ColumnSchema columnSchema = new ColumnSchema();
columnSchema.setName(dbColumn.getColumnName());
columnSchema.setColumnName(dbColumn.getColumnName());
columnSchema.setComment(dbColumn.getComment());
columnSchema.setDataType(dbColumn.getDataType());
columnSchema.setFiledType(dbColumn.getFieldType());
return columnSchema;
private SemanticColumn convert(DBColumn dbColumn) {
SemanticColumn semanticColumn = new SemanticColumn();
semanticColumn.setName(dbColumn.getColumnName());
semanticColumn.setColumnName(dbColumn.getColumnName());
semanticColumn.setExpr(dbColumn.getColumnName());
semanticColumn.setComment(dbColumn.getComment());
semanticColumn.setDataType(dbColumn.getDataType());
semanticColumn.setFiledType(dbColumn.getFieldType());
return semanticColumn;
}
}

View File

@@ -7,6 +7,9 @@ import com.tencent.supersonic.headless.api.pojo.request.ModelBuildReq;
import java.util.List;
/**
* A semantic modeler builds semantic-layer schemas from database-layer schemas.
*/
public interface SemanticModeller {
void build(DbSchema dbSchema, List<DbSchema> otherDbSchema, ModelSchema modelSchema,

View File

@@ -277,8 +277,8 @@ public class ModelServiceImpl implements ModelService {
dimensionService.createDimensionBatch(dimensionReqs, user);
}
private void batchCreateMetric(ModelDO datasourceDO, User user) throws Exception {
List<MetricReq> metricReqs = ModelConverter.convertMetricList(datasourceDO);
private void batchCreateMetric(ModelDO modelDO, User user) throws Exception {
List<MetricReq> metricReqs = ModelConverter.convertMetricList(modelDO);
metricService.createMetricBatch(metricReqs, user);
}

View File

@@ -425,8 +425,12 @@ public class DictUtils {
.format(DateTimeFormatter.ofPattern(format));
String end = LocalDate.now().minusDays(itemValueDateEnd)
.format(DateTimeFormatter.ofPattern(format));
return String.format("( %s >= '%s' and %s <= '%s' )", dateConf.getDateField(), start,
dateConf.getDateField(), end);
if (Objects.nonNull(dateConf)) {
return String.format("( %s >= '%s' and %s <= '%s' )", dateConf.getDateField(), start,
dateConf.getDateField(), end);
} else {
return String.format("( %s >= '%s' and %s <= '%s' )", "dt", start, "dt", end);
}
}
private String generateDictDateFilter(DictItemResp dictItemResp) {
@@ -440,7 +444,7 @@ public class DictUtils {
}
// 未进行设置
if (Objects.isNull(config) || Objects.isNull(config.getDateConf())) {
return defaultDateFilter(config.getDateConf());
return defaultDateFilter(null);
}
// 全表扫描
if (DateConf.DateMode.ALL.equals(config.getDateConf().getDateMode())) {

View File

@@ -157,23 +157,28 @@ public class ModelConverter {
modelDetail.setQueryType(ModelDefineType.TABLE_QUERY.getName());
modelDetail.setTableQuery(String.format("%s.%s", modelBuildReq.getDb(), tableName));
}
for (ColumnSchema columnSchema : modelSchema.getColumnSchemas()) {
FieldType fieldType = columnSchema.getFiledType();
List<Field> fields = new ArrayList<>();
for (SemanticColumn semanticColumn : modelSchema.getSemanticColumns()) {
FieldType fieldType = semanticColumn.getFiledType();
fields.add(new Field(semanticColumn.getName(), semanticColumn.getDataType()));
if (getIdentifyType(fieldType) != null) {
Identify identify = new Identify(columnSchema.getName(),
getIdentifyType(fieldType).name(), columnSchema.getColumnName(), 1);
Identify identify = new Identify(semanticColumn.getName(),
getIdentifyType(fieldType).name(), semanticColumn.getColumnName(), 1);
modelDetail.getIdentifiers().add(identify);
} else if (FieldType.measure.equals(fieldType)) {
Measure measure = new Measure(columnSchema.getName(), columnSchema.getColumnName(),
columnSchema.getColumnName(), columnSchema.getAgg().getOperator(), 1);
Measure measure = new Measure(semanticColumn.getName(),
semanticColumn.getColumnName(), semanticColumn.getExpr(),
semanticColumn.getAgg().getOperator(), semanticColumn.getUnit(), 1);
modelDetail.getMeasures().add(measure);
} else {
Dimension dim = new Dimension(columnSchema.getName(), columnSchema.getColumnName(),
columnSchema.getColumnName(),
DimensionType.valueOf(columnSchema.getFiledType().name()), 1);
Dimension dim = new Dimension(semanticColumn.getName(),
semanticColumn.getColumnName(), semanticColumn.getExpr(),
DimensionType.valueOf(semanticColumn.getFiledType().name()), 1);
modelDetail.getDimensions().add(dim);
}
}
modelDetail.setFields(fields);
modelReq.setModelDetail(modelDetail);
return modelReq;
}

View File

@@ -410,4 +410,7 @@ ALTER TABLE s2_query_stat_info RENAME COLUMN `sql` TO `query_sql`;
--20250224
ALTER TABLE s2_agent add column `admin_org` varchar(3000) DEFAULT NULL COMMENT '管理员组织';
ALTER TABLE s2_agent add column `view_org` varchar(3000) DEFAULT NULL COMMENT '可用组织';
ALTER TABLE s2_agent add column `is_open` tinyint DEFAULT NULL COMMENT '是否公开';
ALTER TABLE s2_agent add column `is_open` tinyint DEFAULT NULL COMMENT '是否公开';
--20250309
ALTER TABLE s2_model_rela alter column join_condition type text;

View File

@@ -268,7 +268,7 @@ CREATE TABLE IF NOT EXISTS s2_model_rela
from_model_id BIGINT,
to_model_id BIGINT,
join_type VARCHAR(255),
join_condition VARCHAR(255),
join_condition TEXT,
PRIMARY KEY (`id`)
);

View File

@@ -404,7 +404,7 @@ CREATE TABLE IF NOT EXISTS s2_model_rela
from_model_id bigint,
to_model_id bigint,
join_type VARCHAR(255),
join_condition VARCHAR(255)
join_condition text
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `s2_collect` (

View File

@@ -465,7 +465,7 @@ CREATE TABLE IF NOT EXISTS s2_model_rela (
from_model_id bigint,
to_model_id bigint,
join_type VARCHAR(255),
join_condition VARCHAR(255)
join_condition text
);
CREATE TABLE IF NOT EXISTS s2_collect (

View File

@@ -39,14 +39,14 @@ public class SemanticModellerTest extends BaseTest {
Map<String, ModelSchema> modelSchemaMap = modelService.buildModelSchema(modelSchemaReq);
ModelSchema userModelSchema = modelSchemaMap.get("s2_user_department");
Assertions.assertEquals(2, userModelSchema.getColumnSchemas().size());
Assertions.assertEquals(2, userModelSchema.getSemanticColumns().size());
Assertions.assertEquals(FieldType.primary_key,
userModelSchema.getColumnByName("user_name").getFiledType());
Assertions.assertEquals(FieldType.categorical,
userModelSchema.getColumnByName("department").getFiledType());
ModelSchema stayTimeModelSchema = modelSchemaMap.get("s2_stay_time_statis");
Assertions.assertEquals(4, stayTimeModelSchema.getColumnSchemas().size());
Assertions.assertEquals(4, stayTimeModelSchema.getSemanticColumns().size());
Assertions.assertEquals(FieldType.foreign_key,
stayTimeModelSchema.getColumnByName("user_name").getFiledType());
Assertions.assertEquals(FieldType.partition_time,
@@ -72,7 +72,7 @@ public class SemanticModellerTest extends BaseTest {
Map<String, ModelSchema> modelSchemaMap = modelService.buildModelSchema(modelSchemaReq);
ModelSchema pvModelSchema = modelSchemaMap.values().iterator().next();
Assertions.assertEquals(5, pvModelSchema.getColumnSchemas().size());
Assertions.assertEquals(5, pvModelSchema.getSemanticColumns().size());
Assertions.assertEquals(FieldType.partition_time,
pvModelSchema.getColumnByName("imp_date").getFiledType());
Assertions.assertEquals(FieldType.categorical,

View File

@@ -32,7 +32,7 @@
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<file.encoding>UTF-8</file.encoding>
<jsqlparser.version>4.7</jsqlparser.version>
<jsqlparser.version>4.9</jsqlparser.version>
<pagehelper.version>6.1.0</pagehelper.version>
<pagehelper.spring.version>2.1.0</pagehelper.spring.version>
<mybatis.version>3.5.3</mybatis.version>