blackbeam / rust-mysql-simple

Mysql client library implemented in rust.
Apache License 2.0
658 stars 144 forks source link

Binlog RowsEvent Support geometry field #282

Closed jiuker closed 3 years ago

jiuker commented 3 years ago

If mysql binlog contain geometry field will panic!

use mysql::{Conn, BinlogRequest, Opts};
use mysql::prelude::{TextQuery, WithParams};
use mysql::binlog::events::{EventData, RowsEventData};
use mysql::binlog::events::EventData::TableMapEvent;
use std::collections::HashMap;

fn main() -> mysql::Result<()>{
    let mut conn = Conn::new(Opts::from_url("mysql://root:123456@127.0.0.1:3306")?)?;
    let mut binlog_stream = conn
        .get_binlog_stream(
            BinlogRequest::new(11114)
                .with_filename("mysql-bin.000140".as_bytes().to_vec())
                .with_pos(70889u64))
        .unwrap();
    let mut tmes = HashMap::new();
    while let Some(event) = binlog_stream.next() {
        let event = event.unwrap();
        event.header().event_type().unwrap();
        if  let Some(e) = event.read_data()? {
            match e {
                EventData::RowsEvent(e)=>{
                    match e {
                        RowsEventData::UpdateRowsEvent(e)=>{
                            dbg!(e.rows(&tmes[&e.table_id()]));
                        },
                        _ => {}
                    }
                }
                EventData::TableMapEvent(e)=>{
                    tmes.insert(e.table_id(), e.into_owned());
                }
                _ => {}
            }
        };
    }
    Ok(())
}

table define:


-- dmall.testType definition

CREATE TABLE `testType` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `json` json DEFAULT NULL,
  `update_at` datetime DEFAULT NULL,
  `set` set('a','b','c','e') DEFAULT NULL,
  `bit` bit(1) DEFAULT NULL,
  `blob` blob,
  `decimal` decimal(10,2) DEFAULT NULL,
  `binary` binary(1) DEFAULT NULL,
  `enum` enum('A','B','C') DEFAULT NULL,
  `text` text,
  `bool` tinyint(1) NOT NULL,
  `char` char(1) DEFAULT NULL,
  `interger` int(11) DEFAULT NULL,
  `mytest` varchar(101) DEFAULT NULL,
  `longblob` longblob,
  `float` float DEFAULT NULL,
  `local` geometry DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `testType_UN` (`id`),
  UNIQUE KEY `NewTable_id_IDX` (`id`) USING BTREE,
  KEY `testType_mytest_IDX` (`mytest`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
blackbeam commented 3 years ago

Thanks for report, I'll look into it. Which mysql server version do you use?

jiuker commented 3 years ago
[src/main.rs:24] e.rows(&tmes[&e.table_id()]) = [
    Err(
        Custom {
            kind: UnexpectedEof,
            error: "can't parse: buf doesn't have enough data",
        },
    ),
thread 'main' panicked at 'attempt to negate with overflow',
jiuker commented 3 years ago

Thanks for report, I'll look into it. Which mysql server version do you use?

5.7.16

jiuker commented 3 years ago

Thanks for report, I'll look into it. Which mysql server version do you use?

8.0.0+

will loop print:

 Err(
        Custom {
            kind: UnexpectedEof,
            error: "can't parse: buf doesn't have enough data",
        },
    ),
blackbeam commented 3 years ago

mysql_common v0.27.3 should fix the issue. Could you please invoke cargo update and try again?

jiuker commented 3 years ago

mysql_common v0.27.3 should fix the issue. Could you please invoke cargo update and try again?

It Work!