Search in sources :

Example 1 with LazyString

use of com.mysql.cj.util.LazyString in project ABC by RuiPinto96274.

the class ColumnDefinitionReader method unpackField.

/**
 * Unpacks the Field information from the given packet.
 *
 * @param packet
 *            the packet containing the field information
 * @param characterSetMetadata
 *            encoding of the metadata in the packet
 *
 * @return the unpacked field
 */
protected Field unpackField(NativePacketPayload packet, String characterSetMetadata) {
    int offset, length;
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    // skip database name
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString databaseName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString tableName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString originalTableName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString columnName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString originalColumnName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    packet.readInteger(IntegerDataType.INT1);
    short collationIndex = (short) packet.readInteger(IntegerDataType.INT2);
    long colLength = packet.readInteger(IntegerDataType.INT4);
    int colType = (int) packet.readInteger(IntegerDataType.INT1);
    short colFlag = (short) packet.readInteger(this.protocol.getServerSession().hasLongColumnInfo() ? IntegerDataType.INT2 : IntegerDataType.INT1);
    int colDecimals = (int) packet.readInteger(IntegerDataType.INT1);
    String encoding = this.protocol.getServerSession().getCharsetSettings().getJavaEncodingForCollationIndex(collationIndex);
    MysqlType mysqlType = NativeProtocol.findMysqlType(this.protocol.getPropertySet(), colType, colFlag, colLength, tableName, originalTableName, collationIndex, encoding);
    // Protocol returns precision and scale differently for some types. We need to align then to I_S.
    switch(mysqlType) {
        case TINYINT:
        case TINYINT_UNSIGNED:
        case SMALLINT:
        case SMALLINT_UNSIGNED:
        case MEDIUMINT:
        case MEDIUMINT_UNSIGNED:
        case INT:
        case INT_UNSIGNED:
        case BIGINT:
        case BIGINT_UNSIGNED:
        case BOOLEAN:
            colLength = mysqlType.getPrecision().intValue();
            break;
        case DECIMAL:
            colLength--;
            if (colDecimals > 0) {
                colLength--;
            }
            break;
        case DECIMAL_UNSIGNED:
            if (colDecimals > 0) {
                colLength--;
            }
            break;
        case FLOAT:
        case FLOAT_UNSIGNED:
        case DOUBLE:
        case DOUBLE_UNSIGNED:
            // It's probably a mistake that it's exposed by protocol as a decimals and it should be replaced with 0.
            if (colDecimals == 31) {
                colDecimals = 0;
            }
            break;
        default:
            break;
    }
    return new Field(databaseName, tableName, originalTableName, columnName, originalColumnName, colLength, colType, colFlag, colDecimals, collationIndex, encoding, mysqlType);
}
Also used : MysqlType(com.mysql.cj.MysqlType) Field(com.mysql.cj.result.Field) LazyString(com.mysql.cj.util.LazyString) LazyString(com.mysql.cj.util.LazyString)

Example 2 with LazyString

use of com.mysql.cj.util.LazyString in project ABC by RuiPinto96274.

the class FieldFactory method columnMetaDataToField.

/**
 * Convert a X Protocol {@link ColumnMetaData} message to a C/J {@link Field} object.
 *
 * @param col
 *            the message from the server
 * @param characterSet
 *            the encoding of the strings in the message
 * @return {@link Field}
 */
