[Bug] When using view, make toSql method generates the final sql (#6736)
1. Fix the problem that the WITH statement cannot be printed when `UNION` is included in SQL 2. In the `toSql` method, convert the normal VIEW into the final statement 3. Replace `selectStmt.originSql` with `selectStmt.toSql`
This commit is contained in:
@ -424,14 +424,23 @@ public class InlineViewRef extends TableRef {
|
||||
String aliasSql = null;
|
||||
String alias = getExplicitAlias();
|
||||
if (alias != null) aliasSql = ToSqlUtils.getIdentSql(alias);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (view != null) {
|
||||
// TODO(zc):
|
||||
// return view_.toSql() + (aliasSql == null ? "" : " " + aliasSql);
|
||||
return name.toSql() + (aliasSql == null ? "" : " " + aliasSql);
|
||||
// When it is a local view, it does not need to be expanded into a statement,
|
||||
// because toSql function already contains `with` statement
|
||||
if (view.isLocalView()) {
|
||||
return name.toSql() + (aliasSql == null ? "" : " " + aliasSql);
|
||||
}
|
||||
|
||||
sb.append("(")
|
||||
.append(view.getInlineViewDef())
|
||||
.append(")")
|
||||
.append(aliasSql == null ? "" : " " + aliasSql);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder()
|
||||
.append("(")
|
||||
sb.append("(")
|
||||
.append(queryStmt.toSql())
|
||||
.append(") ")
|
||||
.append(aliasSql);
|
||||
|
||||
@ -598,6 +598,10 @@ public class SetOperationStmt extends QueryStmt {
|
||||
return toSqlString;
|
||||
}
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
if (withClause_ != null) {
|
||||
strBuilder.append(withClause_.toSql());
|
||||
strBuilder.append(" ");
|
||||
}
|
||||
Preconditions.checkState(operands.size() > 0);
|
||||
strBuilder.append(operands.get(0).getQueryStmt().toSql());
|
||||
for (int i = 1; i < operands.size() - 1; ++i) {
|
||||
|
||||
@ -41,7 +41,7 @@ public class SqlCache extends Cache {
|
||||
|
||||
public InternalService.PFetchCacheResult getCacheData(Status status) {
|
||||
InternalService.PFetchCacheRequest request = InternalService.PFetchCacheRequest.newBuilder()
|
||||
.setSqlKey(CacheProxy.getMd5(selectStmt.getOrigStmt().originStmt))
|
||||
.setSqlKey(CacheProxy.getMd5(selectStmt.toSql()))
|
||||
.addParams(InternalService.PCacheParam.newBuilder()
|
||||
.setPartitionKey(latestTable.latestPartitionId)
|
||||
.setLastVersion(latestTable.latestVersion)
|
||||
@ -74,8 +74,8 @@ public class SqlCache extends Cache {
|
||||
}
|
||||
|
||||
InternalService.PUpdateCacheRequest updateRequest =
|
||||
rowBatchBuilder.buildSqlUpdateRequest(selectStmt.getOrigStmt().originStmt,
|
||||
latestTable.latestPartitionId, latestTable.latestVersion, latestTable.latestTime);
|
||||
rowBatchBuilder.buildSqlUpdateRequest(selectStmt.toSql(), latestTable.latestPartitionId,
|
||||
latestTable.latestVersion, latestTable.latestTime);
|
||||
if (updateRequest.getValuesCount() > 0) {
|
||||
CacheBeProxy proxy = new CacheBeProxy();
|
||||
Status status = new Status();
|
||||
|
||||
@ -715,4 +715,88 @@ public class SelectStmtTest {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithUnionToSql() throws Exception {
|
||||
ConnectContext ctx = UtFrameUtils.createDefaultCtx();
|
||||
String sql1 =
|
||||
"select \n" +
|
||||
" t.k1 \n" +
|
||||
"from (\n" +
|
||||
" with \n" +
|
||||
" v1 as (select t1.k1 from db1.tbl1 t1),\n" +
|
||||
" v2 as (select t2.k1 from db1.tbl1 t2)\n" +
|
||||
" select v1.k1 as k1 from v1\n" +
|
||||
" union\n" +
|
||||
" select v2.k1 as k1 from v2\n" +
|
||||
") t";
|
||||
SelectStmt stmt1 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql1, ctx);
|
||||
stmt1.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
|
||||
Assert.assertTrue(stmt1.toSql().equals("SELECT `t`.`k1` AS `k1` " +
|
||||
"FROM (WITH v1 AS (SELECT `t1`.`k1` AS `k1` FROM `default_cluster:db1`.`tbl1` t1)," +
|
||||
"v2 AS (SELECT `t2`.`k1` AS `k1` FROM `default_cluster:db1`.`tbl1` t2) " +
|
||||
"SELECT `v1`.`k1` AS `k1` FROM `v1` UNION SELECT `v2`.`k1` AS `k1` FROM `v2`) t"));
|
||||
|
||||
String sql2 =
|
||||
"with\n" +
|
||||
" v1 as (select t1.k1 from db1.tbl1 t1),\n" +
|
||||
" v2 as (select t2.k1 from db1.tbl1 t2)\n" +
|
||||
"select\n" +
|
||||
" t.k1\n" +
|
||||
"from (\n" +
|
||||
" select v1.k1 as k1 from v1\n" +
|
||||
" union\n" +
|
||||
" select v2.k1 as k1 from v2\n" +
|
||||
") t";
|
||||
SelectStmt stmt2 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql2, ctx);
|
||||
stmt2.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
|
||||
Assert.assertTrue(stmt2.toSql().contains("WITH v1 AS (SELECT `t1`.`k1` AS `k1` FROM " +
|
||||
"`default_cluster:db1`.`tbl1` t1),v2 AS (SELECT `t2`.`k1` AS `k1` FROM `default_cluster:db1`.`tbl1` t2)"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testViewConvertFinalSql() throws Exception {
|
||||
ConnectContext ctx = UtFrameUtils.createDefaultCtx();
|
||||
dorisAssert.useDatabase("db1");
|
||||
String testView1 = "CREATE VIEW `view1` as (select t1.k1, t1.k2 from db1.tbl1 t1)";
|
||||
dorisAssert.withView(testView1);
|
||||
|
||||
String sql1 = "select * from db1.view1;";
|
||||
SelectStmt stmt1 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql1, ctx);
|
||||
stmt1.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
|
||||
Assert.assertTrue(stmt1.toSql().contains("FROM " +
|
||||
"(SELECT `t1`.`k1` AS `k1`, `t1`.`k2` AS `k2` FROM `default_cluster:db1`.`tbl1` t1)"));
|
||||
|
||||
String sql2 =
|
||||
"select \n" +
|
||||
" t.k1 \n" +
|
||||
"from (\n" +
|
||||
" select v1.k1 from db1.view1 v1\n" +
|
||||
") t";
|
||||
SelectStmt stmt2 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql2, ctx);
|
||||
stmt2.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
|
||||
Assert.assertTrue(stmt2.toSql().contains("FROM " +
|
||||
"(SELECT `t1`.`k1` AS `k1`, `t1`.`k2` AS `k2` FROM `default_cluster:db1`.`tbl1` t1) v1"));
|
||||
|
||||
// WITH statement contains view, that is, localView contains normal view
|
||||
String sql3 =
|
||||
"with\n" +
|
||||
" v1 as (select t1.k1 from db1.view1 t1),\n" +
|
||||
" v2 as (select t2.k1 from db1.view1 t2)\n" +
|
||||
"select\n" +
|
||||
" t.k1\n" +
|
||||
"from (\n" +
|
||||
" select v1.k1 as k1 from v1\n" +
|
||||
" union\n" +
|
||||
" select v2.k1 as k1 from v2\n" +
|
||||
") t";
|
||||
SelectStmt stmt3 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql3, ctx);
|
||||
stmt3.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
|
||||
System.out.println(stmt3.toSql());
|
||||
Assert.assertTrue(stmt3.toSql().contains("WITH " +
|
||||
"v1 AS (SELECT `t1`.`k1` AS `k1` FROM (SELECT `t1`.`k1` AS `k1`, `t1`.`k2` AS `k2` FROM `default_cluster:db1`.`tbl1` t1) t1)," +
|
||||
"v2 AS (SELECT `t2`.`k1` AS `k1` FROM (SELECT `t1`.`k1` AS `k1`, `t1`.`k2` AS `k2` FROM `default_cluster:db1`.`tbl1` t1) t2)"));
|
||||
|
||||
dorisAssert.dropView("view1");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user