Skip to content

Commit c96e47e

Browse files
authored
[Feature][Metric] Custom SQL support export error data (#586)
1 parent c7955f6 commit c96e47e

14 files changed

Lines changed: 279 additions & 20 deletions

File tree

datavines-common/src/main/java/io/datavines/common/ConfigConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class ConfigConstants {
3838
public static final String ACTUAL_NAME = "actual_name";
3939
public static final String ACTUAL_EXECUTE_SQL = "actual_execute_sql";
4040
public static final String ACTUAL_AGGREGATE_SQL = "actual_aggregate_sql";
41+
public static final String INVALIDATE_ITEMS_SQL = "invalidate_items_sql";
4142
public static final String ACTUAL_CUSTOM_SQL = "actual_custom_sql";
4243
public static final String EXPECTED_NAME = "expected_name";
4344
public static final String EXPECTED_TYPE = "expected_type";

datavines-engine/datavines-engine-plugins/datavines-engine-flink/datavines-engine-flink-config/src/main/java/io/datavines/engine/flink/config/BaseFlinkConfigurationBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ protected List<SourceConfig> getSourceConfigs() throws DataVinesException {
7676

7777
.getNewPlugin(metricType);
7878
if (sqlMetric.isCustomSql()) {
79-
List<String> tables = SqlUtils.extractTablesFromSelect(metricInputParameter.get(ACTUAL_AGGREGATE_SQL));
79+
List<String> tables = SqlUtils.extractTablesFromSelect(sqlMetric.getTableDiscoverySql(metricInputParameter));
8080
if (CollectionUtils.isEmpty(tables)) {
8181
throw new DataVinesException("custom sql must have table");
8282
}
@@ -138,13 +138,13 @@ protected List<SourceConfig> getSourceConfigs() throws DataVinesException {
138138
sourceConnectorSet.add(connectorUUID);
139139
}
140140

141-
if (StringUtils.isNotEmpty(metricInputParameter.get(ACTUAL_AGGREGATE_SQL))) {
142-
String sql = metricInputParameter.get(ACTUAL_AGGREGATE_SQL);
141+
if (StringUtils.isNotEmpty(sqlMetric.getTableDiscoverySql(metricInputParameter))) {
142+
String sql = sqlMetric.getTableDiscoverySql(metricInputParameter);
143143
for (Map.Entry<String, String> entry : table2OutputTable.entrySet()) {
144144
sql = sql.replaceAll(entry.getKey(), entry.getValue());
145145
}
146146

147-
metricInputParameter.put(ACTUAL_AGGREGATE_SQL, sql);
147+
sqlMetric.setTableDiscoverySql(metricInputParameter, sql);
148148
}
149149
} else {
150150
ConnectorParameter connectorParameter = jobExecutionParameter.getConnectorParameter();

datavines-engine/datavines-engine-plugins/datavines-engine-local/datavines-engine-local-config/src/main/java/io/datavines/engine/local/config/BaseLocalConfigurationBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ protected List<SourceConfig> getSourceConfigs() throws DataVinesException {
7373

7474
.getNewPlugin(connectorParameter.getType());
7575

76-
List<String> tables = SqlUtils.extractTablesFromSelect(metricInputParameter.get(ACTUAL_AGGREGATE_SQL));
76+
List<String> tables = SqlUtils.extractTablesFromSelect(sqlMetric.getTableDiscoverySql(metricInputParameter));
7777
if (CollectionUtils.isEmpty(tables)) {
7878
throw new DataVinesException("custom sql must have table");
7979
}

datavines-engine/datavines-engine-plugins/datavines-engine-spark/datavines-engine-spark-config/src/main/java/io/datavines/engine/spark/config/BaseSparkConfigurationBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ protected List<SourceConfig> getSourceConfigs() throws DataVinesException {
102102

103103
.getNewPlugin(metricType);
104104
if (sqlMetric.isCustomSql()) {
105-
List<String> tables = SqlUtils.extractTablesFromSelect(metricInputParameter.get(ACTUAL_AGGREGATE_SQL));
105+
List<String> tables = SqlUtils.extractTablesFromSelect(sqlMetric.getTableDiscoverySql(metricInputParameter));
106106
if (CollectionUtils.isEmpty(tables)) {
107107
throw new DataVinesException("custom sql must have table");
108108
}
@@ -164,13 +164,13 @@ protected List<SourceConfig> getSourceConfigs() throws DataVinesException {
164164
sourceConnectorSet.add(connectorUUID);
165165
}
166166

167-
if (StringUtils.isNotEmpty(metricInputParameter.get(ACTUAL_AGGREGATE_SQL))) {
168-
String sql = metricInputParameter.get(ACTUAL_AGGREGATE_SQL);
167+
if (StringUtils.isNotEmpty(sqlMetric.getTableDiscoverySql(metricInputParameter))) {
168+
String sql = sqlMetric.getTableDiscoverySql(metricInputParameter);
169169
for (Map.Entry<String, String> entry : table2OutputTable.entrySet()) {
170170
sql = sql.replaceAll(entry.getKey(), entry.getValue());
171171
}
172172

173-
metricInputParameter.put(ACTUAL_AGGREGATE_SQL, sql);
173+
sqlMetric.setTableDiscoverySql(metricInputParameter, sql);
174174
}
175175
} else {
176176
ConnectorParameter connectorParameter = jobExecutionParameter.getConnectorParameter();

datavines-metric/datavines-metric-api/src/main/java/io/datavines/metric/api/SqlMetric.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import io.datavines.common.entity.ExecuteSql;
2626
import io.datavines.common.enums.DataVinesDataType;
2727

28+
import static io.datavines.common.ConfigConstants.ACTUAL_AGGREGATE_SQL;
29+
2830
public interface SqlMetric {
2931

3032
String getName();
@@ -115,4 +117,12 @@ default MetricDirectionType getDirectionType() {
115117
default boolean isCustomSql() {
116118
return false;
117119
}
120+
121+
default String getTableDiscoverySql(Map<String, String> inputParameter) {
122+
return inputParameter.get(ACTUAL_AGGREGATE_SQL);
123+
}
124+
125+
default void setTableDiscoverySql(Map<String, String> inputParameter, String sql) {
126+
inputParameter.put(ACTUAL_AGGREGATE_SQL, sql);
127+
}
118128
}

datavines-metric/datavines-metric-plugins/datavines-metric-all/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,12 @@
180180
<version>${project.version}</version>
181181
</dependency>
182182

183+
<dependency>
184+
<groupId>io.datavines</groupId>
185+
<artifactId>datavines-metric-custom-count-sql</artifactId>
186+
<version>${project.version}</version>
187+
</dependency>
188+
183189
<dependency>
184190
<groupId>io.datavines</groupId>
185191
<artifactId>datavines-metric-multi-table-accuracy</artifactId>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Licensed to the Apache Software Foundation (ASF) under one or more
5+
contributor license agreements. See the NOTICE file distributed with
6+
this work for additional information regarding copyright ownership.
7+
The ASF licenses this file to You under the Apache License, Version 2.0
8+
(the "License"); you may not use this file except in compliance with
9+
the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
<project xmlns="http://maven.apache.org/POM/4.0.0"
22+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
24+
<parent>
25+
<artifactId>datavines-metric-plugins</artifactId>
26+
<groupId>io.datavines</groupId>
27+
<version>1.0.0-SNAPSHOT</version>
28+
</parent>
29+
<modelVersion>4.0.0</modelVersion>
30+
31+
<artifactId>datavines-metric-custom-count-sql</artifactId>
32+
33+
34+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package io.datavines.metric.plugin;
18+
19+
import java.util.*;
20+
21+
import io.datavines.common.config.CheckResult;
22+
import io.datavines.common.config.ConfigChecker;
23+
import io.datavines.common.entity.ExecuteSql;
24+
import io.datavines.common.enums.DataVinesDataType;
25+
import io.datavines.common.utils.StringUtils;
26+
import io.datavines.metric.api.ConfigItem;
27+
import io.datavines.metric.api.MetricDimension;
28+
import io.datavines.metric.api.MetricType;
29+
import io.datavines.metric.api.SqlMetric;
30+
31+
import static io.datavines.common.CommonConstants.TABLE;
32+
import static io.datavines.common.ConfigConstants.*;
33+
34+
public class CustomCountSql implements SqlMetric {
35+
36+
private final Set<String> requiredOptions = new HashSet<>();
37+
38+
private final HashMap<String, ConfigItem> configMap = new HashMap<>();
39+
40+
private String invalidateItemsSql = null;
41+
42+
public CustomCountSql() {
43+
configMap.put(INVALIDATE_ITEMS_SQL, new ConfigItem(INVALIDATE_ITEMS_SQL, "错误数据SQL", INVALIDATE_ITEMS_SQL));
44+
45+
requiredOptions.add(INVALIDATE_ITEMS_SQL);
46+
}
47+
48+
@Override
49+
public String getName() {
50+
return "custom_count_sql";
51+
}
52+
53+
@Override
54+
public String getZhName() {
55+
return "自定义统计SQL";
56+
}
57+
58+
@Override
59+
public MetricDimension getDimension() {
60+
return MetricDimension.ACCURACY;
61+
}
62+
63+
@Override
64+
public MetricType getType() {
65+
return MetricType.SINGLE_TABLE;
66+
}
67+
68+
@Override
69+
public boolean isInvalidateItemsCanOutput() {
70+
return true;
71+
}
72+
73+
@Override
74+
public CheckResult validateConfig(Map<String, Object> config) {
75+
CheckResult basicCheck = ConfigChecker.checkConfig(config, requiredOptions);
76+
if (!basicCheck.isSuccess()) {
77+
return basicCheck;
78+
}
79+
80+
Object sqlValue = config.get(INVALIDATE_ITEMS_SQL);
81+
if (sqlValue == null || StringUtils.isEmpty(String.valueOf(sqlValue).trim())) {
82+
return new CheckResult(false, INVALIDATE_ITEMS_SQL + " cannot be empty");
83+
}
84+
85+
return new CheckResult(true, "");
86+
}
87+
88+
@Override
89+
public void prepare(Map<String, String> config) {
90+
if (config.containsKey(INVALIDATE_ITEMS_SQL) && StringUtils.isNotEmpty(config.get(INVALIDATE_ITEMS_SQL))) {
91+
this.invalidateItemsSql = config.get(INVALIDATE_ITEMS_SQL);
92+
}
93+
}
94+
95+
@Override
96+
public Map<String, ConfigItem> getConfigMap() {
97+
return configMap;
98+
}
99+
100+
@Override
101+
public ExecuteSql getInvalidateItems(Map<String, String> inputParameter) {
102+
if (StringUtils.isEmpty(invalidateItemsSql)) {
103+
throw new IllegalStateException("invalidate_items_sql is not configured or empty");
104+
}
105+
106+
String uniqueKey = inputParameter.get(METRIC_UNIQUE_KEY);
107+
if (StringUtils.isEmpty(uniqueKey)) {
108+
throw new IllegalStateException("metric_unique_key is missing in input parameters");
109+
}
110+
111+
ExecuteSql executeSql = new ExecuteSql();
112+
executeSql.setResultTable("invalidate_items_" + uniqueKey);
113+
executeSql.setSql(invalidateItemsSql);
114+
executeSql.setErrorOutput(true);
115+
return executeSql;
116+
}
117+
118+
@Override
119+
public ExecuteSql getActualValue(Map<String, String> inputParameter) {
120+
if (StringUtils.isEmpty(invalidateItemsSql)) {
121+
throw new IllegalStateException("invalidate_items_sql is not configured or empty");
122+
}
123+
124+
String uniqueKey = inputParameter.get(METRIC_UNIQUE_KEY);
125+
if (StringUtils.isEmpty(uniqueKey)) {
126+
throw new IllegalStateException("metric_unique_key is missing in input parameters");
127+
}
128+
129+
inputParameter.put(ACTUAL_TABLE, inputParameter.get(TABLE));
130+
131+
String actualAggregateSql = "select count(1) as actual_value_" + uniqueKey + " from ${invalidate_items_table}";
132+
133+
return new ExecuteSql(actualAggregateSql, "invalidate_count_" + uniqueKey);
134+
}
135+
136+
@Override
137+
public ExecuteSql getDirectActualValue(Map<String, String> inputParameter) {
138+
if (StringUtils.isEmpty(invalidateItemsSql)) {
139+
throw new IllegalStateException("invalidate_items_sql is not configured or empty");
140+
}
141+
142+
String uniqueKey = inputParameter.get(METRIC_UNIQUE_KEY);
143+
if (StringUtils.isEmpty(uniqueKey)) {
144+
throw new IllegalStateException("metric_unique_key is missing in input parameters");
145+
}
146+
147+
String actualAggregateSql = "select count(1) as actual_value_" + uniqueKey
148+
+ " from ( " + invalidateItemsSql + " ) t";
149+
150+
return new ExecuteSql(actualAggregateSql, "invalidate_count_" + uniqueKey);
151+
}
152+
153+
@Override
154+
public List<DataVinesDataType> suitableType() {
155+
return Collections.emptyList();
156+
}
157+
158+
@Override
159+
public boolean isCustomSql() {
160+
return true;
161+
}
162+
163+
@Override
164+
public String getTableDiscoverySql(Map<String, String> inputParameter) {
165+
return inputParameter.get(INVALIDATE_ITEMS_SQL);
166+
}
167+
168+
@Override
169+
public void setTableDiscoverySql(Map<String, String> inputParameter, String sql) {
170+
inputParameter.put(INVALIDATE_ITEMS_SQL, sql);
171+
this.invalidateItemsSql = sql;
172+
}
173+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.datavines.metric.plugin.CustomCountSql

datavines-metric/datavines-metric-plugins/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<module>datavines-metric-all</module>
3434
<module>datavines-metric-base</module>
3535
<module>datavines-metric-custom-aggregate-sql</module>
36+
<module>datavines-metric-custom-count-sql</module>
3637
<module>datavines-metric-multi-table-accuracy</module>
3738
<module>datavines-metric-table-freshness</module>
3839
<module>datavines-metric-table-row-count</module>

0 commit comments

Comments
 (0)