Browse Source

Fix SqlTask cannot split the given sql when browser in windows (#15062)

augit-log
Wenjun Ruan 7 months ago committed by GitHub
parent
commit
99214d0fc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 54
      dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/main/java/org/apache/dolphinscheduler/plugin/task/sql/SqlTask.java
  2. 50
      dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/main/java/org/apache/dolphinscheduler/plugin/task/sql/utils/SqlSplitUtils.java
  3. 4
      dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/test/java/org/apache/dolphinscheduler/plugin/task/sql/SqlTaskTest.java
  4. 34
      dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/test/java/org/apache/dolphinscheduler/plugin/task/sql/utils/SqlSplitUtilsTest.java

54
dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/main/java/org/apache/dolphinscheduler/plugin/task/sql/SqlTask.java

@ -37,6 +37,7 @@ import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters
import org.apache.dolphinscheduler.plugin.task.api.parameters.SqlParameters;
import org.apache.dolphinscheduler.plugin.task.api.parameters.resource.UdfFuncParameters;
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
import org.apache.dolphinscheduler.plugin.task.sql.utils.SqlSplitUtils;
import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam;
import org.apache.dolphinscheduler.spi.enums.DbType;
@ -60,8 +61,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@ -98,13 +97,8 @@ public class SqlTask extends AbstractTask {
public static final int TEST_FLAG_YES = 1;
private static final String SQL_SEPARATOR = ";\n";
private final DbType dbType;
/**
* Abstract Yarn Task
*
* @param taskRequest taskRequest
*/
public SqlTask(TaskExecutionContext taskRequest) {
super(taskRequest);
this.taskExecutionContext = taskRequest;
@ -119,6 +113,7 @@ public class SqlTask extends AbstractTask {
sqlTaskExecutionContext =
sqlParameters.generateExtendedContext(taskExecutionContext.getResourceParametersHelper());
dbType = DbType.valueOf(sqlParameters.getType());
}
@Override
@ -140,18 +135,17 @@ public class SqlTask extends AbstractTask {
sqlParameters.getConnParams(),
sqlParameters.getVarPool(),
sqlParameters.getLimit());
String separator = SQL_SEPARATOR;
try {
// get datasource
baseConnectionParam = (BaseConnectionParam) DataSourceUtils.buildConnectionParams(
DbType.valueOf(sqlParameters.getType()),
baseConnectionParam = (BaseConnectionParam) DataSourceUtils.buildConnectionParams(dbType,
sqlTaskExecutionContext.getConnectionParams());
if (DbType.valueOf(sqlParameters.getType()).isSupportMultipleStatement()) {
separator = "";
}
List<String> subSqls =
dbType.isSupportMultipleStatement() ? Collections.singletonList(sqlParameters.getSql())
: SqlSplitUtils.splitSql(sqlParameters.getSql());
// ready to execute SQL and parameter entity Map
List<SqlBinds> mainStatementSqlBinds = split(sqlParameters.getSql(), separator)
List<SqlBinds> mainStatementSqlBinds = subSqls
.stream()
.map(this::getSqlAndSqlParamsMap)
.collect(Collectors.toList());
@ -167,7 +161,7 @@ public class SqlTask extends AbstractTask {
.map(this::getSqlAndSqlParamsMap)
.collect(Collectors.toList());
List<String> createFuncs = createFuncs(sqlTaskExecutionContext.getUdfFuncParametersList(), log);
List<String> createFuncs = createFuncs(sqlTaskExecutionContext.getUdfFuncParametersList());
// execute sql task
executeFuncAndSql(mainStatementSqlBinds, preStatementSqlBinds, postStatementSqlBinds, createFuncs);
@ -186,31 +180,6 @@ public class SqlTask extends AbstractTask {
}
/**
* split sql by segment separator
* <p>The segment separator is used
* when the data source does not support multi-segment SQL execution,
* and the client needs to split the SQL and execute it multiple times.</p>
* @param sql
* @param segmentSeparator
* @return
*/
public static List<String> split(String sql, String segmentSeparator) {
if (StringUtils.isEmpty(segmentSeparator)) {
return Collections.singletonList(sql);
}
String[] lines = sql.split(segmentSeparator);
List<String> segments = new ArrayList<>();
for (String line : lines) {
if (line.trim().isEmpty() || line.startsWith("--")) {
continue;
}
segments.add(line);
}
return segments;
}
/**
* execute function and sql
*
@ -526,10 +495,9 @@ public class SqlTask extends AbstractTask {
* create function list
*
* @param udfFuncParameters udfFuncParameters
* @param log log
* @return
*/
private List<String> createFuncs(List<UdfFuncParameters> udfFuncParameters, Logger log) {
private List<String> createFuncs(List<UdfFuncParameters> udfFuncParameters) {
if (CollectionUtils.isEmpty(udfFuncParameters)) {
log.info("can't find udf function resource");

50
dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/main/java/org/apache/dolphinscheduler/plugin/task/sql/utils/SqlSplitUtils.java

@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.plugin.task.sql.utils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SqlSplitUtils {
private static final String UNIX_SQL_SEPARATOR = ";\n";
private static final String WINDOWS_SQL_SEPARATOR = ";\r\n";
/**
* split sql to submit sql.
* e.g.
* <pre>
* select * from table1\n;select * from table2\n;select * from table2\r\n;
* </pre>
* will be split to
* <pre>
* select * from table1
* select * from table2
* </pre>
*/
public static List<String> splitSql(String sql) {
return Arrays.stream(sql.replaceAll(WINDOWS_SQL_SEPARATOR, UNIX_SQL_SEPARATOR).split(UNIX_SQL_SEPARATOR))
.filter(subSql -> {
String trim = subSql.trim();
return !trim.isEmpty() && !trim.startsWith("--");
}).collect(Collectors.toList());
}
}

4
dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/test/java/org/apache/dolphinscheduler/plugin/task/sql/SqlTaskTest.java

@ -138,4 +138,8 @@ class SqlTaskTest {
sqlTask.setSqlParamsMap(querySql, sqlTask.rgex, sqlParamsMap, paramsMap, 1);
Assertions.assertEquals(sqlParamsMap, expectedSQLParamsMap);
}
@Test
void splitSql() {
}
}

34
dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/test/java/org/apache/dolphinscheduler/plugin/task/sql/utils/SqlSplitUtilsTest.java

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.plugin.task.sql.utils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.google.common.collect.Lists;
class SqlSplitUtilsTest {
@Test
void splitSql() {
String sql = "select * from table1;\nselect * from table2;\nselect * from table3;\r\n";
Assertions.assertEquals(
Lists.newArrayList("select * from table1", "select * from table2", "select * from table3"),
SqlSplitUtils.splitSql(sql));
}
}
Loading…
Cancel
Save