mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
@@ -10,11 +10,7 @@ import java.util.stream.Collectors;
|
|||||||
import com.alibaba.fastsql.sql.SQLUtils;
|
import com.alibaba.fastsql.sql.SQLUtils;
|
||||||
import com.alibaba.fastsql.sql.ast.SQLExpr;
|
import com.alibaba.fastsql.sql.ast.SQLExpr;
|
||||||
import com.alibaba.fastsql.sql.ast.expr.*;
|
import com.alibaba.fastsql.sql.ast.expr.*;
|
||||||
import com.alibaba.fastsql.sql.ast.statement.SQLExprTableSource;
|
import com.alibaba.fastsql.sql.ast.statement.*;
|
||||||
import com.alibaba.fastsql.sql.ast.statement.SQLJoinTableSource;
|
|
||||||
import com.alibaba.fastsql.sql.ast.statement.SQLSelectStatement;
|
|
||||||
import com.alibaba.fastsql.sql.ast.statement.SQLSubqueryTableSource;
|
|
||||||
import com.alibaba.fastsql.sql.ast.statement.SQLTableSource;
|
|
||||||
import com.alibaba.fastsql.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
import com.alibaba.fastsql.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||||
import com.alibaba.fastsql.sql.dialect.mysql.parser.MySqlStatementParser;
|
import com.alibaba.fastsql.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||||
import com.alibaba.fastsql.sql.parser.ParserException;
|
import com.alibaba.fastsql.sql.parser.ParserException;
|
||||||
@@ -232,4 +228,49 @@ public class SqlParser {
|
|||||||
throw new UnsupportedOperationException("Unsupported for complex of on-condition");
|
throw new UnsupportedOperationException("Unsupported for complex of on-condition");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MySqlSelectQueryBlock parseSQLSelectQueryBlock(String sql) {
|
||||||
|
if (sql == null || "".equals(sql)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||||
|
SQLSelectStatement statement = (SQLSelectStatement) parser.parseStatement();
|
||||||
|
return (MySqlSelectQueryBlock) statement.getSelect().getQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String parse4SQLSelectItem(MySqlSelectQueryBlock sqlSelectQueryBlock) {
|
||||||
|
List<SQLSelectItem> selectItems = sqlSelectQueryBlock.getSelectList();
|
||||||
|
StringBuilder subSql = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
for (SQLSelectItem sqlSelectItem : selectItems) {
|
||||||
|
if (i != 0) {
|
||||||
|
subSql.append(",");
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
subSql.append(SQLUtils.toMySqlString(sqlSelectItem));
|
||||||
|
}
|
||||||
|
return subSql.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String parse4FromTableSource(MySqlSelectQueryBlock sqlSelectQueryBlock) {
|
||||||
|
SQLTableSource sqlTableSource = sqlSelectQueryBlock.getFrom();
|
||||||
|
return SQLUtils.toMySqlString(sqlTableSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String parse4WhereItem(MySqlSelectQueryBlock sqlSelectQueryBlock) {
|
||||||
|
SQLExpr sqlExpr = sqlSelectQueryBlock.getWhere();
|
||||||
|
if (sqlExpr != null) {
|
||||||
|
return SQLUtils.toMySqlString(sqlExpr);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String parse4GroupBy(MySqlSelectQueryBlock sqlSelectQueryBlock) {
|
||||||
|
SQLSelectGroupByClause expr = sqlSelectQueryBlock.getGroupBy();
|
||||||
|
if (expr != null) {
|
||||||
|
return SQLUtils.toMySqlString(expr);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import java.util.*;
|
|||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import com.alibaba.fastsql.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||||
|
import com.alibaba.otter.canal.client.adapter.es.config.SqlParser;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -583,16 +585,34 @@ public class ESSyncService {
|
|||||||
private void subTableSimpleFieldOperation(ESSyncConfig config, Dml dml, Map<String, Object> data,
|
private void subTableSimpleFieldOperation(ESSyncConfig config, Dml dml, Map<String, Object> data,
|
||||||
Map<String, Object> old, TableItem tableItem) {
|
Map<String, Object> old, TableItem tableItem) {
|
||||||
ESMapping mapping = config.getEsMapping();
|
ESMapping mapping = config.getEsMapping();
|
||||||
StringBuilder sql = new StringBuilder(
|
|
||||||
"SELECT * FROM (" + tableItem.getSubQuerySql() + ") " + tableItem.getAlias() + " WHERE ");
|
|
||||||
|
|
||||||
|
MySqlSelectQueryBlock queryBlock = SqlParser.parseSQLSelectQueryBlock(tableItem.getSubQuerySql());
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
sql.append("SELECT ")
|
||||||
|
.append(SqlParser.parse4SQLSelectItem(queryBlock))
|
||||||
|
.append(" FROM ")
|
||||||
|
.append(SqlParser.parse4FromTableSource(queryBlock));
|
||||||
|
|
||||||
|
String whereSql = SqlParser.parse4WhereItem(queryBlock);
|
||||||
|
if (whereSql != null) {
|
||||||
|
sql.append(" WHERE ").append(whereSql);
|
||||||
|
} else {
|
||||||
|
sql.append(" WHERE 1=1 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> values = new ArrayList<>();
|
||||||
for (FieldItem fkFieldItem : tableItem.getRelationTableFields().keySet()) {
|
for (FieldItem fkFieldItem : tableItem.getRelationTableFields().keySet()) {
|
||||||
String columnName = fkFieldItem.getColumn().getColumnName();
|
String columnName = fkFieldItem.getColumn().getColumnName();
|
||||||
Object value = esTemplate.getValFromData(mapping, data, fkFieldItem.getFieldName(), columnName);
|
Object value = esTemplate.getValFromData(mapping, data, fkFieldItem.getFieldName(), columnName);
|
||||||
ESSyncUtil.appendCondition(sql, value, tableItem.getAlias(), columnName);
|
sql.append(" AND ").append(columnName).append("=? ");
|
||||||
|
values.add(value);
|
||||||
}
|
}
|
||||||
int len = sql.length();
|
|
||||||
sql.delete(len - 5, len);
|
String groupSql = SqlParser.parse4GroupBy(queryBlock);
|
||||||
|
if (groupSql != null) {
|
||||||
|
sql.append(groupSql);
|
||||||
|
}
|
||||||
|
|
||||||
DataSource ds = DatasourceConfig.DATA_SOURCES.get(config.getDataSourceKey());
|
DataSource ds = DatasourceConfig.DATA_SOURCES.get(config.getDataSourceKey());
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Join table update es index by query sql, destination:{}, table: {}, index: {}, sql: {}",
|
logger.trace("Join table update es index by query sql, destination:{}, table: {}, index: {}, sql: {}",
|
||||||
@@ -601,7 +621,7 @@ public class ESSyncService {
|
|||||||
mapping.get_index(),
|
mapping.get_index(),
|
||||||
sql.toString().replace("\n", " "));
|
sql.toString().replace("\n", " "));
|
||||||
}
|
}
|
||||||
Util.sqlRS(ds, sql.toString(), rs -> {
|
Util.sqlRS(ds, sql.toString(), values, rs -> {
|
||||||
try {
|
try {
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
Map<String, Object> esFieldData = new LinkedHashMap<>();
|
Map<String, Object> esFieldData = new LinkedHashMap<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user