use of herddb.utils.TuplesList in project herddb by diennea.
the class CalcitePlannerTest method showCreateTableTest_with_Indexes.
@Test
public void showCreateTableTest_with_Indexes() throws Exception {
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
execute(manager, "CREATE TABLE tblspace1.test23 (k1 string not null ," + "s1 string not null, n1 int, primary key(k1,n1))", Collections.emptyList());
execute(manager, "CREATE INDEX ixn1s1 on tblspace1.test23(n1,s1)", Collections.emptyList());
execute(manager, "CREATE UNIQUE INDEX ixn1s2 on tblspace1.test23(n1,s1,k1)", Collections.emptyList());
TranslatedQuery translatedQuery = manager.getPlanner().translate("tblspace1", "SHOW CREATE TABLE tblspace1.test23 WITH INDEXES", Collections.emptyList(), true, false, true, -1);
assertTrue(translatedQuery.plan.mainStatement instanceof SQLPlannedOperationStatement || translatedQuery.plan.mainStatement instanceof ScanStatement);
ScanResult scanResult = (ScanResult) manager.executePlan(translatedQuery.plan, translatedQuery.context, TransactionContext.NO_TRANSACTION);
DataScanner dataScanner = scanResult.dataScanner;
String[] columns = dataScanner.getFieldNames();
List<DataAccessor> records = dataScanner.consumeAndClose();
TuplesList tuplesList = new TuplesList(columns, records);
assertTrue(tuplesList.columnNames[0].equalsIgnoreCase("tabledef"));
Tuple values = (Tuple) records.get(0);
assertEquals("CREATE TABLE tblspace1.test23(k1 string not null,s1 string not null,n1 integer,PRIMARY KEY(k1,n1),INDEX ixn1s1(n1,s1),UNIQUE KEY ixn1s2 (n1,s1,k1))", values.get("tabledef").toString());
// Drop the table and indexes and recreate them again.
String showCreateCommandOutput = values.get("tabledef").toString();
// drop the table
execute(manager, "DROP TABLE tblspace1.test23", Collections.emptyList());
// ensure table has been dropped
try (DataScanner scan = scan(manager, "SELECT * FROM tblspace1.systables where table_name='test23'", Collections.emptyList())) {
assertTrue(scan.consume().isEmpty());
}
// ensure index has been dropped
try (DataScanner scan = scan(manager, "SELECT * FROM tblspace1.sysindexes where index_name='ixn1s1'", Collections.emptyList())) {
assertTrue(scan.consume().isEmpty());
}
try (DataScanner scan = scan(manager, "SELECT * FROM tblspace1.sysindexes where index_name='ixn1s2'", Collections.emptyList())) {
assertTrue(scan.consume().isEmpty());
}
execute(manager, showCreateCommandOutput, Collections.emptyList());
// Ensure the table is getting created
try (DataScanner scan = scan(manager, "SELECT * FROM tblspace1.systables where table_name='test23'", Collections.emptyList())) {
assertFalse(scan.consume().isEmpty());
}
// Ensure index got created as well.
try (DataScanner scan = scan(manager, "SELECT * FROM tblspace1.sysindexes where index_name='ixn1s1'", Collections.emptyList())) {
assertFalse(scan.consume().isEmpty());
}
}
}
use of herddb.utils.TuplesList in project herddb by diennea.
the class ServerSideConnectionPeer method handleFetchScannerData.
private void handleFetchScannerData(Message message, Channel _channel) {
String scannerId = (String) message.parameters.get("scannerId");
int fetchSize = (Integer) message.parameters.get("fetchSize");
ServerSideScannerPeer scanner = scanners.get(scannerId);
if (scanner != null) {
try {
DataScanner dataScanner = scanner.getScanner();
List<DataAccessor> records = dataScanner.consume(fetchSize);
String[] columns = dataScanner.getFieldNames();
TuplesList tuplesList = new TuplesList(columns, records);
boolean last = false;
if (dataScanner.isFinished()) {
LOGGER.log(Level.FINEST, "unregistering scanner {0}, resultset is finished", scannerId);
scanners.remove(scannerId);
last = true;
}
// LOGGER.log(Level.SEVERE, "sending " + converted.size() + " records to scanner " + scannerId);
_channel.sendReplyMessage(message, Message.RESULTSET_CHUNK(null, scannerId, tuplesList, last, dataScanner.transactionId));
} catch (DataScannerException error) {
_channel.sendReplyMessage(message, Message.ERROR(null, error).setParameter("scannerId", scannerId));
}
} else {
_channel.sendReplyMessage(message, Message.ERROR(null, new Exception("no such scanner " + scannerId + ", only " + scanners.keySet())).setParameter("scannerId", scannerId));
}
}
use of herddb.utils.TuplesList in project herddb by diennea.
the class MessageUtils method writeEncodedSimpleValue.
@SuppressWarnings("rawtypes")
private static void writeEncodedSimpleValue(ByteBuf output, Object o) {
if (o == null) {
output.writeByte(OPCODE_NULL_VALUE);
} else if (o instanceof String) {
output.writeByte(OPCODE_STRING_VALUE);
writeUTF8String(output, (String) o);
} else if (o instanceof RawString) {
output.writeByte(OPCODE_STRING_VALUE);
writeUTF8String(output, (RawString) o);
} else if (o instanceof java.sql.Timestamp) {
output.writeByte(OPCODE_TIMESTAMP_VALUE);
ByteBufUtils.writeVLong(output, ((java.sql.Timestamp) o).getTime());
} else if (o instanceof java.lang.Byte) {
output.writeByte(OPCODE_BYTE_VALUE);
output.writeByte(((Byte) o));
} else if (o instanceof KeyValue) {
KeyValue kv = (KeyValue) o;
output.writeByte(OPCODE_KEYVALUE_VALUE);
ByteBufUtils.writeArray(output, kv.key);
ByteBufUtils.writeArray(output, kv.value);
} else if (o instanceof Integer) {
int i = (int) o;
if (i < 0) {
if (i < WRITE_MIN_Z_INT_LIMIT) {
output.writeByte(OPCODE_INT_VALUE);
output.writeInt(i);
} else {
output.writeByte(OPCODE_Z_INT_VALUE);
ByteBufUtils.writeZInt(output, i);
}
} else {
if (i > WRITE_MAX_V_INT_LIMIT) {
output.writeByte(OPCODE_INT_VALUE);
output.writeInt(i);
} else {
output.writeByte(OPCODE_V_INT_VALUE);
ByteBufUtils.writeVInt(output, i);
}
}
} else if (o instanceof Long) {
long l = (long) o;
if (l < 0) {
if (l < WRITE_MIN_Z_LONG_LIMIT) {
output.writeByte(OPCODE_LONG_VALUE);
output.writeLong(l);
} else {
output.writeByte(OPCODE_Z_LONG_VALUE);
ByteBufUtils.writeZLong(output, l);
}
} else {
if (l > WRITE_MAX_V_LONG_LIMIT) {
output.writeByte(OPCODE_LONG_VALUE);
output.writeLong(l);
} else {
output.writeByte(OPCODE_V_LONG_VALUE);
ByteBufUtils.writeVLong(output, l);
}
}
} else if (o instanceof Boolean) {
output.writeByte(OPCODE_BOOLEAN_VALUE);
output.writeByte(((Boolean) o).booleanValue() ? 1 : 0);
} else if (o instanceof Double) {
output.writeByte(OPCODE_DOUBLE_VALUE);
ByteBufUtils.writeDouble(output, ((Double) o).doubleValue());
} else if (o instanceof Set) {
Set set = (Set) o;
output.writeByte(OPCODE_SET_VALUE);
ByteBufUtils.writeVInt(output, set.size());
for (Object o2 : set) {
writeEncodedSimpleValue(output, o2);
}
} else if (o instanceof List) {
List set = (List) o;
output.writeByte(OPCODE_LIST_VALUE);
ByteBufUtils.writeVInt(output, set.size());
for (Object o2 : set) {
writeEncodedSimpleValue(output, o2);
}
} else if (o instanceof Map) {
Map set = (Map) o;
output.writeByte(OPCODE_MAP_VALUE);
ByteBufUtils.writeVInt(output, set.size());
for (Map.Entry entry : (Iterable<Map.Entry>) set.entrySet()) {
writeEncodedSimpleValue(output, entry.getKey());
writeEncodedSimpleValue(output, entry.getValue());
}
} else if (o instanceof DataAccessor) {
DataAccessor set = (DataAccessor) o;
output.writeByte(OPCODE_MAP2_VALUE);
// number of entries is not known
set.forEach((key, value) -> {
writeEncodedSimpleValue(output, key);
writeEncodedSimpleValue(output, value);
});
output.writeByte(OPCODE_MAP2_VALUE_END);
} else if (o instanceof TuplesList) {
TuplesList set = (TuplesList) o;
output.writeByte(OPCODE_TUPLELIST_VALUE);
final int numColumns = set.columnNames.length;
ByteBufUtils.writeVInt(output, numColumns);
for (String columnName : set.columnNames) {
writeUTF8String(output, columnName);
}
ByteBufUtils.writeVInt(output, set.tuples.size());
for (DataAccessor da : set.tuples) {
IntHolder currentColumn = new IntHolder();
da.forEach((String key, Object value) -> {
String expectedColumnName = set.columnNames[currentColumn.value];
while (!key.equals(expectedColumnName)) {
// nulls are not returned for some special accessors, lie DataAccessorForFullRecord
writeEncodedSimpleValue(output, null);
currentColumn.value++;
expectedColumnName = set.columnNames[currentColumn.value];
}
writeEncodedSimpleValue(output, value);
currentColumn.value++;
});
// fill with nulls
while (currentColumn.value < numColumns) {
writeEncodedSimpleValue(output, null);
currentColumn.value++;
}
if (currentColumn.value > numColumns) {
throw new RuntimeException("unexpected number of columns " + currentColumn.value + " > " + numColumns);
}
}
} else if (o instanceof byte[]) {
byte[] set = (byte[]) o;
output.writeByte(OPCODE_BYTEARRAY_VALUE);
ByteBufUtils.writeArray(output, set);
} else {
throw new RuntimeException("unsupported class " + o.getClass());
}
}
use of herddb.utils.TuplesList in project herddb by diennea.
the class MessageUtilsTest method testEncodeMessage.
@Test
public void testEncodeMessage() {
final String clientId = "2331";
System.out.println("encodeMessage");
ByteBuf buffer = Unpooled.buffer();
Map<String, Object> payload = new HashMap<>();
payload.put("string", "value");
payload.put("int", 1234);
payload.put("long", 12345L);
payload.put("rawstring", RawString.of("value"));
payload.put("list", Arrays.asList("foo", "bar"));
payload.put("set", new HashSet<>(Arrays.asList("foo", "bar")));
String[] colNames = { "one", "null", "two", "notfound" };
List<DataAccessor> records = new ArrayList<>();
Map<String, Object> record1 = new HashMap<>();
record1.put("one", 1234);
record1.put("two", RawString.of("test"));
records.add(new MapDataAccessor(record1, colNames));
Map<String, Object> record2 = new HashMap<>();
record2.put("one", 2234);
record2.put("two", RawString.of("test2"));
record2.put("null", null);
records.add(new MapDataAccessor(record2, colNames));
TuplesList tl = new TuplesList(colNames, records);
payload.put("data", tl);
Message m = new Message(clientId, 1234, payload);
m.assignMessageId();
m.setReplyMessageId("2343");
MessageUtils.encodeMessage(buffer, m);
Message read = MessageUtils.decodeMessage(buffer);
assertEquals(read.clientId, m.clientId);
assertEquals(read.messageId, m.messageId);
assertEquals(read.replyMessageId, m.replyMessageId);
assertEquals(read.type, m.type);
assertEquals(read.parameters.size(), m.parameters.size());
read.parameters.forEach((String k, Object v) -> {
Object o = m.parameters.get(k);
assertEquals(o, v);
});
TuplesList tl2 = (TuplesList) read.parameters.get("data");
assertEquals(4, tl2.tuples.get(0).getValues().length);
assertArrayEquals(colNames, tl2.tuples.get(0).getFieldNames());
assertEquals(4, tl2.tuples.get(1).getValues().length);
assertArrayEquals(colNames, tl2.tuples.get(1).getFieldNames());
}
use of herddb.utils.TuplesList in project herddb by diennea.
the class ServerSideConnectionPeer method handleOpenScanner.
private void handleOpenScanner(Pdu message, Channel channel) {
long txId = PduCodec.OpenScanner.readTx(message);
String tableSpace = PduCodec.OpenScanner.readTablespace(message);
long statementId = PduCodec.OpenScanner.readStatementId(message);
String query = statementId > 0 ? preparedStatements.resolveQuery(tableSpace, statementId) : PduCodec.OpenScanner.readQuery(message);
if (query == null) {
ByteBuf error = PduCodec.ErrorResponse.writeMissingPreparedStatementError(message.messageId, "bad statement id: " + statementId);
channel.sendReplyMessage(message.messageId, error);
return;
}
long scannerId = PduCodec.OpenScanner.readScannerId(message);
int fetchSize = PduCodec.OpenScanner.readFetchSize(message);
if (fetchSize <= 0) {
fetchSize = 10;
}
// default 0
int maxRows = PduCodec.OpenScanner.readMaxRows(message);
PduCodec.ObjectListReader parametersReader = PduCodec.OpenScanner.startReadParameters(message);
List<Object> parameters = new ArrayList<>(parametersReader.getNumParams());
for (int i = 0; i < parametersReader.getNumParams(); i++) {
parameters.add(parametersReader.nextObject());
}
// with clients older than 0.20.0 keepReadLocks will be always true
byte trailer = parametersReader.readTrailer();
boolean keepReadLocks = !isDontKeepReadLocks(trailer);
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.log(Level.FINER, "openScanner txId+" + txId + ", fetchSize " + fetchSize + ", maxRows " + maxRows + ", keepReadLocks " + keepReadLocks + ", " + query + " with " + parameters);
}
RunningStatementsStats runningStatements = server.getManager().getRunningStatements();
RunningStatementInfo statementInfo = new RunningStatementInfo(query, System.currentTimeMillis(), tableSpace, "", 1);
try {
TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, true, true, false, maxRows);
translatedQuery.context.setForceRetainReadLock(keepReadLocks);
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "{0} -> {1}", new Object[] { query, translatedQuery.plan.mainStatement });
}
TransactionContext transactionContext = new TransactionContext(txId);
if (translatedQuery.plan.mainStatement instanceof SQLPlannedOperationStatement || translatedQuery.plan.mainStatement instanceof ScanStatement) {
runningStatements.registerRunningStatement(statementInfo);
ScanResult scanResult = (ScanResult) server.getManager().executePlan(translatedQuery.plan, translatedQuery.context, transactionContext);
DataScanner dataScanner = scanResult.dataScanner;
ServerSideScannerPeer scanner = new ServerSideScannerPeer(dataScanner);
String[] columns = dataScanner.getFieldNames();
List<DataAccessor> records = dataScanner.consume(fetchSize);
TuplesList tuplesList = new TuplesList(columns, records);
boolean last = dataScanner.isFinished();
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "sending first {0} records to scanner {1} query {2}", new Object[] { records.size(), scannerId, query });
}
if (!last) {
scanners.put(scannerId, scanner);
}
try {
ByteBuf result = PduCodec.ResultSetChunk.write(message.messageId, tuplesList, last, dataScanner.getTransactionId());
channel.sendReplyMessage(message.messageId, result);
} catch (HerdDBInternalException err) {
// do not leak an unserializable scanner
scanner.close();
throw err;
}
if (last) {
// no need to hold the scanner anymore
scanner.close();
}
} else {
ByteBuf error = PduCodec.ErrorResponse.write(message.messageId, "unsupported query type for scan " + query + ": PLAN is " + translatedQuery.plan);
channel.sendReplyMessage(message.messageId, error);
}
} catch (DataScannerException | HerdDBInternalException err) {
if (err.getCause() != null && err.getCause() instanceof ValidationException) {
// no stacktraces for bad queries
LOGGER.log(Level.FINE, "SQL error on scanner " + scannerId + ": " + err);
} else {
LOGGER.log(Level.SEVERE, "error on scanner " + scannerId + ": " + err, err);
}
scanners.remove(scannerId);
ByteBuf error = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, error);
} finally {
runningStatements.unregisterRunningStatement(statementInfo);
}
}
Aggregations