提交 6c53da29 编写于 作者: V Vlad Ilyushchenko

GRIFFIN: fixed timestamp(field) clause behaviour in sub-queries

上级 03e56745
......@@ -135,9 +135,7 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
try {
types.getQuick(i).write(w, i, dbcs);
} catch (Exception ignore) {
LogRecord logRecord = LOG.error().$("type syntax [type=").$(ColumnType.nameOf(types.getQuick(i).getType())).$("]\n\t");
logRecord.$('[').$(line).$(':').$(i).$("] -> ").$(dbcs).$();
columnErrorCounts.increment(i);
logError(line, i, dbcs);
switch (atomicity) {
case Atomicity.SKIP_ALL:
writer.rollback();
......@@ -154,6 +152,12 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
w.append();
}
private void logError(long line, int i, DirectByteCharSequence dbcs) {
LogRecord logRecord = LOG.error().$("type syntax [type=").$(ColumnType.nameOf(types.getQuick(i).getType())).$("]\n\t");
logRecord.$('[').$(line).$(':').$(i).$("] -> ").$(dbcs).$();
columnErrorCounts.increment(i);
}
private void createTable(
ObjList<CharSequence> names,
ObjList<TypeAdapter> detectedTypes,
......
......@@ -41,18 +41,9 @@ public class TextLexer implements Closeable, Mutable {
private final ObjList<DirectByteCharSequence> fields = new ObjList<>();
private final ObjectPool<DirectByteCharSequence> csPool;
private final TextMetadataDetector metadataDetector;
private CharSequence tableName;
private final int lineRollBufLimit;
private boolean ignoreEolOnce;
private byte columnDelimiter;
private boolean inQuote;
private boolean delayedOutQuote;
private boolean eol;
private int fieldIndex;
private int fieldMax = -1;
private long fieldLo;
private long fieldHi;
private long lineCount;
private boolean useLineRollBuf = false;
private long lineRollBufCur;
private Listener textLexerListener;
private long lastLineStart;
......@@ -61,9 +52,18 @@ public class TextLexer implements Closeable, Mutable {
private boolean header;
private long lastQuotePos = -1;
private long errorCount = 0;
private boolean rollBufferUnusable = false;
private CharSequence tableName;
private int lineCountLimit;
private int fieldMax = -1;
private int fieldIndex;
private long lineCount;
private boolean eol;
private boolean useLineRollBuf = false;
private boolean rollBufferUnusable = false;
private byte columnDelimiter;
private boolean inQuote;
private boolean delayedOutQuote;
private long fieldLo;
private long fieldHi;
public TextLexer(TextConfiguration textConfiguration, TypeManager typeManager) {
this.metadataDetector = new TextMetadataDetector(typeManager, textConfiguration);
......
......@@ -72,7 +72,7 @@ public class SqlCodeGenerator {
this.recordComparatorCompiler = new RecordComparatorCompiler(asm);
}
private RecordMetadata copyMetadata(RecordMetadata that) {
private GenericRecordMetadata copyMetadata(RecordMetadata that) {
// todo: this metadata is immutable. Ideally we shouldn't be creating metadata for the same table over and over
return GenericRecordMetadata.copyOf(that);
}
......@@ -1238,7 +1238,16 @@ public class SqlCodeGenerator {
model.getTableName().token,
model.getTableVersion())
) {
final RecordMetadata metadata = reader.getMetadata();
final GenericRecordMetadata metadata = copyMetadata(reader.getMetadata());
final int timestampIndex;
final ExpressionNode timestamp = model.getTimestamp();
if (timestamp != null) {
timestampIndex = metadata.getColumnIndexQuiet(timestamp.token);
metadata.setTimestampIndex(timestampIndex);
} else {
timestampIndex = -1;
}
final int latestByIndex;
if (latestBy != null) {
......@@ -1256,19 +1265,11 @@ public class SqlCodeGenerator {
if (whereClause != null) {
final int timestampIndex;
final ExpressionNode timestamp = model.getTimestamp();
if (timestamp != null) {
timestampIndex = metadata.getColumnIndexQuiet(timestamp.token);
} else {
timestampIndex = -1;
}
final IntrinsicModel intrinsicModel = filterAnalyser.extract(model, whereClause, metadata, latestBy != null ? latestBy.token : null, timestampIndex);
if (intrinsicModel.intrinsicValue == IntrinsicModel.FALSE) {
return new EmptyTableRecordCursorFactory(copyMetadata(metadata));
return new EmptyTableRecordCursorFactory(metadata);
}
Function filter;
......@@ -1286,7 +1287,7 @@ public class SqlCodeGenerator {
// filter is constant "true", do not evaluate for every row
filter = null;
} else {
return new EmptyTableRecordCursorFactory(copyMetadata(metadata));
return new EmptyTableRecordCursorFactory(metadata);
}
}
} else {
......@@ -1353,7 +1354,7 @@ public class SqlCodeGenerator {
rcf = new SymbolIndexFilteredRowCursorFactory(keyColumnIndex, symbolKey, filter, true);
}
}
return new DataFrameRecordCursorFactory(copyMetadata(metadata), dfcFactory, rcf, filter);
return new DataFrameRecordCursorFactory(metadata, dfcFactory, rcf, filter);
}
return new FilterOnValuesRecordCursorFactory(
......@@ -1368,9 +1369,9 @@ public class SqlCodeGenerator {
if (filter != null) {
// filter lifecycle is managed by top level
return new FilteredRecordCursorFactory(new DataFrameRecordCursorFactory(copyMetadata(metadata), dfcFactory, new DataFrameRowCursorFactory(), null), filter);
return new FilteredRecordCursorFactory(new DataFrameRecordCursorFactory(metadata, dfcFactory, new DataFrameRowCursorFactory(), null), filter);
}
return new DataFrameRecordCursorFactory(copyMetadata(metadata), dfcFactory, new DataFrameRowCursorFactory(), filter);
return new DataFrameRecordCursorFactory(metadata, dfcFactory, new DataFrameRowCursorFactory(), filter);
}
// no where clause
......
......@@ -1115,7 +1115,7 @@ public final class SqlParser {
if (Chars.equalsLowerCaseAsciiNc(tok, "timestamp")) {
expectTok(lexer, '(');
final ExpressionNode result = expectLiteral(lexer);
expectTok(lexer, ')');
expectTok(SqlUtil.fetchNext(lexer), lexer.lastTokenPosition(), ')');
return result;
}
return null;
......
......@@ -275,7 +275,9 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
final CharSequence name = columnNames.getQuick(i);
this.aliasToColumnMap.put(name, name);
}
if (this.timestamp == null && other.timestamp != null) {
// do not copy timestamp from nested model to join models
// join type will determine timestamp
if (this.timestamp == null && other.timestamp != null && joinModels.size() < 2) {
this.timestamp = other.timestamp;
}
}
......
......@@ -36,11 +36,13 @@ public final class Numbers {
public static final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
public final static int[] hexNumbers;
private static final long[] pow10;
private static final long LONG_OVERFLOW_MAX = Long.MAX_VALUE / 10;
private static final long LONG_OVERFLOW_MAX = Long.MAX_VALUE / 10 + 1;
private static final long INT_OVERFLOW_MAX = Integer.MAX_VALUE / 10;
private final static String NaN = "NaN";
private static final String INFINITY = "Infinity";
private static final double[] pow10d = new double[]{1, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15, 1E16, 1E17, 1E18, 1E19, 1E20, 1E21, 1E22, 1E23, 1E24, 1E25, 1E26, 1E27, 1E28, 1E29, 1E30, 1E31, 1E32, 1E33, 1E34, 1E35, 1E36, 1E37, 1E38, 1E39, 1E40, 1E41, 1E42, 1E43, 1E44, 1E45, 1E46, 1E47, 1E48, 1E49, 1E50, 1E51, 1E52, 1E53, 1E54, 1E55, 1E56, 1E57, 1E58, 1E59, 1E60, 1E61, 1E62, 1E63, 1E64, 1E65, 1E66, 1E67, 1E68, 1E69, 1E70, 1E71, 1E72, 1E73, 1E74, 1E75, 1E76, 1E77, 1E78, 1E79, 1E80, 1E81, 1E82, 1E83, 1E84, 1E85, 1E86, 1E87, 1E88, 1E89, 1E90, 1E91, 1E92, 1E93, 1E94, 1E95, 1E96, 1E97, 1E98, 1E99, 1E100, 1E101, 1E102, 1E103, 1E104, 1E105, 1E106, 1E107, 1E108, 1E109, 1E110, 1E111, 1E112, 1E113, 1E114, 1E115, 1E116, 1E117, 1E118, 1E119, 1E120, 1E121, 1E122, 1E123, 1E124, 1E125, 1E126, 1E127, 1E128, 1E129, 1E130, 1E131, 1E132, 1E133, 1E134, 1E135, 1E136, 1E137, 1E138, 1E139, 1E140, 1E141, 1E142, 1E143, 1E144, 1E145, 1E146, 1E147, 1E148, 1E149, 1E150, 1E151, 1E152, 1E153, 1E154, 1E155, 1E156, 1E157, 1E158, 1E159, 1E160, 1E161, 1E162, 1E163, 1E164, 1E165, 1E166, 1E167, 1E168, 1E169, 1E170, 1E171, 1E172, 1E173, 1E174, 1E175, 1E176, 1E177, 1E178, 1E179, 1E180, 1E181, 1E182, 1E183, 1E184, 1E185, 1E186, 1E187, 1E188, 1E189, 1E190, 1E191, 1E192, 1E193, 1E194, 1E195, 1E196, 1E197, 1E198, 1E199, 1E200, 1E201, 1E202, 1E203, 1E204, 1E205, 1E206, 1E207, 1E208, 1E209, 1E210, 1E211, 1E212, 1E213, 1E214, 1E215, 1E216, 1E217, 1E218, 1E219, 1E220, 1E221, 1E222, 1E223, 1E224, 1E225, 1E226, 1E227, 1E228, 1E229, 1E230, 1E231, 1E232, 1E233, 1E234, 1E235, 1E236, 1E237, 1E238, 1E239, 1E240, 1E241, 1E242, 1E243, 1E244, 1E245, 1E246, 1E247, 1E248, 1E249, 1E250, 1E251, 1E252, 1E253, 1E254, 1E255, 1E256, 1E257, 1E258, 1E259, 1E260, 1E261, 1E262, 1E263, 1E264, 1E265, 1E266, 1E267, 1E268, 1E269, 1E270, 1E271, 1E272, 1E273, 1E274, 1E275, 1E276, 1E277, 1E278, 1E279, 1E280, 1E281, 1E282, 1E283, 1E284, 1E285, 1E286, 1E287, 1E288, 1E289, 1E290, 1E291, 1E292, 1E293, 1E294, 1E295, 1E296, 1E297, 1E298, 1E299, 1E300, 1E301, 1E302, 1E303, 1E304, 1E305, 1E306, 1E307, 1E308};
private static final double[] pow10dNeg =
new double[]{1, 1E-1, 1E-2, 1E-3, 1E-4, 1E-5, 1E-6, 1E-7, 1E-8, 1E-9, 1E-10, 1E-11, 1E-12, 1E-13, 1E-14, 1E-15, 1E-16, 1E-17, 1E-18, 1E-19, 1E-20, 1E-21, 1E-22, 1E-23, 1E-24, 1E-25, 1E-26, 1E-27, 1E-28, 1E-29, 1E-30, 1E-31, 1E-32, 1E-33, 1E-34, 1E-35, 1E-36, 1E-37, 1E-38, 1E-39, 1E-40, 1E-41, 1E-42, 1E-43, 1E-44, 1E-45, 1E-46, 1E-47, 1E-48, 1E-49, 1E-50, 1E-51, 1E-52, 1E-53, 1E-54, 1E-55, 1E-56, 1E-57, 1E-58, 1E-59, 1E-60, 1E-61, 1E-62, 1E-63, 1E-64, 1E-65, 1E-66, 1E-67, 1E-68, 1E-69, 1E-70, 1E-71, 1E-72, 1E-73, 1E-74, 1E-75, 1E-76, 1E-77, 1E-78, 1E-79, 1E-80, 1E-81, 1E-82, 1E-83, 1E-84, 1E-85, 1E-86, 1E-87, 1E-88, 1E-89, 1E-90, 1E-91, 1E-92, 1E-93, 1E-94, 1E-95, 1E-96, 1E-97, 1E-98, 1E-99, 1E-100, 1E-101, 1E-102, 1E-103, 1E-104, 1E-105, 1E-106, 1E-107, 1E-108, 1E-109, 1E-110, 1E-111, 1E-112, 1E-113, 1E-114, 1E-115, 1E-116, 1E-117, 1E-118, 1E-119, 1E-120, 1E-121, 1E-122, 1E-123, 1E-124, 1E-125, 1E-126, 1E-127, 1E-128, 1E-129, 1E-130, 1E-131, 1E-132, 1E-133, 1E-134, 1E-135, 1E-136, 1E-137, 1E-138, 1E-139, 1E-140, 1E-141, 1E-142, 1E-143, 1E-144, 1E-145, 1E-146, 1E-147, 1E-148, 1E-149, 1E-150, 1E-151, 1E-152, 1E-153, 1E-154, 1E-155, 1E-156, 1E-157, 1E-158, 1E-159, 1E-160, 1E-161, 1E-162, 1E-163, 1E-164, 1E-165, 1E-166, 1E-167, 1E-168, 1E-169, 1E-170, 1E-171, 1E-172, 1E-173, 1E-174, 1E-175, 1E-176, 1E-177, 1E-178, 1E-179, 1E-180, 1E-181, 1E-182, 1E-183, 1E-184, 1E-185, 1E-186, 1E-187, 1E-188, 1E-189, 1E-190, 1E-191, 1E-192, 1E-193, 1E-194, 1E-195, 1E-196, 1E-197, 1E-198, 1E-199, 1E-200, 1E-201, 1E-202, 1E-203, 1E-204, 1E-205, 1E-206, 1E-207, 1E-208, 1E-209, 1E-210, 1E-211, 1E-212, 1E-213, 1E-214, 1E-215, 1E-216, 1E-217, 1E-218, 1E-219, 1E-220, 1E-221, 1E-222, 1E-223, 1E-224, 1E-225, 1E-226, 1E-227, 1E-228, 1E-229, 1E-230, 1E-231, 1E-232, 1E-233, 1E-234, 1E-235, 1E-236, 1E-237, 1E-238, 1E-239, 1E-240, 1E-241, 1E-242, 1E-243, 1E-244, 1E-245, 1E-246, 1E-247, 1E-248, 1E-249, 1E-250, 1E-251, 1E-252, 1E-253, 1E-254, 1E-255, 1E-256, 1E-257, 1E-258, 1E-259, 1E-260, 1E-261, 1E-262, 1E-263, 1E-264, 1E-265, 1E-266, 1E-267, 1E-268, 1E-269, 1E-270, 1E-271, 1E-272, 1E-273, 1E-274, 1E-275, 1E-276, 1E-277, 1E-278, 1E-279, 1E-280, 1E-281, 1E-282, 1E-283, 1E-284, 1E-285, 1E-286, 1E-287, 1E-288, 1E-289, 1E-290, 1E-291, 1E-292, 1E-293, 1E-294, 1E-295, 1E-296, 1E-297, 1E-298, 1E-299, 1E-300, 1E-301, 1E-302, 1E-303, 1E-304, 1E-305, 1E-306, 1E-307, 1E-308};
private static final float[] pow10f = new float[]{1, 1E1f, 1E2f, 1E3f, 1E4f, 1E5f, 1E6f, 1E7f, 1E8f, 1E9f, 1E10f, 1E11f, 1E12f, 1E13f, 1E14f, 1E15f, 1E16f, 1E17f, 1E18f, 1E19f, 1E20f, 1E21f, 1E22f, 1E23f, 1E24f, 1E25f, 1E26f, 1E27f, 1E28f, 1E29f, 1E30f, 1E31f, 1E32f, 1E33f, 1E34f, 1E35f, 1E36f, 1E37f, 1E38f};
private final static int pow10max;
private static final LongHexAppender[] longHexAppender = new LongHexAppender[Long.SIZE + 1];
......@@ -942,16 +944,17 @@ public final class Numbers {
}
boolean negative = sequence.charAt(0) == '-';
int i = 0;
int i;
if (negative) {
i++;
i = 1;
} else {
i = 0;
}
if (i >= lim) {
throw NumericException.INSTANCE;
}
switch (sequence.charAt(i)) {
case 'N':
return parseConst(sequence, i, lim, NaN, Double.NaN);
......@@ -967,7 +970,7 @@ public final class Numbers {
int exp = 0;
out:
for (; i < lim; i++) {
int c = sequence.charAt(i);
final int c = sequence.charAt(i);
switch (c) {
case '.':
dp = i;
......@@ -993,7 +996,7 @@ public final class Numbers {
throw NumericException.INSTANCE;
}
if (val <= LONG_OVERFLOW_MAX) {
if (val < LONG_OVERFLOW_MAX) {
// val * 10 + (c - '0')
val = (val << 3) + (val << 1) + (c - '0');
} else if (dpe == lim) {
......@@ -1011,10 +1014,10 @@ public final class Numbers {
exp = -308;
}
if (exp > 0) {
if (exp > -1) {
return (negative ? -val : val) * pow10d[exp];
} else {
return (negative ? -val : val) / pow10d[-exp];
return (negative ? -val : val) * pow10dNeg[-exp];
}
}
......
......@@ -442,6 +442,198 @@ public class JoinTest extends AbstractGriffinTest {
});
}
@Test
public void testAsOfJoinNoSelect() throws Exception {
TestUtils.assertMemoryLeak(() -> {
try {
final String query = "x asof join y on y.sym2 = x.sym";
final String expected = "i\tsym\tamt\ttimestamp\ti1\tsym2\tprice\ttimestamp1\n" +
"1\tmsft\t22.463000000000\t2018-01-01T00:12:00.000000Z\tNaN\t\tNaN\t\n" +
"2\tgoogl\t29.920000000000\t2018-01-01T00:24:00.000000Z\t12\tgoogl\t0.885000000000\t2018-01-01T00:24:00.000000Z\n" +
"3\tmsft\t65.086000000000\t2018-01-01T00:36:00.000000Z\t18\tmsft\t0.566000000000\t2018-01-01T00:36:00.000000Z\n" +
"4\tibm\t98.563000000000\t2018-01-01T00:48:00.000000Z\t17\tibm\t0.405000000000\t2018-01-01T00:34:00.000000Z\n" +
"5\tmsft\t50.938000000000\t2018-01-01T01:00:00.000000Z\t23\tmsft\t0.545000000000\t2018-01-01T00:46:00.000000Z\n" +
"6\tibm\t76.110000000000\t2018-01-01T01:12:00.000000Z\t28\tibm\t0.954000000000\t2018-01-01T00:56:00.000000Z\n" +
"7\tmsft\t55.992000000000\t2018-01-01T01:24:00.000000Z\t23\tmsft\t0.545000000000\t2018-01-01T00:46:00.000000Z\n" +
"8\tibm\t23.905000000000\t2018-01-01T01:36:00.000000Z\t28\tibm\t0.954000000000\t2018-01-01T00:56:00.000000Z\n" +
"9\tgoogl\t67.786000000000\t2018-01-01T01:48:00.000000Z\t30\tgoogl\t0.198000000000\t2018-01-01T01:00:00.000000Z\n" +
"10\tgoogl\t38.540000000000\t2018-01-01T02:00:00.000000Z\t30\tgoogl\t0.198000000000\t2018-01-01T01:00:00.000000Z\n";
compiler.compile(
"create table x as (" +
"select" +
" to_int(x) i," +
" rnd_symbol('msft','ibm', 'googl') sym," +
" round(rnd_double(0)*100, 3) amt," +
" to_timestamp('2018-01', 'yyyy-MM') + x * 720000000 timestamp" +
" from long_sequence(10)" +
") timestamp (timestamp)"
);
compiler.compile(
"create table y as (" +
"select to_int(x) i," +
" rnd_symbol('msft','ibm', 'googl') sym2," +
" round(rnd_double(0), 3) price," +
" to_timestamp('2018-01', 'yyyy-MM') + x * 120000000 timestamp" +
" from long_sequence(30)" +
") timestamp(timestamp)"
);
assertQueryAndCache(expected, query, "timestamp");
compiler.compile(
"insert into x select * from (" +
"select" +
" to_int(x + 10) i," +
" rnd_symbol('msft','ibm', 'googl') sym," +
" round(rnd_double(0)*100, 3) amt," +
" to_timestamp('2018-01', 'yyyy-MM') + (x + 10) * 720000000 timestamp" +
" from long_sequence(10)" +
") timestamp(timestamp)"
);
compiler.compile(
"insert into y select * from (" +
"select" +
" to_int(x + 30) i," +
" rnd_symbol('msft','ibm', 'googl') sym2," +
" round(rnd_double(0), 3) price," +
" to_timestamp('2018-01', 'yyyy-MM') + (x + 30) * 120000000 timestamp" +
" from long_sequence(30)" +
") timestamp(timestamp)"
);
assertQuery("i\tsym\tamt\ttimestamp\ti1\tsym2\tprice\ttimestamp1\n" +
"1\tmsft\t22.463000000000\t2018-01-01T00:12:00.000000Z\tNaN\t\tNaN\t\n" +
"2\tgoogl\t29.920000000000\t2018-01-01T00:24:00.000000Z\t12\tgoogl\t0.885000000000\t2018-01-01T00:24:00.000000Z\n" +
"3\tmsft\t65.086000000000\t2018-01-01T00:36:00.000000Z\t18\tmsft\t0.566000000000\t2018-01-01T00:36:00.000000Z\n" +
"4\tibm\t98.563000000000\t2018-01-01T00:48:00.000000Z\t17\tibm\t0.405000000000\t2018-01-01T00:34:00.000000Z\n" +
"5\tmsft\t50.938000000000\t2018-01-01T01:00:00.000000Z\t23\tmsft\t0.545000000000\t2018-01-01T00:46:00.000000Z\n" +
"6\tibm\t76.110000000000\t2018-01-01T01:12:00.000000Z\t36\tibm\t0.337000000000\t2018-01-01T01:12:00.000000Z\n" +
"7\tmsft\t55.992000000000\t2018-01-01T01:24:00.000000Z\t38\tmsft\t0.226000000000\t2018-01-01T01:16:00.000000Z\n" +
"8\tibm\t23.905000000000\t2018-01-01T01:36:00.000000Z\t48\tibm\t0.767000000000\t2018-01-01T01:36:00.000000Z\n" +
"9\tgoogl\t67.786000000000\t2018-01-01T01:48:00.000000Z\t54\tgoogl\t0.101000000000\t2018-01-01T01:48:00.000000Z\n" +
"10\tgoogl\t38.540000000000\t2018-01-01T02:00:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n" +
"11\tmsft\t68.069000000000\t2018-01-01T02:12:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"12\tmsft\t24.008000000000\t2018-01-01T02:24:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"13\tgoogl\t94.559000000000\t2018-01-01T02:36:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n" +
"14\tibm\t62.474000000000\t2018-01-01T02:48:00.000000Z\t50\tibm\t0.068000000000\t2018-01-01T01:40:00.000000Z\n" +
"15\tmsft\t39.017000000000\t2018-01-01T03:00:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"16\tgoogl\t10.643000000000\t2018-01-01T03:12:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n" +
"17\tmsft\t7.246000000000\t2018-01-01T03:24:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"18\tmsft\t36.798000000000\t2018-01-01T03:36:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"19\tmsft\t66.980000000000\t2018-01-01T03:48:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"20\tgoogl\t26.369000000000\t2018-01-01T04:00:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n",
query,
"timestamp");
Assert.assertEquals(0, engine.getBusyReaderCount());
Assert.assertEquals(0, engine.getBusyWriterCount());
} finally {
engine.releaseAllWriters();
engine.releaseAllReaders();
}
});
}
@Test
public void testAsOfJoinNoTimestamps() throws Exception {
TestUtils.assertMemoryLeak(() -> {
try {
final String query = "(x timestamp(timestamp)) x asof join (y timestamp(timestamp)) y on y.sym2 = x.sym";
final String expected = "i\tsym\tamt\ttimestamp\ti1\tsym2\tprice\ttimestamp1\n" +
"1\tmsft\t22.463000000000\t2018-01-01T00:12:00.000000Z\tNaN\t\tNaN\t\n" +
"2\tgoogl\t29.920000000000\t2018-01-01T00:24:00.000000Z\t12\tgoogl\t0.885000000000\t2018-01-01T00:24:00.000000Z\n" +
"3\tmsft\t65.086000000000\t2018-01-01T00:36:00.000000Z\t18\tmsft\t0.566000000000\t2018-01-01T00:36:00.000000Z\n" +
"4\tibm\t98.563000000000\t2018-01-01T00:48:00.000000Z\t17\tibm\t0.405000000000\t2018-01-01T00:34:00.000000Z\n" +
"5\tmsft\t50.938000000000\t2018-01-01T01:00:00.000000Z\t23\tmsft\t0.545000000000\t2018-01-01T00:46:00.000000Z\n" +
"6\tibm\t76.110000000000\t2018-01-01T01:12:00.000000Z\t28\tibm\t0.954000000000\t2018-01-01T00:56:00.000000Z\n" +
"7\tmsft\t55.992000000000\t2018-01-01T01:24:00.000000Z\t23\tmsft\t0.545000000000\t2018-01-01T00:46:00.000000Z\n" +
"8\tibm\t23.905000000000\t2018-01-01T01:36:00.000000Z\t28\tibm\t0.954000000000\t2018-01-01T00:56:00.000000Z\n" +
"9\tgoogl\t67.786000000000\t2018-01-01T01:48:00.000000Z\t30\tgoogl\t0.198000000000\t2018-01-01T01:00:00.000000Z\n" +
"10\tgoogl\t38.540000000000\t2018-01-01T02:00:00.000000Z\t30\tgoogl\t0.198000000000\t2018-01-01T01:00:00.000000Z\n";
compiler.compile(
"create table x as (" +
"select" +
" to_int(x) i," +
" rnd_symbol('msft','ibm', 'googl') sym," +
" round(rnd_double(0)*100, 3) amt," +
" to_timestamp('2018-01', 'yyyy-MM') + x * 720000000 timestamp" +
" from long_sequence(10)" +
")"
);
compiler.compile(
"create table y as (" +
"select to_int(x) i," +
" rnd_symbol('msft','ibm', 'googl') sym2," +
" round(rnd_double(0), 3) price," +
" to_timestamp('2018-01', 'yyyy-MM') + x * 120000000 timestamp" +
" from long_sequence(30)" +
")"
);
assertQueryAndCache(expected, query, "timestamp");
compiler.compile(
"insert into x select * from (" +
"select" +
" to_int(x + 10) i," +
" rnd_symbol('msft','ibm', 'googl') sym," +
" round(rnd_double(0)*100, 3) amt," +
" to_timestamp('2018-01', 'yyyy-MM') + (x + 10) * 720000000 timestamp" +
" from long_sequence(10)" +
") timestamp(timestamp)"
);
compiler.compile(
"insert into y select * from (" +
"select" +
" to_int(x + 30) i," +
" rnd_symbol('msft','ibm', 'googl') sym2," +
" round(rnd_double(0), 3) price," +
" to_timestamp('2018-01', 'yyyy-MM') + (x + 30) * 120000000 timestamp" +
" from long_sequence(30)" +
") timestamp(timestamp)"
);
assertQuery("i\tsym\tamt\ttimestamp\ti1\tsym2\tprice\ttimestamp1\n" +
"1\tmsft\t22.463000000000\t2018-01-01T00:12:00.000000Z\tNaN\t\tNaN\t\n" +
"2\tgoogl\t29.920000000000\t2018-01-01T00:24:00.000000Z\t12\tgoogl\t0.885000000000\t2018-01-01T00:24:00.000000Z\n" +
"3\tmsft\t65.086000000000\t2018-01-01T00:36:00.000000Z\t18\tmsft\t0.566000000000\t2018-01-01T00:36:00.000000Z\n" +
"4\tibm\t98.563000000000\t2018-01-01T00:48:00.000000Z\t17\tibm\t0.405000000000\t2018-01-01T00:34:00.000000Z\n" +
"5\tmsft\t50.938000000000\t2018-01-01T01:00:00.000000Z\t23\tmsft\t0.545000000000\t2018-01-01T00:46:00.000000Z\n" +
"6\tibm\t76.110000000000\t2018-01-01T01:12:00.000000Z\t36\tibm\t0.337000000000\t2018-01-01T01:12:00.000000Z\n" +
"7\tmsft\t55.992000000000\t2018-01-01T01:24:00.000000Z\t38\tmsft\t0.226000000000\t2018-01-01T01:16:00.000000Z\n" +
"8\tibm\t23.905000000000\t2018-01-01T01:36:00.000000Z\t48\tibm\t0.767000000000\t2018-01-01T01:36:00.000000Z\n" +
"9\tgoogl\t67.786000000000\t2018-01-01T01:48:00.000000Z\t54\tgoogl\t0.101000000000\t2018-01-01T01:48:00.000000Z\n" +
"10\tgoogl\t38.540000000000\t2018-01-01T02:00:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n" +
"11\tmsft\t68.069000000000\t2018-01-01T02:12:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"12\tmsft\t24.008000000000\t2018-01-01T02:24:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"13\tgoogl\t94.559000000000\t2018-01-01T02:36:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n" +
"14\tibm\t62.474000000000\t2018-01-01T02:48:00.000000Z\t50\tibm\t0.068000000000\t2018-01-01T01:40:00.000000Z\n" +
"15\tmsft\t39.017000000000\t2018-01-01T03:00:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"16\tgoogl\t10.643000000000\t2018-01-01T03:12:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n" +
"17\tmsft\t7.246000000000\t2018-01-01T03:24:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"18\tmsft\t36.798000000000\t2018-01-01T03:36:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"19\tmsft\t66.980000000000\t2018-01-01T03:48:00.000000Z\t55\tmsft\t0.051000000000\t2018-01-01T01:50:00.000000Z\n" +
"20\tgoogl\t26.369000000000\t2018-01-01T04:00:00.000000Z\t60\tgoogl\t0.690000000000\t2018-01-01T02:00:00.000000Z\n",
query,
"timestamp");
Assert.assertEquals(0, engine.getBusyReaderCount());
Assert.assertEquals(0, engine.getBusyWriterCount());
} finally {
engine.releaseAllWriters();
engine.releaseAllReaders();
}
});
}
@Test
public void testAsOfJoinAllTypes() throws Exception {
TestUtils.assertMemoryLeak(() -> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册