Skip to content

Commit

Permalink
issue apache#244 Should support SQL with table alias (apache#247)
Browse files Browse the repository at this point in the history
* issue apache#110 fix RM channel management

* fix merge mistake

* issue apache#110 enhance: if no channel found on my application set, try other application on the same resource.

* bug fix and enhance

* issue apache#110 enhance the original fix

* issue apache#227 SQLVisitorFactory should recognize FOR UPDATE from normal SELECT SQL

* issue apache#24 Should support SQL with table alias

* remove useless import
  • Loading branch information
sharajava authored and slievrly committed Jan 23, 2019
1 parent 5357a7b commit 3debcad
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@

package com.alibaba.fescar.rm.datasource.exec;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import com.alibaba.fescar.core.context.RootContext;
import com.alibaba.fescar.rm.datasource.StatementProxy;
import com.alibaba.fescar.rm.datasource.sql.SQLRecognizer;
import com.alibaba.fescar.rm.datasource.sql.struct.Field;
import com.alibaba.fescar.rm.datasource.sql.struct.TableMeta;
import com.alibaba.fescar.rm.datasource.sql.struct.TableMetaCache;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

public abstract class BaseTransactionalExecutor<T, S extends Statement> implements Executor {

protected StatementProxy<S> statementProxy;
Expand Down Expand Up @@ -56,14 +56,33 @@ protected String buildWhereConditionByPKs(List<Field> pkRows) throws SQLExceptio
StringBuffer whereConditionAppender = new StringBuffer();
for (int i = 0; i < pkRows.size(); i++) {
Field field = pkRows.get(i);
whereConditionAppender.append(field.getName() + " = ?");
whereConditionAppender.append(getColumnNameInSQL(field.getName()) + " = ?");
if (i < (pkRows.size() - 1)) {
whereConditionAppender.append(" OR ");
}
}
return whereConditionAppender.toString();
}

protected String getColumnNameInSQL(String columnName) {
String tableAlias = sqlRecognizer.getTableAlias();
if (tableAlias == null) {
return columnName;
} else {
return tableAlias + "." + columnName;
}
}

protected String getFromTableInSQL() {
String tableName = sqlRecognizer.getTableName();
String tableAlias = sqlRecognizer.getTableAlias();
if (tableAlias == null) {
return tableName;
} else {
return tableName + " " + tableAlias;
}
}