private Field columnMetaDataToField(ColumnMetaData col, String characterSet) {
    try {
        LazyString databaseName = new LazyString(col.getSchema().toString(characterSet));
        LazyString tableName = new LazyString(col.getTable().toString(characterSet));
        LazyString originalTableName = new LazyString(col.getOriginalTable().toString(characterSet));
        LazyString columnName = new LazyString(col.getName().toString(characterSet));
        LazyString originalColumnName = new LazyString(col.getOriginalName().toString(characterSet));
        long length = Integer.toUnsignedLong(col.getLength());
        int decimals = col.getFractionalDigits();
        int collationIndex = 0;
        if (col.hasCollation()) {
            // TODO: support custom character set
            collationIndex = (int) col.getCollation();
        }
        String encoding = CharsetMapping.getStaticJavaEncodingForCollationIndex(collationIndex);
        MysqlType mysqlType = findMysqlType(col.getType(), col.getContentType(), col.getFlags(), collationIndex);
        int mysqlTypeId = xProtocolTypeToMysqlType(col.getType(), col.getContentType());
        // flags translation; unsigned is handled in Field by checking the MysqlType, so here we check others
        short flags = (short) 0;
        if (col.getType().equals(FieldType.UINT) && 0 < (col.getFlags() & XPROTOCOL_COLUMN_FLAGS_UINT_ZEROFILL)) {
            flags |= MysqlType.FIELD_FLAG_ZEROFILL;
        } else if (col.getType().equals(FieldType.BYTES) && 0 < (col.getFlags() & XPROTOCOL_COLUMN_FLAGS_BYTES_RIGHTPAD)) {
            mysqlType = MysqlType.CHAR;
        } else if (col.getType().equals(FieldType.DATETIME) && 0 < (col.getFlags() & XPROTOCOL_COLUMN_FLAGS_DATETIME_TIMESTAMP)) {
            mysqlType = MysqlType.TIMESTAMP;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_NOT_NULL) > 0) {
            flags |= MysqlType.FIELD_FLAG_NOT_NULL;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_PRIMARY_KEY) > 0) {
            flags |= MysqlType.FIELD_FLAG_PRIMARY_KEY;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_UNIQUE_KEY) > 0) {
            flags |= MysqlType.FIELD_FLAG_UNIQUE_KEY;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_MULTIPLE_KEY) > 0) {
            flags |= MysqlType.FIELD_FLAG_MULTIPLE_KEY;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_AUTO_INCREMENT) > 0) {
            flags |= MysqlType.FIELD_FLAG_AUTO_INCREMENT;
        }
        // It's probably a mistake that it's exposed by protocol as a decimals and it should be replaced with 0.
        switch(mysqlType) {
            case FLOAT:
            case FLOAT_UNSIGNED:
            case DOUBLE:
            case DOUBLE_UNSIGNED:
                if (decimals == 31) {
                    decimals = 0;
                }
                break;
            default:
                break;
        }
        Field f = new Field(databaseName, tableName, originalTableName, columnName, originalColumnName, length, mysqlTypeId, flags, decimals, collationIndex, encoding, mysqlType);
        return f;
    } catch (UnsupportedEncodingException ex) {
        throw new WrongArgumentException("Unable to decode metadata strings", ex);
    }
}
Also used : MysqlType(com.mysql.cj.MysqlType) Field(com.mysql.cj.result.Field) LazyString(com.mysql.cj.util.LazyString) UnsupportedEncodingException(java.io.UnsupportedEncodingException) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException) LazyString(com.mysql.cj.util.LazyString)

Example 3 with LazyString

use of com.mysql.cj.util.LazyString in project JavaSegundasQuintas by ecteruel.

the class NativeProtocol method sendQueryPacket.

/**
 * Send a query stored in a packet to the server.
 *
 * @param <T>
 *            extends {@link Resultset}
 * @param callingQuery
 *            {@link Query}
 * @param queryPacket
 *            {@link NativePacketPayload} containing query
 * @param maxRows
 *            rows limit
 * @param streamResults
 *            whether a stream result should be created
 * @param cachedMetadata
 *            use this metadata instead of the one provided on wire
 * @param resultSetFactory
 *            {@link ProtocolEntityFactory}
 * @return T instance
 * @throws IOException
 *             if an i/o error occurs
 */
