Execute Prepared Statement https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_stmt_execute.html
(args []driver.Value)
| 1043 | // Execute Prepared Statement |
| 1044 | // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_stmt_execute.html |
| 1045 | func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error { |
| 1046 | if len(args) != stmt.paramCount { |
| 1047 | return fmt.Errorf( |
| 1048 | "argument count mismatch (got: %d; has: %d)", |
| 1049 | len(args), |
| 1050 | stmt.paramCount, |
| 1051 | ) |
| 1052 | } |
| 1053 | |
| 1054 | const minPktLen = 4 + 1 + 4 + 1 + 4 |
| 1055 | mc := stmt.mc |
| 1056 | |
| 1057 | // Determine threshold dynamically to avoid packet size shortage. |
| 1058 | longDataSize := max(mc.maxAllowedPacket/(stmt.paramCount+1), 64) |
| 1059 | |
| 1060 | // Reset packet-sequence |
| 1061 | mc.resetSequence() |
| 1062 | |
| 1063 | var data []byte |
| 1064 | var err error |
| 1065 | |
| 1066 | if len(args) == 0 { |
| 1067 | data, err = mc.buf.takeBuffer(minPktLen) |
| 1068 | } else { |
| 1069 | data, err = mc.buf.takeCompleteBuffer() |
| 1070 | // In this case the len(data) == cap(data) which is used to optimise the flow below. |
| 1071 | } |
| 1072 | if err != nil { |
| 1073 | return err |
| 1074 | } |
| 1075 | |
| 1076 | // command [1 byte] |
| 1077 | data[4] = comStmtExecute |
| 1078 | |
| 1079 | // statement_id [4 bytes] |
| 1080 | binary.LittleEndian.PutUint32(data[5:], stmt.id) |
| 1081 | |
| 1082 | // flags (0: CURSOR_TYPE_NO_CURSOR) [1 byte] |
| 1083 | data[9] = 0x00 |
| 1084 | |
| 1085 | // iteration_count (uint32(1)) [4 bytes] |
| 1086 | binary.LittleEndian.PutUint32(data[10:], 1) |
| 1087 | |
| 1088 | if len(args) > 0 { |
| 1089 | pos := minPktLen |
| 1090 | |
| 1091 | var nullMask []byte |
| 1092 | if maskLen, typesLen := (len(args)+7)/8, 1+2*len(args); pos+maskLen+typesLen >= cap(data) { |
| 1093 | // buffer has to be extended but we don't know by how much so |
| 1094 | // we depend on append after all data with known sizes fit. |
| 1095 | // We stop at that because we deal with a lot of columns here |
| 1096 | // which makes the required allocation size hard to guess. |
| 1097 | tmp := make([]byte, pos+maskLen+typesLen) |
| 1098 | copy(tmp[:pos], data[:pos]) |
| 1099 | data = tmp |
| 1100 | nullMask = data[pos : pos+maskLen] |
| 1101 | // No need to clean nullMask as make ensures that. |
| 1102 | pos += maskLen |
no test coverage detected