[Fix](planner) Set inline view output as non constant after analyze (#21212)

Problem:
Select list should be non const when from list have tables or multiple tuples. Or upper query will regard wrong of isConstant
And make wrong constant folding
For example: when using nullif funtion with subquery which result in two alternative constant, planner would treat it as constant expr. So analyzer would report an error of order by clause can not be constant

Solusion:
Change inline view output to non constant, because (select 1 a from table) as view , a in output is no constant when we see
view.a outside
This commit is contained in:
LiBinfeng
2023-07-06 15:37:43 +08:00
committed by GitHub
parent 068fe44493
commit 0c3acfdb7c
5 changed files with 54 additions and 14 deletions

View File

@ -466,6 +466,13 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
isAnalyzed = true;
}
/**
* Set the expr isConstant parameter, when select list return it can not be constant
*/
public void setIsConstant(boolean isConstant) {
this.isConstant = isConstant;
}
protected void computeNumDistinctValues() {
if (isConstant()) {
numDistinctValues = 1;

View File

@ -524,6 +524,10 @@ public class SelectStmt extends QueryStmt {
// Analyze the resultExpr before generating a label to ensure enforcement
// of expr child and depth limits (toColumn() label may call toSql()).
item.getExpr().analyze(analyzer);
// select list output must not be constant because it is not scalar expression.
if (!fromClause.isEmpty()) {
item.getExpr().setIsConstant(false);
}
if (!(item.getExpr() instanceof CaseExpr)
&& item.getExpr().contains(Predicates.instanceOf(Subquery.class))) {
throw new AnalysisException("Subquery is not supported in the select list.");

View File

@ -211,7 +211,7 @@ public class QueryStmtTest {
Assert.assertEquals(5, exprsMap.size());
constMap.clear();
constMap = getConstantExprMap(exprsMap, analyzer);
Assert.assertEquals(2, constMap.size());
Assert.assertEquals(1, constMap.size());
// expr in subquery associate with column in grandparent level
sql = "WITH aa AS\n"
@ -252,20 +252,9 @@ public class QueryStmtTest {
@Test
public void testPutBackExprs() throws Exception {
ConnectContext ctx = UtFrameUtils.createDefaultCtx();
String sql = "SELECT username, @@license, @@time_zone\n"
+ "FROM db1.table1\n"
+ "WHERE siteid in\n"
+ " (SELECT abs(5+abs(0))+1)\n"
String sql = "SELECT @@license, @@time_zone\n"
+ "UNION\n"
+ "SELECT CASE\n"
+ " WHEN\n"
+ " (SELECT count(*)+abs(8)\n"
+ " FROM db1.table1\n"
+ " WHERE username='helen')>1 THEN 888\n"
+ " ELSE 999\n"
+ " END AS ccc, @@language, @@storage_engine\n"
+ "FROM\n"
+ " (SELECT curdate()) a;";
+ "SELECT @@language, @@storage_engine;";
StatementBase stmt = UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
SessionVariable sessionVariable = new SessionVariable();
TQueryOptions queryOptions = sessionVariable.getQueryOptionVariables();

View File

@ -570,3 +570,7 @@ null 12 1 true
-- !if_nullif28 --
2020-02-09
-- !if_nullif29 --
1 1
2 2

View File

@ -151,4 +151,40 @@ suite("test_nullif") {
qt_if_nullif27 """select ifnull(2+3, 2), ifnull((3*1 > 1 || 1>0), 2), ifnull((3*1 > 1 or 1>0), 2),
ifnull(upper("null"), concat("NUL", "LL"))"""
qt_if_nullif28 """select ifnull(date(substring("2020-02-09", 1, 1024)), null)"""
def tableName2 = "testsort"
sql """ DROP TABLE IF EXISTS ${tableName2}; """
sql """
CREATE TABLE IF NOT EXISTS ${tableName2} (
c_int int NULL COMMENT "",
c_pv bitmap BITMAP_UNION NULL COMMENT ""
)
AGGREGATE KEY(c_int)
DISTRIBUTED BY HASH(c_int) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
"""
sql """ INSERT INTO ${tableName2} VALUES(1, to_bitmap(1)), (2, to_bitmap(2));"""
qt_if_nullif29 """
select
sortNum,
BITMAP_UNION_COUNT (c.pv) over (ORDER BY sortNum ) totalNum
from(
select
ifnull(a.sortNum, b.sortNum) sortNum,
BITMAP_UNION (ifnull(a.c_pv, b.c_pv)) pv
from
(select 1 sortNum, c_pv from ${tableName2} t where t.c_int = 1) a
full join
(select 2 sortNum, c_pv from ${tableName2} t where t.c_int = 2) b
on a.sortNum = b.sortNum
GROUP BY
sortNum
ORDER BY
sortNum
) c
;"""
}