Back to articles list
- 2 minutes read

Relational databases are not rocket science ready

As usual I’ve tried to make the title of my article something catchy. This article will not be about rocket science per se, but instead it will be about a specific usage of relational databases. So, keep reading!

Suppose you’re working at some top secret corporation and you’re developing a rocket controller. The rocket controller must:

  1. explode when it is near a target
  2. log time and distance (in case it doesn’t explode)

The Java code to achieve this may looks like the following:

while (true) {

    double distance = computeDistance();

	log("" + System.currentTimeMillis() + " " + distance);

    if (distance < CLOSE_ENOUGH) {
        explode();
        throw new RuntimeException("Fuse has failed");
    }
}

The code works perfectly, but for some reason management decided to use a database to log the time and position.

They hired a database consultant who designed a single-table database:

create table track (
	time int8, 
	distance float8
);

You’ve changed the controller and now the code looks like the following:

PreparedStatement stm = conn.prepareStatement("insert into track values(?,?)");
try {

    while (true) {

    	distance = computeDistance();

        stm.setLong(1, System.currentTimeMillis());
       	stm.setDouble(2, distance);
       	stm.execute();
              
       	if (distance < CLOSE_ENOUGH) {
           	explode();
           	throw new RuntimeException("Fuse has failed");
        }
    }

} finally {
        stm.close();
}

The tests were green. You’re happy and waiting for a bonus.

Some weeks later they deployed your code into new rockets. A day later, you were ... fired. Oops.

100% of the rockets didn’t explode because of the following error:

Exception in thread "main" java.lang.RuntimeException: Fatal error.
	at MissleController.v2(MissleController.java:89)
	at MissleController.main(MissleController.java:102)
Caused by: org.postgresql.util.PSQLException: ERROR: "1.1125369292536007E-308" is out of range for type double precision
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)

What happened? It’s simple. Types in the database are not the same as types in Java. In this case, the range of database type FLOAT8 doesn’t cover the same range as java.lang.Double. The same type may behave differently among database engines or even versions. You should have consulted a database manual to be prepared for such situations.

Do you have a similar (perhaps less explosive) story to share?

go to top