chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
68
sqlparser/seata-sqlparser-druid/pom.xml
Normal file
68
sqlparser/seata-sqlparser-druid/pom.xml
Normal file
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed 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.
|
||||
-->
|
||||
<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>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-sqlparser</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>seata-sqlparser-druid</artifactId>
|
||||
<name>seata-sqlparser-druid ${project.version}</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-sqlparser-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-druid</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includeGroupIds>com.alibaba</includeGroupIds>
|
||||
<includeArtifactIds>druid</includeArtifactIds>
|
||||
<stripVersion>true</stripVersion>
|
||||
<outputDirectory>
|
||||
${project.build.outputDirectory}/lib/sqlparser
|
||||
</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLExistsExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
|
||||
/**
|
||||
* The type Base recognizer.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public abstract class BaseRecognizer implements SQLRecognizer {
|
||||
|
||||
/**
|
||||
* The type V marker.
|
||||
*/
|
||||
public static class VMarker {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "?";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The Original sql.
|
||||
*/
|
||||
protected String originalSQL;
|
||||
|
||||
/**
|
||||
* Instantiates a new Base recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
*/
|
||||
public BaseRecognizer(String originalSQL) {
|
||||
this.originalSQL = originalSQL;
|
||||
|
||||
}
|
||||
|
||||
public void executeVisit(SQLExpr where, SQLASTVisitor visitor) {
|
||||
if (where instanceof SQLBinaryOpExpr) {
|
||||
visitor.visit((SQLBinaryOpExpr) where);
|
||||
} else if (where instanceof SQLInListExpr) {
|
||||
visitor.visit((SQLInListExpr) where);
|
||||
} else if (where instanceof SQLBetweenExpr) {
|
||||
visitor.visit((SQLBetweenExpr) where);
|
||||
} else if (where instanceof SQLExistsExpr) {
|
||||
visitor.visit((SQLExistsExpr) where);
|
||||
} else {
|
||||
throw new IllegalArgumentException("unexpected WHERE expr: " + where.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalSQL() {
|
||||
return originalSQL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.security.CodeSource;
|
||||
|
||||
/**
|
||||
* @author ggndnn
|
||||
*/
|
||||
class DefaultDruidLoader implements DruidLoader {
|
||||
/**
|
||||
* Default druid location in classpath
|
||||
*/
|
||||
private final static String DRUID_LOCATION = "lib/sqlparser/druid.jar";
|
||||
|
||||
private final static DefaultDruidLoader DRUID_LOADER = new DefaultDruidLoader(DRUID_LOCATION);
|
||||
|
||||
private final URL druidUrl;
|
||||
|
||||
/**
|
||||
* @param druidLocation druid location in classpath
|
||||
*/
|
||||
private DefaultDruidLoader(String druidLocation) {
|
||||
if (druidLocation == null) {
|
||||
druidLocation = DRUID_LOCATION;
|
||||
}
|
||||
URL url = DefaultDruidLoader.class.getClassLoader().getResource(druidLocation);
|
||||
if (url != null) {
|
||||
try {
|
||||
// extract druid.jar to temp file
|
||||
// TODO use URLStreamHandler to handle nested jar loading in the future
|
||||
File tempFile = File.createTempFile("seata", "sqlparser");
|
||||
try (InputStream input = url.openStream(); OutputStream output = new FileOutputStream(tempFile)) {
|
||||
byte[] buf = new byte[1024];
|
||||
while (true) {
|
||||
int readCnt = input.read(buf);
|
||||
if (readCnt < 0) {
|
||||
break;
|
||||
}
|
||||
output.write(buf, 0, readCnt);
|
||||
}
|
||||
output.flush();
|
||||
}
|
||||
tempFile.deleteOnExit();
|
||||
druidUrl = tempFile.toURI().toURL();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
// try to find druid in class code source if it's not in classpath which should usually happen in unit test
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
clazz = DefaultDruidLoader.class.getClassLoader().loadClass("com.alibaba.druid.util.StringUtils");
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
if (clazz != null) {
|
||||
CodeSource cs = clazz.getProtectionDomain().getCodeSource();
|
||||
if (cs == null) {
|
||||
throw new IllegalStateException("Can not find druid code source");
|
||||
}
|
||||
druidUrl = cs.getLocation();
|
||||
} else {
|
||||
druidUrl = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default druid loader
|
||||
*
|
||||
* @return default druid loader
|
||||
*/
|
||||
static DruidLoader get() {
|
||||
return DRUID_LOADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getEmbeddedDruidLocation() {
|
||||
if (druidUrl == null) {
|
||||
throw new IllegalStateException("Can not find embedded druid");
|
||||
}
|
||||
return druidUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import io.seata.sqlparser.util.DbTypeParser;
|
||||
|
||||
/**
|
||||
* @author ggndnn
|
||||
*/
|
||||
class DruidDbTypeParserImpl implements DbTypeParser {
|
||||
@Override
|
||||
public String parseFromJdbcUrl(String jdbcUrl) {
|
||||
return JdbcUtils.getDbType(jdbcUrl, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.sqlparser.SqlParserType;
|
||||
import io.seata.sqlparser.util.DbTypeParser;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
/**
|
||||
* @author ggndnn
|
||||
*/
|
||||
@LoadLevel(name = SqlParserType.SQL_PARSER_TYPE_DRUID)
|
||||
public class DruidDelegatingDbTypeParser implements DbTypeParser {
|
||||
private DbTypeParser dbTypeParserImpl;
|
||||
|
||||
public DruidDelegatingDbTypeParser() {
|
||||
setClassLoader(DruidIsolationClassLoader.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for unit test
|
||||
*
|
||||
* @param classLoader classLoader
|
||||
*/
|
||||
void setClassLoader(ClassLoader classLoader) {
|
||||
try {
|
||||
Class<?> druidDbTypeParserImplClass = classLoader.loadClass("io.seata.sqlparser.druid.DruidDbTypeParserImpl");
|
||||
Constructor<?> implConstructor = druidDbTypeParserImplClass.getDeclaredConstructor();
|
||||
implConstructor.setAccessible(true);
|
||||
try {
|
||||
dbTypeParserImpl = (DbTypeParser) implConstructor.newInstance();
|
||||
} finally {
|
||||
implConstructor.setAccessible(false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseFromJdbcUrl(String jdbcUrl) {
|
||||
return dbTypeParserImpl.parseFromJdbcUrl(jdbcUrl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.SQLRecognizerFactory;
|
||||
import io.seata.sqlparser.SqlParserType;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ggndnn
|
||||
*/
|
||||
@LoadLevel(name = SqlParserType.SQL_PARSER_TYPE_DRUID)
|
||||
public class DruidDelegatingSQLRecognizerFactory implements SQLRecognizerFactory {
|
||||
private volatile SQLRecognizerFactory recognizerFactoryImpl;
|
||||
|
||||
public DruidDelegatingSQLRecognizerFactory() {
|
||||
setClassLoader(DruidIsolationClassLoader.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for unit test
|
||||
*
|
||||
* @param classLoader classLoader
|
||||
*/
|
||||
void setClassLoader(ClassLoader classLoader) {
|
||||
try {
|
||||
Class<?> recognizerFactoryImplClass = classLoader.loadClass("io.seata.sqlparser.druid.DruidSQLRecognizerFactoryImpl");
|
||||
Constructor<?> implConstructor = recognizerFactoryImplClass.getDeclaredConstructor();
|
||||
implConstructor.setAccessible(true);
|
||||
try {
|
||||
recognizerFactoryImpl = (SQLRecognizerFactory) implConstructor.newInstance();
|
||||
} finally {
|
||||
implConstructor.setAccessible(false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new SQLParsingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SQLRecognizer> create(String sql, String dbType) {
|
||||
return recognizerFactoryImpl.create(sql, dbType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.CodeSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Used for druid isolation.
|
||||
*
|
||||
* @author ggndnn
|
||||
*/
|
||||
class DruidIsolationClassLoader extends URLClassLoader {
|
||||
private final static String[] DRUID_CLASS_PREFIX = new String[]{"com.alibaba.druid.", "io.seata.sqlparser.druid."};
|
||||
|
||||
private final static DruidIsolationClassLoader INSTANCE = new DruidIsolationClassLoader(DefaultDruidLoader.get());
|
||||
|
||||
DruidIsolationClassLoader(DruidLoader druidLoader) {
|
||||
super(getDruidUrls(druidLoader), DruidIsolationClassLoader.class.getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
for (String prefix : DRUID_CLASS_PREFIX) {
|
||||
if (name.startsWith(prefix)) {
|
||||
return loadInternalClass(name, resolve);
|
||||
}
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
|
||||
private Class<?> loadInternalClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
Class<?> c;
|
||||
synchronized (getClassLoadingLock(name)) {
|
||||
c = findLoadedClass(name);
|
||||
if (c == null) {
|
||||
c = findClass(name);
|
||||
}
|
||||
}
|
||||
if (c == null) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
if (resolve) {
|
||||
resolveClass(c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private static URL[] getDruidUrls(DruidLoader druidLoader) {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
urls.add(findClassLocation(DruidIsolationClassLoader.class));
|
||||
urls.add(druidLoader.getEmbeddedDruidLocation());
|
||||
return urls.toArray(new URL[0]);
|
||||
}
|
||||
|
||||
private static URL findClassLocation(Class<?> clazz) {
|
||||
CodeSource cs = clazz.getProtectionDomain().getCodeSource();
|
||||
if (cs == null) {
|
||||
throw new IllegalStateException("Not a normal druid startup environment");
|
||||
}
|
||||
return cs.getLocation();
|
||||
}
|
||||
|
||||
static DruidIsolationClassLoader get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* ggndnn
|
||||
*/
|
||||
interface DruidLoader {
|
||||
/**
|
||||
* Gets embedded druid.jar
|
||||
*
|
||||
* @return embedded druid.jar url
|
||||
*/
|
||||
URL getEmbeddedDruidLocation();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.SQLRecognizerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DruidSQLRecognizerFactoryImpl
|
||||
*
|
||||
* @author sharajava
|
||||
* @author ggndnn
|
||||
*/
|
||||
class DruidSQLRecognizerFactoryImpl implements SQLRecognizerFactory {
|
||||
@Override
|
||||
public List<SQLRecognizer> create(String sql, String dbType) {
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, dbType);
|
||||
if (CollectionUtils.isEmpty(asts)) {
|
||||
throw new UnsupportedOperationException("Unsupported SQL: " + sql);
|
||||
}
|
||||
if (asts.size() > 1 && !(asts.stream().allMatch(statement -> statement instanceof SQLUpdateStatement)
|
||||
|| asts.stream().allMatch(statement -> statement instanceof SQLDeleteStatement))) {
|
||||
throw new UnsupportedOperationException("ONLY SUPPORT SAME TYPE (UPDATE OR DELETE) MULTI SQL -" + sql);
|
||||
}
|
||||
List<SQLRecognizer> recognizers = null;
|
||||
SQLRecognizer recognizer = null;
|
||||
for (SQLStatement ast : asts) {
|
||||
SQLOperateRecognizerHolder recognizerHolder =
|
||||
SQLOperateRecognizerHolderFactory.getSQLRecognizerHolder(dbType.toLowerCase());
|
||||
if (ast instanceof SQLInsertStatement) {
|
||||
recognizer = recognizerHolder.getInsertRecognizer(sql, ast);
|
||||
} else if (ast instanceof SQLUpdateStatement) {
|
||||
recognizer = recognizerHolder.getUpdateRecognizer(sql, ast);
|
||||
} else if (ast instanceof SQLDeleteStatement) {
|
||||
recognizer = recognizerHolder.getDeleteRecognizer(sql, ast);
|
||||
} else if (ast instanceof SQLSelectStatement) {
|
||||
recognizer = recognizerHolder.getSelectForUpdateRecognizer(sql, ast);
|
||||
}
|
||||
if (recognizer != null) {
|
||||
if (recognizers == null) {
|
||||
recognizers = new ArrayList<>();
|
||||
}
|
||||
recognizers.add(recognizer);
|
||||
}
|
||||
}
|
||||
return recognizers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
|
||||
/**
|
||||
* The interface SQLOperateRecognizerHolder
|
||||
*
|
||||
* @author: Zhibei Hao
|
||||
*/
|
||||
public interface SQLOperateRecognizerHolder {
|
||||
|
||||
/**
|
||||
* Get delete recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @param ast the ast
|
||||
* @return the delete recognizer
|
||||
*/
|
||||
SQLRecognizer getDeleteRecognizer(String sql, SQLStatement ast);
|
||||
|
||||
/**
|
||||
* Get insert recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @param ast the ast
|
||||
* @return the insert recognizer
|
||||
*/
|
||||
SQLRecognizer getInsertRecognizer(String sql, SQLStatement ast);
|
||||
|
||||
/**
|
||||
* Get update recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @param ast the ast
|
||||
* @return the update recognizer
|
||||
*/
|
||||
SQLRecognizer getUpdateRecognizer(String sql, SQLStatement ast);
|
||||
|
||||
/**
|
||||
* Get SelectForUpdate recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @param ast the ast
|
||||
* @return the SelectForUpdate recognizer
|
||||
*/
|
||||
SQLRecognizer getSelectForUpdateRecognizer(String sql, SQLStatement ast);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* The SQLOperateRecognizerHolderFactory
|
||||
*
|
||||
* @author: Zhibei Hao
|
||||
*/
|
||||
public class SQLOperateRecognizerHolderFactory {
|
||||
|
||||
private static final Map<String, SQLOperateRecognizerHolder> RECOGNIZER_HOLDER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* get SQLOperateRecognizer by db type
|
||||
*
|
||||
* @param dbType the db type
|
||||
* @return the SQLOperateRecognizer
|
||||
*/
|
||||
public static SQLOperateRecognizerHolder getSQLRecognizerHolder(String dbType) {
|
||||
return CollectionUtils.computeIfAbsent(RECOGNIZER_HOLDER_MAP, dbType,
|
||||
key -> EnhancedServiceLoader.load(SQLOperateRecognizerHolder.class, dbType, SQLOperateRecognizerHolderFactory.class.getClassLoader()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.mysql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLLimit;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.druid.BaseRecognizer;
|
||||
import io.seata.sqlparser.struct.Null;
|
||||
|
||||
/**
|
||||
* @author will
|
||||
*/
|
||||
public abstract class BaseMySQLRecognizer extends BaseRecognizer {
|
||||
|
||||
/**
|
||||
* Instantiates a new mysql base recognizer
|
||||
*
|
||||
* @param originalSql the original sql
|
||||
*/
|
||||
public BaseMySQLRecognizer(String originalSql) {
|
||||
super(originalSql);
|
||||
}
|
||||
|
||||
public MySqlOutputVisitor createOutputVisitor(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList,
|
||||
final StringBuilder sb) {
|
||||
return new MySqlOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLVariantRefExpr x) {
|
||||
if ("?".equals(x.getName())) {
|
||||
ArrayList<Object> oneParamValues = parametersHolder.getParameters().get(x.getIndex() + 1);
|
||||
if (paramAppenderList.isEmpty()) {
|
||||
oneParamValues.forEach(t -> paramAppenderList.add(new ArrayList<>()));
|
||||
}
|
||||
for (int i = 0; i < oneParamValues.size(); i++) {
|
||||
Object o = oneParamValues.get(i);
|
||||
paramAppenderList.get(i).add(o instanceof Null ? null : o);
|
||||
}
|
||||
}
|
||||
return super.visit(x);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String getWhereCondition(SQLExpr where, final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
if (Objects.isNull(where)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
executeVisit(where, createOutputVisitor(parametersHolder, paramAppenderList, sb));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getWhereCondition(SQLExpr where) {
|
||||
if (Objects.isNull(where)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
executeVisit(where, new MySqlOutputVisitor(sb));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected String getLimit(SQLStatement sqlStatement, SQLType sqlType, ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLLimit limit = null;
|
||||
if (SQLType.UPDATE == sqlType) {
|
||||
limit = ((MySqlUpdateStatement)sqlStatement).getLimit();
|
||||
} else if (SQLType.DELETE == sqlType) {
|
||||
limit = ((MySqlDeleteStatement)sqlStatement).getLimit();
|
||||
}
|
||||
if (limit != null) {
|
||||
StringBuilder builder = new StringBuilder(" LIMIT ");
|
||||
SQLIntegerExpr expr;
|
||||
if (limit.getOffset() != null) {
|
||||
if (limit.getOffset() instanceof SQLVariantRefExpr) {
|
||||
builder.append("?,");
|
||||
Map<Integer, ArrayList<Object>> parameters = parametersHolder.getParameters();
|
||||
paramAppenderList.add(parameters.get(parameters.size() - 1));
|
||||
} else {
|
||||
expr = (SQLIntegerExpr)limit.getOffset();
|
||||
builder.append(expr.getNumber()).append(",");
|
||||
}
|
||||
}
|
||||
if (limit.getRowCount() != null) {
|
||||
if (limit.getRowCount() instanceof SQLVariantRefExpr) {
|
||||
builder.append("?");
|
||||
Map<Integer, ArrayList<Object>> parameters = parametersHolder.getParameters();
|
||||
paramAppenderList.add(parameters.get(parameters.size()));
|
||||
} else {
|
||||
expr = (SQLIntegerExpr)limit.getRowCount();
|
||||
builder.append(expr.getNumber());
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getOrderBy(SQLStatement sqlStatement, SQLType sqlType) {
|
||||
SQLOrderBy orderBy = null;
|
||||
if (SQLType.UPDATE == sqlType) {
|
||||
orderBy = ((MySqlUpdateStatement)sqlStatement).getOrderBy();
|
||||
} else if (SQLType.DELETE == sqlType) {
|
||||
orderBy = ((MySqlDeleteStatement)sqlStatement).getOrderBy();
|
||||
}
|
||||
if (orderBy != null) {
|
||||
String space = " ";
|
||||
String comma = ",";
|
||||
StringBuilder builder = new StringBuilder(space).append("ORDER BY").append(space);
|
||||
List<SQLSelectOrderByItem> items = orderBy.getItems();
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
SQLSelectOrderByItem item = items.get(i);
|
||||
SQLIdentifierExpr expr = (SQLIdentifierExpr)item.getExpr();
|
||||
builder.append(expr.getName());
|
||||
SQLOrderingSpecification specification = item.getType();
|
||||
if (specification != null) {
|
||||
builder.append(space);
|
||||
builder.append(specification.name);
|
||||
}
|
||||
if (i + 1 != items.size()) {
|
||||
builder.append(comma);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLDeleteRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type My sql delete recognizer.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class MySQLDeleteRecognizer extends BaseMySQLRecognizer implements SQLDeleteRecognizer {
|
||||
|
||||
private final MySqlDeleteStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql delete recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public MySQLDeleteRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (MySqlDeleteStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
if (ast.getFrom() == null) {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
return ast.getFrom().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLJoinTableSource x) {
|
||||
throw new NotSupportYetException("not support the syntax of delete with join table");
|
||||
}
|
||||
};
|
||||
SQLTableSource tableSource;
|
||||
if (ast.getFrom() == null) {
|
||||
tableSource = ast.getTableSource();
|
||||
} else {
|
||||
tableSource = ast.getFrom();
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
visitor.visit((SQLExprTableSource) tableSource);
|
||||
} else if (tableSource instanceof SQLJoinTableSource) {
|
||||
visitor.visit((SQLJoinTableSource) tableSource);
|
||||
} else {
|
||||
throw new NotSupportYetException("not support the syntax of delete with unknow");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimit(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) {
|
||||
return super.getLimit(ast, getSQLType(), parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrderBy() {
|
||||
return super.getOrderBy(ast, getSQLType());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLValuableExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.sqlparser.SQLInsertRecognizer;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.struct.NotPlaceholderExpr;
|
||||
import io.seata.sqlparser.struct.Null;
|
||||
import io.seata.sqlparser.struct.SqlMethodExpr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type My sql insert recognizer.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class MySQLInsertRecognizer extends BaseMySQLRecognizer implements SQLInsertRecognizer {
|
||||
|
||||
private final MySqlInsertStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql insert recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public MySQLInsertRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (MySqlInsertStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.INSERT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
visitor.visit(ast.getTableSource());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertColumnsIsEmpty() {
|
||||
return CollectionUtils.isEmpty(ast.getColumns());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getInsertColumns() {
|
||||
List<SQLExpr> columnSQLExprs = ast.getColumns();
|
||||
if (columnSQLExprs.isEmpty()) {
|
||||
// INSERT INTO ta VALUES (...), without fields clarified
|
||||
return null;
|
||||
}
|
||||
List<String> list = new ArrayList<>(columnSQLExprs.size());
|
||||
for (SQLExpr expr : columnSQLExprs) {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr)expr).getName());
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<Object>> getInsertRows(Collection<Integer> primaryKeyIndex) {
|
||||
List<SQLInsertStatement.ValuesClause> valuesClauses = ast.getValuesList();
|
||||
List<List<Object>> rows = new ArrayList<>(valuesClauses.size());
|
||||
for (SQLInsertStatement.ValuesClause valuesClause : valuesClauses) {
|
||||
List<SQLExpr> exprs = valuesClause.getValues();
|
||||
List<Object> row = new ArrayList<>(exprs.size());
|
||||
rows.add(row);
|
||||
for (int i = 0, len = exprs.size(); i < len; i++) {
|
||||
SQLExpr expr = exprs.get(i);
|
||||
if (expr instanceof SQLNullExpr) {
|
||||
row.add(Null.get());
|
||||
} else if (expr instanceof SQLValuableExpr) {
|
||||
row.add(((SQLValuableExpr) expr).getValue());
|
||||
} else if (expr instanceof SQLVariantRefExpr) {
|
||||
row.add(((SQLVariantRefExpr) expr).getName());
|
||||
} else if (expr instanceof SQLMethodInvokeExpr) {
|
||||
row.add(SqlMethodExpr.get());
|
||||
} else {
|
||||
if (primaryKeyIndex.contains(i)) {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
row.add(NotPlaceholderExpr.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.druid.SQLOperateRecognizerHolder;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
|
||||
/**
|
||||
* The class MySqlOperateRecognizerHolder
|
||||
*
|
||||
* @author: Zhibei Hao
|
||||
*/
|
||||
@LoadLevel(name = JdbcConstants.MYSQL)
|
||||
public class MySQLOperateRecognizerHolder implements SQLOperateRecognizerHolder {
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getDeleteRecognizer(String sql, SQLStatement ast) {
|
||||
return new MySQLDeleteRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getInsertRecognizer(String sql, SQLStatement ast) {
|
||||
return new MySQLInsertRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getUpdateRecognizer(String sql, SQLStatement ast) {
|
||||
return new MySQLUpdateRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getSelectForUpdateRecognizer(String sql, SQLStatement ast) {
|
||||
if (((SQLSelectStatement) ast).getSelect().getFirstQueryBlock().isForUpdate()) {
|
||||
return new MySQLSelectForUpdateRecognizer(sql, ast);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLSelectRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type My sql select for update recognizer.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class MySQLSelectForUpdateRecognizer extends BaseMySQLRecognizer implements SQLSelectRecognizer {
|
||||
|
||||
private final SQLSelectStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql select for update recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public MySQLSelectForUpdateRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (SQLSelectStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.SELECT_FOR_UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLExpr where = selectQueryBlock.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLExpr where = selectQueryBlock.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
private SQLSelectQueryBlock getSelect() {
|
||||
SQLSelect select = ast.getSelect();
|
||||
if (select == null) {
|
||||
throw new SQLParsingException("should never happen!");
|
||||
}
|
||||
SQLSelectQueryBlock selectQueryBlock = select.getQueryBlock();
|
||||
if (selectQueryBlock == null) {
|
||||
throw new SQLParsingException("should never happen!");
|
||||
}
|
||||
return selectQueryBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLTableSource tableSource = selectQueryBlock.getFrom();
|
||||
return tableSource.getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLTableSource tableSource = selectQueryBlock.getFrom();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
visitor.visit((SQLExprTableSource)tableSource);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLValuableExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.SQLUpdateRecognizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type My sql update recognizer.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class MySQLUpdateRecognizer extends BaseMySQLRecognizer implements SQLUpdateRecognizer {
|
||||
|
||||
private MySqlUpdateStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql update recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public MySQLUpdateRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (MySqlUpdateStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUpdateColumns() {
|
||||
List<SQLUpdateSetItem> updateSetItems = ast.getItems();
|
||||
List<String> list = new ArrayList<>(updateSetItems.size());
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
SQLExpr expr = updateSetItem.getColumn();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr)expr).getName());
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
// This is alias case, like UPDATE xxx_tbl a SET a.name = ? WHERE a.id = ?
|
||||
SQLExpr owner = ((SQLPropertyExpr)expr).getOwner();
|
||||
if (owner instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr)owner).getName() + "." + ((SQLPropertyExpr)expr).getName());
|
||||
//This is table Field Full path, like update xxx_database.xxx_tbl set xxx_database.xxx_tbl.xxx_field...
|
||||
} else if (((SQLPropertyExpr)expr).getOwnernName().split("\\.").length > 1) {
|
||||
list.add(((SQLPropertyExpr)expr).getOwnernName() + "." + ((SQLPropertyExpr)expr).getName());
|
||||
}
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getUpdateValues() {
|
||||
List<SQLUpdateSetItem> updateSetItems = ast.getItems();
|
||||
List<Object> list = new ArrayList<>(updateSetItems.size());
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
SQLExpr expr = updateSetItem.getValue();
|
||||
if (expr instanceof SQLValuableExpr) {
|
||||
list.add(((SQLValuableExpr)expr).getValue());
|
||||
} else if (expr instanceof SQLVariantRefExpr) {
|
||||
list.add(new VMarker());
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLJoinTableSource x) {
|
||||
throw new NotSupportYetException("not support the syntax of update with join table");
|
||||
}
|
||||
};
|
||||
|
||||
SQLTableSource tableSource = ast.getTableSource();
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
visitor.visit((SQLExprTableSource) tableSource);
|
||||
} else if (tableSource instanceof SQLJoinTableSource) {
|
||||
visitor.visit((SQLJoinTableSource) tableSource);
|
||||
} else {
|
||||
throw new NotSupportYetException("not support the syntax of update with unknow");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimit(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) {
|
||||
return super.getLimit(ast, getSQLType(), parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrderBy() {
|
||||
return super.getOrderBy(ast, getSQLType());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.oracle;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.druid.BaseRecognizer;
|
||||
import io.seata.sqlparser.struct.Null;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author will
|
||||
*/
|
||||
public abstract class BaseOracleRecognizer extends BaseRecognizer {
|
||||
|
||||
/**
|
||||
* Instantiates a new oracle base recognizer
|
||||
*
|
||||
* @param originalSql the original sql
|
||||
*/
|
||||
public BaseOracleRecognizer(String originalSql) {
|
||||
super(originalSql);
|
||||
}
|
||||
|
||||
public OracleOutputVisitor createOutputVisitor(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList,
|
||||
final StringBuilder sb) {
|
||||
|
||||
return new OracleOutputVisitor(sb) {
|
||||
@Override
|
||||
public boolean visit(SQLVariantRefExpr x) {
|
||||
if ("?".equals(x.getName())) {
|
||||
ArrayList<Object> oneParamValues = parametersHolder.getParameters().get(x.getIndex() + 1);
|
||||
if (paramAppenderList.isEmpty()) {
|
||||
oneParamValues.forEach(t -> paramAppenderList.add(new ArrayList<>()));
|
||||
}
|
||||
for (int i = 0; i < oneParamValues.size(); i++) {
|
||||
Object o = oneParamValues.get(i);
|
||||
paramAppenderList.get(i).add(o instanceof Null ? null : o);
|
||||
}
|
||||
}
|
||||
return super.visit(x);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String getWhereCondition(SQLExpr where, final ParametersHolder parametersHolder, final ArrayList<List<Object>> paramAppenderList) {
|
||||
if (Objects.isNull(where)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
executeVisit(where, createOutputVisitor(parametersHolder, paramAppenderList, sb));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getWhereCondition(SQLExpr where) {
|
||||
if (Objects.isNull(where)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
executeVisit(where, new OracleOutputVisitor(sb));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.oracle;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
|
||||
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLDeleteRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type oracle delete recognizer.
|
||||
*
|
||||
* @author ccg
|
||||
*/
|
||||
public class OracleDeleteRecognizer extends BaseOracleRecognizer implements SQLDeleteRecognizer {
|
||||
|
||||
private final OracleDeleteStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql delete recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public OracleDeleteRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (OracleDeleteStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
OracleOutputVisitor visitor = new OracleOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLJoinTableSource x) {
|
||||
throw new NotSupportYetException("not support the syntax of delete with join table");
|
||||
}
|
||||
};
|
||||
SQLTableSource tableSource;
|
||||
if (ast.getFrom() == null) {
|
||||
tableSource = ast.getTableSource();
|
||||
} else {
|
||||
tableSource = ast.getFrom();
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
visitor.visit((SQLExprTableSource) tableSource);
|
||||
} else if (tableSource instanceof SQLJoinTableSource) {
|
||||
visitor.visit((SQLJoinTableSource) tableSource);
|
||||
} else {
|
||||
throw new NotSupportYetException("not support the syntax of delete with unknow");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.oracle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLSequenceExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLValuableExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.sqlparser.SQLInsertRecognizer;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.struct.NotPlaceholderExpr;
|
||||
import io.seata.sqlparser.struct.Null;
|
||||
import io.seata.sqlparser.struct.SqlMethodExpr;
|
||||
import io.seata.sqlparser.struct.SqlSequenceExpr;
|
||||
|
||||
/**
|
||||
* The type oracle insert recognizer.
|
||||
*
|
||||
* @author ccg
|
||||
*/
|
||||
public class OracleInsertRecognizer extends BaseOracleRecognizer implements SQLInsertRecognizer {
|
||||
|
||||
private final OracleInsertStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql insert recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public OracleInsertRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (OracleInsertStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.INSERT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
OracleOutputVisitor visitor = new OracleOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
visitor.visit(ast.getTableSource());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertColumnsIsEmpty() {
|
||||
return CollectionUtils.isEmpty(ast.getColumns());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getInsertColumns() {
|
||||
List<SQLExpr> columnSQLExprs = ast.getColumns();
|
||||
if (columnSQLExprs.isEmpty()) {
|
||||
// INSERT INTO ta VALUES (...), without fields clarified
|
||||
return null;
|
||||
}
|
||||
List<String> list = new ArrayList<>(columnSQLExprs.size());
|
||||
for (SQLExpr expr : columnSQLExprs) {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr)expr).getName());
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<Object>> getInsertRows(Collection<Integer> primaryKeyIndex) {
|
||||
List<SQLInsertStatement.ValuesClause> valuesClauses = ast.getValuesList();
|
||||
List<List<Object>> rows = new ArrayList<>(valuesClauses.size());
|
||||
for (SQLInsertStatement.ValuesClause valuesClause : valuesClauses) {
|
||||
List<SQLExpr> exprs = valuesClause.getValues();
|
||||
List<Object> row = new ArrayList<>(exprs.size());
|
||||
rows.add(row);
|
||||
for (int i = 0, len = exprs.size(); i < len; i++) {
|
||||
SQLExpr expr = exprs.get(i);
|
||||
if (expr instanceof SQLNullExpr) {
|
||||
row.add(Null.get());
|
||||
} else if (expr instanceof SQLValuableExpr) {
|
||||
row.add(((SQLValuableExpr) expr).getValue());
|
||||
} else if (expr instanceof SQLVariantRefExpr) {
|
||||
row.add(((SQLVariantRefExpr) expr).getName());
|
||||
} else if (expr instanceof SQLMethodInvokeExpr) {
|
||||
row.add(SqlMethodExpr.get());
|
||||
} else if (expr instanceof SQLSequenceExpr) {
|
||||
SQLSequenceExpr sequenceExpr = (SQLSequenceExpr) expr;
|
||||
String sequence = sequenceExpr.getSequence().getSimpleName();
|
||||
String function = sequenceExpr.getFunction().name;
|
||||
row.add(new SqlSequenceExpr(sequence, function));
|
||||
} else {
|
||||
if (primaryKeyIndex.contains(i)) {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
row.add(NotPlaceholderExpr.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.oracle;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.druid.SQLOperateRecognizerHolder;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
|
||||
/**
|
||||
* The Type OracleOperateRecognizerHolder
|
||||
*
|
||||
* @author: Zhibei Hao
|
||||
*/
|
||||
@LoadLevel(name = JdbcConstants.ORACLE)
|
||||
public class OracleOperateRecognizerHolder implements SQLOperateRecognizerHolder {
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getDeleteRecognizer(String sql, SQLStatement ast) {
|
||||
return new OracleDeleteRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getInsertRecognizer(String sql, SQLStatement ast) {
|
||||
return new OracleInsertRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getUpdateRecognizer(String sql, SQLStatement ast) {
|
||||
return new OracleUpdateRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getSelectForUpdateRecognizer(String sql, SQLStatement ast) {
|
||||
if (((SQLSelectStatement) ast).getSelect().getFirstQueryBlock().isForUpdate()) {
|
||||
return new OracleSelectForUpdateRecognizer(sql, ast);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.oracle;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
|
||||
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLSelectRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type oracle select for update recognizer.
|
||||
*
|
||||
* @author ccg
|
||||
*/
|
||||
public class OracleSelectForUpdateRecognizer extends BaseOracleRecognizer implements SQLSelectRecognizer {
|
||||
|
||||
private final SQLSelectStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql select for update recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public OracleSelectForUpdateRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (SQLSelectStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.SELECT_FOR_UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLExpr where = selectQueryBlock.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLExpr where = selectQueryBlock.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
private SQLSelectQueryBlock getSelect() {
|
||||
SQLSelect select = ast.getSelect();
|
||||
if (select == null) {
|
||||
throw new SQLParsingException("should never happen!");
|
||||
}
|
||||
SQLSelectQueryBlock selectQueryBlock = select.getQueryBlock();
|
||||
if (selectQueryBlock == null) {
|
||||
throw new SQLParsingException("should never happen!");
|
||||
}
|
||||
return selectQueryBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLTableSource tableSource = selectQueryBlock.getFrom();
|
||||
return tableSource.getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLTableSource tableSource = selectQueryBlock.getFrom();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
OracleOutputVisitor visitor = new OracleOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
visitor.visit((SQLExprTableSource)tableSource);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.oracle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLValuableExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
|
||||
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.SQLUpdateRecognizer;
|
||||
|
||||
/**
|
||||
* The type oracle update recognizer.
|
||||
*
|
||||
* @author ccg
|
||||
*/
|
||||
public class OracleUpdateRecognizer extends BaseOracleRecognizer implements SQLUpdateRecognizer {
|
||||
|
||||
private OracleUpdateStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new My sql update recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public OracleUpdateRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (OracleUpdateStatement)ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUpdateColumns() {
|
||||
List<SQLUpdateSetItem> updateSetItems = ast.getItems();
|
||||
List<String> list = new ArrayList<>(updateSetItems.size());
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
SQLExpr expr = updateSetItem.getColumn();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr)expr).getName());
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
// This is alias case, like UPDATE xxx_tbl a SET a.name = ? WHERE a.id = ?
|
||||
SQLExpr owner = ((SQLPropertyExpr)expr).getOwner();
|
||||
if (owner instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr)owner).getName() + "." + ((SQLPropertyExpr)expr).getName());
|
||||
//This is table Field Full path, like update xxx_database.xxx_tbl set xxx_database.xxx_tbl.xxx_field...
|
||||
} else if (((SQLPropertyExpr) expr).getOwnernName().split("\\.").length > 1) {
|
||||
list.add(((SQLPropertyExpr)expr).getOwnernName() + "." + ((SQLPropertyExpr)expr).getName());
|
||||
}
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getUpdateValues() {
|
||||
List<SQLUpdateSetItem> updateSetItems = ast.getItems();
|
||||
List<Object> list = new ArrayList<>(updateSetItems.size());
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
SQLExpr expr = updateSetItem.getValue();
|
||||
if (expr instanceof SQLValuableExpr) {
|
||||
list.add(((SQLValuableExpr)expr).getValue());
|
||||
} else if (expr instanceof SQLVariantRefExpr) {
|
||||
list.add(new VMarker());
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
OracleOutputVisitor visitor = new OracleOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLJoinTableSource x) {
|
||||
throw new NotSupportYetException("not support the syntax of update with join table");
|
||||
}
|
||||
};
|
||||
SQLTableSource tableSource = ast.getTableSource();
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
visitor.visit((SQLExprTableSource) tableSource);
|
||||
} else if (tableSource instanceof SQLJoinTableSource) {
|
||||
visitor.visit((SQLJoinTableSource) tableSource);
|
||||
} else {
|
||||
throw new NotSupportYetException("not support the syntax of update with unknow");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.postgresql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.druid.BaseRecognizer;
|
||||
import io.seata.sqlparser.struct.Null;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author will
|
||||
*/
|
||||
public abstract class BasePostgresqlRecognizer extends BaseRecognizer {
|
||||
|
||||
/**
|
||||
* Instantiates a new postgresql base recognizer
|
||||
*
|
||||
* @param originalSql the original sql
|
||||
*/
|
||||
public BasePostgresqlRecognizer(String originalSql) {
|
||||
super(originalSql);
|
||||
}
|
||||
|
||||
public PGOutputVisitor createOutputVisitor(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList, final StringBuilder sb) {
|
||||
PGOutputVisitor visitor = new PGOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLVariantRefExpr x) {
|
||||
if ("?".equals(x.getName())) {
|
||||
ArrayList<Object> oneParamValues = parametersHolder.getParameters().get(x.getIndex() + 1);
|
||||
if (paramAppenderList.size() == 0) {
|
||||
oneParamValues.forEach(t -> paramAppenderList.add(new ArrayList<>()));
|
||||
}
|
||||
for (int i = 0; i < oneParamValues.size(); i++) {
|
||||
Object o = oneParamValues.get(i);
|
||||
paramAppenderList.get(i).add(o instanceof Null ? null : o);
|
||||
}
|
||||
|
||||
}
|
||||
return super.visit(x);
|
||||
}
|
||||
};
|
||||
return visitor;
|
||||
}
|
||||
|
||||
public String getWhereCondition(SQLExpr where, final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
if (Objects.isNull(where)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
executeVisit(where, createOutputVisitor(parametersHolder, paramAppenderList, sb));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getWhereCondition(SQLExpr where) {
|
||||
if (Objects.isNull(where)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
executeVisit(where, new PGOutputVisitor(sb));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.postgresql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLDeleteRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author japsercloud
|
||||
*/
|
||||
public class PostgresqlDeleteRecognizer extends BasePostgresqlRecognizer implements SQLDeleteRecognizer {
|
||||
|
||||
private final PGDeleteStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new Postgresql delete recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public PostgresqlDeleteRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (PGDeleteStatement) ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
PGOutputVisitor visitor = new PGOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLJoinTableSource x) {
|
||||
throw new NotSupportYetException("not support the syntax of delete with join table");
|
||||
}
|
||||
};
|
||||
SQLTableSource tableSource;
|
||||
if (ast.getFrom() == null) {
|
||||
tableSource = ast.getTableSource();
|
||||
} else {
|
||||
tableSource = ast.getFrom();
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
visitor.visit((SQLExprTableSource) tableSource);
|
||||
} else if (tableSource instanceof SQLJoinTableSource) {
|
||||
visitor.visit((SQLJoinTableSource) tableSource);
|
||||
} else {
|
||||
throw new NotSupportYetException("not support the syntax of delete with unknow");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.postgresql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLSequenceExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLValuableExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.sqlparser.SQLInsertRecognizer;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.struct.NotPlaceholderExpr;
|
||||
import io.seata.sqlparser.struct.Null;
|
||||
import io.seata.sqlparser.struct.SqlDefaultExpr;
|
||||
import io.seata.sqlparser.struct.SqlMethodExpr;
|
||||
import io.seata.sqlparser.struct.SqlSequenceExpr;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author japsercloud
|
||||
*/
|
||||
public class PostgresqlInsertRecognizer extends BasePostgresqlRecognizer implements SQLInsertRecognizer {
|
||||
|
||||
private final PGInsertStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new Postgresql insert recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public PostgresqlInsertRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (PGInsertStatement) ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.INSERT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
PGOutputVisitor visitor = new PGOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
visitor.visit(ast.getTableSource());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertColumnsIsEmpty() {
|
||||
return CollectionUtils.isEmpty(ast.getColumns());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getInsertColumns() {
|
||||
List<SQLExpr> columnSQLExprs = ast.getColumns();
|
||||
if (columnSQLExprs.size() == 0) {
|
||||
// INSERT INTO ta VALUES (...), without fields clarified
|
||||
return null;
|
||||
}
|
||||
List<String> list = new ArrayList<>(columnSQLExprs.size());
|
||||
for (SQLExpr expr : columnSQLExprs) {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr) expr).getName());
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<Object>> getInsertRows(Collection<Integer> primaryKeyIndex) {
|
||||
List<SQLInsertStatement.ValuesClause> valuesClauses = ast.getValuesList();
|
||||
List<List<Object>> rows = new ArrayList<>(valuesClauses.size());
|
||||
for (SQLInsertStatement.ValuesClause valuesClause : valuesClauses) {
|
||||
List<SQLExpr> exprs = valuesClause.getValues();
|
||||
List<Object> row = new ArrayList<>(exprs.size());
|
||||
rows.add(row);
|
||||
for (int i = 0, len = exprs.size(); i < len; i++) {
|
||||
SQLExpr expr = exprs.get(i);
|
||||
if (expr instanceof SQLNullExpr) {
|
||||
row.add(Null.get());
|
||||
} else if (expr instanceof SQLValuableExpr) {
|
||||
row.add(((SQLValuableExpr) expr).getValue());
|
||||
} else if (expr instanceof SQLVariantRefExpr) {
|
||||
row.add(((SQLVariantRefExpr) expr).getName());
|
||||
} else if (expr instanceof SQLMethodInvokeExpr) {
|
||||
SQLMethodInvokeExpr sqlMethodInvokeExpr = (SQLMethodInvokeExpr) expr;
|
||||
String function = sqlMethodInvokeExpr.getMethodName();
|
||||
if (StringUtils.equalsIgnoreCase(function, "nextval")) {
|
||||
String sequence = sqlMethodInvokeExpr.getParameters().get(0).toString();
|
||||
row.add(new SqlSequenceExpr(sequence, function));
|
||||
} else {
|
||||
row.add(SqlMethodExpr.get());
|
||||
}
|
||||
} else if (expr instanceof SQLSequenceExpr) {
|
||||
SQLSequenceExpr sequenceExpr = (SQLSequenceExpr) expr;
|
||||
String sequence = sequenceExpr.getSequence().getSimpleName();
|
||||
String function = sequenceExpr.getFunction().name;
|
||||
row.add(new SqlSequenceExpr(sequence, function));
|
||||
} else if (expr instanceof SQLDefaultExpr) {
|
||||
row.add(SqlDefaultExpr.get());
|
||||
} else {
|
||||
if (primaryKeyIndex.contains(i)) {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
row.add(NotPlaceholderExpr.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.postgresql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock;
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.druid.SQLOperateRecognizerHolder;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
|
||||
/**
|
||||
* The type PostgresqlOperateRecognizerHolder
|
||||
*
|
||||
* @author will.zjw
|
||||
*/
|
||||
@LoadLevel(name = JdbcConstants.POSTGRESQL)
|
||||
public class PostgresqlOperateRecognizerHolder implements SQLOperateRecognizerHolder {
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getDeleteRecognizer(String sql, SQLStatement ast) {
|
||||
return new PostgresqlDeleteRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getInsertRecognizer(String sql, SQLStatement ast) {
|
||||
return new PostgresqlInsertRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getUpdateRecognizer(String sql, SQLStatement ast) {
|
||||
return new PostgresqlUpdateRecognizer(sql, ast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getSelectForUpdateRecognizer(String sql, SQLStatement ast) {
|
||||
PGSelectQueryBlock selectQueryBlock = (PGSelectQueryBlock) ((SQLSelectStatement) ast).getSelect().getFirstQueryBlock();
|
||||
if (selectQueryBlock.getForClause() != null && selectQueryBlock.getForClause().getOption().equals(PGSelectQueryBlock.ForClause.Option.UPDATE)) {
|
||||
return new PostgresqlSelectForUpdateRecognizer(sql, ast);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.postgresql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLSelectRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author japsercloud
|
||||
*/
|
||||
public class PostgresqlSelectForUpdateRecognizer extends BasePostgresqlRecognizer implements SQLSelectRecognizer {
|
||||
|
||||
private final SQLSelectStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new Postgresql select for update recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public PostgresqlSelectForUpdateRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (SQLSelectStatement) ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.SELECT_FOR_UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLExpr where = selectQueryBlock.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLExpr where = selectQueryBlock.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
private SQLSelectQueryBlock getSelect() {
|
||||
SQLSelect select = ast.getSelect();
|
||||
if (select == null) {
|
||||
throw new SQLParsingException("should never happen!");
|
||||
}
|
||||
SQLSelectQueryBlock selectQueryBlock = select.getQueryBlock();
|
||||
if (selectQueryBlock == null) {
|
||||
throw new SQLParsingException("should never happen!");
|
||||
}
|
||||
return selectQueryBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLTableSource tableSource = selectQueryBlock.getFrom();
|
||||
return tableSource.getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
SQLSelectQueryBlock selectQueryBlock = getSelect();
|
||||
SQLTableSource tableSource = selectQueryBlock.getFrom();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
PGOutputVisitor visitor = new PGOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
visitor.visit((SQLExprTableSource) tableSource);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid.postgresql;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLValuableExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.SQLUpdateRecognizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author japsercloud
|
||||
*/
|
||||
public class PostgresqlUpdateRecognizer extends BasePostgresqlRecognizer implements SQLUpdateRecognizer {
|
||||
|
||||
private PGUpdateStatement ast;
|
||||
|
||||
/**
|
||||
* Instantiates a new Postgresql update recognizer.
|
||||
*
|
||||
* @param originalSQL the original sql
|
||||
* @param ast the ast
|
||||
*/
|
||||
public PostgresqlUpdateRecognizer(String originalSQL, SQLStatement ast) {
|
||||
super(originalSQL);
|
||||
this.ast = (PGUpdateStatement) ast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUpdateColumns() {
|
||||
List<SQLUpdateSetItem> updateSetItems = ast.getItems();
|
||||
List<String> list = new ArrayList<>(updateSetItems.size());
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
SQLExpr expr = updateSetItem.getColumn();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr) expr).getName());
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
// This is alias case, like UPDATE xxx_tbl a SET a.name = ? WHERE a.id = ?
|
||||
SQLExpr owner = ((SQLPropertyExpr) expr).getOwner();
|
||||
if (owner instanceof SQLIdentifierExpr) {
|
||||
list.add(((SQLIdentifierExpr) owner).getName() + "." + ((SQLPropertyExpr) expr).getName());
|
||||
//This is table Field Full path, like update xxx_database.xxx_tbl set xxx_database.xxx_tbl.xxx_field...
|
||||
} else if (((SQLPropertyExpr) expr).getOwnernName().split("\\.").length > 1) {
|
||||
list.add(((SQLPropertyExpr)expr).getOwnernName() + "." + ((SQLPropertyExpr)expr).getName());
|
||||
}
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getUpdateValues() {
|
||||
List<SQLUpdateSetItem> updateSetItems = ast.getItems();
|
||||
List<Object> list = new ArrayList<>(updateSetItems.size());
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
SQLExpr expr = updateSetItem.getValue();
|
||||
if (expr instanceof SQLValuableExpr) {
|
||||
list.add(((SQLValuableExpr) expr).getValue());
|
||||
} else if (expr instanceof SQLVariantRefExpr) {
|
||||
list.add(new VMarker());
|
||||
} else {
|
||||
throw new SQLParsingException("Unknown SQLExpr: " + expr.getClass() + " " + expr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(final ParametersHolder parametersHolder,
|
||||
final ArrayList<List<Object>> paramAppenderList) {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where, parametersHolder, paramAppenderList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
SQLExpr where = ast.getWhere();
|
||||
return super.getWhereCondition(where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return ast.getTableSource().getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
PGOutputVisitor visitor = new PGOutputVisitor(sb) {
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
printTableSourceExpr(x.getExpr());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLJoinTableSource x) {
|
||||
throw new NotSupportYetException("not support the syntax of update with join table");
|
||||
}
|
||||
};
|
||||
SQLTableSource tableSource = ast.getTableSource();
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
visitor.visit((SQLExprTableSource) tableSource);
|
||||
} else if (tableSource instanceof SQLJoinTableSource) {
|
||||
visitor.visit((SQLJoinTableSource) tableSource);
|
||||
} else {
|
||||
throw new NotSupportYetException("not support the syntax of update with unknow");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory
|
||||
@@ -0,0 +1,3 @@
|
||||
io.seata.sqlparser.druid.mysql.MySQLOperateRecognizerHolder
|
||||
io.seata.sqlparser.druid.oracle.OracleOperateRecognizerHolder
|
||||
io.seata.sqlparser.druid.postgresql.PostgresqlOperateRecognizerHolder
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.sqlparser.druid.DruidDelegatingDbTypeParser
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
|
||||
/**
|
||||
* The type Abstract my sql recognizer test.
|
||||
*
|
||||
* @author hanwen created at 2019-01-25
|
||||
*/
|
||||
public abstract class AbstractRecognizerTest {
|
||||
|
||||
/**
|
||||
* Gets sql statement.
|
||||
*
|
||||
* @param sql the sql
|
||||
* @return the sql statement
|
||||
*/
|
||||
public SQLStatement getSQLStatement(String sql) {
|
||||
List<SQLStatement> stats = SQLUtils.parseStatements(sql, getDbType());
|
||||
return stats.get(0);
|
||||
}
|
||||
|
||||
public abstract String getDbType();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.sqlparser.SqlParserType;
|
||||
import io.seata.sqlparser.util.DbTypeParser;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author ggndnn
|
||||
*/
|
||||
public class DruidDbTypeParserTest {
|
||||
@Test
|
||||
public void testDruidDbTypeParserLoading() {
|
||||
String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/seata";
|
||||
DruidDelegatingDbTypeParser dbTypeParser = (DruidDelegatingDbTypeParser) EnhancedServiceLoader.load(DbTypeParser.class, SqlParserType.SQL_PARSER_TYPE_DRUID);
|
||||
Assertions.assertNotNull(dbTypeParser);
|
||||
Assertions.assertEquals(DruidDelegatingDbTypeParser.class, dbTypeParser.getClass());
|
||||
String dbType = dbTypeParser.parseFromJdbcUrl(jdbcUrl);
|
||||
Assertions.assertEquals("mysql", dbType);
|
||||
|
||||
DruidLoader druidLoaderForTest = new DruidLoaderForTest();
|
||||
dbTypeParser.setClassLoader(new DruidIsolationClassLoader(druidLoaderForTest));
|
||||
Assertions.assertThrows(NoClassDefFoundError.class, () -> dbTypeParser.parseFromJdbcUrl(jdbcUrl));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.SQLRecognizerFactory;
|
||||
import io.seata.sqlparser.SqlParserType;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ggndnn
|
||||
*/
|
||||
public class DruidIsolationTest {
|
||||
private final static String TEST_SQL = "insert into t_table_1 values(?, ?)";
|
||||
|
||||
@Test
|
||||
public void testDruidIsolation() throws Exception {
|
||||
DruidDelegatingSQLRecognizerFactory recognizerFactory = (DruidDelegatingSQLRecognizerFactory) EnhancedServiceLoader.load(SQLRecognizerFactory.class, SqlParserType.SQL_PARSER_TYPE_DRUID);
|
||||
Assertions.assertNotNull(recognizerFactory);
|
||||
List<SQLRecognizer> sqlRecognizer = recognizerFactory.create(TEST_SQL, JdbcConstants.MYSQL);
|
||||
Assertions.assertNotNull(sqlRecognizer);
|
||||
DruidLoader druidLoaderForTest = new DruidLoaderForTest();
|
||||
recognizerFactory.setClassLoader(new DruidIsolationClassLoader(druidLoaderForTest));
|
||||
// because druid-test.jar not exists, so NoClassDefFoundError should be threw
|
||||
Assertions.assertThrows(NoClassDefFoundError.class, () -> recognizerFactory.create(TEST_SQL, JdbcConstants.MYSQL));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClass(){
|
||||
DruidDelegatingSQLRecognizerFactory recognizerFactory = (DruidDelegatingSQLRecognizerFactory) EnhancedServiceLoader.load(SQLRecognizerFactory.class,
|
||||
SqlParserType.SQL_PARSER_TYPE_DRUID);
|
||||
recognizerFactory.setClassLoader(DruidIsolationTest.class.getClassLoader());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
class DruidLoaderForTest implements DruidLoader {
|
||||
@Override
|
||||
public URL getEmbeddedDruidLocation() {
|
||||
try {
|
||||
return URI.create("file://druid-test.jar").toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.SQLRecognizerFactory;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.SqlParserType;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DruidSQLRecognizerFactoryTest {
|
||||
@Test
|
||||
public void testSqlRecognizerCreation() {
|
||||
SQLRecognizerFactory recognizerFactory = EnhancedServiceLoader.load(SQLRecognizerFactory.class, SqlParserType.SQL_PARSER_TYPE_DRUID);
|
||||
Assertions.assertNotNull(recognizerFactory);
|
||||
List<SQLRecognizer> recognizers = recognizerFactory.create("delete from t1", JdbcConstants.MYSQL);
|
||||
Assertions.assertNotNull(recognizers);
|
||||
Assertions.assertEquals(recognizers.size(),1);
|
||||
Assertions.assertEquals(SQLType.DELETE, recognizers.get(0).getSQLType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.druid.mysql.MySQLDeleteRecognizer;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The type My sql delete recognizer test.
|
||||
*
|
||||
* @author hanwen created at 2019-01-25
|
||||
*/
|
||||
public class MySQLDeleteRecognizerTest extends AbstractRecognizerTest {
|
||||
|
||||
@Test
|
||||
public void testVMarker() {
|
||||
Assertions.assertEquals("?", new BaseRecognizer.VMarker().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_0() {
|
||||
ParametersHolder parametersHolder = new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
return Collections.EMPTY_MAP;
|
||||
}
|
||||
};
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id = 'id1' order by id asc,name desc limit 1,2";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
|
||||
MySQLDeleteRecognizer mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement);
|
||||
String orderBy = mySQLDeleteRecognizer.getOrderBy();
|
||||
Assertions.assertTrue(orderBy.equalsIgnoreCase(" ORDER BY id asc,name desc"));
|
||||
Assertions.assertEquals(sql, mySQLDeleteRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLDeleteRecognizer.getTableName());
|
||||
Assertions.assertEquals("id = 'id1'", mySQLDeleteRecognizer.getWhereCondition());
|
||||
String limit = mySQLDeleteRecognizer.getLimit(parametersHolder, paramAppenderList);
|
||||
Assertions.assertEquals(" LIMIT 1,2", limit);
|
||||
sql = "DELETE FROM t1 WHERE id > 1 order by id ,name desc limit 1";
|
||||
statement = getSQLStatement(sql);
|
||||
mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement);
|
||||
orderBy = mySQLDeleteRecognizer.getOrderBy();
|
||||
Assertions.assertTrue(orderBy.equalsIgnoreCase(" order by id,name desc"));
|
||||
Assertions.assertEquals(" LIMIT 1", mySQLDeleteRecognizer.getLimit(parametersHolder, paramAppenderList));
|
||||
sql = "DELETE FROM t1 WHERE id > 1";
|
||||
statement = getSQLStatement(sql);
|
||||
mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement);
|
||||
Assertions.assertEquals(null, mySQLDeleteRecognizer.getLimit(parametersHolder, paramAppenderList));
|
||||
orderBy = mySQLDeleteRecognizer.getOrderBy();
|
||||
Assertions.assertEquals(null, mySQLDeleteRecognizer.getOrderBy());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_1() {
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id = ?";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLDeleteRecognizer mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLDeleteRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLDeleteRecognizer.getTableName());
|
||||
|
||||
// test overflow parameters
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLDeleteRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add("id1");
|
||||
Map result = new HashMap<>();
|
||||
result.put(1,idParam);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Collections.singletonList("id1")), paramAppenderList);
|
||||
Assertions.assertEquals("id = ?", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete recognizer test 2.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_2() {
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id IN (?, ?)";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLDeleteRecognizer mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLDeleteRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLDeleteRecognizer.getTableName());
|
||||
|
||||
// test overflow parameters
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLDeleteRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add("id1");
|
||||
ArrayList<Object> id2Param = new ArrayList<>();
|
||||
id2Param.add("id2");
|
||||
Map result = new HashMap();
|
||||
result.put(1, idParam);
|
||||
result.put(2, id2Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Arrays.asList(Arrays.asList("id1", "id2")), paramAppenderList);
|
||||
Assertions.assertEquals("id IN (?, ?)", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete recognizer test 3.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_3() {
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id between ? AND ?";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLDeleteRecognizer mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLDeleteRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLDeleteRecognizer.getTableName());
|
||||
|
||||
// test overflow parameters
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLDeleteRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add("id1");
|
||||
ArrayList<Object> id2Param = new ArrayList<>();
|
||||
id2Param.add("id2");
|
||||
Map result = new HashMap();
|
||||
result.put(1, idParam);
|
||||
result.put(2, id2Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Arrays.asList("id1", "id2")), paramAppenderList);
|
||||
Assertions.assertEquals("id BETWEEN ? AND ?", whereCondition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSqlType() {
|
||||
String sql = "delete from t where id = ?";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLDeleteRecognizer recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
Assertions.assertEquals(recognizer.getSQLType(), SQLType.DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTableAlias() {
|
||||
String sql = "delete from t where id = ?";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLDeleteRecognizer recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
Assertions.assertNull(recognizer.getTableAlias());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWhereCondition_0() {
|
||||
String sql = "delete from t";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLDeleteRecognizer recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
String whereCondition = recognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
return null;
|
||||
}
|
||||
}, new ArrayList<>());
|
||||
|
||||
//test for no condition
|
||||
Assertions.assertEquals("", whereCondition);
|
||||
|
||||
sql = "delete from t where id = ?";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
whereCondition = recognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add(1);
|
||||
Map result = new HashMap();
|
||||
result.put(1, idParam);
|
||||
return result;
|
||||
}
|
||||
}, new ArrayList<>());
|
||||
|
||||
//test for normal sql
|
||||
Assertions.assertEquals("id = ?", whereCondition);
|
||||
|
||||
sql = "delete from t where id in (?)";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
whereCondition = recognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add(1);
|
||||
Map result = new HashMap();
|
||||
result.put(1, idParam);
|
||||
return result;
|
||||
}
|
||||
}, new ArrayList<>());
|
||||
|
||||
//test for sql with in
|
||||
Assertions.assertEquals("id IN (?)", whereCondition);
|
||||
|
||||
sql = "delete from t where id between ? and ?";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
whereCondition = recognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add(1);
|
||||
ArrayList<Object> idParam2 = new ArrayList<>();
|
||||
idParam.add(2);
|
||||
Map result = new HashMap();
|
||||
result.put(1, idParam);
|
||||
result.put(2, idParam2);
|
||||
return result;
|
||||
}
|
||||
}, new ArrayList<>());
|
||||
//test for sql with in
|
||||
Assertions.assertEquals("id BETWEEN ? AND ?", whereCondition);
|
||||
|
||||
//test for exception
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
||||
String s = "delete from t where id in (?)";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLDeleteStatement deleteAst = (SQLDeleteStatement) sqlStatements.get(0);
|
||||
deleteAst.setWhere(new MySqlOrderingExpr());
|
||||
new MySQLDeleteRecognizer(s, deleteAst).getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
return new HashMap();
|
||||
}
|
||||
}, new ArrayList<>());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWhereCondition_1() {
|
||||
|
||||
String sql = "delete from t";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLDeleteRecognizer recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
String whereCondition = recognizer.getWhereCondition();
|
||||
|
||||
//test for no condition
|
||||
Assertions.assertEquals("", whereCondition);
|
||||
|
||||
sql = "delete from t where id = 1";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
whereCondition = recognizer.getWhereCondition();
|
||||
|
||||
//test for normal sql
|
||||
Assertions.assertEquals("id = 1", whereCondition);
|
||||
|
||||
sql = "delete from t where id in (1)";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
whereCondition = recognizer.getWhereCondition();
|
||||
|
||||
//test for sql with in
|
||||
Assertions.assertEquals("id IN (1)", whereCondition);
|
||||
|
||||
sql = "delete from t where id between 1 and 2";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
recognizer = new MySQLDeleteRecognizer(sql, asts.get(0));
|
||||
whereCondition = recognizer.getWhereCondition();
|
||||
//test for sql with in
|
||||
Assertions.assertEquals("id BETWEEN 1 AND 2", whereCondition);
|
||||
|
||||
//test for exception
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
||||
String s = "delete from t where id in (1)";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLDeleteStatement deleteAst = (SQLDeleteStatement) sqlStatements.get(0);
|
||||
deleteAst.setWhere(new MySqlOrderingExpr());
|
||||
new MySQLDeleteRecognizer(s, deleteAst).getWhereCondition();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDbType() {
|
||||
return JdbcConstants.MYSQL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
|
||||
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.druid.mysql.MySQLInsertRecognizer;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The type My sql insert recognizer test.
|
||||
*
|
||||
* @author hanwen created at 2019-01-25
|
||||
*/
|
||||
public class MySQLInsertRecognizerTest extends AbstractRecognizerTest {
|
||||
|
||||
private final int pkIndex = 0;
|
||||
|
||||
/**
|
||||
* Insert recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void insertRecognizerTest_0() {
|
||||
|
||||
String sql = "INSERT INTO t1 (name) VALUES ('name1')";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLInsertRecognizer mySQLInsertRecognizer = new MySQLInsertRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLInsertRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLInsertRecognizer.getTableName());
|
||||
Assertions.assertEquals(Collections.singletonList("name"), mySQLInsertRecognizer.getInsertColumns());
|
||||
Assertions.assertEquals(1, mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).size());
|
||||
Assertions.assertEquals(Collections.singletonList("name1"), mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void insertRecognizerTest_1() {
|
||||
|
||||
String sql = "INSERT INTO t1 (name1, name2) VALUES ('name1', 'name2')";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLInsertRecognizer mySQLInsertRecognizer = new MySQLInsertRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLInsertRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLInsertRecognizer.getTableName());
|
||||
Assertions.assertEquals(Arrays.asList("name1", "name2"), mySQLInsertRecognizer.getInsertColumns());
|
||||
Assertions.assertEquals(1, mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).size());
|
||||
Assertions.assertEquals(Arrays.asList("name1", "name2"), mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert recognizer test 3.
|
||||
*/
|
||||
@Test
|
||||
public void insertRecognizerTest_3() {
|
||||
|
||||
String sql = "INSERT INTO t1 (name1, name2) VALUES ('name1', 'name2'), ('name3', 'name4'), ('name5', 'name6')";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLInsertRecognizer mySQLInsertRecognizer = new MySQLInsertRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLInsertRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLInsertRecognizer.getTableName());
|
||||
Assertions.assertEquals(Arrays.asList("name1", "name2"), mySQLInsertRecognizer.getInsertColumns());
|
||||
Assertions.assertEquals(3, mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).size());
|
||||
Assertions.assertEquals(Arrays.asList("name1", "name2"), mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).get(0));
|
||||
Assertions.assertEquals(Arrays.asList("name3", "name4"), mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).get(1));
|
||||
Assertions.assertEquals(Arrays.asList("name5", "name6"), mySQLInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex)).get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSqlType() {
|
||||
String sql = "insert into t(id) values (?)";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLInsertRecognizer recognizer = new MySQLInsertRecognizer(sql, asts.get(0));
|
||||
Assertions.assertEquals(recognizer.getSQLType(), SQLType.INSERT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTableAlias() {
|
||||
String sql = "insert into t(id) values (?)";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLInsertRecognizer recognizer = new MySQLInsertRecognizer(sql, asts.get(0));
|
||||
Assertions.assertNull(recognizer.getTableAlias());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInsertColumns() {
|
||||
|
||||
//test for no column
|
||||
String sql = "insert into t values (?)";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLInsertRecognizer recognizer = new MySQLInsertRecognizer(sql, asts.get(0));
|
||||
List<String> insertColumns = recognizer.getInsertColumns();
|
||||
Assertions.assertNull(insertColumns);
|
||||
|
||||
//test for normal
|
||||
sql = "insert into t(a) values (?)";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
recognizer = new MySQLInsertRecognizer(sql, asts.get(0));
|
||||
insertColumns = recognizer.getInsertColumns();
|
||||
Assertions.assertEquals(1, insertColumns.size());
|
||||
|
||||
//test for exception
|
||||
Assertions.assertThrows(SQLParsingException.class, () -> {
|
||||
String s = "insert into t(a) values (?)";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLInsertStatement sqlInsertStatement = (SQLInsertStatement)sqlStatements.get(0);
|
||||
sqlInsertStatement.getColumns().add(new MySqlOrderingExpr());
|
||||
|
||||
MySQLInsertRecognizer oracleInsertRecognizer = new MySQLInsertRecognizer(s, sqlInsertStatement);
|
||||
oracleInsertRecognizer.getInsertColumns();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInsertRows() {
|
||||
//test for null value
|
||||
String sql = "insert into t(id, no, name, age, time) values (1, null, 'a', ?, now())";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLInsertRecognizer recognizer = new MySQLInsertRecognizer(sql, asts.get(0));
|
||||
List<List<Object>> insertRows = recognizer.getInsertRows(Collections.singletonList(pkIndex));
|
||||
Assertions.assertEquals(1, insertRows.size());
|
||||
|
||||
//test for exception
|
||||
Assertions.assertThrows(SQLParsingException.class, () -> {
|
||||
String s = "insert into t(a) values (?)";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLInsertStatement sqlInsertStatement = (SQLInsertStatement)sqlStatements.get(0);
|
||||
sqlInsertStatement.getValuesList().get(0).getValues().set(pkIndex, new MySqlOrderingExpr());
|
||||
|
||||
MySQLInsertRecognizer mysqlInsertRecognizer = new MySQLInsertRecognizer(s, sqlInsertStatement);
|
||||
mysqlInsertRecognizer.getInsertRows(Collections.singletonList(pkIndex));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDbType() {
|
||||
return JdbcConstants.MYSQL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.druid.mysql.MySQLSelectForUpdateRecognizer;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The type My sql select for update recognizer test.
|
||||
*/
|
||||
public class MySQLSelectForUpdateRecognizerTest extends AbstractRecognizerTest {
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_0() {
|
||||
|
||||
String sql = "SELECT name FROM t1 WHERE id = 'id1' FOR UPDATE";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLSelectForUpdateRecognizer mySQLUpdateRecognizer = new MySQLSelectForUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
Assertions.assertEquals("id = 'id1'", mySQLUpdateRecognizer.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_1() {
|
||||
|
||||
String sql = "SELECT name FROM t1 WHERE id = ? FOR UPDATE";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLSelectForUpdateRecognizer mySQLUpdateRecognizer = new MySQLSelectForUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add("id1");
|
||||
Map result = new HashMap();
|
||||
result.put(1, idParam);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Collections.singletonList("id1")), paramAppenderList);
|
||||
Assertions.assertEquals("id = ?", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 3.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_3() {
|
||||
|
||||
String sql = "SELECT name1, name2 FROM t1 WHERE id = ? FOR UPDATE";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLSelectForUpdateRecognizer mySQLUpdateRecognizer = new MySQLSelectForUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
|
||||
// test overflow parameters
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> id1Param = new ArrayList<>();
|
||||
id1Param.add("id1");
|
||||
Map result = new HashMap();
|
||||
result.put(1, id1Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Collections.singletonList("id1")), paramAppenderList);
|
||||
Assertions.assertEquals("id = ?", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 4.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_4() {
|
||||
|
||||
String sql = "SELECT name1, name2 FROM t1 WHERE id IN (?,?) FOR UPDATE";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLSelectForUpdateRecognizer mySQLUpdateRecognizer = new MySQLSelectForUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
|
||||
// test overflow parameters
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> id1Param = new ArrayList<>();
|
||||
id1Param.add("id1");
|
||||
ArrayList<Object> id2Param = new ArrayList<>();
|
||||
id2Param.add("id2");
|
||||
Map result = new HashMap();
|
||||
result.put(1, id1Param);
|
||||
result.put(2, id2Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Arrays.asList("id1", "id2")), paramAppenderList);
|
||||
Assertions.assertEquals("id IN (?, ?)", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 5.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_5() {
|
||||
|
||||
String sql = "SELECT name1, name2 FROM t1 WHERE id between ? and ? FOR UPDATE";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLSelectForUpdateRecognizer mySQLUpdateRecognizer = new MySQLSelectForUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
|
||||
// test overflow parameters
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> id1Param = new ArrayList<>();
|
||||
id1Param.add("id1");
|
||||
ArrayList<Object> id2Param = new ArrayList<>();
|
||||
id2Param.add("id2");
|
||||
Map result = new HashMap();
|
||||
result.put(1, id1Param);
|
||||
result.put(2, id2Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Arrays.asList("id1", "id2")), paramAppenderList);
|
||||
Assertions.assertEquals("id BETWEEN ? AND ?", whereCondition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWhereCondition_1() {
|
||||
String sql = "select * from t for update";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLSelectForUpdateRecognizer recognizer = new MySQLSelectForUpdateRecognizer(sql, asts.get(0));
|
||||
String whereCondition = recognizer.getWhereCondition();
|
||||
|
||||
Assertions.assertEquals("", whereCondition);
|
||||
|
||||
//test for select was null
|
||||
Assertions.assertThrows(SQLParsingException.class, () -> {
|
||||
String s = "select * from t for update";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLSelectStatement selectAst = (SQLSelectStatement) sqlStatements.get(0);
|
||||
selectAst.setSelect(null);
|
||||
new MySQLSelectForUpdateRecognizer(s, selectAst).getWhereCondition();
|
||||
});
|
||||
|
||||
//test for query was null
|
||||
Assertions.assertThrows(SQLParsingException.class, () -> {
|
||||
String s = "select * from t";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLSelectStatement selectAst = (SQLSelectStatement) sqlStatements.get(0);
|
||||
selectAst.getSelect().setQuery(null);
|
||||
new MySQLSelectForUpdateRecognizer(s, selectAst).getWhereCondition();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSqlType() {
|
||||
String sql = "select * from t where id = ? for update";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLSelectForUpdateRecognizer recognizer = new MySQLSelectForUpdateRecognizer(sql, asts.get(0));
|
||||
Assertions.assertEquals(recognizer.getSQLType(), SQLType.SELECT_FOR_UPDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTableAlias() {
|
||||
String sql = "select * from t where id = ? for update";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLSelectForUpdateRecognizer recognizer = new MySQLSelectForUpdateRecognizer(sql, asts.get(0));
|
||||
Assertions.assertNull(recognizer.getTableAlias());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDbType() {
|
||||
return JdbcConstants.MYSQL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.sqlparser.druid;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.druid.mysql.MySQLUpdateRecognizer;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The type My sql update recognizer test.
|
||||
*/
|
||||
public class MySQLUpdateRecognizerTest extends AbstractRecognizerTest {
|
||||
|
||||
/**
|
||||
* Update recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_0() {
|
||||
|
||||
String sql = "UPDATE t1 SET name = 'name1' WHERE id = 'id1'";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLUpdateRecognizer mySQLUpdateRecognizer = new MySQLUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
Assertions.assertEquals(1, mySQLUpdateRecognizer.getUpdateColumns().size());
|
||||
Assertions.assertEquals("name", mySQLUpdateRecognizer.getUpdateColumns().get(0));
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateValues().get(0));
|
||||
Assertions.assertEquals("id = 'id1'", mySQLUpdateRecognizer.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_1() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = 'name1', name2 = 'name2' WHERE id = 'id1'";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLUpdateRecognizer mySQLUpdateRecognizer = new MySQLUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
Assertions.assertEquals(2, mySQLUpdateRecognizer.getUpdateColumns().size());
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateColumns().get(0));
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateValues().get(0));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateColumns().get(1));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateValues().get(1));
|
||||
Assertions.assertEquals("id = 'id1'", mySQLUpdateRecognizer.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 2.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_2() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = 'name1', name2 = 'name2' WHERE id = ?";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLUpdateRecognizer mySQLUpdateRecognizer = new MySQLUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
Assertions.assertEquals(2, mySQLUpdateRecognizer.getUpdateColumns().size());
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateColumns().get(0));
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateValues().get(0));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateColumns().get(1));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateValues().get(1));
|
||||
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> idParam = new ArrayList<>();
|
||||
idParam.add("id1");
|
||||
Map result = new HashMap();
|
||||
result.put(1, idParam);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Collections.singletonList("id1")), paramAppenderList);
|
||||
|
||||
Assertions.assertEquals("id = ?", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 3.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_3() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = 'name1', name2 = 'name2' WHERE id in (?, ?)";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLUpdateRecognizer mySQLUpdateRecognizer = new MySQLUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
Assertions.assertEquals(2, mySQLUpdateRecognizer.getUpdateColumns().size());
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateColumns().get(0));
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateValues().get(0));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateColumns().get(1));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateValues().get(1));
|
||||
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> id1Param = new ArrayList<>();
|
||||
id1Param.add("id1");
|
||||
ArrayList<Object> id2Param = new ArrayList<>();
|
||||
id2Param.add("id2");
|
||||
Map result = new HashMap();
|
||||
result.put(1, id1Param);
|
||||
result.put(2, id2Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Arrays.asList("id1", "id2")), paramAppenderList);
|
||||
|
||||
Assertions.assertEquals("id IN (?, ?)", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 4.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_4() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = 'name1', name2 = 'name2' WHERE id in (?, ?) and name1 = ?";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLUpdateRecognizer mySQLUpdateRecognizer = new MySQLUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
Assertions.assertEquals(2, mySQLUpdateRecognizer.getUpdateColumns().size());
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateColumns().get(0));
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateValues().get(0));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateColumns().get(1));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateValues().get(1));
|
||||
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> id1Param = new ArrayList<>();
|
||||
id1Param.add("id1");
|
||||
ArrayList<Object> id2Param = new ArrayList<>();
|
||||
id2Param.add("id2");
|
||||
ArrayList<Object> name1Param = new ArrayList<>();
|
||||
name1Param.add("name");
|
||||
Map result = new HashMap();
|
||||
result.put(1, id1Param);
|
||||
result.put(2, id2Param);
|
||||
result.put(3, name1Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Arrays.asList("id1", "id2", "name")), paramAppenderList);
|
||||
|
||||
Assertions.assertEquals("id IN (?, ?)\nAND name1 = ?", whereCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 5.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_5() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = 'name1', name2 = 'name2' WHERE id between ? and ?";
|
||||
|
||||
SQLStatement statement = getSQLStatement(sql);
|
||||
|
||||
MySQLUpdateRecognizer mySQLUpdateRecognizer = new MySQLUpdateRecognizer(sql, statement);
|
||||
|
||||
Assertions.assertEquals(sql, mySQLUpdateRecognizer.getOriginalSQL());
|
||||
Assertions.assertEquals("t1", mySQLUpdateRecognizer.getTableName());
|
||||
Assertions.assertEquals(2, mySQLUpdateRecognizer.getUpdateColumns().size());
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateColumns().get(0));
|
||||
Assertions.assertEquals("name1", mySQLUpdateRecognizer.getUpdateValues().get(0));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateColumns().get(1));
|
||||
Assertions.assertEquals("name2", mySQLUpdateRecognizer.getUpdateValues().get(1));
|
||||
|
||||
ArrayList<List<Object>> paramAppenderList = new ArrayList<>();
|
||||
String whereCondition = mySQLUpdateRecognizer.getWhereCondition(new ParametersHolder() {
|
||||
@Override
|
||||
public Map<Integer,ArrayList<Object>> getParameters() {
|
||||
ArrayList<Object> id1Param = new ArrayList<>();
|
||||
id1Param.add("id1");
|
||||
ArrayList<Object> id2Param = new ArrayList<>();
|
||||
id2Param.add("id2");
|
||||
Map result = new HashMap();
|
||||
result.put(1, id1Param);
|
||||
result.put(2, id2Param);
|
||||
return result;
|
||||
}
|
||||
}, paramAppenderList);
|
||||
|
||||
Assertions.assertEquals(Collections.singletonList(Arrays.asList("id1", "id2")), paramAppenderList);
|
||||
Assertions.assertEquals("id BETWEEN ? AND ?", whereCondition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSqlType() {
|
||||
String sql = "update t set n = ?";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLUpdateRecognizer recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
Assertions.assertEquals(recognizer.getSQLType(), SQLType.UPDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUpdateColumns() {
|
||||
// test with normal
|
||||
String sql = "update t set a = ?, b = ?, c = ?";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
MySQLUpdateRecognizer recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
List<String> updateColumns = recognizer.getUpdateColumns();
|
||||
Assertions.assertEquals(updateColumns.size(), 3);
|
||||
|
||||
// test with alias
|
||||
sql = "update t set a.a = ?, a.b = ?, a.c = ?";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
updateColumns = recognizer.getUpdateColumns();
|
||||
Assertions.assertEquals(updateColumns.size(), 3);
|
||||
|
||||
//test with error
|
||||
Assertions.assertThrows(SQLParsingException.class, () -> {
|
||||
String s = "update t set a = a";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLUpdateStatement sqlUpdateStatement = (SQLUpdateStatement) sqlStatements.get(0);
|
||||
List<SQLUpdateSetItem> updateSetItems = sqlUpdateStatement.getItems();
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
updateSetItem.setColumn(new MySqlCharExpr());
|
||||
}
|
||||
MySQLUpdateRecognizer oracleUpdateRecognizer = new MySQLUpdateRecognizer(s, sqlUpdateStatement);
|
||||
oracleUpdateRecognizer.getUpdateColumns();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetUpdateDatabaseNameColumns() {
|
||||
// test with normal
|
||||
String sql = "update d.t set d.t.a = ?, d.t.b = ?, d.t.c = ?";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
MySQLUpdateRecognizer recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
List<String> updateColumns = recognizer.getUpdateColumns();
|
||||
Assertions.assertEquals(updateColumns.size(), 3);
|
||||
|
||||
// test with alias
|
||||
sql = "update t set a.a = ?, a.b = ?, a.c = ?";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
updateColumns = recognizer.getUpdateColumns();
|
||||
Assertions.assertEquals(updateColumns.size(), 3);
|
||||
|
||||
//test with error
|
||||
Assertions.assertThrows(SQLParsingException.class, () -> {
|
||||
String s = "update t set a = a";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLUpdateStatement sqlUpdateStatement = (SQLUpdateStatement) sqlStatements.get(0);
|
||||
List<SQLUpdateSetItem> updateSetItems = sqlUpdateStatement.getItems();
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
updateSetItem.setColumn(new MySqlCharExpr());
|
||||
}
|
||||
MySQLUpdateRecognizer oracleUpdateRecognizer = new MySQLUpdateRecognizer(s, sqlUpdateStatement);
|
||||
oracleUpdateRecognizer.getUpdateColumns();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUpdateValues() {
|
||||
// test with normal
|
||||
String sql = "update t set a = ?, b = ?, c = ?";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
MySQLUpdateRecognizer recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
List<Object> updateValues = recognizer.getUpdateValues();
|
||||
Assertions.assertEquals(updateValues.size(), 3);
|
||||
|
||||
// test with values
|
||||
sql = "update t set a = 1, b = 2, c = 3";
|
||||
asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
updateValues = recognizer.getUpdateValues();
|
||||
Assertions.assertEquals(updateValues.size(), 3);
|
||||
|
||||
// test with error
|
||||
Assertions.assertThrows(SQLParsingException.class, () -> {
|
||||
String s = "update t set a = ?";
|
||||
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(s, JdbcConstants.MYSQL);
|
||||
SQLUpdateStatement sqlUpdateStatement = (SQLUpdateStatement)sqlStatements.get(0);
|
||||
List<SQLUpdateSetItem> updateSetItems = sqlUpdateStatement.getItems();
|
||||
for (SQLUpdateSetItem updateSetItem : updateSetItems) {
|
||||
updateSetItem.setValue(new MySqlOrderingExpr());
|
||||
}
|
||||
MySQLUpdateRecognizer oracleUpdateRecognizer = new MySQLUpdateRecognizer(s, sqlUpdateStatement);
|
||||
oracleUpdateRecognizer.getUpdateValues();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTableAlias() {
|
||||
String sql = "update t set a = ?, b = ?, c = ?";
|
||||
List<SQLStatement> asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
MySQLUpdateRecognizer recognizer = new MySQLUpdateRecognizer(sql, asts.get(0));
|
||||
Assertions.assertNull(recognizer.getTableAlias());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDbType() {
|
||||
return JdbcConstants.MYSQL;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user