未验证 提交 7cd9a4d2 编写于 作者: B Bolek Ziobrowski 提交者: GitHub

fix(sql): fix error on order by empty string & join condition pushdown (#3646)

上级 14435253
......@@ -2914,7 +2914,11 @@ public class SqlOptimiser implements Mutable {
emitLiteralsTopDown(leftJoinWhere, jm);
emitLiteralsTopDown(leftJoinWhere, model);
}
}
// propagate join models columns in separate loop to catch columns added to models prior to the current one
for (int i = 1, n = joinModels.size(); i < n; i++) {
final QueryModel jm = joinModels.getQuick(i);
propagateTopDownColumns0(jm, false, model, true);
}
......
......@@ -1305,6 +1305,11 @@ public class SqlParser {
throw SqlException.$(lexer.lastTokenPosition(), "literal or expression expected");
}
if ((n.type == ExpressionNode.CONSTANT && Chars.equals("''", n.token)) ||
(n.type == ExpressionNode.LITERAL && n.token.length() == 0)) {
throw SqlException.$(lexer.lastTokenPosition(), "non-empty literal or expression expected");
}
tok = optTok(lexer);
if (tok != null && isDescKeyword(tok)) {
......
......@@ -27,10 +27,7 @@ package io.questdb.test.griffin;
import io.questdb.cairo.*;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.cairo.sql.TableRecordMetadata;
import io.questdb.griffin.SqlCompiler;
import io.questdb.griffin.SqlCompilerImpl;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.SqlExecutionContext;
import io.questdb.griffin.*;
import io.questdb.griffin.engine.ops.AlterOperationBuilder;
import io.questdb.log.Log;
import io.questdb.log.LogFactory;
......@@ -3147,6 +3144,43 @@ public class SqlCompilerImplTest extends AbstractCairoTest {
assertFailure(43, "cannot compare LONG with type DOUBLE", "select 1 from long_sequence(1) where x in (123.456)");
}
@Test
public void testInnerJoinConditionPushdown() throws Exception {
assertMemoryLeak(() -> {
compile("create table tab ( created timestamp, value long ) timestamp(created) ");
compile("insert into tab values (0, 0), (1, 1), (2,2)");
for (String join : new String[]{"", "LEFT", "LT", "ASOF",}) {
assertSql("count\n3\n",
"SELECT count(T2.created) " +
"FROM tab as T1 " +
"JOIN (SELECT * FROM tab) as T2 ON T1.created < T2.created " +
join + " JOIN tab as T3 ON T2.value=T3.value"
);
}
assertSql("count\n1\n",
"SELECT count(T2.created) " +
"FROM tab as T1 " +
"JOIN tab T2 ON T1.created < T2.created " +
"JOIN (SELECT * FROM tab) as T3 ON T2.value=T3.value " +
"JOIN tab T4 on T3.created < T4.created");
assertSql("count\n3\n",
"SELECT count(T2.created) " +
"FROM tab as T1 " +
"JOIN tab T2 ON T1.created < T2.created " +
"JOIN (SELECT * FROM tab) as T3 ON T2.value=T3.value " +
"LEFT JOIN tab T4 on T3.created < T4.created");
assertSql("count\n3\n",
"SELECT count(T2.created) " +
"FROM tab as T1 " +
"JOIN tab T2 ON T1.created < T2.created " +
"JOIN (SELECT * FROM tab) as T3 ON T2.value=T3.value " +
"LEFT JOIN tab T4 on T3.created-T4.created = 0 ");
});
}
@Test
public void testInsertAsSelect() throws Exception {
String expectedData = "a\tb\tc\td\te\tf\tg\th\ti\tj\tk\tl\tm\tn\to\tp\n" +
......@@ -4582,6 +4616,15 @@ public class SqlCompilerImplTest extends AbstractCairoTest {
);
}
@Test
public void testOrderByEmptyIdentifier() throws Exception {
assertMemoryLeak(() -> {
assertFailure(40, "non-empty literal or expression expected", "select 1 from long_sequence(1) order by ''");
assertFailure(40, "non-empty literal or expression expected", "select 1 from long_sequence(1) order by \"\"");
});
}
@Test
public void testOrderByFloat() throws Exception {
assertQuery("f\n" +
......@@ -5191,20 +5234,6 @@ public class SqlCompilerImplTest extends AbstractCairoTest {
);
}
@Test
public void testTimestampWithNanosInWhereClause() throws Exception {
assertQuery("x\tts\n" +
"2\t2019-10-17T00:00:00.200000Z\n" +
"3\t2019-10-17T00:00:00.700000Z\n" +
"4\t2019-10-17T00:00:00.800000Z\n",
"select * from x where ts between '2019-10-17T00:00:00.200000123Z' and '2019-10-17T00:00:00.800000123Z'",
"create table x as " +
"(SELECT x, timestamp_sequence(to_timestamp('2019-10-17T00:00:00', 'yyyy-MM-ddTHH:mm:ss'), rnd_short(1,5) * 100000L) as ts FROM long_sequence(5)" +
")",
null, true, false
);
}
@Test
public void testSelectTimestampInNullString() throws Exception {
assertQuery("c\n\n",
......@@ -5319,6 +5348,20 @@ public class SqlCompilerImplTest extends AbstractCairoTest {
);
}
@Test
public void testTimestampWithNanosInWhereClause() throws Exception {
assertQuery("x\tts\n" +
"2\t2019-10-17T00:00:00.200000Z\n" +
"3\t2019-10-17T00:00:00.700000Z\n" +
"4\t2019-10-17T00:00:00.800000Z\n",
"select * from x where ts between '2019-10-17T00:00:00.200000123Z' and '2019-10-17T00:00:00.800000123Z'",
"create table x as " +
"(SELECT x, timestamp_sequence(to_timestamp('2019-10-17T00:00:00', 'yyyy-MM-ddTHH:mm:ss'), rnd_short(1,5) * 100000L) as ts FROM long_sequence(5)" +
")",
null, true, false
);
}
@Test
public void testUseExtensionPoints() {
try (SqlCompilerWrapper compiler = new SqlCompilerWrapper(engine)) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册