Skip to content

Commit 180bb29

Browse files
author
gaoht
committed
fix #63 derive column bug
1 parent dfb3c5c commit 180bb29

File tree

15 files changed

+179
-92
lines changed

15 files changed

+179
-92
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 1999-2015 dangdang.com.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
* </p>
16+
*/
17+
18+
package com.dangdang.ddframe.rdb.sharding.parser.result.merger;
19+
20+
import com.google.common.base.Optional;
21+
import lombok.Getter;
22+
import lombok.RequiredArgsConstructor;
23+
import lombok.ToString;
24+
25+
/**
26+
* 可排序列.
27+
*
28+
* @author gaohongtao.
29+
*/
30+
@ToString
31+
@Getter
32+
@RequiredArgsConstructor
33+
public abstract class AbstractSortableColumn {
34+
35+
private final Optional<String> owner;
36+
37+
private final Optional<String> name;
38+
39+
private final Optional<String> alias;
40+
41+
private final OrderByColumn.OrderByType orderByType;
42+
}

sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/GroupByColumn.java

+8-12
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn.OrderByType;
2121
import com.google.common.base.Optional;
2222
import lombok.Getter;
23-
import lombok.RequiredArgsConstructor;
2423
import lombok.Setter;
2524
import lombok.ToString;
2625

