This is an automated email from the ASF dual-hosted git repository.
lihaopeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new ec3c911f97 [Feature][Materialized-View] support materialized view on
vectorized engine (#10792)
ec3c911f97 is described below
commit ec3c911f97bcf686547a33130ffdf0cad08d2491
Author: Pxl <[email protected]>
AuthorDate: Thu Aug 4 14:07:48 2022 +0800
[Feature][Materialized-View] support materialized view on vectorized engine
(#10792)
---
.gitattributes | 1 +
be/src/olap/hll.cpp | 40 -----------------
be/src/olap/hll.h | 9 ----
be/src/olap/rowset/segment_v2/segment_iterator.cpp | 10 ++---
be/src/olap/rowset/segment_v2/segment_iterator.h | 2 +-
be/src/olap/schema_change.cpp | 48 +++++++++-----------
be/src/olap/schema_change.h | 1 +
be/src/runtime/descriptors.h | 5 ---
be/src/runtime/primitive_type.h | 1 -
be/src/vec/columns/column_complex.h | 50 ++++++++-------------
be/src/vec/exec/volap_scanner.cpp | 13 ++++--
.../java/org/apache/doris/alter/RollupJobV2.java | 11 ++---
.../org/apache/doris/alter/SchemaChangeJobV2.java | 4 +-
.../doris/analysis/CreateMaterializedViewStmt.java | 13 ++++--
.../doris/rewrite/mvrewrite/CountFieldToSum.java | 6 +--
.../rewrite/mvrewrite/HLLHashToSlotRefRule.java | 3 +-
.../org/apache/doris/alter/RollupJobV2Test.java | 5 ++-
.../analysis/CreateMaterializedViewStmtTest.java | 21 ++++++---
.../data/rollup/test_materialized_view.out | Bin 926 -> 1399 bytes
.../suites/rollup/test_materialized_view.groovy | 10 ++++-
20 files changed, 100 insertions(+), 153 deletions(-)
diff --git a/.gitattributes b/.gitattributes
index 6c01695fd2..01e299f06e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -14,3 +14,4 @@
*.thrift text eol=lf
*.proto text eol=lf
*.conf text eol=lf
+*.out text eol=lf -diff
diff --git a/be/src/olap/hll.cpp b/be/src/olap/hll.cpp
index a2ec6e39a0..bc2ba3de39 100644
--- a/be/src/olap/hll.cpp
+++ b/be/src/olap/hll.cpp
@@ -407,44 +407,4 @@ void HllSetResolver::parse() {
}
}
-void HllSetHelper::set_sparse(char* result, const std::map<int, uint8_t>&
index_to_value,
- int& len) {
- result[0] = HLL_DATA_SPARSE;
- len = sizeof(HllSetResolver::SetTypeValueType) +
sizeof(HllSetResolver::SparseLengthValueType);
- char* write_value_pos = result + len;
- for (auto iter = index_to_value.begin(); iter != index_to_value.end();
++iter) {
- write_value_pos[0] = (char)(iter->first & 0xff);
- write_value_pos[1] = (char)(iter->first >> 8 & 0xff);
- write_value_pos[2] = iter->second;
- write_value_pos += 3;
- }
- int registers_count = index_to_value.size();
- len += registers_count *
- (sizeof(HllSetResolver::SparseIndexType) +
sizeof(HllSetResolver::SparseValueType));
- *(int*)(result + 1) = registers_count;
-}
-
-void HllSetHelper::set_explicit(char* result, const std::set<uint64_t>&
hash_value_set, int& len) {
- result[0] = HLL_DATA_EXPLICIT;
- result[1] =
(HllSetResolver::ExplicitLengthValueType)(hash_value_set.size());
- len = sizeof(HllSetResolver::SetTypeValueType) +
- sizeof(HllSetResolver::ExplicitLengthValueType);
- char* write_pos = result + len;
- for (auto iter = hash_value_set.begin(); iter != hash_value_set.end();
++iter) {
- uint64_t hash_value = *iter;
- *(uint64_t*)write_pos = hash_value;
- write_pos += 8;
- }
- len += sizeof(uint64_t) * hash_value_set.size();
-}
-
-void HllSetHelper::set_full(char* result, const std::map<int, uint8_t>&
index_to_value,
- const int registers_len, int& len) {
- result[0] = HLL_DATA_FULL;
- for (auto iter = index_to_value.begin(); iter != index_to_value.end();
++iter) {
- result[1 + iter->first] = iter->second;
- }
- len = registers_len + sizeof(HllSetResolver::SetTypeValueType);
-}
-
} // namespace doris
diff --git a/be/src/olap/hll.h b/be/src/olap/hll.h
index 81c17be252..a3347f4626 100644
--- a/be/src/olap/hll.h
+++ b/be/src/olap/hll.h
@@ -370,13 +370,4 @@ private:
SparseLengthValueType* _sparse_count;
};
-// todo(kks): remove this when dpp_sink class was removed
-class HllSetHelper {
-public:
- static void set_sparse(char* result, const std::map<int, uint8_t>&
index_to_value, int& len);
- static void set_explicit(char* result, const std::set<uint64_t>&
hash_value_set, int& len);
- static void set_full(char* result, const std::map<int, uint8_t>&
index_to_value,
- const int set_len, int& len);
-};
-
} // namespace doris
diff --git a/be/src/olap/rowset/segment_v2/segment_iterator.cpp
b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
index 9aa4173fd3..1b39703863 100644
--- a/be/src/olap/rowset/segment_v2/segment_iterator.cpp
+++ b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
@@ -1001,16 +1001,15 @@ uint16_t
SegmentIterator::_evaluate_short_circuit_predicate(uint16_t* vec_sel_ro
Status SegmentIterator::_read_columns_by_rowids(std::vector<ColumnId>&
read_column_ids,
std::vector<rowid_t>&
rowid_vector,
- uint16_t* sel_rowid_idx,
size_t select_size,
- vectorized::MutableColumns*
mutable_columns) {
+ uint16_t* sel_rowid_idx,
size_t select_size) {
SCOPED_RAW_TIMER(&_opts.stats->lazy_read_ns);
std::vector<rowid_t> rowids(select_size);
for (size_t i = 0; i < select_size; ++i) {
rowids[i] = rowid_vector[sel_rowid_idx[i]];
}
for (auto cid : read_column_ids) {
- auto& column = (*mutable_columns)[cid];
- RETURN_IF_ERROR(_column_iterators[cid]->read_by_rowids(rowids.data(),
select_size, column));
+ RETURN_IF_ERROR(_column_iterators[cid]->read_by_rowids(rowids.data(),
select_size,
+
_current_return_columns[cid]));
}
return Status::OK();
@@ -1117,8 +1116,7 @@ Status SegmentIterator::next_batch(vectorized::Block*
block) {
// step3: read non_predicate column
RETURN_IF_ERROR(_read_columns_by_rowids(_non_predicate_columns,
_block_rowids,
- sel_rowid_idx, selected_size,
- &_current_return_columns));
+ sel_rowid_idx, selected_size));
// step4: output columns
// 4.1 output non-predicate column
diff --git a/be/src/olap/rowset/segment_v2/segment_iterator.h
b/be/src/olap/rowset/segment_v2/segment_iterator.h
index b99f8b379a..7170d60108 100644
--- a/be/src/olap/rowset/segment_v2/segment_iterator.h
+++ b/be/src/olap/rowset/segment_v2/segment_iterator.h
@@ -116,7 +116,7 @@ private:
void _output_non_pred_columns(vectorized::Block* block);
Status _read_columns_by_rowids(std::vector<ColumnId>& read_column_ids,
std::vector<rowid_t>& rowid_vector,
uint16_t* sel_rowid_idx,
- size_t select_size,
vectorized::MutableColumns* mutable_columns);
+ size_t select_size);
template <class Container>
Status _output_column_by_sel_idx(vectorized::Block* block, const
Container& column_ids,
diff --git a/be/src/olap/schema_change.cpp b/be/src/olap/schema_change.cpp
index 743393e555..783ec85272 100644
--- a/be/src/olap/schema_change.cpp
+++ b/be/src/olap/schema_change.cpp
@@ -785,22 +785,11 @@ Status RowBlockChanger::change_block(vectorized::Block*
ref_block,
return Status::OLAPInternalError(OLAP_ERR_NOT_INITED);
}
- // material-view or rollup task will fail now
- if (_desc_tbl.get_row_tuples().size() != ref_block->columns()) {
- return Status::NotSupported(
- "_desc_tbl.get_row_tuples().size() != ref_block->columns(),
maybe because rollup "
- "not supported now. ");
- }
-
- std::vector<bool> nullable_tuples;
- for (int i = 0; i < ref_block->columns(); i++) {
-
nullable_tuples.emplace_back(ref_block->get_by_position(i).column->is_nullable());
- }
-
ObjectPool pool;
RuntimeState* state = pool.add(new RuntimeState());
state->set_desc_tbl(&_desc_tbl);
- RowDescriptor row_desc = RowDescriptor::create_default(_desc_tbl,
nullable_tuples);
+ RowDescriptor row_desc =
+
RowDescriptor(_desc_tbl.get_tuple_descriptor(_desc_tbl.get_row_tuples()[0]),
false);
const int row_size = ref_block->rows();
const int column_size = new_block->columns();
@@ -811,10 +800,6 @@ Status RowBlockChanger::change_block(vectorized::Block*
ref_block,
for (int idx = 0; idx < column_size; idx++) {
int ref_idx = _schema_mapping[idx].ref_column;
- if (!_schema_mapping[idx].materialized_function.empty()) {
- return Status::NotSupported("Materialized function not supported
now. ");
- }
-
if (ref_idx < 0) {
// new column, write default value
auto value = _schema_mapping[idx].default_value;
@@ -1547,15 +1532,14 @@ Status
VSchemaChangeWithSorting::_inner_process(RowsetReaderSharedPtr rowset_rea
rowset_reader->next_block(ref_block.get());
while (ref_block->rows()) {
RETURN_IF_ERROR(_changer.change_block(ref_block.get(),
new_block.get()));
- if
(!_mem_tracker->check_limit(config::memory_limitation_per_thread_for_schema_change_bytes,
- new_block->allocated_bytes())) {
+ if (!_mem_tracker->check_limit(_memory_limitation,
new_block->allocated_bytes())) {
RETURN_IF_ERROR(create_rowset());
- if (!_mem_tracker->check_limit(
-
config::memory_limitation_per_thread_for_schema_change_bytes,
- new_block->allocated_bytes())) {
+ if (!_mem_tracker->check_limit(_memory_limitation,
new_block->allocated_bytes())) {
LOG(WARNING) << "Memory limitation is too small for Schema
Change."
- << "memory_limitation=" << _memory_limitation;
+ << " _memory_limitation=" << _memory_limitation
+ << ", new_block->allocated_bytes()=" <<
new_block->allocated_bytes()
+ << ", consumption=" <<
_mem_tracker->consumption();
return
Status::OLAPInternalError(OLAP_ERR_INPUT_PARAMETER_ERROR);
}
}
@@ -1649,9 +1633,8 @@ bool
SchemaChangeWithSorting::_external_sorting(vector<RowsetSharedPtr>& src_row
rs_readers.push_back(rs_reader);
}
// get cur schema if rowset schema exist, rowset schema must be newer than
tablet schema
- auto max_version_rowset = src_rowsets.back();
const TabletSchema* cur_tablet_schema =
- max_version_rowset->rowset_meta()->tablet_schema().get();
+ src_rowsets.back()->rowset_meta()->tablet_schema().get();
if (cur_tablet_schema == nullptr) {
cur_tablet_schema = new_tablet->tablet_schema().get();
}
@@ -1680,6 +1663,12 @@ Status
VSchemaChangeWithSorting::_external_sorting(vector<RowsetSharedPtr>& src_
rs_readers.push_back(rs_reader);
}
+ // get cur schema if rowset schema exist, rowset schema must be newer than
tablet schema
+ auto cur_tablet_schema =
src_rowsets.back()->rowset_meta()->tablet_schema();
+ if (cur_tablet_schema == nullptr) {
+ cur_tablet_schema = new_tablet->tablet_schema();
+ }
+
Merger::Statistics stats;
RETURN_IF_ERROR(Merger::vmerge_rowsets(new_tablet, READER_ALTER_TABLE,
new_tablet->tablet_schema().get(),
rs_readers,
@@ -1717,6 +1706,7 @@ Status SchemaChangeHandler::process_alter_tablet_v2(const
TAlterTabletReqV2& req
std::shared_mutex SchemaChangeHandler::_mutex;
std::unordered_set<int64_t> SchemaChangeHandler::_tablet_ids_in_converting;
+std::set<std::string> SchemaChangeHandler::_supported_functions = {"hll_hash",
"to_bitmap"};
// In the past schema change and rollup will create new tablet and will wait
for txns starting before the task to finished
// It will cost a lot of time to wait and the task is very difficult to
understand.
@@ -1848,7 +1838,7 @@ Status
SchemaChangeHandler::_do_process_alter_tablet_v2(const TAlterTabletReqV2&
LOG(WARNING) << "New tablet has a version " << pair.first
<< " crossing base tablet's max_version="
<< max_rowset->end_version();
- Status::OLAPInternalError(OLAP_ERR_VERSION_ALREADY_MERGED);
+ return
Status::OLAPInternalError(OLAP_ERR_VERSION_ALREADY_MERGED);
}
}
std::vector<RowsetSharedPtr> empty_vec;
@@ -1949,9 +1939,14 @@ Status
SchemaChangeHandler::_do_process_alter_tablet_v2(const TAlterTabletReqV2&
if (item.__isset.mv_expr) {
if (item.mv_expr.nodes[0].node_type ==
TExprNodeType::FUNCTION_CALL) {
mv_param.mv_expr =
item.mv_expr.nodes[0].fn.name.function_name;
+ if (!_supported_functions.count(mv_param.mv_expr)) {
+ return Status::NotSupported("Unknow materialized
view expr " +
+ mv_param.mv_expr);
+ }
} else if (item.mv_expr.nodes[0].node_type ==
TExprNodeType::CASE_EXPR) {
mv_param.mv_expr = "count_field";
}
+
mv_param.expr = std::make_shared<TExpr>(item.mv_expr);
}
sc_params.materialized_params_map.insert(
@@ -2152,6 +2147,7 @@ Status SchemaChangeHandler::_parse_request(
const TabletColumn& new_column =
new_tablet->tablet_schema()->column(i);
const string& column_name = new_column.name();
ColumnMapping* column_mapping =
rb_changer->get_mutable_column_mapping(i);
+ column_mapping->new_column = &new_column;
if (new_column.has_reference_column()) {
int32_t column_index =
base_tablet_schema->field_index(new_column.referenced_column());
diff --git a/be/src/olap/schema_change.h b/be/src/olap/schema_change.h
index 0ce3761d4f..79b5da2852 100644
--- a/be/src/olap/schema_change.h
+++ b/be/src/olap/schema_change.h
@@ -328,6 +328,7 @@ private:
static std::shared_mutex _mutex;
static std::unordered_set<int64_t> _tablet_ids_in_converting;
+ static std::set<std::string> _supported_functions;
};
using RowBlockDeleter = std::function<void(RowBlock*)>;
diff --git a/be/src/runtime/descriptors.h b/be/src/runtime/descriptors.h
index 85f5bea18a..74f59655af 100644
--- a/be/src/runtime/descriptors.h
+++ b/be/src/runtime/descriptors.h
@@ -392,11 +392,6 @@ public:
RowDescriptor(const DescriptorTbl& desc_tbl, const std::vector<TTupleId>&
row_tuples,
const std::vector<bool>& nullable_tuples);
- static RowDescriptor create_default(const DescriptorTbl& desc_tbl,
- const std::vector<bool>&
nullable_tuples) {
- return RowDescriptor(desc_tbl, desc_tbl.get_row_tuples(),
nullable_tuples);
- }
-
// standard copy c'tor, made explicit here
RowDescriptor(const RowDescriptor& desc)
: _tuple_desc_map(desc._tuple_desc_map),
diff --git a/be/src/runtime/primitive_type.h b/be/src/runtime/primitive_type.h
index 03362acd65..e6aba461fb 100644
--- a/be/src/runtime/primitive_type.h
+++ b/be/src/runtime/primitive_type.h
@@ -209,7 +209,6 @@ struct PrimitiveTypeTraits<TYPE_HLL> {
using ColumnType = vectorized::ColumnString;
};
-// only for adapt get_predicate_column_ptr
template <PrimitiveType type>
struct PredicatePrimitiveTypeTraits {
using PredicateFieldType = typename PrimitiveTypeTraits<type>::CppType;
diff --git a/be/src/vec/columns/column_complex.h
b/be/src/vec/columns/column_complex.h
index 35bfa45b52..fe732ec8a9 100644
--- a/be/src/vec/columns/column_complex.h
+++ b/be/src/vec/columns/column_complex.h
@@ -62,41 +62,30 @@ public:
data.push_back(*reinterpret_cast<const T*>(pos));
}
- void insert_many_binary_data(char* data_array, uint32_t* len_array,
- uint32_t* start_offset_array, size_t num)
override {
+ void insert_binary_data(const char* pos, size_t length) {
+ insert_default();
+ T* pvalue = &get_element(size() - 1);
+ if (!length) {
+ *pvalue = *reinterpret_cast<const T*>(pos);
+ return;
+ }
+
if constexpr (std::is_same_v<T, BitmapValue>) {
- for (size_t i = 0; i < num; i++) {
- uint32_t len = len_array[i];
- uint32_t start_offset = start_offset_array[i];
- insert_default();
- BitmapValue* pvalue = &get_element(size() - 1);
- if (len != 0) {
- BitmapValue value;
- value.deserialize(data_array + start_offset);
- *pvalue = std::move(value);
- } else {
- *pvalue =
std::move(*reinterpret_cast<BitmapValue*>(data_array + start_offset));
- }
- }
+ pvalue->deserialize(pos);
} else if constexpr (std::is_same_v<T, HyperLogLog>) {
- for (size_t i = 0; i < num; i++) {
- uint32_t len = len_array[i];
- uint32_t start_offset = start_offset_array[i];
- insert_default();
- HyperLogLog* pvalue = &get_element(size() - 1);
- if (len != 0) {
- HyperLogLog value;
- value.deserialize(Slice(data_array + start_offset, len));
- *pvalue = std::move(value);
- } else {
- *pvalue =
std::move(*reinterpret_cast<HyperLogLog*>(data_array + start_offset));
- }
- }
+ pvalue->deserialize(Slice(pos, length));
} else {
LOG(FATAL) << "Unexpected type in column complex";
}
}
+ void insert_many_binary_data(char* data_array, uint32_t* len_array,
+ uint32_t* start_offset_array, size_t num)
override {
+ for (size_t i = 0; i < num; i++) {
+ insert_binary_data(data_array + start_offset_array[i],
len_array[i]);
+ }
+ }
+
void insert_default() override { data.push_back(T()); }
void insert_many_defaults(size_t length) override {
@@ -299,10 +288,7 @@ template <typename T>
ColumnPtr ColumnComplexType<T>::permute(const IColumn::Permutation& perm,
size_t limit) const {
size_t size = data.size();
- if (limit == 0)
- limit = size;
- else
- limit = std::min(size, limit);
+ limit = limit ? std::min(size, limit) : size;
if (perm.size() < limit) {
LOG(FATAL) << "Size of permutation is less than required.";
diff --git a/be/src/vec/exec/volap_scanner.cpp
b/be/src/vec/exec/volap_scanner.cpp
index 02fae4de8d..194da3ca7d 100644
--- a/be/src/vec/exec/volap_scanner.cpp
+++ b/be/src/vec/exec/volap_scanner.cpp
@@ -252,9 +252,13 @@ Status VOlapScanner::_init_return_columns(bool
need_seq_col) {
if (!slot->is_materialized()) {
continue;
}
- int32_t index = slot->col_unique_id() >= 0
- ?
_tablet_schema.field_index(slot->col_unique_id())
- : _tablet_schema.field_index(slot->col_name());
+
+ int32_t index = _tablet_schema.field_index(slot->col_unique_id());
+ if (index < 0) {
+ // rollup/materialized view should use col_name to find index
+ index = _tablet_schema.field_index(slot->col_name());
+ }
+
if (index < 0) {
std::stringstream ss;
ss << "field name is invalid. field=" << slot->col_name();
@@ -262,8 +266,9 @@ Status VOlapScanner::_init_return_columns(bool
need_seq_col) {
return Status::InternalError(ss.str());
}
_return_columns.push_back(index);
- if (slot->is_nullable() && !_tablet_schema.column(index).is_nullable())
+ if (slot->is_nullable() &&
!_tablet_schema.column(index).is_nullable()) {
_tablet_columns_convert_to_null_set.emplace(index);
+ }
}
// expand the sequence column
diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
index 3412a999bb..a1e7d0b149 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
@@ -138,10 +138,10 @@ public class RollupJobV2 extends AlterJobV2 implements
GsonPostProcessable {
super(JobType.ROLLUP);
}
- public RollupJobV2(long jobId, long dbId, long tableId, String tableName,
long timeoutMs,
- long baseIndexId, long rollupIndexId, String baseIndexName, String
rollupIndexName,
- List<Column> rollupSchema, int baseSchemaHash, int
rollupSchemaHash, KeysType rollupKeysType,
- short rollupShortKeyColumnCount, OriginStatement origStmt) {
+ public RollupJobV2(long jobId, long dbId, long tableId, String tableName,
long timeoutMs, long baseIndexId,
+ long rollupIndexId, String baseIndexName, String rollupIndexName,
List<Column> rollupSchema,
+ int baseSchemaHash, int rollupSchemaHash, KeysType rollupKeysType,
short rollupShortKeyColumnCount,
+ OriginStatement origStmt) {
super(jobId, JobType.ROLLUP, dbId, tableId, tableName, timeoutMs);
this.baseIndexId = baseIndexId;
@@ -150,6 +150,7 @@ public class RollupJobV2 extends AlterJobV2 implements
GsonPostProcessable {
this.rollupIndexName = rollupIndexName;
this.rollupSchema = rollupSchema;
+
this.baseSchemaHash = baseSchemaHash;
this.rollupSchemaHash = rollupSchemaHash;
this.rollupKeysType = rollupKeysType;
@@ -376,8 +377,8 @@ public class RollupJobV2 extends AlterJobV2 implements
GsonPostProcessable {
List<Column> fullSchema = tbl.getBaseSchema(true);
DescriptorTable descTable = new DescriptorTable();
+ TupleDescriptor destTupleDesc =
descTable.createTupleDescriptor();
for (Column column : fullSchema) {
- TupleDescriptor destTupleDesc =
descTable.createTupleDescriptor();
SlotDescriptor destSlotDesc =
descTable.addSlotDescriptor(destTupleDesc);
destSlotDesc.setIsMaterialized(true);
destSlotDesc.setColumn(column);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
index 062b3b5e27..d31769dbec 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
@@ -416,8 +416,8 @@ public class SchemaChangeJobV2 extends AlterJobV2 {
List<Column> fullSchema = tbl.getBaseSchema(true);
DescriptorTable descTable = new DescriptorTable();
+ TupleDescriptor destTupleDesc =
descTable.createTupleDescriptor();
for (Column column : fullSchema) {
- TupleDescriptor destTupleDesc =
descTable.createTupleDescriptor();
SlotDescriptor destSlotDesc =
descTable.addSlotDescriptor(destTupleDesc);
destSlotDesc.setIsMaterialized(true);
destSlotDesc.setColumn(column);
@@ -648,7 +648,7 @@ public class SchemaChangeJobV2 extends AlterJobV2 {
tbl.setStorageFormat(storageFormat);
}
- //update max column unique id
+ // update max column unique id
int maxColUniqueId = tbl.getMaxColUniqueId();
for (Column column : tbl.getFullSchema()) {
if (column.getUniqueId() > maxColUniqueId) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
index 61e33892a4..5a44022748 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
@@ -139,7 +139,7 @@ public class CreateMaterializedViewStmt extends DdlStmt {
if (selectStmt.getAggInfo() != null) {
mvKeysType = KeysType.AGG_KEYS;
}
- analyzeSelectClause();
+ analyzeSelectClause(analyzer);
analyzeFromClause();
if (selectStmt.getWhereClause() != null) {
throw new AnalysisException("The where clause is not supported in
add materialized view clause, expr:"
@@ -156,7 +156,7 @@ public class CreateMaterializedViewStmt extends DdlStmt {
}
}
- public void analyzeSelectClause() throws AnalysisException {
+ public void analyzeSelectClause(Analyzer analyzer) throws
AnalysisException {
SelectList selectList = selectStmt.getSelectList();
if (selectList.getItems().isEmpty()) {
throw new AnalysisException("The materialized view must contain at
least one column");
@@ -222,7 +222,7 @@ public class CreateMaterializedViewStmt extends DdlStmt {
}
meetAggregate = true;
// build mv column item
- mvColumnItemList.add(buildMVColumnItem(functionCallExpr));
+ mvColumnItemList.add(buildMVColumnItem(analyzer,
functionCallExpr));
// TODO(ml): support REPLACE, REPLACE_IF_NOT_NULL,
bitmap_union, hll_union only for aggregate table
// TODO(ml): support different type of column, int ->
bigint(sum)
}
@@ -347,7 +347,8 @@ public class CreateMaterializedViewStmt extends DdlStmt {
}
}
- private MVColumnItem buildMVColumnItem(FunctionCallExpr functionCallExpr)
throws AnalysisException {
+ private MVColumnItem buildMVColumnItem(Analyzer analyzer, FunctionCallExpr
functionCallExpr)
+ throws AnalysisException {
String functionName = functionCallExpr.getFnName().getFunction();
List<SlotRef> slots = new ArrayList<>();
functionCallExpr.collect(SlotRef.class, slots);
@@ -399,6 +400,9 @@ public class CreateMaterializedViewStmt extends DdlStmt {
mvColumnName = baseColumnName;
} else {
mvColumnName = mvColumnBuilder(functionName,
baseColumnName);
+ if (!functionChild0.getType().isStringType()) {
+ functionChild0.uncheckedCastChild(Type.VARCHAR, 0);
+ }
defineExpr = functionChild0;
}
mvAggregateType =
AggregateType.valueOf(functionName.toUpperCase());
@@ -410,6 +414,7 @@ public class CreateMaterializedViewStmt extends DdlStmt {
defineExpr = new CaseExpr(null, Lists.newArrayList(new
CaseWhenClause(
new IsNullPredicate(baseColumnRef, false),
new IntLiteral(0, Type.BIGINT))), new IntLiteral(1,
Type.BIGINT));
+ defineExpr.analyze(analyzer);
type = Type.BIGINT;
break;
default:
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/CountFieldToSum.java
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/CountFieldToSum.java
index a636c39f94..ee57c6317a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/CountFieldToSum.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/CountFieldToSum.java
@@ -33,8 +33,6 @@ import org.apache.doris.rewrite.ExprRewriter;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
-import java.util.List;
-
/**
* Rewrite count(k1) to sum(mv_count_k1) when MV Column exists.
* For example:
@@ -92,9 +90,7 @@ public class CountFieldToSum implements ExprRewriteRule {
// exception to Unknown column, because we can't find an alias which
named as origin table name that has
// required column.
SlotRef mvSlotRef = new SlotRef(null, mvColumn.getName());
- List<Expr> newFnParams = Lists.newArrayList();
- newFnParams.add(mvSlotRef);
- FunctionCallExpr result = new FunctionCallExpr("sum", newFnParams);
+ FunctionCallExpr result = new FunctionCallExpr("sum",
Lists.newArrayList(mvSlotRef));
result.analyzeNoThrow(analyzer);
return result;
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/HLLHashToSlotRefRule.java
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/HLLHashToSlotRefRule.java
index 22a311d0f8..cf13f52cb4 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/HLLHashToSlotRefRule.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/HLLHashToSlotRefRule.java
@@ -106,8 +106,7 @@ public class HLLHashToSlotRefRule implements
ExprRewriteRule {
TableName tableName = queryColumnSlotRef.getTableName();
Preconditions.checkNotNull(tableName);
SlotRef mvSlotRef = new SlotRef(tableName, mvColumn.getName());
- List<Expr> newFnParams = Lists.newArrayList();
- newFnParams.add(mvSlotRef);
+ List<Expr> newFnParams = Lists.newArrayList(mvSlotRef);
FunctionCallExpr result = new FunctionCallExpr(fnName, newFnParams);
result.analyzeNoThrow(analyzer);
return result;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/alter/RollupJobV2Test.java
b/fe/fe-core/src/test/java/org/apache/doris/alter/RollupJobV2Test.java
index 72b06e2efe..1637829cca 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/alter/RollupJobV2Test.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/alter/RollupJobV2Test.java
@@ -314,8 +314,8 @@ public class RollupJobV2Test {
@Test
- public void testSerializeOfRollupJob(@Mocked CreateMaterializedViewStmt
stmt) throws IOException,
- AnalysisException {
+ public void testSerializeOfRollupJob(@Mocked CreateMaterializedViewStmt
stmt)
+ throws IOException {
// prepare file
File file = new File(fileName);
file.createNewFile();
@@ -326,6 +326,7 @@ public class RollupJobV2Test {
String mvColumnName =
CreateMaterializedViewStmt.MATERIALIZED_VIEW_NAME_PREFIX + "to_bitmap_" + "c1";
Column column = new Column(mvColumnName, Type.BITMAP, false,
AggregateType.BITMAP_UNION, false, "1", "");
columns.add(column);
+
RollupJobV2 rollupJobV2 = new RollupJobV2(1, 1, 1, "test", 1, 1, 1,
"test", "rollup", columns, 1, 1,
KeysType.AGG_KEYS, keysCount,
new OriginStatement("create materialized view rollup as select
bitmap_union(to_bitmap(c1)) from test",
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateMaterializedViewStmtTest.java
b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateMaterializedViewStmtTest.java
index ce4a9c029d..0ae3b543b0 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateMaterializedViewStmtTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateMaterializedViewStmtTest.java
@@ -1167,7 +1167,8 @@ public class CreateMaterializedViewStmtTest {
result = Type.LARGEINT;
}
};
- MVColumnItem mvColumnItem =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
functionCallExpr);
+ MVColumnItem mvColumnItem =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
analyzer,
+ functionCallExpr);
Assert.assertEquals(Type.LARGEINT, mvColumnItem.getType());
SlotRef slotRef2 = new SlotRef(new TableName(internalCtl, "db",
"table"), "a");
@@ -1183,7 +1184,8 @@ public class CreateMaterializedViewStmtTest {
result = Type.BIGINT;
}
};
- MVColumnItem mvColumnItem2 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
functionCallExpr2);
+ MVColumnItem mvColumnItem2 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
analyzer,
+ functionCallExpr2);
Assert.assertEquals(Type.BIGINT, mvColumnItem2.getType());
SlotRef slotRef3 = new SlotRef(new TableName(internalCtl, "db",
"table"), "a");
@@ -1199,7 +1201,8 @@ public class CreateMaterializedViewStmtTest {
result = Type.VARCHAR;
}
};
- MVColumnItem mvColumnItem3 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
functionCallExpr3);
+ MVColumnItem mvColumnItem3 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
analyzer,
+ functionCallExpr3);
Assert.assertEquals(Type.VARCHAR, mvColumnItem3.getType());
SlotRef slotRef4 = new SlotRef(new TableName(internalCtl, "db",
"table"), "a");
@@ -1215,7 +1218,8 @@ public class CreateMaterializedViewStmtTest {
result = Type.DOUBLE;
}
};
- MVColumnItem mvColumnItem4 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
functionCallExpr4);
+ MVColumnItem mvColumnItem4 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
analyzer,
+ functionCallExpr4);
Assert.assertEquals(Type.DOUBLE, mvColumnItem4.getType());
}
@@ -1242,7 +1246,8 @@ public class CreateMaterializedViewStmtTest {
result = ScalarType.createVarchar(50);
}
};
- MVColumnItem mvColumnItem =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
functionCallExpr);
+ MVColumnItem mvColumnItem =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
analyzer,
+ functionCallExpr);
Assert.assertEquals(50, mvColumnItem.getType().getLength());
SlotRef slotRef2 = new SlotRef(new TableName(internalCtl, "db",
"table"), "a");
@@ -1258,7 +1263,8 @@ public class CreateMaterializedViewStmtTest {
result = ScalarType.createDecimalType(10, 1);
}
};
- MVColumnItem mvColumnItem2 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
functionCallExpr2);
+ MVColumnItem mvColumnItem2 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
analyzer,
+ functionCallExpr2);
Assert.assertEquals(new Integer(10),
mvColumnItem2.getType().getPrecision());
Assert.assertEquals(1, ((ScalarType)
mvColumnItem2.getType()).getScalarScale());
@@ -1275,7 +1281,8 @@ public class CreateMaterializedViewStmtTest {
result = ScalarType.createChar(5);
}
};
- MVColumnItem mvColumnItem3 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
functionCallExpr3);
+ MVColumnItem mvColumnItem3 =
Deencapsulation.invoke(createMaterializedViewStmt, "buildMVColumnItem",
analyzer,
+ functionCallExpr3);
Assert.assertEquals(5, mvColumnItem3.getType().getLength());
}
}
diff --git a/regression-test/data/rollup/test_materialized_view.out
b/regression-test/data/rollup/test_materialized_view.out
index 444968df72..6c679aa19c 100644
Binary files a/regression-test/data/rollup/test_materialized_view.out and
b/regression-test/data/rollup/test_materialized_view.out differ
diff --git a/regression-test/suites/rollup/test_materialized_view.groovy
b/regression-test/suites/rollup/test_materialized_view.groovy
index 07e040bae3..231ca4de23 100644
--- a/regression-test/suites/rollup/test_materialized_view.groovy
+++ b/regression-test/suites/rollup/test_materialized_view.groovy
@@ -105,10 +105,16 @@ suite("test_materialized_view", "rollup") {
}
}
sql "SELECT store_id, count(sale_amt) FROM ${tbName1} GROUP BY store_id;"
+ qt_sql "DESC ${tbName1} ALL;"
+
+ qt_sql "SELECT store_id, count(sale_amt) FROM ${tbName1} GROUP BY
store_id;"
+
+ explain {
+ sql("SELECT store_id, count(sale_amt) FROM ${tbName1} GROUP BY
store_id;")
+ contains "(amt_count)"
+ }
sql "DROP TABLE ${tbName1} FORCE;"
sql "DROP TABLE ${tbName2} FORCE;"
}
-
-
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]