Search in sources :

Example 1 with DefaultPreparedOKPacket

use of io.mycat.beans.mysql.packet.DefaultPreparedOKPacket in project Mycat2 by MyCATApache.

the class DefaultCommandHandler method handlePrepareStatement.

@Override
public Future<Void> handlePrepareStatement(byte[] sqlBytes, MySQLServerSession session) {
    try {
        MycatDataContext dataContext = session.getDataContext();
        boolean deprecateEOF = session.isDeprecateEOF();
        String sql = new String(sqlBytes);
        // ///////////////////////////////////////////////////
        SQLStatement sqlStatement = SQLUtils.parseSingleMysqlStatement(sql);
        boolean allow = (sqlStatement instanceof SQLSelectStatement || sqlStatement instanceof SQLInsertStatement || sqlStatement instanceof SQLUpdateStatement || sqlStatement instanceof SQLDeleteStatement);
        MetadataManager metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class);
        ResultSetBuilder fieldsBuilder = ResultSetBuilder.create();
        MycatRowMetaData fields = fieldsBuilder.build().getMetaData();
        ResultSetBuilder paramsBuilder = ResultSetBuilder.create();
        sqlStatement.accept(new MySqlASTVisitorAdapter() {

            @Override
            public void endVisit(SQLVariantRefExpr x) {
                if ("?".equalsIgnoreCase(x.getName())) {
                    SQLDataType sqlDataType = x.computeDataType();
                    JDBCType res = JDBCType.VARCHAR;
                    if (sqlDataType != null) {
                        res = JDBCType.valueOf(sqlDataType.jdbcType());
                    }
                    paramsBuilder.addColumnInfo("", res);
                }
                super.endVisit(x);
            }
        });
        MycatRowMetaData params = paramsBuilder.build().getMetaData();
        long stmtId = dataContext.nextPrepareStatementId();
        Map<Long, PreparedStatement> statementMap = dataContext.getPrepareInfo();
        statementMap.put(stmtId, new PreparedStatement(stmtId, sqlStatement, params.getColumnCount()));
        DefaultPreparedOKPacket info = new DefaultPreparedOKPacket(stmtId, fields.getColumnCount(), params.getColumnCount(), session.getWarningCount());
        if (info.getPrepareOkColumnsCount() == 0 && info.getPrepareOkParametersCount() == 0) {
            session.writeBytes(MySQLPacketUtil.generatePrepareOk(info), true);
            return Future.succeededFuture();
        }
        session.writeBytes(MySQLPacketUtil.generatePrepareOk(info), false);
        if (info.getPrepareOkParametersCount() > 0 && info.getPrepareOkColumnsCount() == 0) {
            for (int i = 0; i < info.getPrepareOkParametersCount() - 1; i++) {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(params, i), false);
            }
            if (deprecateEOF) {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(params, info.getPrepareOkParametersCount() - 1), true);
            } else {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(params, info.getPrepareOkParametersCount() - 1), false);
                session.writeBytes(MySQLPacketUtil.generateEof(session.getWarningCount(), session.getServerStatusValue()), true);
            }
            return Future.succeededFuture();
        } else if (info.getPrepareOkParametersCount() == 0 && info.getPrepareOkColumnsCount() > 0) {
            for (int i = 0; i < info.getPrepareOkColumnsCount() - 1; i++) {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, i), false);
            }
            if (deprecateEOF) {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, info.getPrepareOkColumnsCount() - 1), true);
            } else {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, info.getPrepareOkColumnsCount() - 1), false);
                session.writeBytes(MySQLPacketUtil.generateEof(session.getWarningCount(), session.getServerStatusValue()), true);
            }
            return Future.succeededFuture();
        } else {
            for (int i = 0; i < info.getPrepareOkParametersCount() - 1; i++) {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(params, i), false);
            }
            session.writeColumnEndPacket(false);
            for (int i = 0; i < info.getPrepareOkColumnsCount() - 1; i++) {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, i), false);
            }
            if (deprecateEOF) {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, info.getPrepareOkColumnsCount() - 1), true);
            } else {
                session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, info.getPrepareOkColumnsCount() - 1), false);
                session.writeBytes(MySQLPacketUtil.generateEof(session.getWarningCount(), session.getServerStatusValue()), true);
            }
            return Future.succeededFuture();
        }
    } catch (Throwable throwable) {
        return Future.failedFuture(throwable);
    }
}
Also used : MySqlASTVisitorAdapter(com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter) ResultSetBuilder(io.mycat.beans.mycat.ResultSetBuilder) SQLDataType(com.alibaba.druid.sql.ast.SQLDataType) JDBCType(java.sql.JDBCType) SQLUpdateStatement(com.alibaba.druid.sql.ast.statement.SQLUpdateStatement) DefaultPreparedOKPacket(io.mycat.beans.mysql.packet.DefaultPreparedOKPacket) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) SQLDeleteStatement(com.alibaba.druid.sql.ast.statement.SQLDeleteStatement) SQLSelectStatement(com.alibaba.druid.sql.ast.statement.SQLSelectStatement) SQLInsertStatement(com.alibaba.druid.sql.ast.statement.SQLInsertStatement) SQLVariantRefExpr(com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr) MycatRowMetaData(io.mycat.beans.mycat.MycatRowMetaData)