@@ -29,27 +28,24 @@
2928
*
3029
* @author zhangliang
3130
*/
32-
@RequiredArgsConstructor
3331
@Getter
34-
@ToString
35-
public final class GroupByColumn implements IndexColumn {
36-
37-
private final String name;
38-
39-
private final String alias;
40-
41-
private final OrderByType orderByType;
32+
@ToString(callSuper = true)
33+
public final class GroupByColumn extends AbstractSortableColumn implements IndexColumn {
4234

4335
@Setter
4436
private int columnIndex;
4537

38+
public GroupByColumn(final Optional<String> owner, final String name, final Optional<String> alias, final OrderByType orderByType) {
39+
super(owner, Optional.of(name), alias, orderByType);
40+
}
41+
4642
@Override
4743
public Optional<String> getColumnLabel() {
48-
return Optional.of(alias);
44+
return getAlias();
4945
}
5046

5147
@Override
5248
public Optional<String> getColumnName() {
53-
return Optional.of(name);
49+
return getName();
5450
}
5551
}

sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/MergeContext.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public boolean groupByKeysEqualsOrderByKeys() {
105105

106106
@Override
107107
public OrderByColumn apply(final GroupByColumn input) {
108-
OrderByColumn result = new OrderByColumn(input.getName(), input.getAlias(), input.getOrderByType());
108+
OrderByColumn result = new OrderByColumn(input.getOwner(), input.getName().get(), input.getAlias(), input.getOrderByType());
109109
result.setColumnIndex(input.getColumnIndex());
110110
return result;
111111
}

sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/OrderByColumn.java

+15-21
Original file line numberDiff line numberDiff line change
@@ -20,41 +20,35 @@
2020
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
2121
import com.google.common.base.Objects;
2222
import com.google.common.base.Optional;
23-
import lombok.AccessLevel;
2423
import lombok.Getter;
25-
import lombok.RequiredArgsConstructor;
2624
import lombok.ToString;
2725

2826
/**
2927
* 排序列对象.
3028
*
3129
* @author zhangliang
3230
*/
33-
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3431
@Getter
35-
@ToString
36-
public final class OrderByColumn implements IndexColumn {
37-
38-
private final Optional<String> name;
32+
@ToString(callSuper = true)
33+
public final class OrderByColumn extends AbstractSortableColumn implements IndexColumn {
3934

4035
private final Optional<Integer> index;
4136

42-
private final Optional<String> alias;
43-
44-
private final OrderByType orderByType;
45-
4637
private int columnIndex;
4738

48-
public OrderByColumn(final String name, final String alias, final OrderByType orderByType) {
49-
this(Optional.of(name), Optional.<Integer>absent(), Optional.fromNullable(alias), orderByType);
39+
public OrderByColumn(final Optional<String> owner, final String name, final Optional<String> alias, final OrderByType orderByType) {
40+
super(owner, Optional.of(name), alias, orderByType);
41+
index = Optional.absent();
5042
}
5143

5244
public OrderByColumn(final String name, final OrderByType orderByType) {
53-
this(Optional.of(name), Optional.<Integer>absent(), Optional.<String>absent(), orderByType);
45+
super(Optional.<String>absent(), Optional.of(name), Optional.<String>absent(), orderByType);
46+
index = Optional.absent();
5447
}
5548

5649
public OrderByColumn(final int index, final OrderByType orderByType) {
57-
this(Optional.<String>absent(), Optional.of(index), Optional.<String>absent(), orderByType);
50+
super(Optional.<String>absent(), Optional.<String>absent(), Optional.<String>absent(), orderByType);
51+
this.index = Optional.of(index);
5852
columnIndex = index;
5953
}
6054

@@ -68,12 +62,12 @@ public void setColumnIndex(final int index) {
6862

6963
@Override
7064
public Optional<String> getColumnLabel() {
71-
return alias;
65+
return getAlias();
7266
}
7367

7468
@Override
7569
public Optional<String> getColumnName() {
76-
return name;
70+
return getName();
7771
}
7872

7973
/**
@@ -105,14 +99,14 @@ public boolean equals(final Object o) {
10599
return false;
106100
}
107101
OrderByColumn that = (OrderByColumn) o;
108-
return orderByType == that.orderByType && (columnIndex == that.columnIndex
102+
return getOrderByType() == that.getOrderByType() && (columnIndex == that.columnIndex
109103
|| index.isPresent() && that.index.isPresent() && index.get().equals(that.index.get())
110-
|| name.isPresent() && that.name.isPresent() && name.get().equals(that.name.get())
111-
|| alias.isPresent() && that.alias.isPresent() && alias.get().equals(that.alias.get()));
104+
|| getName().isPresent() && that.getName().isPresent() && getName().get().equals(that.getName().get())
105+
|| getAlias().isPresent() && that.getAlias().isPresent() && getAlias().get().equals(that.getAlias().get()));
112106
}
113107

114108
@Override
115109
public int hashCode() {
116-
return Objects.hashCode(orderByType, columnIndex);
110+
return Objects.hashCode(getOrderByType(), columnIndex);
117111
}
118112
}

sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/ParseContext.java

+39-17
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ private AggregationColumn getDerivedCountColumn(final AggregationColumn avgColum
275275
return new AggregationColumn(expression, AggregationType.COUNT, Optional.of(generateDerivedColumnAlias()), avgColumn.getOption());
276276
}
277277

278+
private String generateDerivedColumnAlias() {
279+
return String.format(SHARDING_GEN_ALIAS, ++selectItemsCount);
280+
}
281+
278282
private AggregationColumn getDerivedSumColumn(final AggregationColumn avgColumn) {
279283
String expression = avgColumn.getExpression().replaceFirst(AggregationType.AVG.toString(), AggregationType.SUM.toString());
280284
if (avgColumn.getOption().isPresent()) {
@@ -296,16 +300,20 @@ public void addOrderByColumn(final int index, final OrderByType orderByType) {
296300
/**
297301
* 将排序列加入解析上下文.
298302
*
303+
* @param owner 列拥有者
299304
* @param name 列名称
300305
* @param orderByType 排序类型
301306
*/
302-
public void addOrderByColumn(final String name, final OrderByType orderByType) {
307+
public void addOrderByColumn(final Optional<String> owner, final String name, final OrderByType orderByType) {
303308
String rawName = SQLUtil.getExactlyValue(name);
304-
String alias = null;
305-
if (!containsSelectItem(rawName)) {
306-
alias = generateDerivedColumnAlias();
309+
parsedResult.getMergeContext().getOrderByColumns().add(new OrderByColumn(owner, rawName, getAlias(rawName), orderByType));
310+
}
311+
312+
private Optional<String> getAlias(final String name) {
313+
if (containsSelectItem(name)) {
314+
return Optional.absent();
307315
}
308-
parsedResult.getMergeContext().getOrderByColumns().add(new OrderByColumn(rawName, alias, orderByType));
316+
return Optional.of(generateDerivedColumnAlias());
309317
}
310318

311319
private boolean containsSelectItem(final String selectItem) {
@@ -315,28 +323,42 @@ private boolean containsSelectItem(final String selectItem) {
315323
/**
316324
* 将分组列加入解析上下文.
317325
*
326+
* @param owner 列拥有者
318327
* @param name 列名称
319-
* @param alias 列别名
320328
* @param orderByType 排序类型
321329
*/
322-
public void addGroupByColumns(final String name, final String alias, final OrderByType orderByType) {
323-
parsedResult.getMergeContext().getGroupByColumns().add(new GroupByColumn(SQLUtil.getExactlyValue(name), alias, orderByType));
330+
public void addGroupByColumns(final Optional<String> owner, final String name, final OrderByType orderByType) {
331+
String rawName = SQLUtil.getExactlyValue(name);
332+
parsedResult.getMergeContext().getGroupByColumns().add(new GroupByColumn(owner, rawName, getAlias(rawName), orderByType));
324333
}
325334

326-
/**
327-
* 生成补列别名.
328-
*
329-
* @return 补列的别名
330-
*/
331-
public String generateDerivedColumnAlias() {
332-
return String.format(SHARDING_GEN_ALIAS, ++selectItemsCount);
333-
}
334335

335336
/**
336337
* 将当前解析的条件对象归并入解析结果.
337338
*/
338339
public void mergeCurrentConditionContext() {
339-
parsedResult.getConditionContexts().add(currentConditionContext);
340+
if (!parsedResult.getRouteContext().getTables().isEmpty()) {
341+
parsedResult.getConditionContexts().add(currentConditionContext);
342+
return;
343+
}
344+
Optional<SQLParsedResult> target = findValidParseResult();
345+
if (!target.isPresent()) {
346+
parsedResult.getConditionContexts().add(currentConditionContext);
347+
return;
348+
}
349+
parsedResult.getRouteContext().getTables().addAll(target.get().getRouteContext().getTables());
350+
parsedResult.getConditionContexts().addAll(target.get().getConditionContexts());
351+
}
352+
353+
private Optional<SQLParsedResult> findValidParseResult() {
354+
for (ParseContext each : subParseContext) {
355+
each.mergeCurrentConditionContext();
356+
if (each.getParsedResult().getRouteContext().getTables().isEmpty()) {
357+
continue;
358+
}
359+
return Optional.of(each.getParsedResult());
360+
}
361+
return Optional.absent();
340362
}
341363

342364
/**

sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLSelectVisitor.java

+22-15
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@
3232
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlSelectGroupByExpr;
3333
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
3434
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
35+
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AbstractSortableColumn;
3536
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
3637
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn.AggregationType;
37-
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.GroupByColumn;
3838
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.Limit;
39-
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn;
4039
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn.OrderByType;
4140
import com.google.common.base.Optional;
4241
import com.google.common.base.Strings;
@@ -123,9 +122,11 @@ public boolean visit(final SQLOrderBy x) {
123122
if (expr instanceof SQLIntegerExpr) {
124123
getParseContext().addOrderByColumn(((SQLIntegerExpr) expr).getNumber().intValue(), orderByType);
125124
} else if (expr instanceof SQLIdentifierExpr) {
126-
getParseContext().addOrderByColumn(((SQLIdentifierExpr) expr).getName(), orderByType);
125+
getParseContext().addOrderByColumn(Optional.<String>absent(), ((SQLIdentifierExpr) expr).getName(), orderByType);
127126
} else if (expr instanceof SQLPropertyExpr) {
128-
getParseContext().addOrderByColumn(((SQLPropertyExpr) expr).getName(), orderByType);
127+
SQLPropertyExpr sqlPropertyExpr = (SQLPropertyExpr) expr;
128+
getParseContext().addOrderByColumn(Optional.of(sqlPropertyExpr.getOwner().toString()), sqlPropertyExpr.getName(), orderByType);
129+
129130
}
130131
}
131132
return super.visit(x);
@@ -140,14 +141,13 @@ public boolean visit(final SQLOrderBy x) {
140141
*/
141142
@Override
142143
public boolean visit(final MySqlSelectGroupByExpr x) {
143-
String alias = getParseContext().generateDerivedColumnAlias();
144144
OrderByType orderByType = null == x.getType() ? OrderByType.ASC : OrderByType.valueOf(x.getType());
145145
if (x.getExpr() instanceof SQLPropertyExpr) {
146146
SQLPropertyExpr expr = (SQLPropertyExpr) x.getExpr();
147-
getParseContext().addGroupByColumns(expr.toString(), alias, orderByType);
147+
getParseContext().addGroupByColumns(Optional.of(expr.getOwner().toString()), expr.getName(), orderByType);
148148
} else if (x.getExpr() instanceof SQLIdentifierExpr) {
149149
SQLIdentifierExpr expr = (SQLIdentifierExpr) x.getExpr();
150-
getParseContext().addGroupByColumns(expr.getName(), alias, orderByType);
150+
getParseContext().addGroupByColumns(Optional.<String>absent(), expr.getName(), orderByType);
151151
}
152152
return super.visit(x);
153153
}
@@ -193,18 +193,25 @@ public void endVisit(final MySqlSelectQueryBlock x) {
193193
derivedSelectItems.append(", ").append(derivedColumn.getExpression()).append(" AS ").append(derivedColumn.getAlias().get());
194194
}
195195
}
196-
for (GroupByColumn each : getParseContext().getParsedResult().getMergeContext().getGroupByColumns()) {
197-
derivedSelectItems.append(", ").append(each.getName()).append(" AS ").append(each.getAlias());
198-
}
199-
for (OrderByColumn each : getParseContext().getParsedResult().getMergeContext().getOrderByColumns()) {
200-
if (each.getAlias().isPresent()) {
201-
derivedSelectItems.append(", ").append(each.getName().get()).append(" AS ").append(each.getAlias().get());
202-
}
203-
}
196+
appendSortableColumn(derivedSelectItems, getParseContext().getParsedResult().getMergeContext().getGroupByColumns());
197+
appendSortableColumn(derivedSelectItems, getParseContext().getParsedResult().getMergeContext().getOrderByColumns());
204198
if (0 != derivedSelectItems.length()) {
205199
getSQLBuilder().buildSQL(getParseContext().getAutoGenTokenKey(), derivedSelectItems.toString());
206200
}
207201
super.endVisit(x);
208202
stepOutQuery();
209203
}
204+
205+
private void appendSortableColumn(final StringBuilder derivedSelectItems, final List<? extends AbstractSortableColumn> sortableColumns) {
206+
for (AbstractSortableColumn each : sortableColumns) {
207+
if (!each.getAlias().isPresent()) {
208+
continue;
209+
}
210+
derivedSelectItems.append(", ");
211+
if (each.getOwner().isPresent()) {
212+
derivedSelectItems.append(each.getOwner().get()).append(".");
213+
}
214+
derivedSelectItems.append(each.getName().get()).append(" AS ").append(each.getAlias().get());
215+
}
216+
}
210217
}

sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/row/GroupByRowTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void testToString() throws Exception {
4545
MockResultSet rs = new MockResultSet<>(Arrays.asList(rs1, rs2));
4646
assertThat(rs.next(), is(true));
4747

48-
GroupByColumn groupByColumn = new GroupByColumn("user_id", "", OrderByColumn.OrderByType.ASC);
48+
GroupByColumn groupByColumn = new GroupByColumn(Optional.<String>absent(), "user_id", Optional.<String>absent(), OrderByColumn.OrderByType.ASC);
4949
groupByColumn.setColumnIndex(1);
5050
AggregationColumn aggregationColumn = new AggregationColumn("SUM(0)", AggregationColumn.AggregationType.SUM, Optional.<String>absent(), Optional.<String>absent());
5151
aggregationColumn.setColumnIndex(2);

sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/AbstractBaseParseTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public Comparable<?> apply(final Value input) {
159159
@Override
160160
public OrderByColumn apply(final com.dangdang.ddframe.rdb.sharding.parser.jaxb.OrderByColumn input) {
161161
return Strings.isNullOrEmpty(input.getName()) ? new OrderByColumn(input.getIndex(), OrderByType.valueOf(input.getOrderByType().toUpperCase()))
162-
: new OrderByColumn(input.getName(), input.getAlias(), OrderByType.valueOf(input.getOrderByType().toUpperCase()));
162+
: new OrderByColumn(Optional.fromNullable(input.getOwner()), input.getName(), Optional.fromNullable(input.getAlias()), OrderByType.valueOf(input.getOrderByType().toUpperCase()));
163163
}
164164
}));
165165
}
@@ -168,7 +168,7 @@ public OrderByColumn apply(final com.dangdang.ddframe.rdb.sharding.parser.jaxb.O
168168

169169
@Override
170170
public GroupByColumn apply(final com.dangdang.ddframe.rdb.sharding.parser.jaxb.GroupByColumn input) {
171-
return new GroupByColumn(input.getName(), input.getAlias(), OrderByType.valueOf(input.getOrderByType().toUpperCase()));
171+
return new GroupByColumn(Optional.fromNullable(input.getOwner()), input.getName(), Optional.fromNullable(input.getAlias()), OrderByType.valueOf(input.getOrderByType().toUpperCase()));
172172
}
173173
}));
174174
}

0 commit comments

Comments
 (0)