Signed-off-by: shuming.li <ming.moriarty@gmail.com> Co-authored-by: shuming.li <ming.moriarty@gmail.com>
This commit is contained in:
parent
868b8287de
commit
6d8f208910
|
|
@ -630,17 +630,17 @@ public final class AggregatedMaterializedViewRewriter extends MaterializedViewRe
|
|||
// add projection to make sure that the output columns keep the same with the origin query
|
||||
if (queryAgg.getProjection() == null) {
|
||||
for (int i = 0; i < originalGroupKeys.size(); i++) {
|
||||
newProjection.put(originalGroupKeys.get(i), newGroupByKeyColumnRefs.get(i));
|
||||
addIntoProjection(newProjection, originalGroupKeys.get(i), newGroupByKeyColumnRefs.get(i));
|
||||
}
|
||||
for (Map.Entry<ColumnRefOperator, CallOperator> entry : queryAgg.getAggregations().entrySet()) {
|
||||
newProjection.put(entry.getKey(), queryColumnRefToScalarMap.get(entry.getKey()));
|
||||
addIntoProjection(newProjection, entry.getKey(), queryColumnRefToScalarMap.get(entry.getKey()));
|
||||
}
|
||||
} else {
|
||||
Map<ColumnRefOperator, ScalarOperator> originalMap = queryAgg.getProjection().getColumnRefMap();
|
||||
ReplaceColumnRefRewriter rewriter = new ReplaceColumnRefRewriter(queryColumnRefToScalarMap);
|
||||
for (Map.Entry<ColumnRefOperator, ScalarOperator> entry : originalMap.entrySet()) {
|
||||
ScalarOperator rewritten = rewriter.rewrite(entry.getValue());
|
||||
newProjection.put(entry.getKey(), rewritten);
|
||||
addIntoProjection(newProjection, entry.getKey(), rewritten);
|
||||
}
|
||||
}
|
||||
Projection projection = new Projection(newProjection);
|
||||
|
|
@ -751,7 +751,7 @@ public final class AggregatedMaterializedViewRewriter extends MaterializedViewRe
|
|||
|
||||
ColumnRefOperator outerProject = context.getQueryRefFactory()
|
||||
.create(copyProject, copyProject.getType(), copyProject.isNullable());
|
||||
newProjection.put(outerProject, copyProject);
|
||||
addIntoProjection(newProjection, outerProject, copyProject);
|
||||
newAggregations.put(innerAgg, realAggregate);
|
||||
|
||||
// replace original projection
|
||||
|
|
@ -851,7 +851,7 @@ public final class AggregatedMaterializedViewRewriter extends MaterializedViewRe
|
|||
aggColRef.isNullable());
|
||||
aggregateMapping.put(aggColRef, newAggColRef);
|
||||
rewrittens.put(newAggColRef, newAggregate);
|
||||
newProjection.put(newAggColRef, genRollupProject(aggCall, newAggColRef, hasGroupByKeys));
|
||||
addIntoProjection(newProjection, newAggColRef, genRollupProject(aggCall, newAggColRef, hasGroupByKeys));
|
||||
}
|
||||
|
||||
return rewrittens;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ import com.starrocks.sql.optimizer.operator.logical.LogicalScanOperator;
|
|||
import com.starrocks.sql.optimizer.operator.logical.LogicalUnionOperator;
|
||||
import com.starrocks.sql.optimizer.operator.logical.LogicalViewScanOperator;
|
||||
import com.starrocks.sql.optimizer.operator.scalar.BinaryPredicateOperator;
|
||||
import com.starrocks.sql.optimizer.operator.scalar.CastOperator;
|
||||
import com.starrocks.sql.optimizer.operator.scalar.ColumnRefOperator;
|
||||
import com.starrocks.sql.optimizer.operator.scalar.ConstantOperator;
|
||||
import com.starrocks.sql.optimizer.operator.scalar.IsNullPredicateOperator;
|
||||
|
|
@ -3052,4 +3053,24 @@ public class MaterializedViewRewriter implements IMaterializedViewRewriter {
|
|||
}
|
||||
return projection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columnRefOperator and scalarOperator into newProjection and ensure their type is the same.
|
||||
*/
|
||||
protected void addIntoProjection(Map<ColumnRefOperator, ScalarOperator> newProjection,
|
||||
ColumnRefOperator columnRefOperator,
|
||||
ScalarOperator scalarOperator) {
|
||||
// Ensure columnRefOperator's type is exactly the same as scalarOperator's type,
|
||||
// This can happen when mv and the query's type are different but they are the same columns, such as:
|
||||
// query: char(4)
|
||||
// mv : varchar(-1)
|
||||
// TODO: may it's safe to remove the cast if the type is compatible
|
||||
if (!columnRefOperator.getType().getPrimitiveType().equals(scalarOperator.getType().getPrimitiveType())) {
|
||||
// add cast if type is not the same
|
||||
ScalarOperator newScalarOperator = new CastOperator(columnRefOperator.getType(), scalarOperator, true);
|
||||
newProjection.put(columnRefOperator, newScalarOperator);
|
||||
} else {
|
||||
newProjection.put(columnRefOperator, scalarOperator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@ import com.starrocks.sql.optimizer.operator.logical.LogicalScanOperator;
|
|||
import com.starrocks.sql.optimizer.operator.physical.PhysicalScanOperator;
|
||||
import com.starrocks.sql.optimizer.operator.scalar.ColumnRefOperator;
|
||||
import com.starrocks.sql.plan.PlanTestBase;
|
||||
import com.starrocks.thrift.TExplainLevel;
|
||||
import mockit.Mock;
|
||||
import mockit.MockUp;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
|
@ -981,6 +982,36 @@ public class MvRewriteTest extends MVTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDictWithMVRewrite() throws Exception {
|
||||
FeConstants.USE_MOCK_DICT_MANAGER = true;
|
||||
starRocksAssert.withTable("CREATE TABLE supplier_char(" +
|
||||
" s_suppkey INTEGER NOT NULL,\n" +
|
||||
" s_name CHAR(25) NOT NULL,\n" +
|
||||
" s_address CHAR(40), \n" +
|
||||
" s_nationkey INTEGER NOT NULL,\n" +
|
||||
" s_phone CHAR(15) NOT NULL,\n" +
|
||||
" s_acctbal double NOT NULL,\n" +
|
||||
" s_comment CHAR(101) NOT NULL,\n" +
|
||||
" pad char(1) NOT NULL)\n" +
|
||||
"DUPLICATE KEY(`s_suppkey`)\n" +
|
||||
"DISTRIBUTED BY HASH(`s_suppkey`) BUCKETS 1\n" +
|
||||
"PROPERTIES (\n" +
|
||||
"\"replication_num\" = \"1\"" +
|
||||
");");
|
||||
starRocksAssert.withMaterializedView("CREATE MATERIALIZED VIEW test_mv1\n" +
|
||||
"DISTRIBUTED BY RANDOM\n" +
|
||||
"PROPERTIES (\n" +
|
||||
"\"replication_num\" = \"1\"\n" +
|
||||
")\n" +
|
||||
"AS select s_nationkey, s_name, bitmap_agg(s_suppkey), sum(s_nationkey) from supplier_char group by " +
|
||||
"s_nationkey, s_name;");
|
||||
String query = "select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name;";
|
||||
String plan = getFragmentPlan(query, TExplainLevel.COSTS);
|
||||
PlanTestBase.assertContains(plan, "dict_col=s_name");
|
||||
FeConstants.USE_MOCK_DICT_MANAGER = false;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkFk() throws SQLException {
|
||||
starRocksAssert.withMTables(List.of(
|
||||
|
|
|
|||
|
|
@ -283,6 +283,10 @@ public class PlanTestNoneDBBase {
|
|||
}
|
||||
|
||||
public String getFragmentPlan(String sql, String traceModule) throws Exception {
|
||||
return getFragmentPlan(sql, TExplainLevel.NORMAL, traceModule);
|
||||
}
|
||||
|
||||
public String getFragmentPlan(String sql, TExplainLevel tExplainLevel, String traceModule) throws Exception {
|
||||
Pair<String, Pair<ExecPlan, String>> result =
|
||||
UtFrameUtils.getFragmentPlanWithTrace(connectContext, sql, traceModule);
|
||||
Pair<ExecPlan, String> execPlanWithQuery = result.second;
|
||||
|
|
@ -290,7 +294,7 @@ public class PlanTestNoneDBBase {
|
|||
if (!Strings.isNullOrEmpty(traceLog)) {
|
||||
System.out.println(traceLog);
|
||||
}
|
||||
return execPlanWithQuery.first.getExplainString(TExplainLevel.NORMAL);
|
||||
return execPlanWithQuery.first.getExplainString(tExplainLevel);
|
||||
}
|
||||
|
||||
public String getLogicalFragmentPlan(String sql) throws Exception {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
-- name: test_mv_rewrite_bugfix3
|
||||
create database db_${uuid0};
|
||||
-- result:
|
||||
-- !result
|
||||
use db_${uuid0};
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE TABLE supplier_char(
|
||||
s_suppkey INTEGER NOT NULL,
|
||||
s_name CHAR(25) NOT NULL,
|
||||
s_address CHAR(40),
|
||||
s_nationkey INTEGER NOT NULL,
|
||||
s_phone CHAR(15) NOT NULL,
|
||||
s_acctbal double NOT NULL,
|
||||
s_comment CHAR(101) NOT NULL,
|
||||
pad char(1) NOT NULL)
|
||||
DUPLICATE KEY(`s_suppkey`)
|
||||
DISTRIBUTED BY HASH(`s_suppkey`) BUCKETS 1
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
);
|
||||
-- result:
|
||||
-- !result
|
||||
INSERT INTO supplier_char VALUES (1, 'name1', 'address1', 1, 'phone1', 1.0, 'comment1', 'p'),
|
||||
(2, 'name2', 'address2', 2, 'phone2', 2.0, 'comment2', 'p'),
|
||||
(3, 'name3', 'address3', 3, 'phone3', 3.0, 'comment3', 'p'),
|
||||
(4, 'name4', 'address4', 4, 'phone4', 4.0, 'comment4', 'p'),
|
||||
(5, 'name5', 'address5', 5, 'phone5', 5.0, 'comment5', 'p'),
|
||||
(6, 'name6', 'address6', 6, 'phone6', 6.0, 'comment6', 'p'),
|
||||
(7, 'name7', 'address7', 7, 'phone7', 7.0, 'comment7', 'p'),
|
||||
(8, 'name8', 'address8', 8, 'phone8', 8.0, 'comment8', 'p'),
|
||||
(9, 'name9', 'address9', 9, 'phone9', 9.0, 'comment9', 'p'),
|
||||
(10, 'name10', 'address10', 10, 'phone10', 10.0, 'comment10', 'p');
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE MATERIALIZED VIEW test_mv1
|
||||
DISTRIBUTED BY RANDOM
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
)
|
||||
AS select s_nationkey, s_name, bitmap_agg(s_suppkey), sum(s_nationkey) from supplier_char group by
|
||||
s_nationkey, s_name;
|
||||
-- result:
|
||||
-- !result
|
||||
REFRESH MATERIALIZED VIEW test_mv1 WITH SYNC MODE;
|
||||
[UC] analyze full table supplier_char;
|
||||
-- result:
|
||||
db_611c78b427b640e2b3e00e6241768903.supplier_char analyze status OK
|
||||
-- !result
|
||||
[UC] analyze full table test_mv1;
|
||||
-- result:
|
||||
db_611c78b427b640e2b3e00e6241768903.test_mv1 analyze status OK
|
||||
-- !result
|
||||
function: wait_global_dict_ready('s_name', 'supplier_char')
|
||||
-- result:
|
||||
|
||||
-- !result
|
||||
function: wait_global_dict_ready('s_name', 'test_mv1')
|
||||
-- result:
|
||||
|
||||
-- !result
|
||||
select s_nationkey, s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_nationkey, s_name order by 1,2;
|
||||
-- result:
|
||||
1 name1 1 1
|
||||
2 name2 1 2
|
||||
3 name3 1 3
|
||||
4 name4 1 4
|
||||
5 name5 1 5
|
||||
6 name6 1 6
|
||||
7 name7 1 7
|
||||
8 name8 1 8
|
||||
9 name9 1 9
|
||||
10 name10 1 10
|
||||
-- !result
|
||||
select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name order by 1,2;
|
||||
-- result:
|
||||
name1 1 1
|
||||
name10 1 10
|
||||
name2 1 2
|
||||
name3 1 3
|
||||
name4 1 4
|
||||
name5 1 5
|
||||
name6 1 6
|
||||
name7 1 7
|
||||
name8 1 8
|
||||
name9 1 9
|
||||
-- !result
|
||||
select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name having sum(s_nationkey) > 10 order by 1,2;
|
||||
-- result:
|
||||
-- !result
|
||||
function: print_hit_materialized_views("select s_nationkey, s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_nationkey, s_name order by 1,2;")
|
||||
-- result:
|
||||
test_mv1
|
||||
-- !result
|
||||
function: print_hit_materialized_views("select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name order by 1,2;")
|
||||
-- result:
|
||||
test_mv1
|
||||
-- !result
|
||||
function: print_hit_materialized_views("select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name having sum(s_nationkey) > 10 order by 1,2;")
|
||||
-- result:
|
||||
test_mv1
|
||||
-- !result
|
||||
drop materialized view test_mv1;
|
||||
-- result:
|
||||
-- !result
|
||||
drop database db_${uuid0};
|
||||
-- result:
|
||||
-- !result
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
-- name: test_mv_rewrite_bugfix3
|
||||
|
||||
create database db_${uuid0};
|
||||
use db_${uuid0};
|
||||
CREATE TABLE supplier_char(
|
||||
s_suppkey INTEGER NOT NULL,
|
||||
s_name CHAR(25) NOT NULL,
|
||||
s_address CHAR(40),
|
||||
s_nationkey INTEGER NOT NULL,
|
||||
s_phone CHAR(15) NOT NULL,
|
||||
s_acctbal double NOT NULL,
|
||||
s_comment CHAR(101) NOT NULL,
|
||||
pad char(1) NOT NULL)
|
||||
DUPLICATE KEY(`s_suppkey`)
|
||||
DISTRIBUTED BY HASH(`s_suppkey`) BUCKETS 1
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
);
|
||||
INSERT INTO supplier_char VALUES (1, 'name1', 'address1', 1, 'phone1', 1.0, 'comment1', 'p'),
|
||||
(2, 'name2', 'address2', 2, 'phone2', 2.0, 'comment2', 'p'),
|
||||
(3, 'name3', 'address3', 3, 'phone3', 3.0, 'comment3', 'p'),
|
||||
(4, 'name4', 'address4', 4, 'phone4', 4.0, 'comment4', 'p'),
|
||||
(5, 'name5', 'address5', 5, 'phone5', 5.0, 'comment5', 'p'),
|
||||
(6, 'name6', 'address6', 6, 'phone6', 6.0, 'comment6', 'p'),
|
||||
(7, 'name7', 'address7', 7, 'phone7', 7.0, 'comment7', 'p'),
|
||||
(8, 'name8', 'address8', 8, 'phone8', 8.0, 'comment8', 'p'),
|
||||
(9, 'name9', 'address9', 9, 'phone9', 9.0, 'comment9', 'p'),
|
||||
(10, 'name10', 'address10', 10, 'phone10', 10.0, 'comment10', 'p');
|
||||
|
||||
|
||||
CREATE MATERIALIZED VIEW test_mv1
|
||||
DISTRIBUTED BY RANDOM
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
)
|
||||
AS select s_nationkey, s_name, bitmap_agg(s_suppkey), sum(s_nationkey) from supplier_char group by
|
||||
s_nationkey, s_name;
|
||||
|
||||
REFRESH MATERIALIZED VIEW test_mv1 WITH SYNC MODE;
|
||||
|
||||
[UC] analyze full table supplier_char;
|
||||
[UC] analyze full table test_mv1;
|
||||
function: wait_global_dict_ready('s_name', 'supplier_char')
|
||||
function: wait_global_dict_ready('s_name', 'test_mv1')
|
||||
|
||||
select s_nationkey, s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_nationkey, s_name order by 1,2;
|
||||
select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name order by 1,2;
|
||||
select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name having sum(s_nationkey) > 10 order by 1,2;
|
||||
|
||||
function: print_hit_materialized_views("select s_nationkey, s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_nationkey, s_name order by 1,2;")
|
||||
function: print_hit_materialized_views("select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name order by 1,2;")
|
||||
function: print_hit_materialized_views("select s_name, count(distinct s_suppkey), sum(s_nationkey) from supplier_char group by s_name having sum(s_nationkey) > 10 order by 1,2;")
|
||||
|
||||
drop materialized view test_mv1;
|
||||
drop database db_${uuid0};
|
||||
Loading…
Reference in New Issue