未验证 提交 6299532a 编写于 作者: A Alex Pelagenko 提交者: GitHub

fix(sql): push timestamp required on asof join on both sides (#1225)

上级 ea212baf
......@@ -54,6 +54,7 @@ import org.jetbrains.annotations.Nullable;
import static io.questdb.griffin.SqlKeywords.*;
import static io.questdb.griffin.model.ExpressionNode.FUNCTION;
import static io.questdb.griffin.model.ExpressionNode.LITERAL;
import static io.questdb.griffin.model.QueryModel.*;
public class SqlCodeGenerator implements Mutable {
public static final int GKK_VANILLA_INT = 0;
......@@ -61,7 +62,7 @@ public class SqlCodeGenerator implements Mutable {
private static final IntHashSet limitTypes = new IntHashSet();
private static final FullFatJoinGenerator CREATE_FULL_FAT_LT_JOIN = SqlCodeGenerator::createFullFatLtJoin;
private static final FullFatJoinGenerator CREATE_FULL_FAT_AS_OF_JOIN = SqlCodeGenerator::createFullFatAsOfJoin;
private static final boolean[] joinsRequiringTimestamp = {false, false, false, true, true, false, true};
private static final boolean[] joinsRequiringTimestamp = new boolean[JOIN_MAX + 1];
private static final IntObjHashMap<VectorAggregateFunctionConstructor> sumConstructors = new IntObjHashMap<>();
private static final IntObjHashMap<VectorAggregateFunctionConstructor> ksumConstructors = new IntObjHashMap<>();
private static final IntObjHashMap<VectorAggregateFunctionConstructor> nsumConstructors = new IntObjHashMap<>();
......@@ -102,6 +103,15 @@ public class SqlCodeGenerator implements Mutable {
private boolean fullFatJoins = false;
private final CharSequenceHashSet prefixes = new CharSequenceHashSet();
static {
joinsRequiringTimestamp[JOIN_INNER] = false;
joinsRequiringTimestamp[JOIN_OUTER] = false;
joinsRequiringTimestamp[JOIN_CROSS] = false;
joinsRequiringTimestamp[JOIN_ASOF] = true;
joinsRequiringTimestamp[JOIN_SPLICE] = true;
joinsRequiringTimestamp[JOIN_LT] = true;
}
public SqlCodeGenerator(
CairoEngine engine,
CairoConfiguration configuration,
......@@ -508,7 +518,7 @@ public class SqlCodeGenerator implements Mutable {
valueTypes.add(ColumnType.LONG);
if (slave.recordCursorSupportsRandomAccess() && !fullFatJoins) {
if (joinType == QueryModel.JOIN_INNER) {
if (joinType == JOIN_INNER) {
return new HashJoinLightRecordCursorFactory(
configuration,
metadata,
......@@ -543,7 +553,7 @@ public class SqlCodeGenerator implements Mutable {
false
);
if (joinType == QueryModel.JOIN_INNER) {
if (joinType == JOIN_INNER) {
return new HashJoinRecordCursorFactory(
configuration,
metadata,
......@@ -708,15 +718,19 @@ public class SqlCodeGenerator implements Mutable {
try {
int n = ordered.size();
assert n > 0;
assert n > 1;
for (int i = 0; i < n; i++) {
int index = ordered.getQuick(i);
QueryModel slaveModel = joinModels.getQuick(index);
boolean pop = false;
if (master != null) {
if (i > 0) {
executionContext.pushTimestampRequiredFlag(joinsRequiringTimestamp[slaveModel.getJoinType()]);
pop = true;
} else { // i == 0
// This is first model in the sequence of joins
// TS requirement is symmetrical on both right and left sides
// check if next join requires a timestamp
int nextJointType = joinModels.getQuick(ordered.getQuick(1)).getJoinType();
executionContext.pushTimestampRequiredFlag(joinsRequiringTimestamp[nextJointType]);
}
try {
......@@ -739,7 +753,7 @@ public class SqlCodeGenerator implements Mutable {
final RecordMetadata slaveMetadata = slave.getMetadata();
switch (joinType) {
case QueryModel.JOIN_CROSS:
case JOIN_CROSS:
master = new CrossJoinRecordCursorFactory(
createJoinMetadata(masterAlias, masterMetadata, slaveModel.getName(), slaveMetadata),
master,
......@@ -748,7 +762,7 @@ public class SqlCodeGenerator implements Mutable {
);
masterAlias = null;
break;
case QueryModel.JOIN_ASOF:
case JOIN_ASOF:
validateBothTimestamps(slaveModel, masterMetadata, slaveMetadata);
processJoinContext(index == 1, slaveModel.getContext(), masterMetadata, slaveMetadata);
if (slave.recordCursorSupportsRandomAccess() && !fullFatJoins) {
......@@ -793,7 +807,7 @@ public class SqlCodeGenerator implements Mutable {
}
masterAlias = null;
break;
case QueryModel.JOIN_LT:
case JOIN_LT:
validateBothTimestamps(slaveModel, masterMetadata, slaveMetadata);
processJoinContext(index == 1, slaveModel.getContext(), masterMetadata, slaveMetadata);
if (slave.recordCursorSupportsRandomAccess() && !fullFatJoins) {
......@@ -838,7 +852,7 @@ public class SqlCodeGenerator implements Mutable {
}
masterAlias = null;
break;
case QueryModel.JOIN_SPLICE:
case JOIN_SPLICE:
validateBothTimestamps(slaveModel, masterMetadata, slaveMetadata);
processJoinContext(index == 1, slaveModel.getContext(), masterMetadata, slaveMetadata);
if (slave.recordCursorSupportsRandomAccess() && master.recordCursorSupportsRandomAccess() && !fullFatJoins) {
......@@ -878,9 +892,7 @@ public class SqlCodeGenerator implements Mutable {
}
}
} finally {
if (pop) {
executionContext.popTimestampRequiredFlag();
}
executionContext.popTimestampRequiredFlag();
}
// check if there are post-filters
......
......@@ -43,6 +43,7 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
public static final int JOIN_ASOF = 4;
public static final int JOIN_SPLICE = 5;
public static final int JOIN_LT = 6;
public static final int JOIN_MAX = JOIN_LT;
public static final String SUB_QUERY_ALIAS_PREFIX = "_xQdbA";
public static final int SELECT_MODEL_NONE = 0;
public static final int SELECT_MODEL_CHOOSE = 1;
......
......@@ -79,6 +79,36 @@ public class AsOfJoinTest extends AbstractGriffinTest {
);
}
@Test
public void testAsofJoinDynamicTimestamp() throws Exception {
compiler.compile(
"create table positions2 as (" +
"select x, cast(x * 1000000L as TIMESTAMP) time from long_sequence(10)" +
") timestamp(time)", sqlExecutionContext);
assertSql("select t1.time1 + 1 as time, t1.x, t2.x, t1.x - t2.x\n" +
"from \n" +
"(\n" +
" (\n" +
" select time - 1 as time1, x\n" +
" from positions2\n" +
" )\n" +
" timestamp(time1)\n" +
") t1\n" +
"asof join positions2 t2",
"time\tx\tx1\tcolumn\n" +
"1970-01-01T00:00:01.000000Z\t1\tNaN\tNaN\n" +
"1970-01-01T00:00:02.000000Z\t2\t1\t1\n" +
"1970-01-01T00:00:03.000000Z\t3\t2\t1\n" +
"1970-01-01T00:00:04.000000Z\t4\t3\t1\n" +
"1970-01-01T00:00:05.000000Z\t5\t4\t1\n" +
"1970-01-01T00:00:06.000000Z\t6\t5\t1\n" +
"1970-01-01T00:00:07.000000Z\t7\t6\t1\n" +
"1970-01-01T00:00:08.000000Z\t8\t7\t1\n" +
"1970-01-01T00:00:09.000000Z\t9\t8\t1\n" +
"1970-01-01T00:00:10.000000Z\t10\t9\t1\n");
}
@Test
public void testAsofJoinForSelectWithTimestamps() throws Exception {
final String expected = "tag\thi\tlo\tts\tts1\n" +
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册