Skip to content

Commit a9e5527

Browse files
authored
fix: use updated schema (#19)
* fix: use updated schema * feat(sql): dynamically generate table aliases in SELECT queries * we will need to update ColumnValue to include schema in addition to table name * this commit should make sure existing systems continue to work, however for more * complex queries, this will need to be revisited Signed-off-by: Rakib Ansary <rakibansary@topcoder.com> --------- Signed-off-by: Rakib Ansary <rakibansary@topcoder.com>
1 parent 12e9e41 commit a9e5527

File tree

1 file changed

+52
-21
lines changed

1 file changed

+52
-21
lines changed

src/main/java/com/topcoder/dal/util/QueryHelper.java

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,60 @@
55

66
import org.springframework.stereotype.Component;
77

8-
import java.util.Arrays;
9-
import java.util.List;
10-
import java.util.Objects;
11-
import java.util.Optional;
8+
import java.util.*;
9+
import java.util.concurrent.atomic.AtomicInteger;
1210
import java.util.function.BiFunction;
1311
import java.util.function.Function;
1412
import java.util.stream.Stream;
1513

1614
@Component
1715
public class QueryHelper {
16+
private final AtomicInteger aliasCounter = new AtomicInteger(0);
17+
18+
private String generateAlias(String fullTableName) {
19+
String[] parts = fullTableName.split(":");
20+
String tableName = parts.length > 1 ? parts[1] : parts[0];
21+
String prefix = tableName.substring(0, 1).toLowerCase();
22+
return prefix + aliasCounter.incrementAndGet();
23+
}
24+
1825

1926
public ParameterizedExpression getSelectQuery(SelectQuery query) {
20-
final String tableName = query.hasSchema() ? query.getSchema() + ":" + query.getTable() : query.getTable();
27+
aliasCounter.set(0);
2128

29+
final HashMap<String, String> tableAliases = new HashMap<>();
30+
final String primaryTableName = query.hasSchema() ? query.getSchema() + ":" + query.getTable() : query.getTable();
31+
final String tableAlias = generateAlias(primaryTableName);
32+
tableAliases.put(primaryTableName, tableAlias);
33+
34+
final String table = (query.hasSchema() ? query.getSchema() + ":" + query.getTable() : query.getTable()) + " " + tableAlias;
2235
List<Column> columnsList = query.getColumnList();
2336

37+
final Join[] joins = query.getJoinList().toArray(new Join[0]);
38+
for (Join join : joins) {
39+
tableAliases.computeIfAbsent(join.hasFromTableSchema() ? join.getFromTableSchema() + ":" + join.getFromTable() : join.getFromTable(), this::generateAlias);
40+
tableAliases.computeIfAbsent(join.hasJoinTableSchema() ? join.getJoinTableSchema() + ":" + join.getJoinTable() : join.getJoinTable(), this::generateAlias);
41+
}
42+
2443
final String[] columns = columnsList.stream()
25-
.map((column -> column.hasTableName() ? column.getTableName() + "." + column.getName()
26-
: column.getName()))
44+
.map(column -> column.hasTableName()
45+
? tableAliases.getOrDefault(column.getTableName(), tableAlias) + "." + column.getName() // TODO: This keeps current systems working correctly. Plan to update proto definition of ColumnValue to include schema
46+
: tableAlias + "." + column.getName())
2747
.toArray(String[]::new);
2848

2949
final List<ParameterizedExpression> whereClause = query.getWhereList().stream()
30-
.map(toWhereCriteria).toList();
31-
32-
final Join[] joins = query.getJoinList().toArray(new Join[0]);
50+
.map((criteria) -> {
51+
ParameterizedExpression parameterizedExpression = toWhereCriteria.apply(criteria);
52+
final String key = criteria.getKey();
53+
final String[] parts = key.split("\\.");
54+
if (parts.length > 1) {
55+
parameterizedExpression.setExpression(parameterizedExpression.getExpression().replace(key, tableAliases.get(parts[0]) + "." + parts[1]));
56+
} else {
57+
parameterizedExpression.setExpression(parameterizedExpression.getExpression().replace(key, tableAlias + "." + key));
58+
}
59+
return parameterizedExpression;
60+
})
61+
.toList();
3362

3463
final String[] groupByClause = query.getGroupByList().toArray(new String[0]);
3564
final String[] orderByClause = query.getOrderByList().toArray(new String[0]);
@@ -41,8 +70,8 @@ public ParameterizedExpression getSelectQuery(SelectQuery query) {
4170
expression.setExpression("SELECT"
4271
+ (offset > 0 ? " SKIP " + offset : "")
4372
+ (limit > 0 ? " FIRST " + limit : "")
44-
+ (" " + String.join(",", columns) + " FROM " + tableName)
45-
+ (joins.length > 0 ? " " + String.join(" ", Stream.of(joins).map(toJoin).toArray(String[]::new)) : "")
73+
+ (" " + String.join(",", columns) + " FROM " + table)
74+
+ (joins.length > 0 ? " " + String.join(" ", Stream.of(joins).map(join -> toJoin(join, tableAliases)).toArray(String[]::new)) : "")
4675
+ (!whereClause.isEmpty()
4776
? " WHERE " + String.join(" AND ",
4877
whereClause.stream().map(ParameterizedExpression::getExpression).toArray(String[]::new))
@@ -184,18 +213,20 @@ public static String sanitizeSQLStatement(String sql) {
184213
return sql;
185214
}
186215

187-
private static final Function<Join, String> toJoin = (join) -> {
188-
final String joinType = join.getType().toString();
189-
final String fromTable = join.hasFromTableSchema() ? join.getFromTableSchema() + ":" + join.getFromTable()
190-
: join.getFromTable();
191-
final String joinTable = join.hasJoinTableSchema() ? join.getJoinTableSchema() + ":" + join.getJoinTable()
192-
: join.getJoinTable();
216+
public String toJoin(Join join, HashMap<String, String> tableAliases) {
217+
final String joinType = join.getType().toString().replace("JOIN_TYPE_", "");
218+
219+
final String joinTableName = join.hasJoinTableSchema() ? join.getJoinTableSchema() + ":" + join.getJoinTable() : join.getJoinTable();
220+
final String fromTableName = join.hasFromTableSchema() ? join.getFromTableSchema() + ":" + join.getFromTable() : join.getFromTable();
221+
222+
final String joinTableAlias = tableAliases.getOrDefault(joinTableName, generateAlias(joinTableName));
223+
final String fromTableAlias = tableAliases.getOrDefault(fromTableName, generateAlias(fromTableName));
224+
193225
final String fromColumn = join.getFromColumn();
194226
final String joinColumn = join.getJoinColumn();
195227

196-
return joinType + " JOIN " + joinTable + " ON " + joinTable + "." + joinColumn + " = " + fromTable + "."
197-
+ fromColumn;
198-
};
228+
return joinType + " JOIN " + joinTableName + " AS " + joinTableAlias + " ON " + joinTableAlias + "." + joinColumn + " = " + fromTableAlias + "." + fromColumn;
229+
}
199230

200231
private final Function<WhereCriteria, ParameterizedExpression> toWhereCriteria = (criteria) -> {
201232
String key = criteria.getKey();

0 commit comments

Comments
 (0)