Skip to content
Snippets Groups Projects
Verified Commit bee3b5df authored by Martin Weise's avatar Martin Weise
Browse files

Can process sub-query joins

parent 06fe2b09
No related branches found
No related tags found
2 merge requests!250Master,!246Dev
...@@ -694,13 +694,12 @@ public interface QueryMapper { ...@@ -694,13 +694,12 @@ public interface QueryMapper {
final List<SelectItem> clauses = ps.getSelectItems(); final List<SelectItem> clauses = ps.getSelectItems();
log.trace("columns referenced in the from-clause: {}", clauses); log.trace("columns referenced in the from-clause: {}", clauses);
/* Parse all tables */ /* Parse all tables */
final List<FromItem> tablesOrViews = new ArrayList<>(); final List<FromItem> fromItems = new ArrayList<>(fromItemToFromItems(ps.getFromItem()));
tablesOrViews.add(ps.getFromItem()); if (ps.getJoins() != null && !ps.getJoins().isEmpty()) {
if (ps.getJoins() != null && ps.getJoins().size() > 0) {
log.trace("query contains join items: {}", ps.getJoins()); log.trace("query contains join items: {}", ps.getJoins());
for (net.sf.jsqlparser.statement.select.Join j : ps.getJoins()) { for (net.sf.jsqlparser.statement.select.Join j : ps.getJoins()) {
if (j.getRightItem() != null) { if (j.getRightItem() != null) {
tablesOrViews.add(j.getRightItem()); fromItems.add(j.getRightItem());
} }
} }
} }
...@@ -711,30 +710,30 @@ public interface QueryMapper { ...@@ -711,30 +710,30 @@ public interface QueryMapper {
.toList(); .toList();
log.trace("columns referenced in the from-clause and join-clause(s): {}", clauses); log.trace("columns referenced in the from-clause and join-clause(s): {}", clauses);
/* Checking if all tables or views exist */ /* Checking if all tables or views exist */
log.trace("table(s) or view(s) referenced in the statement: {}", tablesOrViews.stream().map(t -> ((net.sf.jsqlparser.schema.Table) t).getName()).collect(Collectors.toList())); log.trace("table/view/join referenced in the statement: {}", fromItems.stream().map(this::fromItemToFromItems).flatMap(List::stream).collect(Collectors.toList()));
/* Checking if all columns exist */ /* Checking if all columns exist */
for (SelectItem clause : clauses) { for (SelectItem clause : clauses) {
final SelectExpressionItem item = (SelectExpressionItem) clause; final SelectExpressionItem item = (SelectExpressionItem) clause;
final Column column = (Column) item.getExpression(); final Column column = (Column) item.getExpression();
final Optional<net.sf.jsqlparser.schema.Table> optionalTableOrView = tablesOrViews.stream() final Optional<net.sf.jsqlparser.schema.Table> optional = fromItems.stream()
.map(t -> (net.sf.jsqlparser.schema.Table) t) .map(t -> (net.sf.jsqlparser.schema.Table) t)
.filter(t -> { .filter(t -> {
if (column.getTable() == null) { if (column.getTable() == null) {
/* column does not reference a specific table, so there is only one table */ /* column does not reference a specific table, so there is only one table */
final String tableName = ((net.sf.jsqlparser.schema.Table) tablesOrViews.get(0)).getName().replace("`", ""); final String tableName = ((net.sf.jsqlparser.schema.Table) fromItems.get(0)).getName().replace("`", "");
return tableOptionalAliasMatches(t, tableName); return tableMatches(t, tableName);
} }
final String tableName = column.getTable().getName().replace("`", ""); final String tableName = column.getTable().getName().replace("`", "");
return tableOptionalAliasMatches(t, tableName); return tableMatches(t, tableName);
}) })
.findFirst(); .findFirst();
if (optionalTableOrView.isEmpty()) { if (optional.isEmpty()) {
log.error("Failed to find table or view with alias {}", column.getTable().getAlias()); log.error("Failed to find table/view {} (with designator {})", column.getTable().getName(), column.getTable().getAlias());
throw new JSQLParserException("Failed to find table or view with alias " + column.getTable().getAlias()); throw new JSQLParserException("Failed to find table/view " + column.getTable().getName() + " (with alias " + column.getTable().getAlias() + ")");
} }
final Optional<TableColumn> optionalColumn = allColumns.stream() final Optional<TableColumn> optionalColumn = allColumns.stream()
.filter(c -> c.getInternalName().equals(column.getColumnName().replace("`", ""))) .filter(c -> c.getInternalName().equals(column.getColumnName().replace("`", "")))
.filter(c -> columnMatches(c, optionalTableOrView.get().getName().replace("`", ""))) .filter(c -> columnMatches(c, optional.get().getName().replace("`", "")))
.findFirst(); .findFirst();
if (optionalColumn.isEmpty()) { if (optionalColumn.isEmpty()) {
log.error("Failed to find column with name {} in {}", column.getColumnName(), allColumns.stream().map(TableColumn::getInternalName).toList()); log.error("Failed to find column with name {} in {}", column.getColumnName(), allColumns.stream().map(TableColumn::getInternalName).toList());
...@@ -750,22 +749,45 @@ public interface QueryMapper { ...@@ -750,22 +749,45 @@ public interface QueryMapper {
return columns; return columns;
} }
default boolean tableOptionalAliasMatches(net.sf.jsqlparser.schema.Table table, String tableName) { default List<FromItem> fromItemToFromItems(FromItem data) {
if (table.getAlias() == null) { return fromItemToFromItems(data, 0);
/* table is non-aliased */ }
final String otherTableName = table.getName()
default List<FromItem> fromItemToFromItems(FromItem data, Integer level) {
final List<FromItem> fromItems = new LinkedList<>();
if (data instanceof net.sf.jsqlparser.schema.Table table) {
fromItems.add(data);
log.trace("from-item {} is of type table: level ~> {}", table.getName(), level);
return fromItems;
}
if (data instanceof SubJoin subJoin) {
log.trace("from-item is of type sub-join: level ~> {}", level);
for (Join join : subJoin.getJoinList()) {
fromItems.addAll(fromItemToFromItems(join.getRightItem(), level + 1));
}
fromItems.addAll(fromItemToFromItems(((SubJoin) data).getLeft(), level + 1));
return fromItems;
}
log.warn("unknown from-item {}", data);
return null;
}
default boolean tableMatches(net.sf.jsqlparser.schema.Table table, String otherTableName) {
final String tableName = table.getName()
.trim() .trim()
.replace("`", ""); .replace("`", "");
log.trace("table {} has no alias", otherTableName); if (table.getAlias() == null) {
return otherTableName.equals(tableName); /* table does not have designator */
log.trace("table {} has no designator", tableName);
return tableName.equals(otherTableName);
} }
/* has alias */ /* has designator */
final String alias = table.getAlias() final String designator = table.getAlias()
.getName() .getName()
.trim() .trim()
.replace("`", ""); .replace("`", "");
log.trace("table {} has alias {}", table.getName(), alias); log.trace("table {} has designator {}", tableName, designator);
return alias.equals(tableName); return designator.equals(otherTableName);
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
......
...@@ -40,7 +40,7 @@ spring: ...@@ -40,7 +40,7 @@ spring:
loadbalancer.ribbon.enabled: false loadbalancer.ribbon.enabled: false
management.endpoints.web.exposure.include: health,info,prometheus management.endpoints.web.exposure.include: health,info,prometheus
server: server:
port: 19099 port: 9099
logging: logging:
pattern.console: "%d %highlight(%-5level) %msg%n" pattern.console: "%d %highlight(%-5level) %msg%n"
level: level:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment