From d37ad277549b8ec9becae34cf20ed9bde4d82b5e Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Tue, 18 Jul 2017 13:35:01 +0200 Subject: [PATCH] Handle empty tables in concurrency support for MySQL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the table is empty we get nil for min and max values of the id column. In that case we don't compute a set of ranges and “cancel” concurrency support for the empty table. Fixes #596. --- src/sources/mysql/mysql.lisp | 42 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/sources/mysql/mysql.lisp b/src/sources/mysql/mysql.lisp index 968b69e..6d7b7e0 100644 --- a/src/sources/mysql/mysql.lisp +++ b/src/sources/mysql/mysql.lisp @@ -58,25 +58,31 @@ (sql (format nil "select min(`~a`), max(`~a`) from `~a`" col col (table-source-name (source mysql))))) (destructuring-bind (min max) - (mapcar #'parse-integer (first (mysql-query sql))) + (let ((result (first (mysql-query sql)))) + ;; result is (min max), or (nil nil) if table is empty + (if (or (null (first result)) + (null (second result))) + result + (mapcar #'parse-integer result))) ;; generate a list of ranges from min to max - (let ((range-list (split-range min max *rows-per-range*))) - (unless (< (length range-list) concurrency) - ;; affect those ranges to each reader, we have CONCURRENCY - ;; of them - (let ((partitions (distribute range-list concurrency))) - (loop :for part :in partitions :collect - (make-instance 'copy-mysql - :source-db (clone-connection - (source-db mysql)) - :target-db (target-db mysql) - :source (source mysql) - :target (target mysql) - :fields (fields mysql) - :columns (columns mysql) - :transforms (transforms mysql) - :encoding (encoding mysql) - :range-list (cons col part))))))))))))) + (when (and min max) + (let ((range-list (split-range min max *rows-per-range*))) + (unless (< (length range-list) concurrency) + ;; affect those ranges to each reader, we have CONCURRENCY + ;; of them + (let ((partitions (distribute range-list concurrency))) + (loop :for part :in partitions :collect + (make-instance 'copy-mysql + :source-db (clone-connection + (source-db mysql)) + :target-db (target-db mysql) + :source (source mysql) + :target (target mysql) + :fields (fields mysql) + :columns (columns mysql) + :transforms (transforms mysql) + :encoding (encoding mysql) + :range-list (cons col part)))))))))))))) (defmacro with-encoding-handler (&body forms) `(handler-bind