Skip to content

Commit

Permalink
fix(tianmu): fix crashed when the subquery includes a SORT clause (#906
Browse files Browse the repository at this point in the history
)

    the reason is The subquery generates a temp table,
    but the count(*) column of the subquery is not a physical column,
    so the interface is incompatible.
    so if the virtual column does not point to the physical column,
    the check is not performed
  • Loading branch information
adofsauron authored and mergify[bot] committed Nov 16, 2022
1 parent 08ac72f commit 1f86173
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 4 deletions.
118 changes: 118 additions & 0 deletions mysql-test/suite/tianmu/r/issue906.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
USE test;
DROP TABLE IF EXISTS shop;
CREATE TABLE shop (
article INT DEFAULT '0000' NOT NULL,
dealer CHAR(20) DEFAULT '' NOT NULL,
price DECIMAL(16,2) DEFAULT '0.00' NOT NULL
) ENGINE=TIANMU;
INSERT INTO shop
VALUES(1, 'A', 3.45),(1, 'B', 3.99),
(2, 'A', 10.99),(3, 'B', 1.45),
(3, 'C', 1.69),(3, 'D', 1.25),
(4, 'D', 19.95);
SELECT
*
FROM
shop
WHERE
article IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);
article dealer price
1 A 3.45
1 B 3.99
2 A 10.99
3 B 1.45
3 C 1.69
3 D 1.25
SELECT
*
FROM
shop
WHERE
article NOT IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);
article dealer price
4 D 19.95
SELECT
*
FROM
shop
WHERE
article IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
)
UNION
SELECT
*
FROM
shop
WHERE
article NOT IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);
article dealer price
1 A 3.45
1 B 3.99
2 A 10.99
3 B 1.45
3 C 1.69
3 D 1.25
4 D 19.95
SELECT
*
FROM
shop
WHERE
article IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
)
UNION ALL
SELECT
*
FROM
shop
WHERE
article NOT IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);
article dealer price
1 A 3.45
1 B 3.99
2 A 10.99
3 B 1.45
3 C 1.69
3 D 1.25
4 D 19.95
DROP TABLE shop;
118 changes: 118 additions & 0 deletions mysql-test/suite/tianmu/t/issue906.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
--source include/have_tianmu.inc

USE test;

--disable_warnings

DROP TABLE IF EXISTS shop;

CREATE TABLE shop (
article INT DEFAULT '0000' NOT NULL,
dealer CHAR(20) DEFAULT '' NOT NULL,
price DECIMAL(16,2) DEFAULT '0.00' NOT NULL
) ENGINE=TIANMU;

INSERT INTO shop
VALUES(1, 'A', 3.45),(1, 'B', 3.99),
(2, 'A', 10.99),(3, 'B', 1.45),
(3, 'C', 1.69),(3, 'D', 1.25),
(4, 'D', 19.95);

## subquery

### EXPR IN subquery

SELECT
*
FROM
shop
WHERE
article IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);

### EXPR NOT IN subquery

SELECT
*
FROM
shop
WHERE
article NOT IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);

## union

SELECT
*
FROM
shop
WHERE
article IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
)
UNION
SELECT
*
FROM
shop
WHERE
article NOT IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);

## union all

SELECT
*
FROM
shop
WHERE
article IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
)
UNION ALL
SELECT
*
FROM
shop
WHERE
article NOT IN (
SELECT
COUNT(*)
FROM
shop
GROUP BY
article
);

## clear test table of this issue

DROP TABLE shop;

3 changes: 2 additions & 1 deletion storage/tianmu/core/temp_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ class TempTable : public JustATable {
int operator==(const Attr &);
~Attr();

bool ShouldOutput() const { return (mode == common::ColOperation::LISTING) && term.vc && alias; }
bool IsListField() const { return (mode == common::ColOperation::LISTING) && term.vc; };
bool ShouldOutput() const { return alias && IsListField(); }
bool NeedFill() const {
return ((mode == common::ColOperation::LISTING) && term.vc && alias) ||
!term.vc->IsConst(); // constant value, the buffer is already
Expand Down
9 changes: 6 additions & 3 deletions storage/tianmu/vc/subselect_column.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,12 @@ void SubSelectColumn::EvaluatePackImpl([[maybe_unused]] core::MIUpdatingIterator
common::Tribool SubSelectColumn::ContainsImpl(core::MIIterator const &mit, types::RCDataType const &v) {
// If the sub-select is something like 'select null from xxx' then there
// is no need to execute the sub-select, just return common::TRIBOOL_UNKNOWN.
VirtualColumn *vc = tmp_tab_subq_ptr_->GetAttrP(col_idx_)->term.vc;
if (vc->IsFullConst() && vc->IsNull(core::MIIterator(nullptr, multi_index_->ValueOfPower())))
return common::TRIBOOL_UNKNOWN;
Tianmu::core::TempTable::Attr *attr = tmp_tab_subq_ptr_->GetAttrP(col_idx_);
if (attr && attr->IsListField()) {
VirtualColumn *vc = attr->term.vc;
if (vc->IsFullConst() && vc->IsNull(core::MIIterator(nullptr, multi_index_->ValueOfPower())))
return common::TRIBOOL_UNKNOWN;
}

PrepareSubqResult(mit, false);
common::Tribool res = false;
Expand Down

0 comments on commit 1f86173

Please sign in to comment.