ES子表含group的where条件拼接 (#2190)

* ES子表含group的where条件拼接

* modify
This commit is contained in:
rewerma
2019-09-16 09:47:02 +08:00
committed by agapple
parent 365ca4d01f
commit 5214257cd4
2 changed files with 75 additions and 14 deletions

View File

@@ -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;
}
} }

View File

@@ -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<>();