My personal and professional life

2019-01-31

My MySQL Bugs

Since I started using MySQL 3.23.x during my university years I was trying to solve all my problems myself like with all the other free and open source software I was using. At first it was more about learning (or lack of knowledge if you want), but then the problems become more complex and harder to solve. Well, I was successful most of the times, so I didn't consider reporting bugs or asking for support. However MySQL ecosystem grew large since then, the software become lot more complex and the source code base increased significantly, so nowadays it's native to think one could manage to fix all the problems he encounters without going deep in product's internals or relaying on professional support. The first is possible only for MySQL developers well familiar with the code base and large organizations like Facebook, Booking, etc., which have dedicated teams and regularly contribute patches. The second depends on you and of course the company providing the support.

I haven't reported much bugs for MySQL - just 21, but I now consider reporting everything I found which seems like a bug, because this is the right thing to do. I may as well solve the problem myself, but someone else could be stuck by the same and should at least be aware that it's a known (and eventually already resolved) problem. With each one of these I learned a little something, so here below I make a review of my bugs so far describing their fate in chronological order.
  1. Bug 20098 (my first one) was reported on 2006-05-26 and is with status "No Feedback" as of 2006-07-01. It was about Query browser searching for a file that is not present (preferences.glade). I have forgot about this one and found out it was closed later, because no feedback was provided, which is fun as I have provided the requested information...
  2. Bug 69459 was reported 2013-06-13 and is in status "Can't repeat" as of 2013-12-24. It was about MySQL Workbench crashing on entering dot in a SQL string when automatic code completion is enabled. I reported the bug for version 5.2.47 CE, but I was suggested to try 6.0.7, which worked, so the bug didn't receive more attention since 5.2 series didn't receive more updates.
  3. Bug 73076 (my first confirmed and fixed one) was reported on 2014-06-22 and is with status "Closed" as of 2014-08-26. It was about MySQL Workbench actually committing modifications in a record set when you only apply them. It was a nasty one making my daily work with Workbench difficult as I had to be careful not to apply (pardon commit) too early. The problem appeared in 6.0.x, 6.1.x and was finally fixed with the release of 6.2.2 on 2014-09-05 (see release notes) after being verified by support.
  4. Bug 73079 was reported on 2014-06-23 and is with status "Closed" as of 2014-09-15. It was about MySQL Workbench not refreshing the cell after setting value to NULL. It affected 6.1.x and early 6.2.x versions. Although it wasn't officially confirmed for me it was a regression, but more importantly it was fixed with the release of 6.2.3 on 2014-09-23 (see release notes).
  5. Bug 73708 was reported on 2014-08-25 and is with status "Closed" as of 2014-12-01. I was about MySQL Workbench models being completely mangled. I forgot this one for a few months and provided the requested feedback later to realize the problem was already fixed with the release of 6.2.4 on 2014-11-20 although nothing was mentioned in the release notes.
  6. Bug 73770 (my oldest one still open) was reported on 2014-08-29 and is still with status "Verified" as of 2018-02-05. It's a feature request for MySQL synchronizer between model and database to display the actual differences. Whoever used this functionality should know that applying changes in the model to the database could be quite annoying, because there's always some changes you do not expect and furthermore you do not understand. You only see the update script generated, but it would be nice to see the actual difference, which in some cases may not even be difference (see 90772 below).
  7. Bug 82202 was reported on 2016-07-12 and is with status "Closed" as of 2018-01-31. It was about impossibility to link Connector/ODBC 5.3.6 to the shared libmysqlclient.so due to undefined symbols (e.g. my_malloc, my_free, etc.). The problem was quickly explained, but then closed as "Not A Bug". It was reopened after a Fedora maintainer reported the same problem and finally fixed with release of Connector/ODBC 5.3.10 on 2018-01-30 (see release notes).
  8. Bug 84951 (my first suggested patch) was reported on 2017-02-10 and is with status "Duplicate" as of 2017-02-12. It was about problem building MySQL Workbench 6.3.9, because of compile errors in jsonparser.cpp and jsonview.cpp for which I suggested a patch. The bug was made duplicate of 84886, which also contained a patch provided two days earlier, but it was closed on 2018-05-14 as "Won't fix", because they "no longer support 32bit systems" (!?).
  9. Bug 89608 was reported on 2018-02-09 and is still with status "Verified" as of 2018-02-13. It is a feature request about having password requirements messages in MySQL Workbench match the server configuration, so they're more useful. I provided sample code about how it could be done and even wrote a SQL function myself to test the idea.
  10. Bug 89615 was reported on 2018-02-10 and is with status "Unsupported" as of 2018-08-23. It was about failure to build MySQL Shell 1.0.10, because compilation fails for undefined vio* functions. It was related to 82202 and although confirmed it was later closed with the explanation that "MySQL Shell 1.0 is no longer supported and version 8.0 should be used instead" (!?) to which I reacted a bit harsh, but I really do not understand such answers.
  11. Bug 90619 was reported on 2018-04-25 and it is with status "Duplicate" of 79315 as of 2018-04-25. It was about MySQL Installer not offering upgrade from MySQL 5.7 to 8.0, which was explained as "not a bug", because it was "working as expected", so apparently MySQL Installer doesn't support upgrade between major releases. I hope this changes in future.
  12. Bug 90620 (my first of a series) was reported on 2018-04-25 and is still with status "Verified" as of 2018-04-26. It is about MySQL Workbench 8.0.11's SQL editor displaying error on SELECT query with window functions. You wouldn't expect MySQL Workbench having the same version as the server to lack support for new server functionalities, but more about this later.
  13. Bug 90727 was reported on 2018-05-03 and is with status "Closed" as of 2018-06-01. It was about impossibility to link Connector/C++ 1.1.11 due to missing mysql_sys and mysql_strings libraries. It turned out to be a regression from some Solaris specific modifications not made Solaris specific. I got in touch with the developer and it was declared fixed in 1.1.12, which got released on 2019-01-28 (see release notes), so for 1.1.11 I had to patch it myself.
  14. Bug 90772 was reported on 2018-05-06 (St George's Day) and is still with status "Verified" as of 2018-05-09. It is about MySQL Workbench synchronizer making difference between single quotes escapes (e.g. the statement COMMENT 'Currency\' symbol' is different from the statement COMMENT 'Currency''s symbol'). It is because MySQL Workbench allows backslash escape and the server accepts it execution, but then rewrites it with single quote escape. Thus, on the next synchronization the difference remains (e.g. like you haven't synchronized at all).
  15. Bug 90876 was reported on 2018-05-15 and is with status "Closed" as of 2018-06-21. I was about MySQL Shell 8.0.11 giving error 5115 on adding documents to collection in Server 5.7, but what it was actually about was automatically generated identifiers as I explained in details in my article MySQL Shell 8 and automatically generated document IDs. This one resulted in documentation update and since nobody else experienced this problem I guess it's fine, but for me such problems break backwards compatibility.
  16. Bug 91841 was reported on 2018-07-31 and is with status "Closed" as of 2019-01-25. It was about impossibility to build MySQL Connector/ODBC 5.3.11, because of compilation errors. I was able to fix the compilation errors myself (see patch) until waiting for help and explanation. And the explanation was that it was duplicate of an internal bug, "which explains the reasons for the failure", but which I'm not able to read. The funny thing about this one was that there were more than 400 lines wiped out from the beginning of a header most probably related to copyright text updates. It was fixed with the release of 5.3.12 on 2019-01-28 (see release notes).
  17. Bug 92898 was reported on 2018-10-23 and is with status "Not a Bug" as of 2018-10-23. I consider this as my one and only "support request" and I was pleased, that it was explained the same day.  It is about hitting an incompatible change during upgrade from 8.0.12 to 8.0.13, because I still had same old views using ASC or DESC qualifiers for GROUP BY clause. In this regards I'd like to thank MySQL for the detailed release notes they publish although as in this case even if you read them carefully you may omit something by considering it doesn't concern you. For this reason it's highly recommended to use MySQL Shell's Upgrade Checker Utility, which could tell you about compatibility errors and issues in advance.
  18. Bug 92900 was reported on 2018-10-23 and is with status "Verified" as of 2018-10-23. It is about MySQL Workbench 8.0.13 lacking support for expressions in DEFAULT although the feature is supported by the same version of the server.
  19. Bug 92908 was reported on 2018-10-23 and is with status "Verified" as of 2018-10-23. Is is about MySQL Workbench 8.0.13 lacking support for expressions as key parts although the feature is supported by the same version of the server.
  20. Bug 93835 was reported on 2019-01-07 and is with status "Verified" as of 2019-01-10. It's a feature request for having MySQL Workbench display a warning on using keyword as identifier (e.g. table and column names). I opened it after Frédéric Descamps suggested so in a comment on LinkedIn. Fingers crossed it's implemented.
  21. Bug 94012 was reported on 2019-01-23 and is with status "Verified" as of 2019-01-23. It is about MySQL Workbench 8.0.14 not recognizing the new LATERAL keyword and giving error after it in SQL editor. It's by now the last one of the series on MySQL Workbench not supporting the features of the server even though they're the same version. The bug was nominated as MySQL Bug of the Day by Valerii Kravchuk on the same day.
I hope I haven't bored you with all the information above. It's not always easy to properly explain a problem, but I have quite some experience being on the "other side", so I think I know what information is required for a problem to be investigated thoroughly. Still reporting bugs properly is probably an art and I'm looking forward to Valerii Kravchuk's presentation How to create a useful MySQL bug report at FOSDEM on Saturday.

Some of my bugs are pure technical ones (e.g. 82202, 84951, 89615, 90727 and 91841) for which I reported all the details and still the explanations on some of them seem pretty strange to me (e.g. no longer support 32bit systems, MySQL Shell 1.0 is no longer supported and version 8.0 should be used instead) even though the problem and what should be fixed was quite clear. I do not understand how could you not release a new maintenance version when there are open bugs for the last such release in the series? What vendors should understand is that as a package maintainer for me it's more complex to support patches for problems not fixed upstream.

I've made a series of bugs about unsupported sever features in MySQL Workbench (e.g. 90620, 92900, 92908 and 94012), which made me think about the meaning of version number alignment that was done with the release of MySQL 8.0.11 as General Availability release (see MySQL 8.0: It Goes to 11!). As I understand the post it was done, so that we use the "correct versions" of the all the products. It's generally a good idea, but shouldn't the "correct version" support the same feature set of the server? Users should be presumably less confused if so, but so far this is clearly not the case with Workbench. I hope the situation improves in future.

I'd like to complete these post with some final thoughts. As a developer I'm aware that could never be a software completely free of bugs. However, as a user I expect that when a bug is properly reported and the problem is clear the solution to not take that much time, but of course what really matters are priorities and they are normally as higher as the number of affects users is bigger.

2019-01-23

New development features in MySQL 8.0.14

With the release of MySQL 8.0.14 Oracle keeps the already established practice of introducing new development features even with maintenance releases, which usually include only small improvements and mostly bug fixes. I took a look at 8.0.14's release notes, the post The MySQL 8.0.14 Maintenance Release is Generally Available by and of course the manual, experimented and here below are my picks related to development.

Lateral derived tables

Before MySQL 8.0.14 it wasn't possible for derived tables to refer to (depend on) columns of preceding tables in the same FROM clause. Now this restriction is removed with the addition of LATERAL keyword (see Lateral derived tables). The LATERAL keyword means that the derived table depends on the previous table on its left side. You could have more than one LATERAL derived table in a query and each one would depend only on the previous table(s) or derived table(s). Lateral derived tables are so called "for each" loop of SQL and this makes possible some operations that were otherwise not possible or less efficient.
Here's an example. Let's say you want to calculate the minimum, average and maximum salaries for each department in the organization. Previously you would have to write it like this:
Explain plan for derived table query

SELECT D.dname, DT.min_sal, DT.avg_sal, DT.max_sal
  FROM dept D

       LEFT OUTER JOIN
       (SELECT E.deptno, MIN(E.sal) min_sal, AVG(E.sal) avg_sal, MAX(E.sal) max_sal
          FROM emp E
         GROUP BY E.deptno
       ) AS DT
       ON DT.deptno = D.deptno;


So use a derived table DT to calculate min/avg/max salary for all departments from emp table and then join with the dept table to produce the following result:

+------------+---------+-------------+---------+
| dname      | min_sal | avg_sal     | max_sal |
+------------+---------+-------------+---------+
| ACCOUNTING | 1300.00 | 2916.666667 | 5000.00 |
| RESEARCH   |  800.00 | 2175.000000 | 3000.00 |
| SALES      |  950.00 | 1566.666667 | 2850.00 |

| OPERATIONS |         |             |         |
+------------+---------+-------------+---------+
4 rows in set (0.0014 sec)


The derived table is completely independent of the other joined table as it could generate result by itself (i.e. it doesn't depend on the column values of the other table). The explain plan for this query is given on the right and it confirms that the result set of the derived table is first materialized, so it could be joined to the other table.
Another approach would be to use sub queries in the SELECT clause like this:

SELECT D.dname,
       (SELECT MIN(E.sal) FROM emp E WHERE E.deptno = D.deptno) AS min_sal,
       (SELECT AVG(E.sal) FROM emp E WHERE E.deptno = D.deptno) AS avg_sal,
       (SELECT MAX(E.sal) FROM emp E WHERE E.deptno = D.deptno) AS max_sal
  FROM dept D;


which won't be efficient (imagine a sales table and thousands of salesman if you want to evaluate their salaries) as three queries would have to do the job of one. It's not possible to use a single sub query to calculate all the necessary values in SELECT, because such sub queries need to be scalar. Such a query would result in error Error Code: 1241. Operand should contain 1 column(s) if you try it.

If you try to connect the derived table to the other table with a query like the following one:

SELECT D.dname, DT.min_sal, DT.avg_sal, DT.max_sal
  FROM dept D,
       (SELECT MIN(E.sal) min_sal, AVG(E.sal) avg_sal, MAX(E.sal) max_sal
          FROM emp E
         WHERE E.deptno = D.deptno
       ) AS DT;


you'll get Error Code: 1054. Unknown column 'D.deptno' in 'where clause', because D table is not known to the derived table. The query is illegal in SQL-92, but in SQL-1999 it becomes legal if the derived table it's proceeded by the LATERAL keyword:

SELECT D.dname, LDT.min_sal, LDT.avg_sal, LDT.max_sal
  FROM dept D,
       LATERAL
       (SELECT MIN(E.sal) min_sal, AVG(E.sal) avg_sal, MAX(E.sal) max_sal
          FROM emp E
         WHERE E.deptno = D.deptno
       ) AS LDT;

Explain plan for lateral derived table query

and produces the following result:

+------------+---------+-------------+---------+
| dname      | min_sal | avg_sal     | max_sal |
+------------+---------+-------------+---------+
| ACCOUNTING | 1300.00 | 2916.666667 | 5000.00 |
| RESEARCH   |  800.00 | 2175.000000 | 3000.00 |
| SALES      |  950.00 | 1566.666667 | 2850.00 |
| OPERATIONS |    NULL |        NULL |    NULL |
+------------+---------+-------------+---------+
4 rows in set (0.1182 sec)


As clear from the explain plan graph on the right in this case there's no grouping, but MySQL gives higher query cost, because access to the derived table is by full table scan. The more interesting information is however into the tabular explain plan (column partitions is intentionally hidden):

+----+-------------------+------------++------+---------------+-----------+---------+-------------------+------+----------+----------------------------+
| id | select_type       | table      || type | possible_keys | key       | key_len | ref               | rows | filtered | Extra                      |
+----+-------------------+------------++------+---------------+-----------+---------+-------------------+------+----------+----------------------------+
|  1 | PRIMARY           | D          || ALL  | NULL          | NULL      | NULL    | NULL              |    4 |      100 | Rematerialize (<derived2>) |
|  1 | PRIMARY           | <derived2> || ALL  | NULL          | NULL      | NULL    | NULL              |    2 |      100 | NULL                       |
|  2 | DEPENDENT DERIVED | E          || ref  | fk_deptno     | fk_deptno | 5       | dept_emp.D.deptno |    4 |      100 | NULL                       |
+----+-------------------+------------++------+---------------+-----------+---------+-------------------+------+----------+----------------------------+
3 rows in set, 2 warnings (0.0010 sec)
Note (code 1276): Field or reference 'dept_emp.D.deptno' of SELECT #2 was resolved in SELECT #1
Note (code 1003): /* select#1 */ select `dept_emp`.`d`.`dname` AS `dname`,`ldt`.`min_sal` AS `min_sal`,`ldt`.`avg_sal` AS `avg_sal`,`ldt`.`max_sal` AS `max_sal` from `dept_emp`.`dept` `d` join lateral (/* select#2 */ select min(`dept_emp`.`e`.`sal`) AS `min_sal`,avg(`dept_emp`.`e`.`sal`) AS `avg_sal`,max(`dept_emp`.`e`.`sal`) AS `max_sal` from `dept_emp`.`emp` `e` where (`dept_emp`.`e`.`deptno` = `dept_emp`.`d`.`deptno`)) `ldt`

There are two new information and an additional note. The plan clearly shows that the derived table E (derived2) is DEPENDENT on the other table and that its rematerialized for each row of D (see EXPLAIN extra information). This is the reason for which lateral derived tables are also known as the "for each" loop of SQL. The note informs about how the external reference in the derived table was resolved.

Of course MySQL Workbench (even upgraded to 8.0.14 as well) is again not familiar with the new syntax (see my previous post New development features in MySQL 8.0.13), because it doesn't properly color the new keyword and shows error in SQL editor just after it. I reported this as bug 94012, but I have no much hope as 90620, 92900 and 92908 were verified yet still open. Version numbers doesn't mean much nowadays :-)

Please, note that it's possible even to connect to the outer table if the derived table is in a sub query (see an example in WL#461).

JSON aggregation functions can now be used as window functions

It is now possible to use JSON_ARRAYAGG and JSON_OBJECTAGG aggregate functions as window functions by using the OVER clause (see Window Function Concepts and Syntax). This makes all (except COUNT(DISTINCT) and GROUP_CONCAT) of the aggregate functions possible for use as window functions after bitwise AND/OR/XOR functions were made so with MySQL 8.0.12. Here's an example:

SELECT E.ename, E.sal,
       AVG(E.sal) OVER dw AS avg_sal,
       JSON_OBJECTAGG(D.dname, E.sal) OVER dw AS dept_sal
  FROM emp  E,
       dept D
 WHERE E.deptno = D.deptno
WINDOW dw AS (PARTITION BY D.deptno);


+--------+---------+-------------+------------------------+
| ename  | sal     | avg_sal     | dept_sal               |
+--------+---------+-------------+------------------------+
| CLARK  | 2450.00 | 2916.666667 | {"ACCOUNTING": 1300.0} |
| KING   | 5000.00 | 2916.666667 | {"ACCOUNTING": 1300.0} |
| MILLER | 1300.00 | 2916.666667 | {"ACCOUNTING": 1300.0} |
| SMITH  |  800.00 | 2175.000000 | {"RESEARCH": 3000.0}   |
| JONES  | 2975.00 | 2175.000000 | {"RESEARCH": 3000.0}   |
| SCOTT  | 3000.00 | 2175.000000 | {"RESEARCH": 3000.0}   |
| ADAMS  | 1100.00 | 2175.000000 | {"RESEARCH": 3000.0}   |
| FORD   | 3000.00 | 2175.000000 | {"RESEARCH": 3000.0}   |
| ALLEN  | 1600.00 | 1566.666667 | {"SALES": 950.0}       |
| WARD   | 1250.00 | 1566.666667 | {"SALES": 950.0}       |
| MARTIN | 1250.00 | 1566.666667 | {"SALES": 950.0}       |
| BLAKE  | 2850.00 | 1566.666667 | {"SALES": 950.0}       |
| TURNER | 1500.00 | 1566.666667 | {"SALES": 950.0}       |
| JAMES  |  950.00 | 1566.666667 | {"SALES": 950.0}       |
+--------+---------+-------------+------------------------+
14 rows in set (0.0021 sec)


It's important to note that MySQL does not permit duplicate keys in JSON data type, so in a window without ordering function JSON_OBJECTAGG would return the last value for the key, which may not be deterministic.

X Protocol improvements

According to the release notes data is now always converted to utf8mb4 character set (using the utf8mb4_general_ci collation). The other notable improvement is the support for "prepare functionality". The release notes provide no reference about this new functionality, but has mentioned WL#9270 in his article, so I believe this is about preparing CRUD operations (see Preparing CRUD Statements). A simple example in JavaScript would be the following:

MySQL Shell 8.0.14
Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.
 MySQL  JS > \connect user@localhost
Creating a session to 'user@localhost'
Your MySQL connection id is 22 (X protocol)
Server version: 8.0.14 MySQL Community Server - GPL
 MySQL  localhost:33060+ ssl  JS > \use test
Default schema `test` accessible through db.
 MySQL  localhost:33060+ ssl  test  JS > var usr = db.createCollection('users')
 MySQL  localhost:33060+ ssl  test  JS > usr.add({name:"User1",age:15})
Query OK, 1 item affected (0.0108 sec)
 MySQL  localhost:33060+ ssl  test  JS > usr.add({name:"User2",age:17})
Query OK, 1 item affected (0.0138 sec)
 MySQL  localhost:33060+ ssl  test  JS > usr.add({name:"User3",age:20})
Query OK, 1 item affected (0.0105 sec)
 MySQL  localhost:33060+ ssl  test  JS > usr.add({name:"User4",age:19})
Query OK, 1 item affected (0.0137 sec)
 MySQL  localhost:33060+ ssl  test  JS > usr.add({name:"User5",age:16})
Query OK, 1 item affected (0.0118 sec)
 MySQL  localhost:33060+ ssl  test  JS > usr.find()
[
    {"_id": "00005c46e7e5000000000000000a","age": 15,"name": "User1"},
    {"_id": "00005c46e7e5000000000000000e","age": 17,"name": "User2"},
    {"_id": "00005c46e7e5000000000000000f","age": 20,"name": "User3"},
    {"_id": "00005c46e7e50000000000000010","age": 19,"name": "User4"},
    {"_id": "00005c46e7e50000000000000011","age": 16,"name": "User5"}
]
5 documents in set (0.0006 sec)
 MySQL  localhost:33060+ ssl  test  JS > var fcmd = usr.find('age >= :page')
 MySQL  localhost:33060+ ssl  test  JS > fcmd.bind('page', 18)
[
    {"_id": "00005c46e7e5000000000000000f","age": 20,"name": "User3"},
    {"_id": "00005c46e7e50000000000000010","age": 19,"name": "User4"}
]
2 documents in set (0.0006 sec)
 MySQL  localhost:33060+ ssl  test  JS > fcmd.bind('page', 16)
[
    {"_id": "00005c46e7e5000000000000000e","age": 17,"name": "User2"},
    {"_id": "00005c46e7e5000000000000000f","age": 20,"name": "User3"},
    {"_id": "00005c46e7e50000000000000010","age": 19,"name": "User4"},
    {"_id": "00005c46e7e50000000000000011","age": 16,"name": "User5"}
]
4 documents in set (0.0003 sec)

 MySQL  localhost:33060+ ssl  test  JS > fcmd.bind('page', 17)
[
    {"_id": "00005c46e7e5000000000000000e","age": 17,"name": "User2"},
    {"_id": "00005c46e7e5000000000000000f","age": 20,"name": "User3"},
    {"_id": "00005c46e7e50000000000000010","age": 19,"name": "User4"}
]
3 documents in set (0.0004 sec)


The example creates a collection of users with their names and ages, then prints the whole collection. The interesting part starts with the line highlighted in yellow. It prepares a statement using a named parameter (anonymous parameters with ? are not supported by the X protocol), but does not execute it. The execution happens after a value is bind to the parameter and this could be done many times producing different results. It's interesting that in the general log the first bind actually executes a query, then there's prepare and then follow executes:

Query    SELECT doc FROM `test`.`users` -> usr.find()
Query    SELECT doc FROM `test`.`users` WHERE (JSON_EXTRACT(doc,'$.age') >= 18) -> fcmd.bind('page', 18)
Prepare    SELECT doc FROM `test`.`users` WHERE (JSON_EXTRACT(doc,'$.age') >= ?)
Execute    SELECT doc FROM `test`.`users` WHERE (JSON_EXTRACT(doc,'$.age') >= 16) -> fcmd.bind('page', 16)
Execute    SELECT doc FROM `test`.`users` WHERE (JSON_EXTRACT(doc,'$.age') >= 17) -> fcmd.bind('page', 17)


Using prepared statements for repeatedly executed statements could lead do performance improvements, because of the saved parse time, so this is something you should consider if you need to improve the performance of your applications and scripts.

Spatial improvements

The function ST_Distance now accepts an optional third parameter specifying the unit for the returned value. The possible values are defined in INFORMATION_SCHEMA.ST_UNITS_OF_MEASURE table along with conversion factor relative to the basic unit metre, which is the default. Here is an example for calculation of the distance between Sofia and Sydney in kilometers and nautical miles in SRID 4326:

SELECT ST_Distance(ST_PointFromText('POINT( 42.69751 23.32415)', 4326),
                   ST_PointFromText('POINT(-33.86667 151.20000)', 4326)) / 1000 dist_km;
+--------------------+
| dist_km            |
+--------------------+
| 15431.933058990671 |
+--------------------+
1 row in set (0.0023 sec)


SELECT ST_Distance(ST_PointFromText('POINT( 42.69751 23.32415)', 4326),
                   ST_PointFromText('POINT(-33.86667 151.20000)', 4326), 'nautical mile') dist_nm;


+------------------+
| dist_nm          |
+------------------+
| 8332.57724567531 |
+------------------+
1 row in set (0.0008 sec)

This wraps up my review. There is of course lot more in MySQL 8.0.14 not only for developers, so I encourage to explore and find out more. The references at the beginning of this article are a good starting point.

2019-01-15

Should Slackware implement systemd?

Two recent events made me wrote this post. The first one was a user in LinuxSlackware's Facebook group who was thanking Patrick for not switching to systemd. The second one was a recent case where the night jobs of an application were running two many heavy processes on a MySQL 8 server under RHEL 7, which lead to memory exhaustion and unresponsive service. In the second case systemd acted to kill the mysqld process and start it again, so the service was restored and the application could at least work.

Now, the first event just expresses a user opinion, which I, as a long time Slackware user, could understand, because it's something we're used to. It's simple and works at lest for most of the things.

However, the second event made me think, that under Slackware this would not have happened, unless you implement it yourself somehow. The question is does it worth it when it's already implemented and working well on all the other Linuxes I'm using?

2019-01-10

The things I learned about myself in 2018

For me 2018 was a year of hopes, some of which didn't realized. I was hoping for some changes, but at the end they didn't happen however there's nothing tragic in this as I only learned more about myself. In this article I take a look back of what I learned about myself in the past year.

I do not have enough experience with open source

I was told this somewhere in beginning of March and I do not disagree at all. I have contributed small patches, translations and bugs to various open source projects in the past about 20 years, I have published some of my personal projects under free licenses, but I wish I could have done more. It's true I could have contributed more, but unfortunately, I simply haven't found the time for this. I'm still a strong believer in free and open source software (FOSS), which I used since my university years, I still use and I would continue using for the time being. However, nowadays I'm not that picky that FOSS should also be free as in "free beer", which brings me closer to GNU's philosophy.

I do not read enough/your books

I was suggested to read more books by some. Yes, perhaps I could read more, but I'm still reading. And I may not be reading the same as you and you're not the one to tell me what to read just like I'm not telling you. Apart from books I'm also reading some magazines like I've been since my teenage years. And some online resources as well. With this post I'd like to thank my family and friends who gave me books as gifts last year, so there are currently about 10 books on my reading list for 2019. Sorry, the list is private ;-)

I do not have enough experience with this or that technology

I learned this in the summer. I still consider myself a curious person about technology, but I simply cannot have experience with everything out there and I believe nobody could. For me it's more interesting how a person perceives technology and how it deals with changes. Two decades ago software was quite different as well as the tools and technologies used to implement it. The peace of changes has increased as well as the persons involved in developing software. There are many persons that started software development one, two, three or more decades ago that easily adapt to new tools and technologies, because they have the basic understanding about how software is build and works. And more importantly they know they have to learn constantly and be involved. This means reading the manuals, following development progress, discussing, reporting bugs, making feature request, contributing as much as possible and generally getting involved with the community.

I'm not agile

This was something I was told before the Christmas holidays. Yes, perhaps I'm not that agile after all. I know and understand agile values and principles, but at the same time I do not share them completely.
  • I agree that individuals and interactions are more important than processes and tools, but only the later could make the former simple and efficient. Without clear processes and proper tools even best individuals would fail to interact in a way that benefits software development. I believe that such individuals would first create the necessary processes and tools.
  • I agree that working software is more important than comprehensive documentation, but I've seen software written with scarce or no documentation at all. After some time (e.g. 5, 10, 15 years) when such software stops working, has to be upgraded or has to be explained to client it first has to be reverse engineered as most probably original developers have long left the company. So, in short term and for small projects I completely support this, but in the long term and for large projects it won't help anyone. The problem is that if not written on time documentation would most probably never be written.
  • I agree that customer collaboration is more important than contract negotiation, but not all customers could collaborate effectively. Some customers do not even know what exactly they want, they do not read documents (even refuse to do so when asked) hence they do not know the software they're using and they do not properly transfer knowledge over time. These are only my humble observations, but I believe that customer collaboration should be open in terms that it should be accessible to all the involved parties now and in future. I've seen cases where software was implemented in "close collaboration" between a developer and a person at the customer through personal messages, which afterwards nobody knows anything about and doesn't want to.
  • I agree that responding to change is more important than following a plan, but responding to constant changes means no project plan and scope at all. Projects that start as a bubble and constantly change their form easily become malformed and reach out of control. Such projects usually fail. I've seen some never-ending projects in my practice and it's one of the things I truly dislike.
These and perhaps other reasons make organizations choose hybrid approaches to software development as they find agile too extreme and inefficient in large organizations and I have worked in such organizations in the past more than 15 years, so perhaps my views are twisted from this perspective.

I'm an 'advanced user'

This was written to me by a support representative. It was after asking (and insisting) for some simple (in my view) improvements in the software provided and supported by a big vendor for whom this person was working. He wrote it in the sense that it's only me that is asking for these improvements, which made it automatically clear to me that they won't be implemented. Well, if this defines me as "advanced user", so be it, but I'm quite disappointed, because I was expecting more from a SOHO device using free and open source software. I may write a separate article on this later.

I'm myself

Last, but not least I'm still myself with all the pros and cons as a person and professional. I do not pretend to be everything to everyone, I do not pretend to know everything and I do not pretend to be the most experienced out there. Everything I learned about myself in 2018 was based on some experience and I'm sure it would help me become a better person and professional in future.