public static function fromSql(string $format, $data = null)
    {
        if ($data === null) {
            return null;
        }

        switch ($format) {
            case self::NONE:
                return $data;
            case self::DATE:
                $result = DateTime::createFromFormat($format, $data);
                $result->setTime(0, 0, 0);
                return $result;
            case self::TIMESTAMP:
            case self::TIMETZ:
            case self::TIMEUTZ:
            case self::DATETIMETZ:
            case self::DATETIMEUTZ:
                // Format must match - no auto detection
                return DateTime::createFromFormat($format, $data);
            case self::TIME:
            case self::TIMEU:
                // Includes microseconds?
                $timeFormat = (strlen($data) > 8) ? self::TIMEU : self::TIME;
                return DateTime::createFromFormat($timeFormat, $data);
            case self::DATETIME:
            case self::DATETIMEU:
                // Includes microseconds?
                $dateTimeFormat = (strlen($data) > 19) ? self::DATETIMEU : self::DATETIME;
                return DateTime::createFromFormat($dateTimeFormat, $data);
            case self::INT:
                return (integer)$data;
            case self::BOOL:
                return (bool)$data;
            case self::FLOAT:
                return floatval($data);
            case self::STRING:
                return (string)$data;
            case self::ALPHANUMERIC:
                return preg_replace('/[^a-zA-Z0-9_ ]/', '', $data);
            case self::SERIALIZED:
                return unserialize($data);
            case self::JSON:
                return json_decode($data, true);
            case self::CSV:
                return str_getcsv($data);
            default:
                throw new FormatException ('Unknown format: ' . $format);
        }
    }