Example 2 with DefaultPreparedOKPacket

use of io.mycat.beans.mysql.packet.DefaultPreparedOKPacket in project Mycat2 by MyCATApache.

the class MycatVertxMySQLHandler method handlePrepareStatement.

private Future<Void> handlePrepareStatement(byte[] bytes, MycatVertxMysqlSession mysqlSession) {
    boolean deprecateEOF = mysqlSession.isDeprecateEOF();
    String sql = new String(bytes);
    // ///////////////////////////////////////////////////
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("received pstmt sql:{}", sql);
    }
    SQLStatement sqlStatement = SQLUtils.parseSingleMysqlStatement(sql);
    boolean allow = (sqlStatement instanceof SQLSelectStatement || sqlStatement instanceof SQLInsertStatement || sqlStatement instanceof SQLUpdateStatement || sqlStatement instanceof SQLDeleteStatement);
    // MetadataManager metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class);
    MycatRowMetaData fields;
    if ((sqlStatement instanceof SQLSelectStatement)) {
        PrototypeService prototypeService = MetaClusterCurrent.wrapper(PrototypeService.class);
        Optional<MycatRowMetaData> mycatRowMetaDataForPrepareStatement = prototypeService.getMycatRowMetaDataForPrepareStatement(mysqlSession.getDataContext().getDefaultSchema(), sql);
        if (!mycatRowMetaDataForPrepareStatement.isPresent()) {
            return VertxUtil.castPromise(Future.failedFuture(new SQLException("This command is not supported in the prepared statement protocol yet", "HY000", 1295)));
        }
        fields = mycatRowMetaDataForPrepareStatement.get();
    } else {
        fields = ResultSetBuilder.create().build().getMetaData();
    }
    ResultSetBuilder paramsBuilder = ResultSetBuilder.create();
    sqlStatement.accept(new MySqlASTVisitorAdapter() {

        @Override
        public void endVisit(SQLVariantRefExpr x) {
            if ("?".equalsIgnoreCase(x.getName())) {
                JDBCType res = JDBCType.VARCHAR;
                paramsBuilder.addColumnInfo("", res);
            }
            super.endVisit(x);
        }
    });
    MycatRowMetaData params = paramsBuilder.build().getMetaData();
    long stmtId = mycatDataContext.nextPrepareStatementId();
    Map<Long, io.mycat.PreparedStatement> statementMap = this.mycatDataContext.getPrepareInfo();
    PreparedStatement preparedStatement = new PreparedStatement(stmtId, sqlStatement, params.getColumnCount());
    for (int i = 0; i < params.getColumnCount(); i++) {
        preparedStatement.getParametersType()[i] = MysqlDefs.FIELD_TYPE_STRING;
    }
    statementMap.put(stmtId, preparedStatement);
    DefaultPreparedOKPacket info = new DefaultPreparedOKPacket(stmtId, fields.getColumnCount(), params.getColumnCount(), session.getWarningCount());
    Future<Void> writeEndFuture = Future.succeededFuture();
    if (info.getPrepareOkColumnsCount() == 0 && info.getPrepareOkParametersCount() == 0) {
        return session.writeBytes(MySQLPacketUtil.generatePrepareOk(info), true);
    }
    session.writeBytes(MySQLPacketUtil.generatePrepareOk(info), false);
    if (info.getPrepareOkParametersCount() > 0 && info.getPrepareOkColumnsCount() == 0) {
        for (int i = 0; i < info.getPrepareOkParametersCount(); i++) {
            writeEndFuture = session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(params, i), info.getPrepareOkParametersCount() - 1 == i && deprecateEOF);
        }
        if (deprecateEOF) {
            return writeEndFuture;
        } else {
            return session.writeBytes(MySQLPacketUtil.generateEof(session.getWarningCount(), session.getServerStatusValue()), true);
        }
    } else if (info.getPrepareOkParametersCount() == 0 && info.getPrepareOkColumnsCount() > 0) {
        for (int i = 0; i < info.getPrepareOkColumnsCount(); i++) {
            writeEndFuture = session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, i), info.getPrepareOkColumnsCount() - 1 == i && deprecateEOF);
        }
        if (deprecateEOF) {
            return writeEndFuture;
        } else {
            return session.writeBytes(MySQLPacketUtil.generateEof(session.getWarningCount(), session.getServerStatusValue()), true);
        }
    } else {
        for (int i = 0; i < info.getPrepareOkParametersCount(); i++) {
            writeEndFuture = session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(params, i), false);
        }
        writeEndFuture = session.writeColumnEndPacket(false);
        for (int i = 0; i < info.getPrepareOkColumnsCount(); i++) {
            writeEndFuture = session.writeBytes(MySQLPacketUtil.generateColumnDefPayload(fields, i), info.getPrepareOkColumnsCount() - 1 == i && deprecateEOF);
        }
        if (deprecateEOF) {
            return writeEndFuture;
        } else {
            return session.writeBytes(MySQLPacketUtil.generateEof(session.getWarningCount(), session.getServerStatusValue()), true);
        }
    }
}
Also used : MySqlASTVisitorAdapter(com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter) ResultSetBuilder(io.mycat.beans.mycat.ResultSetBuilder) SQLException(java.sql.SQLException) DefaultPreparedOKPacket(io.mycat.beans.mysql.packet.DefaultPreparedOKPacket) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) SQLInsertStatement(com.alibaba.druid.sql.ast.statement.SQLInsertStatement) JDBCType(java.sql.JDBCType) SQLUpdateStatement(com.alibaba.druid.sql.ast.statement.SQLUpdateStatement) PrototypeService(io.mycat.prototypeserver.mysql.PrototypeService) SQLDeleteStatement(com.alibaba.druid.sql.ast.statement.SQLDeleteStatement) SQLSelectStatement(com.alibaba.druid.sql.ast.statement.SQLSelectStatement) SQLVariantRefExpr(com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr) MycatRowMetaData(io.mycat.beans.mycat.MycatRowMetaData)

Aggregations

SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)2 SQLVariantRefExpr (com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr)2 SQLDeleteStatement (com.alibaba.druid.sql.ast.statement.SQLDeleteStatement)2 SQLInsertStatement (com.alibaba.druid.sql.ast.statement.SQLInsertStatement)2 SQLSelectStatement (com.alibaba.druid.sql.ast.statement.SQLSelectStatement)2 SQLUpdateStatement (com.alibaba.druid.sql.ast.statement.SQLUpdateStatement)2 MySqlASTVisitorAdapter (com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter)2 MycatRowMetaData (io.mycat.beans.mycat.MycatRowMetaData)2 ResultSetBuilder (io.mycat.beans.mycat.ResultSetBuilder)2 DefaultPreparedOKPacket (io.mycat.beans.mysql.packet.DefaultPreparedOKPacket)2 JDBCType (java.sql.JDBCType)2 SQLDataType (com.alibaba.druid.sql.ast.SQLDataType)1 PrototypeService (io.mycat.prototypeserver.mysql.PrototypeService)1 SQLException (java.sql.SQLException)1