public final <T extends Resultset> T sendQueryPacket(Query callingQuery, NativePacketPayload queryPacket, int maxRows, boolean streamResults, ColumnDefinition cachedMetadata, ProtocolEntityFactory<T, NativePacketPayload> resultSetFactory) throws IOException {
    final long queryStartTime = getCurrentTimeNanosOrMillis();
    this.statementExecutionDepth++;
    byte[] queryBuf = queryPacket.getByteBuffer();
    // save the packet position
    int oldPacketPosition = queryPacket.getPosition();
    int queryPosition = queryPacket.getTag("QUERY");
    LazyString query = new LazyString(queryBuf, queryPosition, (oldPacketPosition - queryPosition));
    try {
        if (this.queryInterceptors != null) {
            T interceptedResults = invokeQueryInterceptorsPre(query, callingQuery, false);
            if (interceptedResults != null) {
                return interceptedResults;
            }
        }
        if (this.autoGenerateTestcaseScript) {
            StringBuilder debugBuf = new StringBuilder(query.length() + 32);
            generateQueryCommentBlock(debugBuf);
            debugBuf.append(query);
            debugBuf.append(';');
            TestUtils.dumpTestcaseQuery(debugBuf.toString());
        }
        // Send query command and sql query string
        NativePacketPayload resultPacket = sendCommand(queryPacket, false, 0);
        final long queryEndTime = getCurrentTimeNanosOrMillis();
        final long queryDuration = queryEndTime - queryStartTime;
        if (callingQuery != null) {
            callingQuery.setExecuteTime(queryDuration);
        }
        boolean queryWasSlow = this.logSlowQueries && (this.useAutoSlowLog ? this.metricsHolder.checkAbonormallyLongQuery(queryDuration) : queryDuration > this.propertySet.getIntegerProperty(PropertyKey.slowQueryThresholdMillis).getValue());
        long fetchBeginTime = this.profileSQL ? getCurrentTimeNanosOrMillis() : 0L;
        T rs = readAllResults(maxRows, streamResults, resultPacket, false, cachedMetadata, resultSetFactory);
        if (this.profileSQL || queryWasSlow) {
            long fetchEndTime = this.profileSQL ? getCurrentTimeNanosOrMillis() : 0L;
            // Extract the actual query from the network packet
            boolean truncated = oldPacketPosition - queryPosition > this.maxQuerySizeToLog.getValue();
            int extractPosition = truncated ? this.maxQuerySizeToLog.getValue() + queryPosition : oldPacketPosition;
            String extractedQuery = StringUtils.toString(queryBuf, queryPosition, (extractPosition - queryPosition));
            if (truncated) {
                extractedQuery += Messages.getString("Protocol.2");
            }
            ProfilerEventHandler eventSink = this.session.getProfilerEventHandler();
            if (this.logSlowQueries) {
                if (queryWasSlow) {
                    eventSink.processEvent(ProfilerEvent.TYPE_SLOW_QUERY, this.session, callingQuery, rs, queryDuration, new Throwable(), Messages.getString("Protocol.SlowQuery", new Object[] { this.useAutoSlowLog ? " 95% of all queries " : String.valueOf(this.slowQueryThreshold), this.queryTimingUnits, Long.valueOf(queryDuration), extractedQuery }));
                    if (this.propertySet.getBooleanProperty(PropertyKey.explainSlowQueries).getValue()) {
                        if (oldPacketPosition - queryPosition < MAX_QUERY_SIZE_TO_EXPLAIN) {
                            // skip until the query is located in the packet
                            queryPacket.setPosition(queryPosition);
                            explainSlowQuery(query.toString(), extractedQuery);
                        } else {
                            this.log.logWarn(Messages.getString("Protocol.3", new Object[] { MAX_QUERY_SIZE_TO_EXPLAIN }));
                        }
                    }
                }
                if (this.serverSession.noGoodIndexUsed()) {
                    eventSink.processEvent(ProfilerEvent.TYPE_SLOW_QUERY, this.session, callingQuery, rs, queryDuration, new Throwable(), Messages.getString("Protocol.4") + extractedQuery);
                }
                if (this.serverSession.noIndexUsed()) {
                    eventSink.processEvent(ProfilerEvent.TYPE_SLOW_QUERY, this.session, callingQuery, rs, queryDuration, new Throwable(), Messages.getString("Protocol.5") + extractedQuery);
                }
                if (this.serverSession.queryWasSlow()) {
                    eventSink.processEvent(ProfilerEvent.TYPE_SLOW_QUERY, this.session, callingQuery, rs, queryDuration, new Throwable(), Messages.getString("Protocol.ServerSlowQuery") + extractedQuery);
                }
            }
            if (this.profileSQL) {
                eventSink.processEvent(ProfilerEvent.TYPE_QUERY, this.session, callingQuery, rs, queryDuration, new Throwable(), extractedQuery);
                eventSink.processEvent(ProfilerEvent.TYPE_FETCH, this.session, callingQuery, rs, (fetchEndTime - fetchBeginTime), new Throwable(), null);
            }
        }
        if (this.hadWarnings) {
            scanForAndThrowDataTruncation();
        }
        if (this.queryInterceptors != null) {
            rs = invokeQueryInterceptorsPost(query, callingQuery, rs, false);
        }
        return rs;
    } catch (CJException sqlEx) {
        if (this.queryInterceptors != null) {
            // TODO why doing this?
            // we don't do anything with the result set in this case
            invokeQueryInterceptorsPost(query, callingQuery, null, false);
        }
        if (callingQuery != null) {
            callingQuery.checkCancelTimeout();
        }
        throw sqlEx;
    } finally {
        this.statementExecutionDepth--;
    }
}
Also used : ProfilerEventHandler(com.mysql.cj.log.ProfilerEventHandler) LazyString(com.mysql.cj.util.LazyString) LazyString(com.mysql.cj.util.LazyString) CJException(com.mysql.cj.exceptions.CJException)

Example 4 with LazyString

use of com.mysql.cj.util.LazyString in project JavaSegundasQuintas by ecteruel.

the class ColumnDefinitionReader method unpackField.

/**
 * Unpacks the Field information from the given packet.
 *
 * @param packet
 *            the packet containing the field information
 * @param characterSetMetadata
 *            encoding of the metadata in the packet
 *
 * @return the unpacked field
 */
protected Field unpackField(NativePacketPayload packet, String characterSetMetadata) {
    int offset, length;
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    // skip database name
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString databaseName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString tableName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString originalTableName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString columnName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    length = (int) packet.readInteger(IntegerDataType.INT_LENENC);
    offset = packet.getPosition();
    LazyString originalColumnName = new LazyString(packet.getByteBuffer(), offset, length, characterSetMetadata);
    packet.setPosition(packet.getPosition() + length);
    packet.readInteger(IntegerDataType.INT1);
    short collationIndex = (short) packet.readInteger(IntegerDataType.INT2);
    long colLength = packet.readInteger(IntegerDataType.INT4);
    int colType = (int) packet.readInteger(IntegerDataType.INT1);
    short colFlag = (short) packet.readInteger(this.protocol.getServerSession().hasLongColumnInfo() ? IntegerDataType.INT2 : IntegerDataType.INT1);
    int colDecimals = (int) packet.readInteger(IntegerDataType.INT1);
    String encoding = this.protocol.getServerSession().getCharsetSettings().getJavaEncodingForCollationIndex(collationIndex);
    MysqlType mysqlType = NativeProtocol.findMysqlType(this.protocol.getPropertySet(), colType, colFlag, colLength, tableName, originalTableName, collationIndex, encoding);
    // Protocol returns precision and scale differently for some types. We need to align then to I_S.
    switch(mysqlType) {
        case TINYINT:
        case TINYINT_UNSIGNED:
        case SMALLINT:
        case SMALLINT_UNSIGNED:
        case MEDIUMINT:
        case MEDIUMINT_UNSIGNED:
        case INT:
        case INT_UNSIGNED:
        case BIGINT:
        case BIGINT_UNSIGNED:
        case BOOLEAN:
            colLength = mysqlType.getPrecision().intValue();
            break;
        case DECIMAL:
            colLength--;
            if (colDecimals > 0) {
                colLength--;
            }
            break;
        case DECIMAL_UNSIGNED:
            if (colDecimals > 0) {
                colLength--;
            }
            break;
        case FLOAT:
        case FLOAT_UNSIGNED:
        case DOUBLE:
        case DOUBLE_UNSIGNED:
            // It's probably a mistake that it's exposed by protocol as a decimals and it should be replaced with 0.
            if (colDecimals == 31) {
                colDecimals = 0;
            }
            break;
        default:
            break;
    }
    return new Field(databaseName, tableName, originalTableName, columnName, originalColumnName, colLength, colType, colFlag, colDecimals, collationIndex, encoding, mysqlType);
}
Also used : MysqlType(com.mysql.cj.MysqlType) Field(com.mysql.cj.result.Field) LazyString(com.mysql.cj.util.LazyString) LazyString(com.mysql.cj.util.LazyString)

Example 5 with LazyString

use of com.mysql.cj.util.LazyString in project aws-mysql-jdbc by awslabs.

the class FieldFactory method columnMetaDataToField.

/**
 * Convert a X Protocol {@link ColumnMetaData} message to a C/J {@link Field} object.
 *
 * @param col
 *            the message from the server
 * @param characterSet
 *            the encoding of the strings in the message
 * @return {@link Field}
 */
private Field columnMetaDataToField(ColumnMetaData col, String characterSet) {
    try {
        LazyString databaseName = new LazyString(col.getSchema().toString(characterSet));
        LazyString tableName = new LazyString(col.getTable().toString(characterSet));
        LazyString originalTableName = new LazyString(col.getOriginalTable().toString(characterSet));
        LazyString columnName = new LazyString(col.getName().toString(characterSet));
        LazyString originalColumnName = new LazyString(col.getOriginalName().toString(characterSet));
        long length = Integer.toUnsignedLong(col.getLength());
        int decimals = col.getFractionalDigits();
        int collationIndex = 0;
        if (col.hasCollation()) {
            // TODO: support custom character set
            collationIndex = (int) col.getCollation();
        }
        String encoding = CharsetMapping.getStaticJavaEncodingForCollationIndex(collationIndex);
        MysqlType mysqlType = findMysqlType(col.getType(), col.getContentType(), col.getFlags(), collationIndex);
        int mysqlTypeId = xProtocolTypeToMysqlType(col.getType(), col.getContentType());
        // flags translation; unsigned is handled in Field by checking the MysqlType, so here we check others
        short flags = (short) 0;
        if (col.getType().equals(FieldType.UINT) && 0 < (col.getFlags() & XPROTOCOL_COLUMN_FLAGS_UINT_ZEROFILL)) {
            flags |= MysqlType.FIELD_FLAG_ZEROFILL;
        } else if (col.getType().equals(FieldType.BYTES) && 0 < (col.getFlags() & XPROTOCOL_COLUMN_FLAGS_BYTES_RIGHTPAD)) {
            mysqlType = MysqlType.CHAR;
        } else if (col.getType().equals(FieldType.DATETIME) && 0 < (col.getFlags() & XPROTOCOL_COLUMN_FLAGS_DATETIME_TIMESTAMP)) {
            mysqlType = MysqlType.TIMESTAMP;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_NOT_NULL) > 0) {
            flags |= MysqlType.FIELD_FLAG_NOT_NULL;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_PRIMARY_KEY) > 0) {
            flags |= MysqlType.FIELD_FLAG_PRIMARY_KEY;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_UNIQUE_KEY) > 0) {
            flags |= MysqlType.FIELD_FLAG_UNIQUE_KEY;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_MULTIPLE_KEY) > 0) {
            flags |= MysqlType.FIELD_FLAG_MULTIPLE_KEY;
        }
        if ((col.getFlags() & XPROTOCOL_COLUMN_FLAGS_AUTO_INCREMENT) > 0) {
            flags |= MysqlType.FIELD_FLAG_AUTO_INCREMENT;
        }
        // It's probably a mistake that it's exposed by protocol as a decimals and it should be replaced with 0.
        switch(mysqlType) {
            case FLOAT:
            case FLOAT_UNSIGNED:
            case DOUBLE:
            case DOUBLE_UNSIGNED:
                if (decimals == 31) {
                    decimals = 0;
                }
                break;
            default:
                break;
        }
        Field f = new Field(databaseName, tableName, originalTableName, columnName, originalColumnName, length, mysqlTypeId, flags, decimals, collationIndex, encoding, mysqlType);
        return f;
    } catch (UnsupportedEncodingException ex) {
        throw new WrongArgumentException("Unable to decode metadata strings", ex);
    }
}
Also used : MysqlType(com.mysql.cj.MysqlType) Field(com.mysql.cj.result.Field) LazyString(com.mysql.cj.util.LazyString) UnsupportedEncodingException(java.io.UnsupportedEncodingException) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException) LazyString(com.mysql.cj.util.LazyString)

Aggregations

LazyString (com.mysql.cj.util.LazyString)9 MysqlType (com.mysql.cj.MysqlType)6 Field (com.mysql.cj.result.Field)6 CJException (com.mysql.cj.exceptions.CJException)3 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)3 ProfilerEventHandler (com.mysql.cj.log.ProfilerEventHandler)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3