Skip to content

Commit c91ca2a

Browse files
[cherry-pick 7386] fix lm query fail when there are generated columns (#7387)
close #7383, ref #7385
1 parent 4ee1412 commit c91ca2a

File tree

2 files changed

+76
-7
lines changed

2 files changed

+76
-7
lines changed

dbms/src/Storages/StorageDeltaMerge.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <Common/formatReadable.h>
2121
#include <Common/typeid_cast.h>
2222
#include <Core/Defines.h>
23+
#include <DataStreams/GeneratedColumnPlaceholderBlockInputStream.h>
2324
#include <DataStreams/IBlockOutputStream.h>
2425
#include <DataStreams/OneBlockInputStream.h>
2526
#include <DataTypes/isSupportedDataTypeCast.h>
@@ -748,11 +749,30 @@ DM::PushDownFilterPtr StorageDeltaMerge::buildPushDownFilter(const RSOperatorPtr
748749
{
749750
if (!pushed_down_filters.empty())
750751
{
751-
NamesAndTypes columns_to_read_name_and_type;
752-
for (const auto & col : columns_to_read)
752+
// Note: table_scan_column_info is a light copy of column_info from TiDB, so some attributes are missing.
753+
std::unordered_map<ColumnID, ColumnDefine> columns_to_read_map;
754+
for (const auto & column : columns_to_read)
755+
columns_to_read_map.emplace(column.id, column);
756+
757+
// The source_columns_of_analyzer should be the same as the size of table_scan_column_info
758+
// The columns_to_read is a subset of table_scan_column_info, when there are generated columns.
759+
NamesAndTypes source_columns_of_analyzer;
760+
source_columns_of_analyzer.reserve(table_scan_column_info.size());
761+
for (size_t i = 0; i < table_scan_column_info.size(); ++i)
753762
{
754-
columns_to_read_name_and_type.emplace_back(col.name, col.type);
763+
auto const & ci = table_scan_column_info[i];
764+
const auto cid = ci.id;
765+
if (ci.hasGeneratedColumnFlag())
766+
{
767+
const auto & col_name = GeneratedColumnPlaceholderBlockInputStream::getColumnName(i);
768+
const auto & data_type = getDataTypeByColumnInfoForComputingLayer(ci);
769+
source_columns_of_analyzer.emplace_back(col_name, data_type);
770+
continue;
771+
}
772+
RUNTIME_CHECK_MSG(columns_to_read_map.contains(cid), "ColumnID({}) not found in columns_to_read_map", cid);
773+
source_columns_of_analyzer.emplace_back(columns_to_read_map.at(cid).name, columns_to_read_map.at(cid).type);
755774
}
775+
// Get the columns of the filter, is a subset of columns_to_read
756776
std::unordered_set<ColumnID> filter_col_id_set;
757777
for (const auto & expr : pushed_down_filters)
758778
{
@@ -770,14 +790,13 @@ DM::PushDownFilterPtr StorageDeltaMerge::buildPushDownFilter(const RSOperatorPtr
770790
filter_columns.push_back(*iter);
771791
}
772792

793+
// need_cast_column should be the same size as table_scan_column_info and source_columns_of_analyzer
773794
std::vector<ExtraCastAfterTSMode> need_cast_column;
774-
need_cast_column.reserve(columns_to_read.size());
795+
need_cast_column.reserve(table_scan_column_info.size());
775796
for (const auto & col : table_scan_column_info)
776797
{
777798
if (!filter_col_id_set.contains(col.id))
778-
{
779799
need_cast_column.push_back(ExtraCastAfterTSMode::None);
780-
}
781800
else
782801
{
783802
if (col.id != -1 && col.tp == TiDB::TypeTimestamp)
@@ -789,7 +808,7 @@ DM::PushDownFilterPtr StorageDeltaMerge::buildPushDownFilter(const RSOperatorPtr
789808
}
790809
}
791810

792-
std::unique_ptr<DAGExpressionAnalyzer> analyzer = std::make_unique<DAGExpressionAnalyzer>(columns_to_read_name_and_type, context);
811+
std::unique_ptr<DAGExpressionAnalyzer> analyzer = std::make_unique<DAGExpressionAnalyzer>(source_columns_of_analyzer, context);
793812
ExpressionActionsChain chain;
794813
auto & step = analyzer->initAndGetLastStep(chain);
795814
auto & actions = step.actions;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright 2022 PingCAP, Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
mysql> CREATE TABLE test.`IDT_26539` (`COL102` float DEFAULT NULL, `COL103` float DEFAULT NULL, `COL1` float GENERATED ALWAYS AS ((`COL102` DIV 10)) VIRTUAL, `COL2` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL, `COL4` datetime DEFAULT NULL, `COL3` bigint DEFAULT NULL, `COL5` float DEFAULT NULL, KEY `UK_COL1` (`COL1`) /*!80000 INVISIBLE */) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
17+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) values (NULL, NULL, NULL, NULL, NULL, NULL);
18+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
19+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
20+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
21+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
22+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
23+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
24+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
25+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
26+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
27+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
28+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
29+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
30+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
31+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) select COL102, COL103, COL2, COL4, COL3, COL5 from test.IDT_26539;
32+
mysql> insert into test.IDT_26539 (COL102, COL103, COL2, COL4, COL3, COL5) values (NULL, NULL, 'r2Ic', NULL, NULL, NULL);
33+
mysql> alter table test.IDT_26539 set tiflash replica 1;
34+
func> wait_table test IDT_26539
35+
36+
mysql> set tidb_isolation_read_engines='tiflash'; select * from test.IDT_26539 where col2 = 'r2Ic';
37+
+--------+--------+------+------+------+------+------+
38+
| COL102 | COL103 | COL1 | COL2 | COL4 | COL3 | COL5 |
39+
+--------+--------+------+------+------+------+------+
40+
| NULL | NULL | NULL | r2Ic | NULL | NULL | NULL |
41+
+--------+--------+------+------+------+------+------+
42+
43+
mysql> set tidb_isolation_read_engines='tiflash'; select * from test.IDT_26539 where col1 = NULL or col2 = 'r2Ic';
44+
+--------+--------+------+------+------+------+------+
45+
| COL102 | COL103 | COL1 | COL2 | COL4 | COL3 | COL5 |
46+
+--------+--------+------+------+------+------+------+
47+
| NULL | NULL | NULL | r2Ic | NULL | NULL | NULL |
48+
+--------+--------+------+------+------+------+------+
49+
50+
mysql> set tidb_isolation_read_engines='tiflash'; select * from test.IDT_26539 where col2 in ('eC', 'rbsowIO0qt');

0 commit comments

Comments
 (0)