use of io.mycat.net.mysql.ResultSetHeaderPacket in project Mycat_plus by coderczp.
the class EngineCtx method writeHeader.
public void writeHeader(List<byte[]> afields, List<byte[]> bfields) {
if (headerWrited.compareAndSet(false, true)) {
try {
writeLock.lock();
// write new header
ResultSetHeaderPacket headerPkg = new ResultSetHeaderPacket();
headerPkg.fieldCount = afields.size() + bfields.size() - 1;
headerPkg.packetId = incPackageId();
LOGGER.debug("packge id " + headerPkg.packetId);
ServerConnection sc = session.getSource();
ByteBuffer buf = headerPkg.write(sc.allocate(), sc, true);
// wirte a fields
for (byte[] field : afields) {
field[3] = incPackageId();
buf = sc.writeToBuffer(field, buf);
}
// write b field
for (int i = 1; i < bfields.size(); i++) {
byte[] bfield = bfields.get(i);
bfield[3] = incPackageId();
buf = sc.writeToBuffer(bfield, buf);
}
// write field eof
EOFPacket eofPckg = new EOFPacket();
eofPckg.packetId = incPackageId();
buf = eofPckg.write(buf, sc, true);
sc.write(buf);
// LOGGER.info("header outputed ,packgId:" + eofPckg.packetId);
} finally {
writeLock.unlock();
}
}
}
use of io.mycat.net.mysql.ResultSetHeaderPacket in project Mycat-Server by MyCATApache.
the class MysqlInformationSchemaHandler method doWrite.
/**
* 写入数据包
* @param field_count
* @param fields
* @param c
*/
private static void doWrite(int field_count, FieldPacket[] fields, ServerConnection c) {
ByteBuffer buffer = c.allocate();
// write header
ResultSetHeaderPacket header = PacketUtil.getHeader(field_count);
byte packetId = header.packetId;
buffer = header.write(buffer, c, true);
// write fields
for (FieldPacket field : fields) {
field.packetId = ++packetId;
buffer = field.write(buffer, c, true);
}
// write eof
EOFPacket eof = new EOFPacket();
eof.packetId = ++packetId;
buffer = eof.write(buffer, c, true);
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c, true);
// post write
c.write(buffer);
}
use of io.mycat.net.mysql.ResultSetHeaderPacket in project Mycat-Server by MyCATApache.
the class JDBCConnection method ouputResultSet.
private void ouputResultSet(ServerConnection sc, String sql) throws SQLException {
ResultSet rs = null;
Statement stmt = null;
try {
stmt = con.createStatement();
rs = stmt.executeQuery(sql);
List<FieldPacket> fieldPks = new LinkedList<FieldPacket>();
ResultSetUtil.resultSetToFieldPacket(sc.getCharset(), fieldPks, rs, this.isSpark);
int colunmCount = fieldPks.size();
ByteBuffer byteBuf = sc.allocate();
ResultSetHeaderPacket headerPkg = new ResultSetHeaderPacket();
headerPkg.fieldCount = fieldPks.size();
headerPkg.packetId = ++packetId;
byteBuf = headerPkg.write(byteBuf, sc, true);
byteBuf.flip();
byte[] header = new byte[byteBuf.limit()];
byteBuf.get(header);
byteBuf.clear();
List<byte[]> fields = new ArrayList<byte[]>(fieldPks.size());
Iterator<FieldPacket> itor = fieldPks.iterator();
while (itor.hasNext()) {
FieldPacket curField = itor.next();
curField.packetId = ++packetId;
byteBuf = curField.write(byteBuf, sc, false);
byteBuf.flip();
byte[] field = new byte[byteBuf.limit()];
byteBuf.get(field);
byteBuf.clear();
fields.add(field);
}
EOFPacket eofPckg = new EOFPacket();
eofPckg.packetId = ++packetId;
byteBuf = eofPckg.write(byteBuf, sc, false);
byteBuf.flip();
byte[] eof = new byte[byteBuf.limit()];
byteBuf.get(eof);
byteBuf.clear();
this.respHandler.fieldEofResponse(header, fields, eof, this);
// output row
while (rs.next()) {
RowDataPacket curRow = new RowDataPacket(colunmCount);
for (int i = 0; i < colunmCount; i++) {
int j = i + 1;
if (MysqlDefs.isBianry((byte) fieldPks.get(i).type)) {
curRow.add(rs.getBytes(j));
} else if (fieldPks.get(i).type == MysqlDefs.FIELD_TYPE_DECIMAL || fieldPks.get(i).type == (MysqlDefs.FIELD_TYPE_NEW_DECIMAL - 256)) {
// field type is unsigned byte
// ensure that do not use scientific notation format
BigDecimal val = rs.getBigDecimal(j);
curRow.add(StringUtil.encode(val != null ? val.toPlainString() : null, sc.getCharset()));
} else {
curRow.add(StringUtil.encode(rs.getString(j), sc.getCharset()));
}
}
curRow.packetId = ++packetId;
byteBuf = curRow.write(byteBuf, sc, false);
byteBuf.flip();
byte[] row = new byte[byteBuf.limit()];
byteBuf.get(row);
byteBuf.clear();
this.respHandler.rowResponse(row, this);
}
fieldPks.clear();
// end row
eofPckg = new EOFPacket();
eofPckg.packetId = ++packetId;
byteBuf = eofPckg.write(byteBuf, sc, false);
byteBuf.flip();
eof = new byte[byteBuf.limit()];
byteBuf.get(eof);
sc.recycle(byteBuf);
this.respHandler.rowEofResponse(eof, this);
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
}
}
}
}
use of io.mycat.net.mysql.ResultSetHeaderPacket in project Mycat-Server by MyCATApache.
the class MultiNodeQueryHandler method fieldEofResponse.
@Override
public void fieldEofResponse(byte[] header, List<byte[]> fields, byte[] eof, BackendConnection conn) {
// huangyiming add
this.header = header;
this.fields = fields;
MiddlerResultHandler middlerResultHandler = session.getMiddlerResultHandler();
/*if(null !=middlerResultHandler ){
return;
}*/
this.netOutBytes += header.length;
this.netOutBytes += eof.length;
for (int i = 0, len = fields.size(); i < len; ++i) {
byte[] field = fields.get(i);
this.netOutBytes += field.length;
}
ServerConnection source = null;
if (fieldsReturned) {
return;
}
lock.lock();
try {
if (fieldsReturned) {
return;
}
fieldsReturned = true;
boolean needMerg = (dataMergeSvr != null) && dataMergeSvr.getRrs().needMerge();
Set<String> shouldRemoveAvgField = new HashSet<>();
Set<String> shouldRenameAvgField = new HashSet<>();
if (needMerg) {
Map<String, Integer> mergeColsMap = dataMergeSvr.getRrs().getMergeCols();
if (mergeColsMap != null) {
for (Map.Entry<String, Integer> entry : mergeColsMap.entrySet()) {
String key = entry.getKey();
int mergeType = entry.getValue();
if (MergeCol.MERGE_AVG == mergeType && mergeColsMap.containsKey(key + "SUM")) {
shouldRemoveAvgField.add((key + "COUNT").toUpperCase());
shouldRenameAvgField.add((key + "SUM").toUpperCase());
}
}
}
}
source = session.getSource();
ByteBuffer buffer = source.allocate();
fieldCount = fields.size();
if (shouldRemoveAvgField.size() > 0) {
ResultSetHeaderPacket packet = new ResultSetHeaderPacket();
packet.packetId = ++packetId;
packet.fieldCount = fieldCount - shouldRemoveAvgField.size();
buffer = packet.write(buffer, source, true);
} else {
header[3] = ++packetId;
buffer = source.writeToBuffer(header, buffer);
}
String primaryKey = null;
if (rrs.hasPrimaryKeyToCache()) {
String[] items = rrs.getPrimaryKeyItems();
priamaryKeyTable = items[0];
primaryKey = items[1];
}
Map<String, ColMeta> columToIndx = new HashMap<String, ColMeta>(fieldCount);
for (int i = 0, len = fieldCount; i < len; ++i) {
boolean shouldSkip = false;
byte[] field = fields.get(i);
if (needMerg) {
FieldPacket fieldPkg = new FieldPacket();
fieldPkg.read(field);
fieldPackets.add(fieldPkg);
String fieldName = new String(fieldPkg.name).toUpperCase();
if (columToIndx != null && !columToIndx.containsKey(fieldName)) {
if (shouldRemoveAvgField.contains(fieldName)) {
shouldSkip = true;
fieldPackets.remove(fieldPackets.size() - 1);
}
if (shouldRenameAvgField.contains(fieldName)) {
String newFieldName = fieldName.substring(0, fieldName.length() - 3);
fieldPkg.name = newFieldName.getBytes();
fieldPkg.packetId = ++packetId;
shouldSkip = true;
// 处理AVG字段位数和精度, AVG位数 = SUM位数 - 14
fieldPkg.length = fieldPkg.length - 14;
// AVG精度 = SUM精度 + 4
fieldPkg.decimals = (byte) (fieldPkg.decimals + 4);
buffer = fieldPkg.write(buffer, source, false);
// 还原精度
fieldPkg.decimals = (byte) (fieldPkg.decimals - 4);
}
ColMeta colMeta = new ColMeta(i, fieldPkg.type);
colMeta.decimals = fieldPkg.decimals;
columToIndx.put(fieldName, colMeta);
}
} else {
FieldPacket fieldPkg = new FieldPacket();
fieldPkg.read(field);
fieldPackets.add(fieldPkg);
fieldCount = fields.size();
if (primaryKey != null && primaryKeyIndex == -1) {
// find primary key index
String fieldName = new String(fieldPkg.name);
if (primaryKey.equalsIgnoreCase(fieldName)) {
primaryKeyIndex = i;
}
}
}
if (!shouldSkip) {
field[3] = ++packetId;
buffer = source.writeToBuffer(field, buffer);
}
}
eof[3] = ++packetId;
buffer = source.writeToBuffer(eof, buffer);
if (null == middlerResultHandler) {
// session.getSource().write(row);
source.write(buffer);
}
if (dataMergeSvr != null) {
dataMergeSvr.onRowMetaData(columToIndx, fieldCount);
}
} catch (Exception e) {
handleDataProcessException(e);
} finally {
lock.unlock();
}
}
use of io.mycat.net.mysql.ResultSetHeaderPacket in project Mycat-Server by MyCATApache.
the class PostgreSQLBackendConnectionHandler method doProcessBusinessQuery.
/**
*************
* 处理简单查询结果 ,每一个查询都是一件 CommandComplete 为结束
* @param con PostgreSQL 后端连接
* @param response
* @param commandComplete
*/
private void doProcessBusinessQuery(PostgreSQLBackendConnection con, SelectResponse response, CommandComplete commandComplete) {
RowDescription rowHd = response.getDescription();
List<FieldPacket> fieldPks = PgPacketApaterUtils.rowDescConvertFieldPacket(rowHd);
List<RowDataPacket> rowDatas = new ArrayList<>();
for (DataRow dataRow : response.getDataRows()) {
rowDatas.add(PgPacketApaterUtils.rowDataConvertRowDataPacket(dataRow));
}
BufferArray bufferArray = MycatServer.getInstance().getBufferPool().allocateArray();
ResultSetHeaderPacket headerPkg = new ResultSetHeaderPacket();
headerPkg.fieldCount = fieldPks.size();
headerPkg.packetId = ++packetId;
headerPkg.write(bufferArray);
byte[] header = bufferArray.writeToByteArrayAndRecycle();
List<byte[]> fields = new ArrayList<byte[]>(fieldPks.size());
Iterator<FieldPacket> itor = fieldPks.iterator();
while (itor.hasNext()) {
bufferArray = MycatServer.getInstance().getBufferPool().allocateArray();
FieldPacket curField = itor.next();
curField.packetId = ++packetId;
curField.write(bufferArray);
byte[] field = bufferArray.writeToByteArrayAndRecycle();
fields.add(field);
itor.remove();
}
bufferArray = MycatServer.getInstance().getBufferPool().allocateArray();
EOFPacket eofPckg = new EOFPacket();
eofPckg.packetId = ++packetId;
eofPckg.write(bufferArray);
byte[] eof = bufferArray.writeToByteArrayAndRecycle();
if (con.getResponseHandler() != null) {
con.getResponseHandler().fieldEofResponse(header, fields, eof, con);
} else {
LOGGER.error("响应句柄为空");
}
// output row
for (RowDataPacket curRow : rowDatas) {
bufferArray = MycatServer.getInstance().getBufferPool().allocateArray();
curRow.packetId = ++packetId;
curRow.write(bufferArray);
byte[] row = bufferArray.writeToByteArrayAndRecycle();
con.getResponseHandler().rowResponse(row, con);
}
// end row
bufferArray = MycatServer.getInstance().getBufferPool().allocateArray();
eofPckg = new EOFPacket();
eofPckg.packetId = ++packetId;
eofPckg.write(bufferArray);
eof = bufferArray.writeToByteArrayAndRecycle();
if (con.getResponseHandler() != null) {
con.getResponseHandler().rowEofResponse(eof, con);
} else {
LOGGER.error("响应句柄为空");
}
}
Aggregations