public NativePacketPayload buildComStmtExecute()

in src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeMessageBuilder.java [378:477]


    public NativePacketPayload buildComStmtExecute(NativePacketPayload sharedPacket, long serverStatementId, byte flags, boolean sendQueryAttributes,
            PreparedQuery preparedQuery) {
        NativePacketPayload packet = sharedPacket != null ? sharedPacket : new NativePacketPayload(5);

        Session sess = preparedQuery.getSession();
        int parameterCount = preparedQuery.getParameterCount();
        QueryBindings queryBindings = preparedQuery.getQueryBindings();
        BindValue[] parameterBindings = queryBindings.getBindValues();
        QueryAttributesBindings queryAttributesBindings = preparedQuery.getQueryAttributesBindings();

        packet.writeInteger(IntegerDataType.INT1, NativeConstants.COM_STMT_EXECUTE);
        packet.writeInteger(IntegerDataType.INT4, serverStatementId);
        packet.writeInteger(IntegerDataType.INT1, flags);
        packet.writeInteger(IntegerDataType.INT4, 1); // placeholder for parameter iterations

        boolean contextPropagationAttributeWasInjected = false;
        int parametersAndAttributesCount = parameterCount;
        if (this.supportsQueryAttributes) {
            if (sendQueryAttributes) {
                if (!queryAttributesBindings.containsAttribute(sess.getTelemetryHandler().getContextPropagationKey())) {
                    sess.getTelemetryHandler().propagateContext(queryAttributesBindings::setAttribute);
                    contextPropagationAttributeWasInjected = true;
                }
                parametersAndAttributesCount += queryAttributesBindings.getCount();
            }
            if (sendQueryAttributes || parametersAndAttributesCount > 0) {
                // Servers between 8.0.23 and 8.0.25 don't expect a 'parameter_count' value if the statement was prepared without parameters.
                packet.writeInteger(IntegerDataType.INT_LENENC, parametersAndAttributesCount);
            }
        }

        if (parametersAndAttributesCount > 0) {
            /* Reserve place for null-marker bytes */
            int nullCount = (parametersAndAttributesCount + 7) / 8;
            int nullBitsPosition = packet.getPosition();
            for (int i = 0; i < nullCount; i++) {
                packet.writeInteger(IntegerDataType.INT1, 0);
            }
            byte[] nullBitsBuffer = new byte[nullCount];

            // In case if buffers (type) changed or there are query attributes to send.
            if (queryBindings.getSendTypesToServer().get() || sendQueryAttributes && queryAttributesBindings.getCount() > 0) {
                packet.writeInteger(IntegerDataType.INT1, 1);

                // Store types of parameters in the first packet that is sent to the server.
                for (int i = 0; i < parameterCount; i++) {
                    packet.writeInteger(IntegerDataType.INT2, parameterBindings[i].getFieldType());
                    if (this.supportsQueryAttributes) {
                        packet.writeBytes(StringSelfDataType.STRING_LENENC, "".getBytes()); // Parameters have no names.
                    }
                }

                if (sendQueryAttributes) {
                    queryAttributesBindings.runThroughAll(a -> {
                        packet.writeInteger(IntegerDataType.INT2, a.getFieldType());
                        packet.writeBytes(StringSelfDataType.STRING_LENENC, a.getName().getBytes());
                    });
                }
            } else {
                packet.writeInteger(IntegerDataType.INT1, 0);
            }

            // Store the parameter values.
            for (int i = 0; i < parameterCount; i++) {
                if (!parameterBindings[i].isStream()) {
                    if (!parameterBindings[i].isNull()) {
                        parameterBindings[i].writeAsBinary(packet);
                    } else {
                        nullBitsBuffer[i >>> 3] |= 1 << (i & 7);
                    }
                }
            }

            if (sendQueryAttributes) {
                for (int i = 0; i < queryAttributesBindings.getCount(); i++) {
                    if (queryAttributesBindings.getAttributeValue(i).isNull()) {
                        int b = i + parameterCount;
                        nullBitsBuffer[b >>> 3] |= 1 << (b & 7);
                    }
                }
                queryAttributesBindings.runThroughAll(a -> {
                    if (!a.isNull()) {
                        a.writeAsQueryAttribute(packet);
                    }
                });
            }

            // Go back and write the NULL flags to the beginning of the packet
            int endPosition = packet.getPosition();
            packet.setPosition(nullBitsPosition);
            packet.writeBytes(StringLengthDataType.STRING_FIXED, nullBitsBuffer);
            packet.setPosition(endPosition);
        }

        if (contextPropagationAttributeWasInjected) {
            queryAttributesBindings.removeAttribute(sess.getTelemetryHandler().getContextPropagationKey());
        }

        return packet;
    }