提交 11de7c1b 编写于 作者: V Vlad Ilyushchenko

GRIFFIN: min() group by function implementation and testing

上级 1d0da920
......@@ -69,6 +69,155 @@ public class PGConnectionContext implements IOContext, Mutable {
private static final byte MESSAGE_TYPE_PARSE_COMPLETE = '1';
private static final byte MESSAGE_TYPE_COPY_IN_RESPONSE = 'G';
static {
// todo: this should be sparse array
// change after we have good test coverage
typeOidMap.put(ColumnType.STRING, PG_VARCHAR); // VARCHAR
typeOidMap.put(ColumnType.TIMESTAMP, PG_TIMESTAMP); // TIMESTAMPZ
typeOidMap.put(ColumnType.DOUBLE, PG_FLOAT8); // FLOAT8
typeOidMap.put(ColumnType.FLOAT, PG_FLOAT4); // FLOAT4
typeOidMap.put(ColumnType.INT, PG_INT4); // INT4
typeOidMap.put(ColumnType.SHORT, PG_INT2); // INT2
typeOidMap.put(ColumnType.CHAR, PG_CHAR);
typeOidMap.put(ColumnType.SYMBOL, PG_VARCHAR); // NAME
typeOidMap.put(ColumnType.LONG, PG_INT8); // INT8
typeOidMap.put(ColumnType.BYTE, PG_INT2); // INT2
typeOidMap.put(ColumnType.BOOLEAN, PG_BOOL); // BOOL
typeOidMap.put(ColumnType.DATE, PG_TIMESTAMP); // DATE
typeOidMap.put(ColumnType.BINARY, PG_BYTEA); // BYTEA
}
private final long recvBuffer;
private final long sendBuffer;
private final int recvBufferSize;
private final CharacterStore connectionCharacterStore;
private final CharacterStore queryCharacterStore;
private final BindVariableService bindVariableService = new BindVariableService();
private final long sendBufferLimit;
private final int sendBufferSize;
private final ResponseAsciiSink responseAsciiSink = new ResponseAsciiSink();
private final DirectByteCharSequence dbcs = new DirectByteCharSequence();
private final int maxBlobSizeOnQuery;
private final NetworkFacade nf;
private final boolean dumpNetworkTraffic;
private final int idleSendCountBeforeGivingUp;
private final int idleRecvCountBeforeGivingUp;
private final String serverVersion;
private final PGAuthenticator authenticator;
private final SqlExecutionContextImpl sqlExecutionContext = new SqlExecutionContextImpl();
private int sendCurrentCursorTail = TAIL_NONE;
private long sendBufferPtr;
private boolean requireInitalMessage = false;
private long recvBufferWriteOffset = 0;
private long recvBufferReadOffset = 0;
private int bufferRemainingOffset = 0;
private int bufferRemainingSize = 0;
private RecordCursor currentCursor = null;
private RecordCursorFactory currentFactory = null;
private long fd;
private CharSequence queryText;
private CharSequence username;
private boolean authenticationRequired = true;
private long transientCopyBuffer = 0;
public PGConnectionContext(PGWireConfiguration configuration) {
this.nf = configuration.getNetworkFacade();
this.recvBufferSize = Numbers.ceilPow2(configuration.getRecvBufferSize());
this.recvBuffer = Unsafe.malloc(this.recvBufferSize);
this.sendBufferSize = Numbers.ceilPow2(configuration.getSendBufferSize());
this.sendBuffer = Unsafe.malloc(this.sendBufferSize);
this.sendBufferPtr = sendBuffer;
this.sendBufferLimit = sendBuffer + sendBufferSize;
this.queryCharacterStore = new CharacterStore(
configuration.getCharacterStoreCapacity(),
configuration.getCharacterStorePoolCapacity()
);
this.connectionCharacterStore = new CharacterStore(256, 2);
this.maxBlobSizeOnQuery = configuration.getMaxBlobSizeOnQuery();
this.dumpNetworkTraffic = configuration.getDumpNetworkTraffic();
this.idleSendCountBeforeGivingUp = configuration.getIdleSendCountBeforeGivingUp();
this.idleRecvCountBeforeGivingUp = configuration.getIdleRecvCountBeforeGivingUp();
this.serverVersion = configuration.getServerVersion();
this.authenticator = new PGBasicAuthenticator(configuration.getDefaultUsername(), configuration.getDefaultPassword());
}
public static int getInt(long address) {
int b = Unsafe.getUnsafe().getByte(address) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 1) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 2) & 0xff;
return (b << 8) | Unsafe.getUnsafe().getByte(address + 3) & 0xff;
}
public static long getLong(long address) {
long b = Unsafe.getUnsafe().getByte(address) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 1) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 2) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 3) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 4) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 5) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 6) & 0xff;
return (b << 8) | Unsafe.getUnsafe().getByte(address + 7) & 0xff;
}
public static short getShort(long address) {
int b = Unsafe.getUnsafe().getByte(address) & 0xff;
return (short) ((b << 8) | Unsafe.getUnsafe().getByte(address + 1) & 0xff);
}
public static long getStringLength(long x, long limit) {
return Unsafe.getUnsafe().getByte(x) == 0 ? x : getStringLengthTedious(x, limit);
}
public static long getStringLengthTedious(long x, long limit) {
// calculate length
for (long i = x; i < limit; i++) {
if (Unsafe.getUnsafe().getByte(i) == 0) {
return i;
}
}
return -1;
}
public static void putInt(long address, int value) {
Unsafe.getUnsafe().putByte(address, (byte) (value >>> 24));
Unsafe.getUnsafe().putByte(address + 1, (byte) (value >>> 16));
Unsafe.getUnsafe().putByte(address + 2, (byte) (value >>> 8));
Unsafe.getUnsafe().putByte(address + 3, (byte) (value));
}
public static void putShort(long address, short value) {
Unsafe.getUnsafe().putByte(address, (byte) (value >>> 8));
Unsafe.getUnsafe().putByte(address + 1, (byte) (value));
}
private static void ensureValueLength(int required, int valueLen) throws BadProtocolException {
if (required != valueLen) {
LOG.error().$("bad parameter value length [required=").$(required).$(", actual=").$(valueLen).$(']').$();
throw BadProtocolException.INSTANCE;
}
}
private static void ensureData(long lo, int required, long msgLimit, int j) throws BadProtocolException {
if (lo + required > msgLimit) {
LOG.info().$("not enough bytes for parameter [index=").$(j).$(']').$();
throw BadProtocolException.INSTANCE;
}
}
private static void prepareParams(PGConnectionContext.ResponseAsciiSink sink, String name, String value) {
sink.put(MESSAGE_TYPE_PARAMETER_STATUS);
final long addr = sink.skip();
sink.encodeUtf8Z(name);
sink.encodeUtf8Z(value);
sink.putLen(addr);
}
static void prepareReadyForQuery(ResponseAsciiSink responseAsciiSink) {
responseAsciiSink.put(MESSAGE_TYPE_READY_FOR_QUERY);
responseAsciiSink.putNetworkInt(Integer.BYTES + Byte.BYTES);
responseAsciiSink.put('I');
}
/**
* returns address of where parsing stopped. If there are remaining bytes left
* int the buffer they need to be passed again in parse function along with
......@@ -303,136 +452,6 @@ public class PGConnectionContext implements IOContext, Mutable {
}
}
private final long recvBuffer;
private final long sendBuffer;
private final int recvBufferSize;
private final CharacterStore connectionCharacterStore;
private final CharacterStore queryCharacterStore;
private final BindVariableService bindVariableService = new BindVariableService();
private final long sendBufferLimit;
private final int sendBufferSize;
private final ResponseAsciiSink responseAsciiSink = new ResponseAsciiSink();
private final DirectByteCharSequence dbcs = new DirectByteCharSequence();
private final int maxBlobSizeOnQuery;
private final NetworkFacade nf;
private final boolean dumpNetworkTraffic;
private final int idleSendCountBeforeGivingUp;
private final int idleRecvCountBeforeGivingUp;
private final String serverVersion;
private final PGAuthenticator authenticator;
private final SqlExecutionContextImpl sqlExecutionContext = new SqlExecutionContextImpl();
private int sendCurrentCursorTail = TAIL_NONE;
private long sendBufferPtr;
private boolean requireInitalMessage = false;
private long recvBufferWriteOffset = 0;
private long recvBufferReadOffset = 0;
private int bufferRemainingOffset = 0;
private int bufferRemainingSize = 0;
private RecordCursor currentCursor = null;
private RecordCursorFactory currentFactory = null;
private long fd;
private CharSequence queryText;
private CharSequence username;
private boolean authenticationRequired = true;
public PGConnectionContext(PGWireConfiguration configuration) {
this.nf = configuration.getNetworkFacade();
this.recvBufferSize = Numbers.ceilPow2(configuration.getRecvBufferSize());
this.recvBuffer = Unsafe.malloc(this.recvBufferSize);
this.sendBufferSize = Numbers.ceilPow2(configuration.getSendBufferSize());
this.sendBuffer = Unsafe.malloc(this.sendBufferSize);
this.sendBufferPtr = sendBuffer;
this.sendBufferLimit = sendBuffer + sendBufferSize;
this.queryCharacterStore = new CharacterStore(
configuration.getCharacterStoreCapacity(),
configuration.getCharacterStorePoolCapacity()
);
this.connectionCharacterStore = new CharacterStore(256, 2);
this.maxBlobSizeOnQuery = configuration.getMaxBlobSizeOnQuery();
this.dumpNetworkTraffic = configuration.getDumpNetworkTraffic();
this.idleSendCountBeforeGivingUp = configuration.getIdleSendCountBeforeGivingUp();
this.idleRecvCountBeforeGivingUp = configuration.getIdleRecvCountBeforeGivingUp();
this.serverVersion = configuration.getServerVersion();
this.authenticator = new PGBasicAuthenticator(configuration.getDefaultUsername(), configuration.getDefaultPassword());
}
public static int getInt(long address) {
int b = Unsafe.getUnsafe().getByte(address) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 1) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 2) & 0xff;
return (b << 8) | Unsafe.getUnsafe().getByte(address + 3) & 0xff;
}
public static long getLong(long address) {
long b = Unsafe.getUnsafe().getByte(address) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 1) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 2) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 3) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 4) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 5) & 0xff;
b = (b << 8) | Unsafe.getUnsafe().getByte(address + 6) & 0xff;
return (b << 8) | Unsafe.getUnsafe().getByte(address + 7) & 0xff;
}
public static short getShort(long address) {
int b = Unsafe.getUnsafe().getByte(address) & 0xff;
return (short) ((b << 8) | Unsafe.getUnsafe().getByte(address + 1) & 0xff);
}
public static long getStringLength(long x, long limit) {
return Unsafe.getUnsafe().getByte(x) == 0 ? x : getStringLengthTedious(x, limit);
}
public static long getStringLengthTedious(long x, long limit) {
// calculate length
for (long i = x; i < limit; i++) {
if (Unsafe.getUnsafe().getByte(i) == 0) {
return i;
}
}
return -1;
}
public static void putInt(long address, int value) {
Unsafe.getUnsafe().putByte(address, (byte) (value >>> 24));
Unsafe.getUnsafe().putByte(address + 1, (byte) (value >>> 16));
Unsafe.getUnsafe().putByte(address + 2, (byte) (value >>> 8));
Unsafe.getUnsafe().putByte(address + 3, (byte) (value));
}
public static void putShort(long address, short value) {
Unsafe.getUnsafe().putByte(address, (byte) (value >>> 8));
Unsafe.getUnsafe().putByte(address + 1, (byte) (value));
}
private static void ensureValueLength(int required, int valueLen) throws BadProtocolException {
if (required != valueLen) {
LOG.error().$("bad parameter value length [required=").$(required).$(", actual=").$(valueLen).$(']').$();
throw BadProtocolException.INSTANCE;
}
}
private static void ensureData(long lo, int required, long msgLimit, int j) throws BadProtocolException {
if (lo + required > msgLimit) {
LOG.info().$("not enough bytes for parameter [index=").$(j).$(']').$();
throw BadProtocolException.INSTANCE;
}
}
private static void prepareParams(PGConnectionContext.ResponseAsciiSink sink, String name, String value) {
sink.put(MESSAGE_TYPE_PARAMETER_STATUS);
final long addr = sink.skip();
sink.encodeUtf8Z(name);
sink.encodeUtf8Z(value);
sink.putLen(addr);
}
static void prepareReadyForQuery(ResponseAsciiSink responseAsciiSink) {
responseAsciiSink.put(MESSAGE_TYPE_READY_FOR_QUERY);
responseAsciiSink.putNetworkInt(Integer.BYTES + Byte.BYTES);
responseAsciiSink.put('I');
}
@Override
public void clear() {
sendCurrentCursorTail = TAIL_NONE;
......@@ -946,27 +965,10 @@ public class PGConnectionContext implements IOContext, Mutable {
}
}
responseAsciiSink.putLen(addr);
transientCopyBuffer = Unsafe.malloc(1024 * 1024);
send();
}
static {
// todo: this should be sparse array
// change after we have good test coverage
typeOidMap.put(ColumnType.STRING, PG_VARCHAR); // VARCHAR
typeOidMap.put(ColumnType.TIMESTAMP, PG_TIMESTAMP); // TIMESTAMPZ
typeOidMap.put(ColumnType.DOUBLE, PG_FLOAT8); // FLOAT8
typeOidMap.put(ColumnType.FLOAT, PG_FLOAT4); // FLOAT4
typeOidMap.put(ColumnType.INT, PG_INT4); // INT4
typeOidMap.put(ColumnType.SHORT, PG_INT2); // INT2
typeOidMap.put(ColumnType.CHAR, PG_CHAR);
typeOidMap.put(ColumnType.SYMBOL, PG_VARCHAR); // NAME
typeOidMap.put(ColumnType.LONG, PG_INT8); // INT8
typeOidMap.put(ColumnType.BYTE, PG_INT2); // INT2
typeOidMap.put(ColumnType.BOOLEAN, PG_BOOL); // BOOL
typeOidMap.put(ColumnType.DATE, PG_TIMESTAMP); // DATE
typeOidMap.put(ColumnType.BINARY, PG_BYTEA); // BYTEA
}
private void parseQuery(
CharSequence query,
@Transient SqlCompiler compiler,
......
......@@ -39,10 +39,6 @@ public interface GroupByFunction extends Function {
throw new UnsupportedOperationException();
}
default void setDate(MapValue mapValue, long value) {
throw new UnsupportedOperationException();
}
default void setDouble(MapValue mapValue, double value) {
throw new UnsupportedOperationException();
}
......@@ -64,8 +60,4 @@ public interface GroupByFunction extends Function {
default void setShort(MapValue mapValue, short value) {
throw new UnsupportedOperationException();
}
default void setTimestamp(MapValue mapValue, long value) {
throw new UnsupportedOperationException();
}
}
......@@ -50,7 +50,7 @@ public class MaxDoubleGroupByFunction extends DoubleFunction implements GroupByF
public void computeNext(MapValue mapValue, Record record) {
double max = mapValue.getDouble(valueIndex);
double next = value.getDouble(record);
if (next > max) {
if (next > max || Double.isNaN(max)) {
mapValue.putDouble(valueIndex, next);
}
}
......
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.ArrayColumnTypes;
import io.questdb.cairo.ColumnType;
import io.questdb.cairo.map.MapValue;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.engine.functions.ByteFunction;
import io.questdb.griffin.engine.functions.GroupByFunction;
import org.jetbrains.annotations.NotNull;
public class MinByteGroupByFunction extends ByteFunction implements GroupByFunction {
private final Function value;
private int valueIndex;
public MinByteGroupByFunction(int position, @NotNull Function value) {
super(position);
this.value = value;
}
@Override
public void computeFirst(MapValue mapValue, Record record) {
mapValue.putByte(valueIndex, value.getByte(record));
}
@Override
public void computeNext(MapValue mapValue, Record record) {
byte min = mapValue.getByte(valueIndex);
byte next = value.getByte(record);
if (next < min) {
mapValue.putByte(valueIndex, next);
}
}
@Override
public void pushValueTypes(ArrayColumnTypes columnTypes) {
this.valueIndex = columnTypes.getColumnCount();
columnTypes.add(ColumnType.BYTE);
}
@Override
public void setByte(MapValue mapValue, byte value) {
mapValue.putByte(valueIndex, value);
}
@Override
public void setNull(MapValue mapValue) {
mapValue.putByte(valueIndex, (byte) 0);
}
@Override
public byte getByte(Record rec) {
return rec.getByte(valueIndex);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.FunctionFactory;
import io.questdb.std.ObjList;
public class MinByteGroupByFunctionFactory implements FunctionFactory {
@Override
public String getSignature() {
return "min(B)";
}
@Override
public boolean isGroupBy() {
return true;
}
@Override
public Function newInstance(ObjList<Function> args, int position, CairoConfiguration configuration) {
return new MinByteGroupByFunction(position, args.getQuick(0));
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.ArrayColumnTypes;
import io.questdb.cairo.ColumnType;
import io.questdb.cairo.map.MapValue;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.engine.functions.CharFunction;
import io.questdb.griffin.engine.functions.GroupByFunction;
import org.jetbrains.annotations.NotNull;
public class MinCharGroupByFunction extends CharFunction implements GroupByFunction {
private final Function value;
private int valueIndex;
public MinCharGroupByFunction(int position, @NotNull Function value) {
super(position);
this.value = value;
}
@Override
public void computeFirst(MapValue mapValue, Record record) {
mapValue.putChar(valueIndex, value.getChar(record));
}
@Override
public void computeNext(MapValue mapValue, Record record) {
char min = mapValue.getChar(valueIndex);
char next = value.getChar(record);
if (next > 0 && next < min) {
mapValue.putChar(valueIndex, next);
}
}
@Override
public void pushValueTypes(ArrayColumnTypes columnTypes) {
this.valueIndex = columnTypes.getColumnCount();
columnTypes.add(ColumnType.CHAR);
}
@Override
public void setNull(MapValue mapValue) {
mapValue.putChar(valueIndex, (char) 0);
}
@Override
public char getChar(Record rec) {
return rec.getChar(valueIndex);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.FunctionFactory;
import io.questdb.std.ObjList;
public class MinCharGroupByFunctionFactory implements FunctionFactory {
@Override
public String getSignature() {
return "min(A)";
}
@Override
public boolean isGroupBy() {
return true;
}
@Override
public Function newInstance(ObjList<Function> args, int position, CairoConfiguration configuration) {
return new MinCharGroupByFunction(position, args.getQuick(0));
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.ArrayColumnTypes;
import io.questdb.cairo.ColumnType;
import io.questdb.cairo.map.MapValue;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.engine.functions.DoubleFunction;
import io.questdb.griffin.engine.functions.GroupByFunction;
import org.jetbrains.annotations.NotNull;
public class MinDoubleGroupByFunction extends DoubleFunction implements GroupByFunction {
private final Function value;
private int valueIndex;
public MinDoubleGroupByFunction(int position, @NotNull Function value) {
super(position);
this.value = value;
}
@Override
public void computeFirst(MapValue mapValue, Record record) {
mapValue.putDouble(valueIndex, value.getDouble(record));
}
@Override
public void computeNext(MapValue mapValue, Record record) {
double min = mapValue.getDouble(valueIndex);
double next = value.getDouble(record);
if (next < min || Double.isNaN(min)) {
mapValue.putDouble(valueIndex, next);
}
}
@Override
public void pushValueTypes(ArrayColumnTypes columnTypes) {
this.valueIndex = columnTypes.getColumnCount();
columnTypes.add(ColumnType.DOUBLE);
}
@Override
public void setDouble(MapValue mapValue, double value) {
mapValue.putDouble(valueIndex, value);
}
@Override
public void setNull(MapValue mapValue) {
mapValue.putDouble(valueIndex, Double.NaN);
}
@Override
public double getDouble(Record rec) {
return rec.getDouble(valueIndex);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.FunctionFactory;
import io.questdb.std.ObjList;
public class MinDoubleGroupByFunctionFactory implements FunctionFactory {
@Override
public String getSignature() {
return "min(D)";
}
@Override
public boolean isGroupBy() {
return true;
}
@Override
public Function newInstance(ObjList<Function> args, int position, CairoConfiguration configuration) {
return new MinDoubleGroupByFunction(position, args.getQuick(0));
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.ArrayColumnTypes;
import io.questdb.cairo.ColumnType;
import io.questdb.cairo.map.MapValue;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.engine.functions.FloatFunction;
import io.questdb.griffin.engine.functions.GroupByFunction;
import org.jetbrains.annotations.NotNull;
public class MinFloatGroupByFunction extends FloatFunction implements GroupByFunction {
private final Function value;
private int valueIndex;
public MinFloatGroupByFunction(int position, @NotNull Function value) {
super(position);
this.value = value;
}
@Override
public void computeFirst(MapValue mapValue, Record record) {
mapValue.putFloat(valueIndex, value.getFloat(record));
}
@Override
public void computeNext(MapValue mapValue, Record record) {
float min = mapValue.getFloat(valueIndex);
float next = value.getFloat(record);
if (next < min || Float.isNaN(min)) {
mapValue.putFloat(valueIndex, next);
}
}
@Override
public void pushValueTypes(ArrayColumnTypes columnTypes) {
this.valueIndex = columnTypes.getColumnCount();
columnTypes.add(ColumnType.FLOAT);
}
@Override
public void setFloat(MapValue mapValue, float value) {
mapValue.putFloat(valueIndex, value);
}
@Override
public void setNull(MapValue mapValue) {
mapValue.putFloat(valueIndex, Float.NaN);
}
@Override
public float getFloat(Record rec) {
return rec.getFloat(valueIndex);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.FunctionFactory;
import io.questdb.std.ObjList;
public class MinFloatGroupByFunctionFactory implements FunctionFactory {
@Override
public String getSignature() {
return "min(F)";
}
@Override
public boolean isGroupBy() {
return true;
}
@Override
public Function newInstance(ObjList<Function> args, int position, CairoConfiguration configuration) {
return new MinFloatGroupByFunction(position, args.getQuick(0));
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.ArrayColumnTypes;
import io.questdb.cairo.ColumnType;
import io.questdb.cairo.map.MapValue;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.engine.functions.GroupByFunction;
import io.questdb.griffin.engine.functions.IntFunction;
import io.questdb.std.Numbers;
import org.jetbrains.annotations.NotNull;
public class MinIntGroupByFunction extends IntFunction implements GroupByFunction {
private final Function value;
private int valueIndex;
public MinIntGroupByFunction(int position, @NotNull Function value) {
super(position);
this.value = value;
}
@Override
public void computeFirst(MapValue mapValue, Record record) {
mapValue.putInt(valueIndex, value.getInt(record));
}
@Override
public void computeNext(MapValue mapValue, Record record) {
int min = mapValue.getInt(valueIndex);
int next = value.getInt(record);
if (next != Numbers.INT_NaN && next < min || min == Numbers.INT_NaN) {
mapValue.putInt(valueIndex, next);
}
}
@Override
public void pushValueTypes(ArrayColumnTypes columnTypes) {
this.valueIndex = columnTypes.getColumnCount();
columnTypes.add(ColumnType.INT);
}
@Override
public void setInt(MapValue mapValue, int value) {
mapValue.putInt(valueIndex, value);
}
@Override
public void setNull(MapValue mapValue) {
mapValue.putInt(valueIndex, Numbers.INT_NaN);
}
@Override
public int getInt(Record rec) {
return rec.getInt(valueIndex);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.FunctionFactory;
import io.questdb.std.ObjList;
public class MinIntGroupByFunctionFactory implements FunctionFactory {
@Override
public String getSignature() {
return "min(I)";
}
@Override
public boolean isGroupBy() {
return true;
}
@Override
public Function newInstance(ObjList<Function> args, int position, CairoConfiguration configuration) {
return new MinIntGroupByFunction(position, args.getQuick(0));
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.ArrayColumnTypes;
import io.questdb.cairo.ColumnType;
import io.questdb.cairo.map.MapValue;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.engine.functions.GroupByFunction;
import io.questdb.griffin.engine.functions.LongFunction;
import io.questdb.std.Numbers;
import org.jetbrains.annotations.NotNull;
public class MinLongGroupByFunction extends LongFunction implements GroupByFunction {
private final Function value;
private int valueIndex;
public MinLongGroupByFunction(int position, @NotNull Function value) {
super(position);
this.value = value;
}
@Override
public void computeFirst(MapValue mapValue, Record record) {
mapValue.putLong(valueIndex, value.getLong(record));
}
@Override
public void computeNext(MapValue mapValue, Record record) {
long min = mapValue.getLong(valueIndex);
long next = value.getLong(record);
if (next != Numbers.LONG_NaN && next < min || min == Numbers.LONG_NaN) {
mapValue.putLong(valueIndex, next);
}
}
@Override
public void pushValueTypes(ArrayColumnTypes columnTypes) {
this.valueIndex = columnTypes.getColumnCount();
columnTypes.add(ColumnType.LONG);
}
@Override
public void setLong(MapValue mapValue, long value) {
mapValue.putLong(valueIndex, value);
}
@Override
public void setNull(MapValue mapValue) {
mapValue.putLong(valueIndex, Numbers.LONG_NaN);
}
@Override
public long getLong(Record rec) {
return rec.getLong(valueIndex);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.FunctionFactory;
import io.questdb.std.ObjList;
public class MinLongGroupByFunctionFactory implements FunctionFactory {
@Override
public String getSignature() {
return "min(L)";
}
@Override
public boolean isGroupBy() {
return true;
}
@Override
public Function newInstance(ObjList<Function> args, int position, CairoConfiguration configuration) {
return new MinLongGroupByFunction(position, args.getQuick(0));
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.ArrayColumnTypes;
import io.questdb.cairo.ColumnType;
import io.questdb.cairo.map.MapValue;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.engine.functions.GroupByFunction;
import io.questdb.griffin.engine.functions.ShortFunction;
import org.jetbrains.annotations.NotNull;
public class MinShortGroupByFunction extends ShortFunction implements GroupByFunction {
private final Function value;
private int valueIndex;
public MinShortGroupByFunction(int position, @NotNull Function value) {
super(position);
this.value = value;
}
@Override
public void computeFirst(MapValue mapValue, Record record) {
mapValue.putShort(valueIndex, value.getShort(record));
}
@Override
public void computeNext(MapValue mapValue, Record record) {
short min = mapValue.getShort(valueIndex);
short next = value.getShort(record);
if (next < min) {
mapValue.putShort(valueIndex, next);
}
}
@Override
public void pushValueTypes(ArrayColumnTypes columnTypes) {
this.valueIndex = columnTypes.getColumnCount();
columnTypes.add(ColumnType.SHORT);
}
@Override
public void setShort(MapValue mapValue, short value) {
mapValue.putShort(valueIndex, value);
}
@Override
public void setNull(MapValue mapValue) {
mapValue.putShort(valueIndex, (short) 0);
}
@Override
public short getShort(Record rec) {
return rec.getShort(valueIndex);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.FunctionFactory;
import io.questdb.std.ObjList;
public class MinShortGroupByFunctionFactory implements FunctionFactory {
@Override
public String getSignature() {
return "min(E)";
}
@Override
public boolean isGroupBy() {
return true;
}
@Override
public Function newInstance(ObjList<Function> args, int position, CairoConfiguration configuration) {
return new MinShortGroupByFunction(position, args.getQuick(0));
}
}
......@@ -21,6 +21,29 @@
#
################################################################################
################################################################################
# ___ _ ____ ____
# / _ \ _ _ ___ ___| |_| _ \| __ )
# | | | | | | |/ _ \/ __| __| | | | _ \
# | |_| | |_| | __/\__ \ |_| |_| | |_) |
# \__\_\\__,_|\___||___/\__|____/|____/
#
# Copyright (C) 2014-2019 Appsicle
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3,
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
# logical operations
io.questdb.griffin.engine.functions.bool.OrFunctionFactory
io.questdb.griffin.engine.functions.bool.AndFunctionFactory
......@@ -152,6 +175,16 @@ io.questdb.griffin.engine.functions.groupby.SumLongGroupByFunctionFactory
# 'max' group
io.questdb.griffin.engine.functions.groupby.MaxDoubleGroupByFunctionFactory
# 'min' group
io.questdb.griffin.engine.functions.groupby.MinDoubleGroupByFunctionFactory
io.questdb.griffin.engine.functions.groupby.MinFloatGroupByFunctionFactory
io.questdb.griffin.engine.functions.groupby.MinLongGroupByFunctionFactory
io.questdb.griffin.engine.functions.groupby.MinIntGroupByFunctionFactory
io.questdb.griffin.engine.functions.groupby.MinShortGroupByFunctionFactory
io.questdb.griffin.engine.functions.groupby.MinByteGroupByFunctionFactory
io.questdb.griffin.engine.functions.groupby.MinCharGroupByFunctionFactory
# 'count' group by function
io.questdb.griffin.engine.functions.groupby.CountGroupByFunctionFactory
......
......@@ -175,11 +175,6 @@ public class GroupByFunctionTest {
function.setByte(null, (byte) 0);
}
@Test(expected = UnsupportedOperationException.class)
public void testSetDate() {
function.setDate(null, 0);
}
@Test(expected = UnsupportedOperationException.class)
public void testSetDouble() {
function.setDouble(null, 0);
......@@ -204,9 +199,4 @@ public class GroupByFunctionTest {
public void testSetShort() {
function.setShort(null, (short) 0);
}
@Test(expected = UnsupportedOperationException.class)
public void testSetTimestamp() {
function.setTimestamp(null, 0);
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MaxDoubleGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f double)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putDouble(0, rnd.nextDouble2());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select max(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0.9856290845874263, record.getDouble(0), 0.0001);
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f double)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select max(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertTrue(Double.isNaN(record.getDouble(0)));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f double)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putDouble(0, rnd.nextDouble2());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select max(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0.9856290845874263, record.getDouble(0), 0.0001);
}
}
}
@Test
public void testSampleFill() throws Exception {
assertQuery("b\tmax\tk\n" +
"\t0.975019885373\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.868515430542\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t0.565942913986\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t0.844525817721\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t0.977110314605\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t0.675250954711\t1970-01-03T00:00:00.000000Z\n" +
"\t0.894091712658\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t0.944165897553\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t0.945721264691\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t0.945589300480\t1970-01-03T03:00:00.000000Z\n" +
"RXGZ\t0.843845956391\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t0.736511521557\t1970-01-03T03:00:00.000000Z\n" +
"\t0.942367162414\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t0.819655474584\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t0.578074627654\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.690197677807\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t0.434613581293\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t1.216191574671\t1970-01-03T06:00:00.000000Z\n" +
"\t0.837989199122\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t0.727211975593\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t0.773222984852\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t0.132715641029\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t0.210559954828\t1970-01-03T09:00:00.000000Z\n" +
"CPSW\t1.486661884651\t1970-01-03T09:00:00.000000Z\n",
"select b, max(a), k from x sample by 3h fill(linear)",
"create table x as " +
"(" +
"select" +
" rnd_double(0) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(172800000000), 360000000) k" +
" from" +
" long_sequence(100)" +
") timestamp(k) partition by NONE",
"k",
"insert into x select * from (" +
"select" +
" rnd_double(0) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(277200000000), 360000000) k" +
" from" +
" long_sequence(35)" +
") timestamp(k)",
"b\tmax\tk\n" +
"\t0.975019885373\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.868515430542\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t0.565942913986\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t0.844525817721\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t0.977110314605\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t0.675250954711\t1970-01-03T00:00:00.000000Z\n" +
"CGFN\t2.717109453333\t1970-01-03T00:00:00.000000Z\n" +
"NPIW\t4.115364146194\t1970-01-03T00:00:00.000000Z\n" +
"PEVM\t-3.725890404358\t1970-01-03T00:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"\t0.894091712658\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t0.944165897553\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t0.945721264691\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t0.945589300480\t1970-01-03T03:00:00.000000Z\n" +
"RXGZ\t0.843845956391\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t0.736511521557\t1970-01-03T03:00:00.000000Z\n" +
"CGFN\t2.505608562669\t1970-01-03T03:00:00.000000Z\n" +
"NPIW\t3.750106582629\t1970-01-03T03:00:00.000000Z\n" +
"PEVM\t-3.268689246947\t1970-01-03T03:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"\t0.942367162414\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t0.819655474584\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t0.578074627654\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.690197677807\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t0.434613581293\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t1.216191574671\t1970-01-03T06:00:00.000000Z\n" +
"CGFN\t2.294107672004\t1970-01-03T06:00:00.000000Z\n" +
"NPIW\t3.384849019063\t1970-01-03T06:00:00.000000Z\n" +
"PEVM\t-2.811488089536\t1970-01-03T06:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"\t0.837989199122\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t0.727211975593\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t0.773222984852\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t0.132715641029\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t0.210559954828\t1970-01-03T09:00:00.000000Z\n" +
"CPSW\t1.486661884651\t1970-01-03T09:00:00.000000Z\n" +
"CGFN\t2.082606781340\t1970-01-03T09:00:00.000000Z\n" +
"NPIW\t3.019591455498\t1970-01-03T09:00:00.000000Z\n" +
"PEVM\t-2.354286932125\t1970-01-03T09:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"\t0.846851259786\t1970-01-03T12:00:00.000000Z\n" +
"VTJW\t0.726790495120\t1970-01-03T12:00:00.000000Z\n" +
"RXGZ\t0.764226273379\t1970-01-03T12:00:00.000000Z\n" +
"PEHN\t-0.169182299235\t1970-01-03T12:00:00.000000Z\n" +
"HYRX\t-0.156954717997\t1970-01-03T12:00:00.000000Z\n" +
"CPSW\t1.757132194631\t1970-01-03T12:00:00.000000Z\n" +
"CGFN\t1.871105890675\t1970-01-03T12:00:00.000000Z\n" +
"NPIW\t2.654333891932\t1970-01-03T12:00:00.000000Z\n" +
"PEVM\t-1.897085774714\t1970-01-03T12:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"\t0.855713320449\t1970-01-03T15:00:00.000000Z\n" +
"VTJW\t0.680358005387\t1970-01-03T15:00:00.000000Z\n" +
"RXGZ\t0.801240571164\t1970-01-03T15:00:00.000000Z\n" +
"PEHN\t-0.471080239499\t1970-01-03T15:00:00.000000Z\n" +
"HYRX\t-0.524469390823\t1970-01-03T15:00:00.000000Z\n" +
"CPSW\t2.027602504611\t1970-01-03T15:00:00.000000Z\n" +
"CGFN\t1.659605000011\t1970-01-03T15:00:00.000000Z\n" +
"NPIW\t2.289076328367\t1970-01-03T15:00:00.000000Z\n" +
"PEVM\t-1.439884617304\t1970-01-03T15:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"\t0.864575381112\t1970-01-03T18:00:00.000000Z\n" +
"VTJW\t0.633925515655\t1970-01-03T18:00:00.000000Z\n" +
"RXGZ\t0.838254868950\t1970-01-03T18:00:00.000000Z\n" +
"PEHN\t-0.772978179763\t1970-01-03T18:00:00.000000Z\n" +
"HYRX\t-0.891984063649\t1970-01-03T18:00:00.000000Z\n" +
"CPSW\t2.298072814591\t1970-01-03T18:00:00.000000Z\n" +
"CGFN\t1.448104109346\t1970-01-03T18:00:00.000000Z\n" +
"NPIW\t1.923818764802\t1970-01-03T18:00:00.000000Z\n" +
"PEVM\t-0.982683459893\t1970-01-03T18:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"\t0.873437441775\t1970-01-03T21:00:00.000000Z\n" +
"VTJW\t0.587493025923\t1970-01-03T21:00:00.000000Z\n" +
"RXGZ\t0.875269166736\t1970-01-03T21:00:00.000000Z\n" +
"PEHN\t-1.074876120027\t1970-01-03T21:00:00.000000Z\n" +
"HYRX\t-1.259498736475\t1970-01-03T21:00:00.000000Z\n" +
"CPSW\t2.568543124571\t1970-01-03T21:00:00.000000Z\n" +
"CGFN\t1.236603218682\t1970-01-03T21:00:00.000000Z\n" +
"NPIW\t1.558561201236\t1970-01-03T21:00:00.000000Z\n" +
"PEVM\t-0.525482302482\t1970-01-03T21:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"\t0.882299502439\t1970-01-04T00:00:00.000000Z\n" +
"VTJW\t0.541060536191\t1970-01-04T00:00:00.000000Z\n" +
"RXGZ\t0.912283464522\t1970-01-04T00:00:00.000000Z\n" +
"PEHN\t-1.376774060291\t1970-01-04T00:00:00.000000Z\n" +
"HYRX\t-1.627013409301\t1970-01-04T00:00:00.000000Z\n" +
"CPSW\t2.839013434550\t1970-01-04T00:00:00.000000Z\n" +
"CGFN\t1.025102328017\t1970-01-04T00:00:00.000000Z\n" +
"NPIW\t1.193303637671\t1970-01-04T00:00:00.000000Z\n" +
"PEVM\t-0.068281145071\t1970-01-04T00:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"\t0.891161563102\t1970-01-04T03:00:00.000000Z\n" +
"CGFN\t0.813601437353\t1970-01-04T03:00:00.000000Z\n" +
"NPIW\t0.828046074105\t1970-01-04T03:00:00.000000Z\n" +
"PEVM\t0.388920012340\t1970-01-04T03:00:00.000000Z\n" +
"VTJW\t0.494628046458\t1970-01-04T03:00:00.000000Z\n" +
"RXGZ\t0.949297762308\t1970-01-04T03:00:00.000000Z\n" +
"PEHN\t-1.678672000555\t1970-01-04T03:00:00.000000Z\n" +
"HYRX\t-1.994528082127\t1970-01-04T03:00:00.000000Z\n" +
"CPSW\t3.109483744530\t1970-01-04T03:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"WGRM\t0.851484980066\t1970-01-04T06:00:00.000000Z\n" +
"CGFN\t0.602100546689\t1970-01-04T06:00:00.000000Z\n" +
"\t0.943513809864\t1970-01-04T06:00:00.000000Z\n" +
"PEVM\t0.846121169751\t1970-01-04T06:00:00.000000Z\n" +
"ZNFK\t0.780618344203\t1970-01-04T06:00:00.000000Z\n" +
"NPIW\t0.462788510540\t1970-01-04T06:00:00.000000Z\n" +
"VTJW\t0.448195556726\t1970-01-04T06:00:00.000000Z\n" +
"RXGZ\t0.986312060094\t1970-01-04T06:00:00.000000Z\n" +
"PEHN\t-1.980569940819\t1970-01-04T06:00:00.000000Z\n" +
"HYRX\t-2.362042754953\t1970-01-04T06:00:00.000000Z\n" +
"CPSW\t3.379954054510\t1970-01-04T06:00:00.000000Z\n",
true);
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MinByteGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f byte)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putByte(0, rnd.nextByte());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(-127, record.getByte(0));
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f byte)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0, record.getByte(0));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f byte)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putByte(0, rnd.nextByte());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(-127, record.getByte(0));
}
}
}
@Test
public void testSampleFill() throws Exception {
assertQuery("b\tmin\tk\n" +
"\t7\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t4\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t23\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t6\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t6\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t10\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t12\t1970-01-03T03:00:00.000000Z\n" +
"\t4\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t24\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t24\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t5\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t17\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t16\t1970-01-03T06:00:00.000000Z\n" +
"\t9\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t8\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t7\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t6\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t15\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t8\t1970-01-03T09:00:00.000000Z\n" +
"\t8\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t8\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t29\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t18\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t11\t1970-01-03T09:00:00.000000Z\n",
"select b, min(a), k from x sample by 3h fill(linear)",
"create table x as " +
"(" +
"select" +
" rnd_byte(4,30) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(172800000000), 360000000) k" +
" from" +
" long_sequence(100)" +
") timestamp(k) partition by NONE",
"k",
"insert into x select * from (" +
"select" +
" rnd_byte(4,30) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(277200000000), 360000000) k" +
" from" +
" long_sequence(35)" +
") timestamp(k)",
"b\tmin\tk\n" +
"\t7\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t4\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t23\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t6\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t6\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t10\t1970-01-03T00:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T00:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T00:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T00:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T00:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t12\t1970-01-03T03:00:00.000000Z\n" +
"\t4\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t24\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t24\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t5\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t17\t1970-01-03T03:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T03:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T03:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T03:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T03:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t16\t1970-01-03T06:00:00.000000Z\n" +
"\t9\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t8\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t7\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t6\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t15\t1970-01-03T06:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T06:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T06:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T06:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T06:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t8\t1970-01-03T09:00:00.000000Z\n" +
"\t8\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t8\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t29\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t18\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t11\t1970-01-03T09:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T09:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T09:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T09:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T09:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T09:00:00.000000Z\n" +
"\t8\t1970-01-03T12:00:00.000000Z\n" +
"VTJW\t51\t1970-01-03T12:00:00.000000Z\n" +
"RXGZ\t21\t1970-01-03T12:00:00.000000Z\n" +
"PEHN\t10\t1970-01-03T12:00:00.000000Z\n" +
"CPSW\t0\t1970-01-03T12:00:00.000000Z\n" +
"HYRX\t14\t1970-01-03T12:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T12:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T12:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T12:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T12:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T12:00:00.000000Z\n" +
"\t8\t1970-01-03T15:00:00.000000Z\n" +
"VTJW\t73\t1970-01-03T15:00:00.000000Z\n" +
"RXGZ\t24\t1970-01-03T15:00:00.000000Z\n" +
"PEHN\t12\t1970-01-03T15:00:00.000000Z\n" +
"CPSW\t-8\t1970-01-03T15:00:00.000000Z\n" +
"HYRX\t17\t1970-01-03T15:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T15:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T15:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T15:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T15:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T15:00:00.000000Z\n" +
"\t8\t1970-01-03T18:00:00.000000Z\n" +
"VTJW\t95\t1970-01-03T18:00:00.000000Z\n" +
"RXGZ\t27\t1970-01-03T18:00:00.000000Z\n" +
"PEHN\t14\t1970-01-03T18:00:00.000000Z\n" +
"CPSW\t-16\t1970-01-03T18:00:00.000000Z\n" +
"HYRX\t20\t1970-01-03T18:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T18:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T18:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T18:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T18:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T18:00:00.000000Z\n" +
"\t8\t1970-01-03T21:00:00.000000Z\n" +
"VTJW\t117\t1970-01-03T21:00:00.000000Z\n" +
"RXGZ\t30\t1970-01-03T21:00:00.000000Z\n" +
"PEHN\t16\t1970-01-03T21:00:00.000000Z\n" +
"CPSW\t-24\t1970-01-03T21:00:00.000000Z\n" +
"HYRX\t23\t1970-01-03T21:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T21:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T21:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T21:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T21:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T21:00:00.000000Z\n" +
"\t8\t1970-01-04T00:00:00.000000Z\n" +
"VTJW\t-117\t1970-01-04T00:00:00.000000Z\n" +
"RXGZ\t33\t1970-01-04T00:00:00.000000Z\n" +
"PEHN\t18\t1970-01-04T00:00:00.000000Z\n" +
"CPSW\t-32\t1970-01-04T00:00:00.000000Z\n" +
"HYRX\t26\t1970-01-04T00:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-04T00:00:00.000000Z\n" +
"QLDG\t0\t1970-01-04T00:00:00.000000Z\n" +
"LOGI\t0\t1970-01-04T00:00:00.000000Z\n" +
"QEBN\t0\t1970-01-04T00:00:00.000000Z\n" +
"FOUS\t0\t1970-01-04T00:00:00.000000Z\n" +
"\t9\t1970-01-04T03:00:00.000000Z\n" +
"ZMZV\t9\t1970-01-04T03:00:00.000000Z\n" +
"VTJW\t-95\t1970-01-04T03:00:00.000000Z\n" +
"RXGZ\t36\t1970-01-04T03:00:00.000000Z\n" +
"PEHN\t20\t1970-01-04T03:00:00.000000Z\n" +
"CPSW\t-40\t1970-01-04T03:00:00.000000Z\n" +
"HYRX\t29\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\t0\t1970-01-04T03:00:00.000000Z\n" +
"LOGI\t0\t1970-01-04T03:00:00.000000Z\n" +
"QEBN\t0\t1970-01-04T03:00:00.000000Z\n" +
"FOUS\t0\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\t14\t1970-01-04T06:00:00.000000Z\n" +
"LOGI\t6\t1970-01-04T06:00:00.000000Z\n" +
"QEBN\t14\t1970-01-04T06:00:00.000000Z\n" +
"\t8\t1970-01-04T06:00:00.000000Z\n" +
"FOUS\t9\t1970-01-04T06:00:00.000000Z\n" +
"VTJW\t-73\t1970-01-04T06:00:00.000000Z\n" +
"RXGZ\t39\t1970-01-04T06:00:00.000000Z\n" +
"PEHN\t22\t1970-01-04T06:00:00.000000Z\n" +
"CPSW\t-48\t1970-01-04T06:00:00.000000Z\n" +
"HYRX\t32\t1970-01-04T06:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-04T06:00:00.000000Z\n",
true);
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MinCharGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f char)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putChar(0, rnd.nextChar());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(66, record.getChar(0));
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f char)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0, record.getChar(0));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f char)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putChar(0, rnd.nextChar());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0, record.getChar(0));
}
}
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MinDoubleGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f double)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putDouble(0, rnd.nextDouble2());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0.0011075139045715332, record.getDouble(0), 0.0001);
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f double)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertTrue(Double.isNaN(record.getDouble(0)));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f double)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putDouble(0, rnd.nextDouble2());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0.0011075139045715332, record.getDouble(0), 0.0001);
}
}
}
@Test
public void testSampleFill() throws Exception {
assertQuery("b\tmin\tk\n" +
"\t0.097505744144\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.421776884197\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t0.239052901085\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t0.121056302736\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t0.120261224128\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t0.120241608757\t1970-01-03T00:00:00.000000Z\n" +
"\t0.039931248213\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t0.218586583503\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t0.029080850169\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t0.051584599293\t1970-01-03T03:00:00.000000Z\n" +
"RXGZ\t0.659082927506\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t0.736511521557\t1970-01-03T03:00:00.000000Z\n" +
"\t0.078280206815\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t0.483525620204\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t0.234937936017\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.007985454959\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t0.235077540295\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-0.062079908420\t1970-01-03T06:00:00.000000Z\n" +
"\t0.474068460469\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t0.031921080750\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t0.491990017163\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t-0.266356440968\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t0.418291272742\t1970-01-03T09:00:00.000000Z\n" +
"CPSW\t-0.153240667009\t1970-01-03T09:00:00.000000Z\n",
"select b, min(a), k from x sample by 3h fill(linear)",
"create table x as " +
"(" +
"select" +
" rnd_double(0) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(172800000000), 360000000) k" +
" from" +
" long_sequence(100)" +
") timestamp(k) partition by NONE",
"k",
"insert into x select * from (" +
"select" +
" rnd_double(0) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(277200000000), 360000000) k" +
" from" +
" long_sequence(35)" +
") timestamp(k)",
"b\tmin\tk\n" +
"\t0.097505744144\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.421776884197\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t0.239052901085\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t0.121056302736\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t0.120261224128\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t0.120241608757\t1970-01-03T00:00:00.000000Z\n" +
"CGFN\t3.029975503129\t1970-01-03T00:00:00.000000Z\n" +
"NPIW\t4.115364146194\t1970-01-03T00:00:00.000000Z\n" +
"PEVM\t-3.154296897767\t1970-01-03T00:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"\t0.039931248213\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t0.218586583503\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t0.029080850169\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t0.051584599293\t1970-01-03T03:00:00.000000Z\n" +
"RXGZ\t0.659082927506\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t0.736511521557\t1970-01-03T03:00:00.000000Z\n" +
"CGFN\t2.783711718043\t1970-01-03T03:00:00.000000Z\n" +
"NPIW\t3.750106582629\t1970-01-03T03:00:00.000000Z\n" +
"PEVM\t-2.760606129977\t1970-01-03T03:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"\t0.078280206815\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t0.483525620204\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t0.234937936017\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.007985454959\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t0.235077540295\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-0.062079908420\t1970-01-03T06:00:00.000000Z\n" +
"CGFN\t2.537447932957\t1970-01-03T06:00:00.000000Z\n" +
"NPIW\t3.384849019063\t1970-01-03T06:00:00.000000Z\n" +
"PEVM\t-2.366915362188\t1970-01-03T06:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"\t0.474068460469\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t0.031921080750\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t0.491990017163\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t-0.266356440968\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t0.418291272742\t1970-01-03T09:00:00.000000Z\n" +
"CPSW\t-0.153240667009\t1970-01-03T09:00:00.000000Z\n" +
"CGFN\t2.291184147871\t1970-01-03T09:00:00.000000Z\n" +
"NPIW\t3.019591455498\t1970-01-03T09:00:00.000000Z\n" +
"PEVM\t-1.973224594398\t1970-01-03T09:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"\t0.413469242415\t1970-01-03T12:00:00.000000Z\n" +
"VTJW\t0.500454414123\t1970-01-03T12:00:00.000000Z\n" +
"RXGZ\t0.055856706541\t1970-01-03T12:00:00.000000Z\n" +
"PEHN\t-0.767790422230\t1970-01-03T12:00:00.000000Z\n" +
"HYRX\t0.601644609467\t1970-01-03T12:00:00.000000Z\n" +
"CPSW\t-0.244401425598\t1970-01-03T12:00:00.000000Z\n" +
"CGFN\t2.044920362784\t1970-01-03T12:00:00.000000Z\n" +
"NPIW\t2.654333891932\t1970-01-03T12:00:00.000000Z\n" +
"PEVM\t-1.579533826608\t1970-01-03T12:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"\t0.352870024362\t1970-01-03T15:00:00.000000Z\n" +
"VTJW\t0.508918811082\t1970-01-03T15:00:00.000000Z\n" +
"RXGZ\t0.079792332332\t1970-01-03T15:00:00.000000Z\n" +
"PEHN\t-1.269224403493\t1970-01-03T15:00:00.000000Z\n" +
"HYRX\t0.784997946192\t1970-01-03T15:00:00.000000Z\n" +
"CPSW\t-0.335562184186\t1970-01-03T15:00:00.000000Z\n" +
"CGFN\t1.798656577698\t1970-01-03T15:00:00.000000Z\n" +
"NPIW\t2.289076328367\t1970-01-03T15:00:00.000000Z\n" +
"PEVM\t-1.185843058819\t1970-01-03T15:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"\t0.292270806308\t1970-01-03T18:00:00.000000Z\n" +
"VTJW\t0.517383208042\t1970-01-03T18:00:00.000000Z\n" +
"RXGZ\t0.103727958123\t1970-01-03T18:00:00.000000Z\n" +
"PEHN\t-1.770658384755\t1970-01-03T18:00:00.000000Z\n" +
"HYRX\t0.968351282916\t1970-01-03T18:00:00.000000Z\n" +
"CPSW\t-0.426722942775\t1970-01-03T18:00:00.000000Z\n" +
"CGFN\t1.552392792612\t1970-01-03T18:00:00.000000Z\n" +
"NPIW\t1.923818764802\t1970-01-03T18:00:00.000000Z\n" +
"PEVM\t-0.792152291029\t1970-01-03T18:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"\t0.231671588255\t1970-01-03T21:00:00.000000Z\n" +
"VTJW\t0.525847605001\t1970-01-03T21:00:00.000000Z\n" +
"RXGZ\t0.127663583915\t1970-01-03T21:00:00.000000Z\n" +
"PEHN\t-2.272092366017\t1970-01-03T21:00:00.000000Z\n" +
"HYRX\t1.151704619641\t1970-01-03T21:00:00.000000Z\n" +
"CPSW\t-0.517883701364\t1970-01-03T21:00:00.000000Z\n" +
"CGFN\t1.306129007526\t1970-01-03T21:00:00.000000Z\n" +
"NPIW\t1.558561201236\t1970-01-03T21:00:00.000000Z\n" +
"PEVM\t-0.398461523240\t1970-01-03T21:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"\t0.171072370201\t1970-01-04T00:00:00.000000Z\n" +
"VTJW\t0.534312001961\t1970-01-04T00:00:00.000000Z\n" +
"RXGZ\t0.151599209706\t1970-01-04T00:00:00.000000Z\n" +
"PEHN\t-2.773526347280\t1970-01-04T00:00:00.000000Z\n" +
"HYRX\t1.335057956366\t1970-01-04T00:00:00.000000Z\n" +
"CPSW\t-0.609044459952\t1970-01-04T00:00:00.000000Z\n" +
"CGFN\t1.059865222439\t1970-01-04T00:00:00.000000Z\n" +
"NPIW\t1.193303637671\t1970-01-04T00:00:00.000000Z\n" +
"PEVM\t-0.004770755450\t1970-01-04T00:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"\t0.110473152148\t1970-01-04T03:00:00.000000Z\n" +
"CGFN\t0.813601437353\t1970-01-04T03:00:00.000000Z\n" +
"NPIW\t0.828046074105\t1970-01-04T03:00:00.000000Z\n" +
"PEVM\t0.388920012340\t1970-01-04T03:00:00.000000Z\n" +
"VTJW\t0.542776398920\t1970-01-04T03:00:00.000000Z\n" +
"RXGZ\t0.175534835497\t1970-01-04T03:00:00.000000Z\n" +
"PEHN\t-3.274960328542\t1970-01-04T03:00:00.000000Z\n" +
"HYRX\t1.518411293091\t1970-01-04T03:00:00.000000Z\n" +
"CPSW\t-0.700205218541\t1970-01-04T03:00:00.000000Z\n" +
"WGRM\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"ZNFK\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"WGRM\t0.523489245443\t1970-01-04T06:00:00.000000Z\n" +
"CGFN\t0.567337652267\t1970-01-04T06:00:00.000000Z\n" +
"\t0.034652347087\t1970-01-04T06:00:00.000000Z\n" +
"PEVM\t0.782610780129\t1970-01-04T06:00:00.000000Z\n" +
"ZNFK\t0.138906713030\t1970-01-04T06:00:00.000000Z\n" +
"NPIW\t0.462788510540\t1970-01-04T06:00:00.000000Z\n" +
"VTJW\t0.551240795880\t1970-01-04T06:00:00.000000Z\n" +
"RXGZ\t0.199470461288\t1970-01-04T06:00:00.000000Z\n" +
"PEHN\t-3.776394309805\t1970-01-04T06:00:00.000000Z\n" +
"HYRX\t1.701764629815\t1970-01-04T06:00:00.000000Z\n" +
"CPSW\t-0.791365977130\t1970-01-04T06:00:00.000000Z\n",
true);
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MinFloatGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f float)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putFloat(0, rnd.nextFloat2());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0.0011075139045715332, record.getFloat(0), 0.0001);
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f float)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertTrue(Float.isNaN(record.getFloat(0)));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f float)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putFloat(0, rnd.nextFloat2());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0.0011075139045715332, record.getFloat(0), 0.0001);
}
}
}
@Test
public void testSampleFill() throws Exception {
assertQuery("b\tmin\tk\n" +
"HYRX\t0.1143\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t0.1250\t1970-01-03T00:00:00.000000Z\n" +
"\t0.0230\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.2692\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t0.3361\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t0.3864\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.3495\t1970-01-03T03:00:00.000000Z\n" +
"\t0.0268\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t0.1053\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t0.6807\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t0.8231\t1970-01-03T03:00:00.000000Z\n" +
"RXGZ\t0.5403\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t0.0658\t1970-01-03T06:00:00.000000Z\n" +
"\t0.0502\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t0.7365\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t0.4592\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t0.2464\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.6941\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.4440\t1970-01-03T09:00:00.000000Z\n" +
"\t0.0962\t1970-01-03T09:00:00.000000Z\n" +
"CPSW\t0.1195\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t0.2535\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t0.0400\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t-0.2179\t1970-01-03T09:00:00.000000Z\n",
"select b, min(a), k from x sample by 3h fill(linear)",
"create table x as " +
"(" +
"select" +
" rnd_float(0) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(172800000000), 360000000) k" +
" from" +
" long_sequence(100)" +
") timestamp(k) partition by NONE",
"k",
"insert into x select * from (" +
"select" +
" rnd_float(0) a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(277200000000), 360000000) k" +
" from" +
" long_sequence(35)" +
") timestamp(k)",
"b\tmin\tk\n" +
"HYRX\t0.1143\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t0.1250\t1970-01-03T00:00:00.000000Z\n" +
"\t0.0230\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.2692\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t0.3361\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t0.3864\t1970-01-03T00:00:00.000000Z\n" +
"UQDY\t1.9459\t1970-01-03T00:00:00.000000Z\n" +
"UKLG\t3.9211\t1970-01-03T00:00:00.000000Z\n" +
"IMYF\t1.5957\t1970-01-03T00:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t0.3495\t1970-01-03T03:00:00.000000Z\n" +
"\t0.0268\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t0.1053\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t0.6807\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t0.8231\t1970-01-03T03:00:00.000000Z\n" +
"RXGZ\t0.5403\t1970-01-03T03:00:00.000000Z\n" +
"UQDY\t1.8404\t1970-01-03T03:00:00.000000Z\n" +
"UKLG\t3.5400\t1970-01-03T03:00:00.000000Z\n" +
"IMYF\t1.4828\t1970-01-03T03:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t0.0658\t1970-01-03T06:00:00.000000Z\n" +
"\t0.0502\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t0.7365\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t0.4592\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t0.2464\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.6941\t1970-01-03T06:00:00.000000Z\n" +
"UQDY\t1.7350\t1970-01-03T06:00:00.000000Z\n" +
"UKLG\t3.1589\t1970-01-03T06:00:00.000000Z\n" +
"IMYF\t1.3699\t1970-01-03T06:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t0.4440\t1970-01-03T09:00:00.000000Z\n" +
"\t0.0962\t1970-01-03T09:00:00.000000Z\n" +
"CPSW\t0.1195\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t0.2535\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t0.0400\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t-0.2179\t1970-01-03T09:00:00.000000Z\n" +
"UQDY\t1.6295\t1970-01-03T09:00:00.000000Z\n" +
"UKLG\t2.7779\t1970-01-03T09:00:00.000000Z\n" +
"IMYF\t1.2570\t1970-01-03T09:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t-0.1664\t1970-01-03T12:00:00.000000Z\n" +
"PEHN\t0.0479\t1970-01-03T12:00:00.000000Z\n" +
"\t0.1284\t1970-01-03T12:00:00.000000Z\n" +
"VTJW\t-0.5016\t1970-01-03T12:00:00.000000Z\n" +
"CPSW\t-0.4975\t1970-01-03T12:00:00.000000Z\n" +
"RXGZ\t0.1940\t1970-01-03T12:00:00.000000Z\n" +
"UQDY\t1.5240\t1970-01-03T12:00:00.000000Z\n" +
"UKLG\t2.3968\t1970-01-03T12:00:00.000000Z\n" +
"IMYF\t1.1441\t1970-01-03T12:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"HYRX\t-0.3728\t1970-01-03T15:00:00.000000Z\n" +
"PEHN\t-0.1578\t1970-01-03T15:00:00.000000Z\n" +
"\t0.1607\t1970-01-03T15:00:00.000000Z\n" +
"VTJW\t-0.7853\t1970-01-03T15:00:00.000000Z\n" +
"CPSW\t-1.1145\t1970-01-03T15:00:00.000000Z\n" +
"RXGZ\t-0.0561\t1970-01-03T15:00:00.000000Z\n" +
"UQDY\t1.4185\t1970-01-03T15:00:00.000000Z\n" +
"UKLG\t2.0158\t1970-01-03T15:00:00.000000Z\n" +
"IMYF\t1.0312\t1970-01-03T15:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"HYRX\t-0.5792\t1970-01-03T18:00:00.000000Z\n" +
"PEHN\t-0.3635\t1970-01-03T18:00:00.000000Z\n" +
"\t0.1929\t1970-01-03T18:00:00.000000Z\n" +
"VTJW\t-1.0690\t1970-01-03T18:00:00.000000Z\n" +
"CPSW\t-1.7315\t1970-01-03T18:00:00.000000Z\n" +
"RXGZ\t-0.3062\t1970-01-03T18:00:00.000000Z\n" +
"UQDY\t1.3131\t1970-01-03T18:00:00.000000Z\n" +
"UKLG\t1.6347\t1970-01-03T18:00:00.000000Z\n" +
"IMYF\t0.9184\t1970-01-03T18:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"HYRX\t-0.7856\t1970-01-03T21:00:00.000000Z\n" +
"PEHN\t-0.5692\t1970-01-03T21:00:00.000000Z\n" +
"\t0.2252\t1970-01-03T21:00:00.000000Z\n" +
"VTJW\t-1.3526\t1970-01-03T21:00:00.000000Z\n" +
"CPSW\t-2.3485\t1970-01-03T21:00:00.000000Z\n" +
"RXGZ\t-0.5562\t1970-01-03T21:00:00.000000Z\n" +
"UQDY\t1.2076\t1970-01-03T21:00:00.000000Z\n" +
"UKLG\t1.2537\t1970-01-03T21:00:00.000000Z\n" +
"IMYF\t0.8055\t1970-01-03T21:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"HYRX\t-0.9920\t1970-01-04T00:00:00.000000Z\n" +
"PEHN\t-0.7748\t1970-01-04T00:00:00.000000Z\n" +
"\t0.2574\t1970-01-04T00:00:00.000000Z\n" +
"VTJW\t-1.6363\t1970-01-04T00:00:00.000000Z\n" +
"CPSW\t-2.9655\t1970-01-04T00:00:00.000000Z\n" +
"RXGZ\t-0.8063\t1970-01-04T00:00:00.000000Z\n" +
"UQDY\t1.1021\t1970-01-04T00:00:00.000000Z\n" +
"UKLG\t0.8726\t1970-01-04T00:00:00.000000Z\n" +
"IMYF\t0.6926\t1970-01-04T00:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"UQDY\t0.9966\t1970-01-04T03:00:00.000000Z\n" +
"\t0.2896\t1970-01-04T03:00:00.000000Z\n" +
"UKLG\t0.4915\t1970-01-04T03:00:00.000000Z\n" +
"IMYF\t0.5797\t1970-01-04T03:00:00.000000Z\n" +
"HYRX\t-1.1984\t1970-01-04T03:00:00.000000Z\n" +
"PEHN\t-0.9805\t1970-01-04T03:00:00.000000Z\n" +
"VTJW\t-1.9200\t1970-01-04T03:00:00.000000Z\n" +
"CPSW\t-3.5825\t1970-01-04T03:00:00.000000Z\n" +
"RXGZ\t-1.0564\t1970-01-04T03:00:00.000000Z\n" +
"OPHN\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"MXSL\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"\t0.0140\t1970-01-04T06:00:00.000000Z\n" +
"IMYF\t0.4668\t1970-01-04T06:00:00.000000Z\n" +
"OPHN\t0.0181\t1970-01-04T06:00:00.000000Z\n" +
"UKLG\t0.1105\t1970-01-04T06:00:00.000000Z\n" +
"MXSL\t0.7408\t1970-01-04T06:00:00.000000Z\n" +
"UQDY\t0.8912\t1970-01-04T06:00:00.000000Z\n" +
"HYRX\t-1.4048\t1970-01-04T06:00:00.000000Z\n" +
"PEHN\t-1.1862\t1970-01-04T06:00:00.000000Z\n" +
"VTJW\t-2.2037\t1970-01-04T06:00:00.000000Z\n" +
"CPSW\t-4.1995\t1970-01-04T06:00:00.000000Z\n" +
"RXGZ\t-1.3064\t1970-01-04T06:00:00.000000Z\n",
true);
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Numbers;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MinIntGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f int)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putInt(0, i);
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(11, record.getInt(0));
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f int)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(Numbers.INT_NaN, record.getInt(0));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f int)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putInt(0, i);
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(11, record.getInt(0));
}
}
}
@Test
public void testSomeNull() throws SqlException {
compiler.compile("create table tab (f int)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
if (i % 4 == 0) {
r.putInt(0, i);
}
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(12, record.getInt(0));
}
}
}
@Test
public void testSampleFill() throws Exception {
assertQuery("b\tmin\tk\n" +
"\t-1792928964\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t-2002373666\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-1520872171\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t-1252906348\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t-2119387831\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t-1272693194\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-1538602195\t1970-01-03T03:00:00.000000Z\n" +
"\t-2075675260\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t-661194722\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-882371473\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t-1593630138\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t215354468\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t519895483\t1970-01-03T06:00:00.000000Z\n" +
"\t-1470806499\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t-948252781\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t-246923735\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t-2080340570\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t-1383560599\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-1182156192\t1970-01-03T09:00:00.000000Z\n" +
"\t-1901633430\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t-2062507031\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t-1377625589\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t-1228519003\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t-302875424\t1970-01-03T09:00:00.000000Z\n",
"select b, min(a), k from x sample by 3h fill(linear)",
"create table x as " +
"(" +
"select" +
" rnd_int() a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(172800000000), 360000000) k" +
" from" +
" long_sequence(100)" +
") timestamp(k) partition by NONE",
"k",
"insert into x select * from (" +
"select" +
" rnd_int() a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(277200000000), 360000000) k" +
" from" +
" long_sequence(35)" +
") timestamp(k)",
"b\tmin\tk\n" +
"\t-1792928964\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t-2002373666\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-1520872171\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t-1252906348\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t-2119387831\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t-1272693194\t1970-01-03T00:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-1538602195\t1970-01-03T03:00:00.000000Z\n" +
"\t-2075675260\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t-661194722\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-882371473\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t-1593630138\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t215354468\t1970-01-03T03:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t519895483\t1970-01-03T06:00:00.000000Z\n" +
"\t-1470806499\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t-948252781\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t-246923735\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t-2080340570\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t-1383560599\t1970-01-03T06:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-1182156192\t1970-01-03T09:00:00.000000Z\n" +
"\t-1901633430\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t-2062507031\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t-1377625589\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t-1228519003\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t-302875424\t1970-01-03T09:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"\t-1800524746\t1970-01-03T12:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"RXGZ\t-1073477407\t1970-01-03T12:00:00.000000Z\n" +
"PEHN\t-2044673491\t1970-01-03T12:00:00.000000Z\n" +
"CPSW\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"HYRX\t342501933\t1970-01-03T12:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"\t-1699416063\t1970-01-03T15:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"RXGZ\t-918435810\t1970-01-03T15:00:00.000000Z\n" +
"PEHN\t-2026839952\t1970-01-03T15:00:00.000000Z\n" +
"CPSW\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"HYRX\t987879289\t1970-01-03T15:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"\t-1598307380\t1970-01-03T18:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"RXGZ\t-763394215\t1970-01-03T18:00:00.000000Z\n" +
"PEHN\t-2009006413\t1970-01-03T18:00:00.000000Z\n" +
"CPSW\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"HYRX\t1633256647\t1970-01-03T18:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"\t-1497198697\t1970-01-03T21:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"RXGZ\t-608352619\t1970-01-03T21:00:00.000000Z\n" +
"PEHN\t-1991172874\t1970-01-03T21:00:00.000000Z\n" +
"CPSW\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"HYRX\t2147483647\t1970-01-03T21:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"\t-1396090014\t1970-01-04T00:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"RXGZ\t-453311023\t1970-01-04T00:00:00.000000Z\n" +
"PEHN\t-1973339336\t1970-01-04T00:00:00.000000Z\n" +
"CPSW\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"HYRX\t2147483647\t1970-01-04T00:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"\t-1294981331\t1970-01-04T03:00:00.000000Z\n" +
"ZMZV\t-2043541236\t1970-01-04T03:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"RXGZ\t-298269426\t1970-01-04T03:00:00.000000Z\n" +
"PEHN\t-1955505797\t1970-01-04T03:00:00.000000Z\n" +
"CPSW\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"HYRX\t2147483647\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\t-1300367617\t1970-01-04T06:00:00.000000Z\n" +
"LOGI\t-358259591\t1970-01-04T06:00:00.000000Z\n" +
"QEBN\t171760612\t1970-01-04T06:00:00.000000Z\n" +
"\t-2102739504\t1970-01-04T06:00:00.000000Z\n" +
"FOUS\t-1923096605\t1970-01-04T06:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-04T06:00:00.000000Z\n" +
"RXGZ\t-143227831\t1970-01-04T06:00:00.000000Z\n" +
"PEHN\t-1937672257\t1970-01-04T06:00:00.000000Z\n" +
"CPSW\tNaN\t1970-01-04T06:00:00.000000Z\n" +
"HYRX\t2147483647\t1970-01-04T06:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-04T06:00:00.000000Z\n",
true);
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Numbers;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MinLongGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f long)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putLong(0, rnd.nextLong());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(-8968886490993754893L, record.getLong(0));
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f long)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(Numbers.LONG_NaN, record.getLong(0));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f long)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putLong(0, rnd.nextLong());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(-8968886490993754893L, record.getLong(0));
}
}
}
@Test
public void testSomeNull() throws SqlException {
compiler.compile("create table tab (f long)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
if (i % 4 == 0) {
r.putLong(0, i);
}
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(12, record.getLong(0));
}
}
}
@Test
public void testSampleFill() throws Exception {
assertQuery("b\tmin\tk\n" +
"\t-7885528361265853230\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t-7723703968879725602\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t7039584373105579285\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t-6253307669002054137\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t6270672455202306717\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t1205595184115760694\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-7689224645273531603\t1970-01-03T03:00:00.000000Z\n" +
"\t-9128506055317587235\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t-6626590012581323602\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-6161552193869048721\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t-7995393784734742820\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t-5439556746612026472\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-9147563299122452591\t1970-01-03T06:00:00.000000Z\n" +
"\t-8757007522346766135\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t-5817309269683380708\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t-5852887087189258121\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t6624299878707135910\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t-6912707344119330199\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-6703401424236463520\t1970-01-03T09:00:00.000000Z\n" +
"\t-3293392739929464726\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t5552835357100545895\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t-8371487291073160693\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t-6136190042965128192\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t-3639224754632017920\t1970-01-03T09:00:00.000000Z\n",
"select b, min(a), k from x sample by 3h fill(linear)",
"create table x as " +
"(" +
"select" +
" rnd_long() a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(172800000000), 360000000) k" +
" from" +
" long_sequence(100)" +
") timestamp(k) partition by NONE",
"k",
"insert into x select * from (" +
"select" +
" rnd_long() a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(277200000000), 360000000) k" +
" from" +
" long_sequence(35)" +
") timestamp(k)",
"b\tmin\tk\n" +
"\t-7885528361265853230\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t-7723703968879725602\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t7039584373105579285\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t-6253307669002054137\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t6270672455202306717\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t1205595184115760694\t1970-01-03T00:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-7689224645273531603\t1970-01-03T03:00:00.000000Z\n" +
"\t-9128506055317587235\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t-6626590012581323602\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-6161552193869048721\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t-7995393784734742820\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t-5439556746612026472\t1970-01-03T03:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-9147563299122452591\t1970-01-03T06:00:00.000000Z\n" +
"\t-8757007522346766135\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t-5817309269683380708\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t-5852887087189258121\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t6624299878707135910\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t-6912707344119330199\t1970-01-03T06:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-6703401424236463520\t1970-01-03T09:00:00.000000Z\n" +
"\t-3293392739929464726\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t5552835357100545895\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t-8371487291073160693\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t-6136190042965128192\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t-3639224754632017920\t1970-01-03T09:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T09:00:00.000000Z\n" +
"\t-3944981163069335552\t1970-01-03T12:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"RXGZ\t-5359672741810924544\t1970-01-03T12:00:00.000000Z\n" +
"PEHN\t4481370835493956096\t1970-01-03T12:00:00.000000Z\n" +
"CPSW\t-4259239549350473728\t1970-01-03T12:00:00.000000Z\n" +
"HYRX\t-1461140239580656384\t1970-01-03T12:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T12:00:00.000000Z\n" +
"\t-4596569586209205760\t1970-01-03T15:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"RXGZ\t-4583155440656723968\t1970-01-03T15:00:00.000000Z\n" +
"PEHN\t3409906313887367680\t1970-01-03T15:00:00.000000Z\n" +
"CPSW\t-1815077674464482816\t1970-01-03T15:00:00.000000Z\n" +
"HYRX\t716944275470705152\t1970-01-03T15:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T15:00:00.000000Z\n" +
"\t-5248158009349075968\t1970-01-03T18:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"RXGZ\t-3806638139502523904\t1970-01-03T18:00:00.000000Z\n" +
"PEHN\t2338441792280776704\t1970-01-03T18:00:00.000000Z\n" +
"CPSW\t629084200421505024\t1970-01-03T18:00:00.000000Z\n" +
"HYRX\t2895028790522070016\t1970-01-03T18:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T18:00:00.000000Z\n" +
"\t-5899746432488946688\t1970-01-03T21:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"RXGZ\t-3030120838348320256\t1970-01-03T21:00:00.000000Z\n" +
"PEHN\t1266977270674186496\t1970-01-03T21:00:00.000000Z\n" +
"CPSW\t3073246075307492864\t1970-01-03T21:00:00.000000Z\n" +
"HYRX\t5073113305573431296\t1970-01-03T21:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-03T21:00:00.000000Z\n" +
"\t-6551334855628817408\t1970-01-04T00:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"RXGZ\t-2253603537194116608\t1970-01-04T00:00:00.000000Z\n" +
"PEHN\t195512749067602464\t1970-01-04T00:00:00.000000Z\n" +
"CPSW\t5517407950193483776\t1970-01-04T00:00:00.000000Z\n" +
"HYRX\t7251197820624792576\t1970-01-04T00:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-04T00:00:00.000000Z\n" +
"\t-7202923278768687325\t1970-01-04T03:00:00.000000Z\n" +
"ZMZV\t-4058426794463997577\t1970-01-04T03:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"RXGZ\t-1477086236039919616\t1970-01-04T03:00:00.000000Z\n" +
"PEHN\t-875951772538991360\t1970-01-04T03:00:00.000000Z\n" +
"CPSW\t7961569825079475200\t1970-01-04T03:00:00.000000Z\n" +
"HYRX\t9223372036854775807\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"LOGI\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"QEBN\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"FOUS\tNaN\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\t-4284648096271470489\t1970-01-04T06:00:00.000000Z\n" +
"LOGI\t8984932460293088377\t1970-01-04T06:00:00.000000Z\n" +
"QEBN\t-8841102831894340636\t1970-01-04T06:00:00.000000Z\n" +
"\t-8960406850507339854\t1970-01-04T06:00:00.000000Z\n" +
"FOUS\t812677186520066053\t1970-01-04T06:00:00.000000Z\n" +
"VTJW\tNaN\t1970-01-04T06:00:00.000000Z\n" +
"RXGZ\t-700568934885709440\t1970-01-04T06:00:00.000000Z\n" +
"PEHN\t-1947416294145578496\t1970-01-04T06:00:00.000000Z\n" +
"CPSW\t9223372036854775807\t1970-01-04T06:00:00.000000Z\n" +
"HYRX\t9223372036854775807\t1970-01-04T06:00:00.000000Z\n" +
"ZMZV\tNaN\t1970-01-04T06:00:00.000000Z\n",
true);
}
}
\ No newline at end of file
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.groupby;
import io.questdb.cairo.TableWriter;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.RecordCursorFactory;
import io.questdb.griffin.AbstractGriffinTest;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.engine.functions.rnd.SharedRandom;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MinShortGroupByFunctionFactoryTest extends AbstractGriffinTest {
@Before
public void setUp3() {
SharedRandom.RANDOM.set(new Rnd());
}
@Test
public void testNonNull() throws SqlException {
compiler.compile("create table tab (f short)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.putShort(0, rnd.nextShort());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(-32679, record.getShort(0));
}
}
}
@Test
public void testAllNull() throws SqlException {
compiler.compile("create table tab (f short)");
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
for (int i = 100; i > 10; i--) {
TableWriter.Row r = w.newRow();
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(0, record.getShort(0));
}
}
}
@Test
public void testFirstNull() throws SqlException {
compiler.compile("create table tab (f short)");
final Rnd rnd = new Rnd();
try (TableWriter w = engine.getWriter(sqlExecutionContext.getCairoSecurityContext(), "tab")) {
TableWriter.Row r = w.newRow();
r.append();
for (int i = 100; i > 10; i--) {
r = w.newRow();
r.putShort(0, rnd.nextShort());
r.append();
}
w.commit();
}
try (RecordCursorFactory factory = compiler.compile("select min(f) from tab").getRecordCursorFactory()) {
try (RecordCursor cursor = factory.getCursor()) {
Record record = cursor.getRecord();
Assert.assertEquals(-1, cursor.size());
Assert.assertTrue(cursor.hasNext());
Assert.assertEquals(-32679, record.getShort(0));
}
}
}
@Test
public void testSampleFill() throws Exception {
assertQuery("b\tmin\tk\n" +
"\t-31228\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t-1593\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t21781\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t-1271\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t-19127\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t15926\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-13523\t1970-01-03T03:00:00.000000Z\n" +
"\t-24397\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t-2018\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-15331\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t-10913\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t3172\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-8221\t1970-01-03T06:00:00.000000Z\n" +
"\t-26776\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t-12397\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t-25068\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t-31322\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t-30103\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-30595\t1970-01-03T09:00:00.000000Z\n" +
"\t24682\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t-26828\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t6667\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t18853\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t-13881\t1970-01-03T09:00:00.000000Z\n",
"select b, min(a), k from x sample by 3h fill(linear)",
"create table x as " +
"(" +
"select" +
" rnd_short() a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(172800000000), 360000000) k" +
" from" +
" long_sequence(100)" +
") timestamp(k) partition by NONE",
"k",
"insert into x select * from (" +
"select" +
" rnd_short() a," +
" rnd_symbol(5,4,4,1) b," +
" timestamp_sequence(to_timestamp(277200000000), 360000000) k" +
" from" +
" long_sequence(35)" +
") timestamp(k)",
"b\tmin\tk\n" +
"\t-31228\t1970-01-03T00:00:00.000000Z\n" +
"VTJW\t-1593\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t21781\t1970-01-03T00:00:00.000000Z\n" +
"PEHN\t-1271\t1970-01-03T00:00:00.000000Z\n" +
"CPSW\t-19127\t1970-01-03T00:00:00.000000Z\n" +
"HYRX\t15926\t1970-01-03T00:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T00:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T00:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T00:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T00:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T00:00:00.000000Z\n" +
"RXGZ\t-13523\t1970-01-03T03:00:00.000000Z\n" +
"\t-24397\t1970-01-03T03:00:00.000000Z\n" +
"PEHN\t-2018\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-15331\t1970-01-03T03:00:00.000000Z\n" +
"HYRX\t-10913\t1970-01-03T03:00:00.000000Z\n" +
"VTJW\t3172\t1970-01-03T03:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T03:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T03:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T03:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T03:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T03:00:00.000000Z\n" +
"CPSW\t-8221\t1970-01-03T06:00:00.000000Z\n" +
"\t-26776\t1970-01-03T06:00:00.000000Z\n" +
"HYRX\t-12397\t1970-01-03T06:00:00.000000Z\n" +
"VTJW\t-25068\t1970-01-03T06:00:00.000000Z\n" +
"PEHN\t-31322\t1970-01-03T06:00:00.000000Z\n" +
"RXGZ\t-30103\t1970-01-03T06:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T06:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T06:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T06:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T06:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T06:00:00.000000Z\n" +
"CPSW\t-30595\t1970-01-03T09:00:00.000000Z\n" +
"\t24682\t1970-01-03T09:00:00.000000Z\n" +
"PEHN\t-26828\t1970-01-03T09:00:00.000000Z\n" +
"VTJW\t6667\t1970-01-03T09:00:00.000000Z\n" +
"RXGZ\t18853\t1970-01-03T09:00:00.000000Z\n" +
"HYRX\t-13881\t1970-01-03T09:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T09:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T09:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T09:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T09:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T09:00:00.000000Z\n" +
"\t15446\t1970-01-03T12:00:00.000000Z\n" +
"VTJW\t-27134\t1970-01-03T12:00:00.000000Z\n" +
"RXGZ\t2273\t1970-01-03T12:00:00.000000Z\n" +
"PEHN\t-22334\t1970-01-03T12:00:00.000000Z\n" +
"CPSW\t12567\t1970-01-03T12:00:00.000000Z\n" +
"HYRX\t-15365\t1970-01-03T12:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T12:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T12:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T12:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T12:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T12:00:00.000000Z\n" +
"\t6211\t1970-01-03T15:00:00.000000Z\n" +
"VTJW\t4601\t1970-01-03T15:00:00.000000Z\n" +
"RXGZ\t-14307\t1970-01-03T15:00:00.000000Z\n" +
"PEHN\t-17840\t1970-01-03T15:00:00.000000Z\n" +
"CPSW\t-9807\t1970-01-03T15:00:00.000000Z\n" +
"HYRX\t-16849\t1970-01-03T15:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T15:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T15:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T15:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T15:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T15:00:00.000000Z\n" +
"\t-3024\t1970-01-03T18:00:00.000000Z\n" +
"VTJW\t-29200\t1970-01-03T18:00:00.000000Z\n" +
"RXGZ\t-30887\t1970-01-03T18:00:00.000000Z\n" +
"PEHN\t-13346\t1970-01-03T18:00:00.000000Z\n" +
"CPSW\t-32181\t1970-01-03T18:00:00.000000Z\n" +
"HYRX\t-18333\t1970-01-03T18:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T18:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T18:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T18:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T18:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T18:00:00.000000Z\n" +
"\t-12260\t1970-01-03T21:00:00.000000Z\n" +
"VTJW\t2535\t1970-01-03T21:00:00.000000Z\n" +
"RXGZ\t18069\t1970-01-03T21:00:00.000000Z\n" +
"PEHN\t-8852\t1970-01-03T21:00:00.000000Z\n" +
"CPSW\t10981\t1970-01-03T21:00:00.000000Z\n" +
"HYRX\t-19817\t1970-01-03T21:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-03T21:00:00.000000Z\n" +
"QLDG\t0\t1970-01-03T21:00:00.000000Z\n" +
"LOGI\t0\t1970-01-03T21:00:00.000000Z\n" +
"QEBN\t0\t1970-01-03T21:00:00.000000Z\n" +
"FOUS\t0\t1970-01-03T21:00:00.000000Z\n" +
"\t-21495\t1970-01-04T00:00:00.000000Z\n" +
"VTJW\t-31266\t1970-01-04T00:00:00.000000Z\n" +
"RXGZ\t1489\t1970-01-04T00:00:00.000000Z\n" +
"PEHN\t-4358\t1970-01-04T00:00:00.000000Z\n" +
"CPSW\t-11393\t1970-01-04T00:00:00.000000Z\n" +
"HYRX\t-21301\t1970-01-04T00:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-04T00:00:00.000000Z\n" +
"QLDG\t0\t1970-01-04T00:00:00.000000Z\n" +
"LOGI\t0\t1970-01-04T00:00:00.000000Z\n" +
"QEBN\t0\t1970-01-04T00:00:00.000000Z\n" +
"FOUS\t0\t1970-01-04T00:00:00.000000Z\n" +
"\t-30731\t1970-01-04T03:00:00.000000Z\n" +
"ZMZV\t-11913\t1970-01-04T03:00:00.000000Z\n" +
"VTJW\t469\t1970-01-04T03:00:00.000000Z\n" +
"RXGZ\t-15091\t1970-01-04T03:00:00.000000Z\n" +
"PEHN\t136\t1970-01-04T03:00:00.000000Z\n" +
"CPSW\t31769\t1970-01-04T03:00:00.000000Z\n" +
"HYRX\t-22785\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\t0\t1970-01-04T03:00:00.000000Z\n" +
"LOGI\t0\t1970-01-04T03:00:00.000000Z\n" +
"QEBN\t0\t1970-01-04T03:00:00.000000Z\n" +
"FOUS\t0\t1970-01-04T03:00:00.000000Z\n" +
"QLDG\t-15702\t1970-01-04T06:00:00.000000Z\n" +
"LOGI\t-14555\t1970-01-04T06:00:00.000000Z\n" +
"QEBN\t-9244\t1970-01-04T06:00:00.000000Z\n" +
"\t-30798\t1970-01-04T06:00:00.000000Z\n" +
"FOUS\t-22523\t1970-01-04T06:00:00.000000Z\n" +
"VTJW\t32204\t1970-01-04T06:00:00.000000Z\n" +
"RXGZ\t-31671\t1970-01-04T06:00:00.000000Z\n" +
"PEHN\t4630\t1970-01-04T06:00:00.000000Z\n" +
"CPSW\t9395\t1970-01-04T06:00:00.000000Z\n" +
"HYRX\t-24269\t1970-01-04T06:00:00.000000Z\n" +
"ZMZV\t0\t1970-01-04T06:00:00.000000Z\n",
true);
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册