protected TableMeta getTableMeta() {
return getTableMeta(sqlRecognizer.getTableName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@

package com.alibaba.fescar.rm.datasource.exec;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fescar.rm.datasource.ParametersHolder;
import com.alibaba.fescar.rm.datasource.StatementProxy;
import com.alibaba.fescar.rm.datasource.sql.SQLDeleteRecognizer;
import com.alibaba.fescar.rm.datasource.sql.SQLRecognizer;
import com.alibaba.fescar.rm.datasource.sql.struct.TableMeta;
import com.alibaba.fescar.rm.datasource.sql.struct.TableRecords;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class DeleteExecutor<T, S extends Statement> extends AbstractDMLBaseExecutor<T, S> {

public DeleteExecutor(StatementProxy statementProxy, StatementCallback statementCallback, SQLRecognizer sqlRecognizer) {
Expand All @@ -39,6 +39,7 @@ public DeleteExecutor(StatementProxy statementProxy, StatementCallback statement
@Override
protected TableRecords beforeImage() throws SQLException {
SQLDeleteRecognizer visitor = (SQLDeleteRecognizer) sqlRecognizer;

TableMeta tmeta = getTableMeta(visitor.getTableName());
List<String> columns = new ArrayList<>();
for (String column : tmeta.getAllColumns().keySet()) {
Expand All @@ -48,7 +49,7 @@ protected TableRecords beforeImage() throws SQLException {
StringBuffer selectSQLAppender = new StringBuffer("SELECT ");

for (int i = 0; i < columns.size(); i++) {
selectSQLAppender.append(columns.get(i));
selectSQLAppender.append(getColumnNameInSQL(columns.get(i)));
if (i < (columns.size() - 1)) {
selectSQLAppender.append(", ");
}
Expand All @@ -60,7 +61,7 @@ protected TableRecords beforeImage() throws SQLException {
} else {
whereCondition = visitor.getWhereCondition();
}
selectSQLAppender.append(" FROM " + tmeta.getTableName() + " WHERE " + whereCondition + " FOR UPDATE");
selectSQLAppender.append(" FROM " + getFromTableInSQL() + " WHERE " + whereCondition + " FOR UPDATE");
String selectSQL = selectSQLAppender.toString();

TableRecords beforeImage = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ protected TableRecords beforeImage() throws SQLException {

@Override
protected TableRecords afterImage(TableRecords beforeImage) throws SQLException {
SQLInsertRecognizer visitor = (SQLInsertRecognizer) sqlRecognizer;
List<String> insertColumns = visitor.getInsertColumns();
SQLInsertRecognizer recogizier = (SQLInsertRecognizer) sqlRecognizer;
List<String> insertColumns = recogizier.getInsertColumns();
TableMeta tmeta = getTableMeta();
TableRecords afterImage = null;
if (tmeta.containsPK(insertColumns)) {
Expand All @@ -60,7 +60,7 @@ protected TableRecords afterImage(TableRecords beforeImage) throws SQLException
if (statementProxy instanceof PreparedStatementProxy) {
pkValues = ((PreparedStatementProxy) statementProxy).getParamsByIndex(paramIdx);
} else {
List<List<Object>> insertRows = visitor.getInsertRows();
List<List<Object>> insertRows = recogizier.getInsertRows();
pkValues = new ArrayList<>(insertRows.size());
for (List<Object> row : insertRows) {
pkValues.add(row.get(paramIdx));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public Object doExecute(Object... args) throws Throwable {
boolean originalAutoCommit = conn.getAutoCommit();

StringBuffer selectSQLAppender = new StringBuffer("SELECT ");
selectSQLAppender.append(getTableMeta().getPkName());
selectSQLAppender.append(" FROM " + getTableMeta().getTableName());
selectSQLAppender.append(getColumnNameInSQL(getTableMeta().getPkName()));
selectSQLAppender.append(" FROM " + getFromTableInSQL());
String whereCondition = null;
ArrayList<Object> paramAppender = new ArrayList<>();
if (statementProxy instanceof ParametersHolder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ public UpdateExecutor(StatementProxy statementProxy, StatementCallback statement

@Override
protected TableRecords beforeImage() throws SQLException {
SQLUpdateRecognizer visitor = (SQLUpdateRecognizer) sqlRecognizer;
SQLUpdateRecognizer recognizer = (SQLUpdateRecognizer) sqlRecognizer;

TableMeta tmeta = getTableMeta();
List<String> updateColumns = visitor.getUpdateColumns();
List<String> updateColumns = recognizer.getUpdateColumns();

StringBuffer selectSQLAppender = new StringBuffer("SELECT ");
if (!tmeta.containsPK(updateColumns)) {
// PK should be included.
selectSQLAppender.append(tmeta.getPkName() + ", ");
selectSQLAppender.append(getColumnNameInSQL(tmeta.getPkName()) + ", ");
}
for (int i = 0; i < updateColumns.size(); i++) {
selectSQLAppender.append(updateColumns.get(i));
Expand All @@ -57,11 +58,11 @@ protected TableRecords beforeImage() throws SQLException {
String whereCondition = null;
ArrayList<Object> paramAppender = new ArrayList<>();
if (statementProxy instanceof ParametersHolder) {
whereCondition = visitor.getWhereCondition((ParametersHolder) statementProxy, paramAppender);
whereCondition = recognizer.getWhereCondition((ParametersHolder) statementProxy, paramAppender);
} else {
whereCondition = visitor.getWhereCondition();
whereCondition = recognizer.getWhereCondition();
}
selectSQLAppender.append(" FROM " + tmeta.getTableName() + " WHERE " + whereCondition + " FOR UPDATE");
selectSQLAppender.append(" FROM " + getFromTableInSQL() + " WHERE " + whereCondition + " FOR UPDATE");
String selectSQL = selectSQLAppender.toString();

TableRecords beforeImage = null;
Expand Down Expand Up @@ -97,17 +98,18 @@ protected TableRecords beforeImage() throws SQLException {

@Override
protected TableRecords afterImage(TableRecords beforeImage) throws SQLException {
SQLUpdateRecognizer visitor = (SQLUpdateRecognizer) sqlRecognizer;
SQLUpdateRecognizer recognizer = (SQLUpdateRecognizer) sqlRecognizer;

TableMeta tmeta = getTableMeta();
if (beforeImage == null || beforeImage.size() == 0) {
return TableRecords.empty(getTableMeta());
}
List<String> updateColumns = visitor.getUpdateColumns();
List<String> updateColumns = recognizer.getUpdateColumns();

StringBuffer selectSQLAppender = new StringBuffer("SELECT ");
if (!tmeta.containsPK(updateColumns)) {
// PK should be included.
selectSQLAppender.append(tmeta.getPkName() + ", ");
selectSQLAppender.append(getColumnNameInSQL(tmeta.getPkName()) + ", ");
}
for (int i = 0; i < updateColumns.size(); i++) {
selectSQLAppender.append(updateColumns.get(i));
Expand All @@ -116,7 +118,7 @@ protected TableRecords afterImage(TableRecords beforeImage) throws SQLException
}
}
List<Field> pkRows = beforeImage.pkRows();
selectSQLAppender.append(" FROM " + tmeta.getTableName() + " WHERE " + buildWhereConditionByPKs(pkRows) + " FOR UPDATE");
selectSQLAppender.append(" FROM " + getFromTableInSQL() + " WHERE " + buildWhereConditionByPKs(pkRows) + " FOR UPDATE");
String selectSQL = selectSQLAppender.toString();

TableRecords afterImage = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ public interface SQLRecognizer {
/**
* TableRecords source related in the SQL, including alias if any.
* SELECT id, name FROM user u WHERE ...
* TableRecords source should be 'user u' for this SQL.
* Alias should be 'u' for this SQL.
*
* @return table source.
*/
String getTableSource();
String getTableAlias();

/**
* TableRecords name related in the SQL.
* SELECT id, name FROM user u WHERE ...
* TableRecords name should be 'user' for this SQL, without alias 'u'.
*
* @see #getTableSource()
* @see #getTableAlias()
* @return table name.
*/
String getTableName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,8 @@ public SQLType getSQLType() {
}

@Override
public String getTableSource() {
StringBuffer sb = new StringBuffer();
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb);
visitor.visit((SQLExprTableSource)ast.getTableSource());
return sb.toString();
public String getTableAlias() {
return ast.getTableSource().getAlias();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,8 @@ public SQLType getSQLType() {
}

@Override
public String getTableSource() {
StringBuffer sb = new StringBuffer();
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb);
visitor.visit(ast.getTableSource());
return sb.toString();
public String getTableAlias() {
return ast.getTableSource().getAlias();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,19 @@

package com.alibaba.fescar.rm.datasource.sql.druid;

import java.util.ArrayList;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
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.ast.statement.*;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
import com.alibaba.fescar.rm.datasource.ParametersHolder;
import com.alibaba.fescar.rm.datasource.sql.SQLParsingException;
import com.alibaba.fescar.rm.datasource.sql.SQLSelectRecognizer;
import com.alibaba.fescar.rm.datasource.sql.SQLType;

import java.util.ArrayList;

public class MySQLSelectForUpdateRecognizer extends BaseRecognizer implements SQLSelectRecognizer {

private final SQLSelectStatement ast;
Expand Down Expand Up @@ -96,13 +92,10 @@ private SQLSelectQueryBlock getSelect() {
}

@Override
public String getTableSource() {
public String getTableAlias() {
SQLSelectQueryBlock selectQueryBlock = getSelect();
SQLTableSource tableSource = selectQueryBlock.getFrom();
StringBuffer sb = new StringBuffer();
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb);
visitor.visit((SQLExprTableSource)tableSource);
return sb.toString();
return tableSource.getAlias();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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 com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.fescar.rm.datasource.ParametersHolder;
import com.alibaba.fescar.rm.datasource.sql.SQLParsingException;
import com.alibaba.fescar.rm.datasource.sql.SQLType;
Expand Down Expand Up @@ -122,12 +123,8 @@ public String getWhereCondition() {
}

@Override
public String getTableSource() {
StringBuffer sb = new StringBuffer();
MySqlOutputVisitor visitor = new MySqlOutputVisitor(sb);
SQLExprTableSource tableSource = (SQLExprTableSource) ast.getTableSource();
visitor.visit(tableSource);
return sb.toString();
public String getTableAlias() {
return ast.getTableSource().getAlias();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.Date;

public class DataSourceBasicTest {
public void runBusiness(JdbcTemplate jdbcTemplate) {
// jdbcTemplate.update("insert into user0 (id, name, gmt) values (?, ?, ?)",
// new Object[] { 1, "xxx", new Date() });
jdbcTemplate.update("update user0 set name = 'yyyy' where id = ?", new Object[] {1});
// jdbcTemplate.update("delete from user0 where id = ?", new Object[] {1});
//jdbcTemplate.update("insert into user0 (id, name, gmt) values (?, ?, ?)",
// new Object[] { 2, "xxx", new Date() });
// jdbcTemplate.update("update user0 a set a.name = 'yyyy' where a.id = ?", new Object[] {1});
// jdbcTemplate.update("update user0 a set a.name = 'yyyy' where a.name = ?", new Object[] {"yyyy"});
// jdbcTemplate.update("delete from user0 where id = ?", new Object[] {2});
jdbcTemplate.queryForRowSet("select a.name from user0 a where a.id = ? for update", new Object[] {1});


}
Expand Down

0 comments on commit 3debcad

Please sign in to comment.