Read MySQL's new decimal format introduced in MySQL 5
https://dev.mysql.com/doc/refman/5.6/en/precision-math-decimal-characteristics.html
@param array $column
@return string
@throws BinaryDataReaderException
542859
protected function getDecimal(array $column)
    {
        $digitsPerInteger = 9;
        $compressedBytes = [0, 1, 1, 2, 2, 3, 3, 4, 4, 4];
        $integral = $column['precision'] - $column['decimals'];
        $unCompIntegral = (int)($integral / $digitsPerInteger);
        $unCompFractional = (int)($column['decimals'] / $digitsPerInteger);
        $compIntegral = $integral - ($unCompIntegral * $digitsPerInteger);
        $compFractional = $column['decimals'] - ($unCompFractional * $digitsPerInteger);

        $value = $this->binaryDataReader->readUInt8();
        if (0 !== ($value & 0x80)) {
            $mask = 0;
            $res = '';
        } else {
            $mask = -1;
            $res = '-';
        }
        $this->binaryDataReader->unread(pack('C', $value ^ 0x80));

        $size = $compressedBytes[$compIntegral];
        if ($size > 0) {
            $value = $this->binaryDataReader->readIntBeBySize($size) ^ $mask;
            $res .= $value;
        }

        for ($i = 0; $i < $unCompIntegral; ++$i) {
            $value = $this->binaryDataReader->readInt32Be() ^ $mask;
            $res .= sprintf('%09d', $value);
        }

        $res .= '.';

        for ($i = 0; $i < $unCompFractional; ++$i) {
            $value = $this->binaryDataReader->readInt32Be() ^ $mask;
            $res .= sprintf('%09d', $value);
        }

        $size = $compressedBytes[$compFractional];
        if ($size > 0) {
            $value = $this->binaryDataReader->readIntBeBySize($size) ^ $mask;
            $res .= sprintf('%0' . $compFractional . 'd', $value);
        }

        return bcmul($res, 1, $column['precision']);
    }
128292
public function orWhereIs(string $column)
    {
        $instance = $this->whereStrategyInstance();

        $instance->whereStrategy()->orWhereIs($column);

        return $instance;
    }
1084300
public function renderColumnLabel(Column $column): string
    {
        // If already defined in translations, ignore
        $key = "datagrid.{$column->getDataGrid()->getCode()}.{$column->getCode()}"; // Same as base logic
        if ($this->translator instanceof TranslatorBagInterface && $this->translator->getCatalogue()->has($key)) {
            return $this->baseRenderer->renderColumnLabel($column);
        }

        $queryHandler = $column->getDataGrid()->getQueryHandler();
        // EAVFilterBundle might not be installed
        /** @noinspection ClassConstantCanBeUsedInspection */
        if (!is_a($queryHandler, 'Sidus\EAVFilterBundle\Query\Handler\EAVQueryHandlerInterface')) {
            return $this->baseRenderer->renderColumnLabel($column);
        }

        /** @var \Sidus\EAVFilterBundle\Query\Handler\EAVQueryHandlerInterface $queryHandler */
        $family = $queryHandler->getFamily();
        if (!$family->hasAttribute($column->getCode())) {
            return $this->baseRenderer->renderColumnLabel($column);
        }

        return $family->getAttribute($column->getCode())->getLabel();
    }
1345301
protected function createColumn($column)
	{
		$c=new CMssqlColumnSchema;
		$c->name=$column['COLUMN_NAME'];
		$c->rawName=$this->quoteColumnName($c->name);
		$c->allowNull=$column['IS_NULLABLE']=='YES';
		if ($column['NUMERIC_PRECISION_RADIX']!==null)
		{
			// We have a numeric datatype
			$c->size=$c->precision=$column['NUMERIC_PRECISION']!==null?(int)$column['NUMERIC_PRECISION']:null;
			$c->scale=$column['NUMERIC_SCALE']!==null?(int)$column['NUMERIC_SCALE']:null;
		}
		elseif ($column['DATA_TYPE']=='image' || $column['DATA_TYPE']=='text')
			$c->size=$c->precision=null;
		else
			$c->size=$c->precision=($column['CHARACTER_MAXIMUM_LENGTH']!== null)?(int)$column['CHARACTER_MAXIMUM_LENGTH']:null;
		$c->autoIncrement=$column['IsIdentity']==1;
		$c->comment=$column['Comment']===null ? '' : $column['Comment'];

		$c->init($column['DATA_TYPE'],$column['COLUMN_DEFAULT']);
		return $c;
	}
973362
public function unixTimestamp( $column )
    {
        $column = $this->getIdentifier( $column );

        if ( $column != 'NOW()' )
        {
            $column = "CAST( {$column} AS TIMESTAMP )";
//            // alternative
//            if ( preg_match( '/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $column ) ) {
//                $column = "TO_TIMESTAMP( {$column}, 'YYYY-MM-DD HH24:MI:SS' )";
//            }
        }

        $date1 = "CAST( SYS_EXTRACT_UTC( {$column} ) AS DATE )";
        $date2 = "TO_DATE( '19700101000000', 'YYYYMMDDHH24MISS' )";
        return " ROUND( ( {$date1} - {$date2} ) / ( 1 / 86400 ) ) ";
    }
505300
protected function _getIntegerColumn(Column\Integer $column)
    {

        if ($column->getAutoIncrement()) {
            $this->_disablePrimaryConstraint = true;
            return $column->getName().' INTEGER PRIMARY KEY AUTOINCREMENT';
        }

        $type = 'INTEGER';

        $default = '';
        if ($column->getDefault()) {
            $default = ' DEFAULT '.$column->getDefault();
        }

        return sprintf(
            '%s %s%s%s%s',
            $column->getName(),
            $type,
            $this->_columnLength($column),
            $this->_nullableColumn($column),
            $default
        );
    }
898617
public function generateColumnFormat($column)
    {
        if ($column->phpType === 'boolean') {
            return 'boolean';
        } elseif ($column->type === 'text') {
            return 'ntext';
        } elseif (stripos($column->name, 'time') !== false && $column->phpType === 'integer') {
            return 'datetime';
        } elseif (stripos($column->name, 'email') !== false) {
            return 'email';
        } elseif (stripos($column->name, 'url') !== false) {
            return 'url';
        } else {
            return 'text';
        }
    }
1094258
public function column($column)
    {
        $result = $this->fields($column)->one(); 

        // only return something if something is found
        if (is_array($result))
        {
            return reset($result);
        }
    }
45254
protected function getMetaColumnValueByKey(array $column, $key)
    {
        if (array_key_exists('Field', $column)) {
            $keyMap = [
                'Field'        => 'Field',
                'Type'         => 'Type',
                'Null'         => 'Null',
                'Key'          => 'Key',
                'Default'      => 'Default',
                'Extra'        => 'Extra',
                'Comment'      => 'Comment',
                'CharacterSet' => 'CharacterSet',
                'Collation'    => 'Collation',
            ];
        } else {
            $keyMap = [
                'Field'        => 0,
                'Type'         => 1,
                'Null'         => 2,
                'Key'          => 3,
                'Default'      => 4,
                'Extra'        => 5,
                'Comment'      => 6,
                'CharacterSet' => 7,
                'Collation'    => 8,
            ];
        }

        $result = $column[$keyMap[$key]];

        return $result;
    }
255859
public function value($column)
    {
        $result = $this->getBuilder()->value($column);

        // Reset query builder
        $this->resetBuilder();

        return $result;
    }
702552
public function value($column = 0)
    {
        $row = $this->row();
        if ($row) {
            return is_int($column) ? array_values($row)[$column] : $row[$column];
        }

        return false;
    }
669957
final public function getFieldType(string $table, string $column): string
    {
        /* @noinspection PhpUnhandledExceptionInspection */
        return $this->getColumnsMetadata($table)['fieldTypes'][$column];
    }
1341596
protected function getGenericColumn(array $column)
    {
        $typeToken = '(),';
        $databaseType = strtok($column['type'], $typeToken);

        $length = $precision = strtok($typeToken);
        $length = $precision = ($length !== false) ? (int) $length : null;

        $scale = strtok($typeToken);
        $scale = ($scale !== false) ? (int) $scale : null;

        $default = !empty($column['default']) ? $column['default'] : null;

        switch ($databaseType) {
            case 'decimal':
            case 'double':
            case 'float':
            case 'numeric':
            case 'real':
                $length = null;
                break;
            case 'bigint':
            case 'int':
            case 'integer':
            case 'mediumint':
            case 'smallint':
            case 'char':
            case 'longtext':
            case 'mediumint':
            case 'mediumtext':
            case 'string':
            case 'text':
            case 'tinytext':
            case 'varchar':
                $precision = null;
                $scale = null;
                break;
            default:
                $length = null;
                $precision = null;
                $scale = null;
                break;
        }

        return parent::getGenericColumn(
            array(
                'name'           => $column['name'],
                'type'           => $databaseType,
                'length'         => $length,
                'precision'      => $precision,
                'scale'          => $scale,
                'unsigned'       => $column['unsigned'] ? true : null,
                'fixed'          => ($databaseType === 'char') ? true : null,
                'not_null'       => $column['not_null'],
                'default'        => $default,
                'auto_increment' => $column['auto_increment'] ? true : null,
                'comment'        => !empty($column['comment']) ? $column['comment'] : null,
            )
        );
    }
72247
protected function _getIntegerColumn(Column\Integer $column)
    {

        $size = (string) $column->getSize();

        switch ($size) {
            case Column\Size::LONG:
            case Column\Size::BIG:
                $type = 'BIGINT';
                break;
            case Column\Size::SMALL:
            case Column\Size::TINY:
                $type = 'SMALLINT';
                break;
            case Column\Size::NORMAL:
            case Column\Size::MEDIUM:
            default:
                $type = 'INTEGER';
        }

        $autoIncrement = '';
        if ($column->getAutoIncrement()) {
            $autoIncrement = ' AUTO_INCREMENT';
        }

        $default = '';
        if ($column->getDefault()) {
            $default = ' DEFAULT '.$column->getDefault();
        }

        return sprintf(
            '%s %s%s%s%s%s',
            $column->getName(),
            $type,
            $this->_columnLength($column),
            $this->_nullableColumn($column),
            $autoIncrement,
            $default
        );
    }
412142
public function getColumnType($table, $column)
    {
        $table = $this->connection->getTablePrefix().$table;

        return $this->connection->getDoctrineColumn($table, $column)->getType()->getName();
    }
859696
public function values($column = 0)
    {
        if (is_int($column)) {
            return $this->statement->fetchAll(PDO::FETCH_COLUMN, $column);
        }

        return array_map(function ($row) use ($column) {
            return $row[$column];
        }, $this->rows());
    }
894529
public function parseColumn ($column)
	{
		
		// Set attribute
		
		$attribute	=	array ();
		
		// If the datatype can be parsed and the datatype is in the column map
		
		if (preg_match ('/^(\w*)(\((.*?)\))*(.*)$/', $column[1], $dataType) && 
		isset (self::$columnMap[$dataType[1]]))
		{
			
			// Set column map
			
			$columnMap				= self::$columnMap[$dataType[1]];
			
			// Set type
			
			$attribute['type']		= $columnMap[0];
			
			// Charset based on the type
			
			$charsetName			= $dataType[1];
			
			if (strpos ($dataType[4], 'unsigned') !== FALSE)
			{
				
				if ($this->parser->charsetExists ($charsetName . '_unsigned'))
				{
					$charsetName	.= '_unsigned';
				}
			}
			
			if ($this->parser->charsetExists ($charsetName))
			{
				$attribute['charset']	= $charsetName;
			}
			
			// No charset from the column data type so type the attribute type
			
			if (!isset ($attribute['charset']))
			{
				
				$charsetName			= str_replace ('self::TYPE_', '', $columnMap[0]);

				if (strpos ($dataType[4], 'unsigned') !== FALSE)
				{

					if ($this->parser->charsetExists ($charsetName . '_unsigned'))
					{
						$charsetName	.= '_unsigned';
					}
				}

				if ($this->parser->charsetExists ($charsetName))
				{
					$attribute['charset']	= strtolower ($charsetName);
				}
				
			}
			
			// Switch type
			
			switch ($attribute['type'])
			{
				
				case 'self::TYPE_INT':
					
					// Set column min and max
					
					if (isset ($columnMap[1]) && isset ($columnMap[2]))
					{
						
						// If the column is unsigned

						if (strpos ($dataType[4], 'unsigned') !== FALSE)
						{

							// Set min and max to unsigned

							$attribute['min']	= $columnMap[1] . '_UNSIGNED';
							$attribute['max']	= $columnMap[2] . '_UNSIGNED';

						}

						// Else the column is signed

						else
						{

							// Set min and max

							$attribute['min']	= $columnMap[1];
							$attribute['max']	= $columnMap[2];

						}
						
					}
					
					// Set default
					
					$attribute['default']	= $column[4]?: 0;
					
					// Break
					
					break;
				
				
				case 'self::TYPE_STRING':
					
					// Default charset
					
					$attribute['charset']	= 'default';
					
					// Set column min and max
					
					if (isset ($columnMap[1]) && isset ($columnMap[2]))
					{

						$attribute['min']	= $columnMap[1];
						$attribute['max']	= $columnMap[2];
						
					}
					
					// If value constaints have been set
					
					if ($dataType[3])
					{
						
						// Set max
						
						$attribute['max']	= (int)$dataType[3];
						
					}
					
					// Set default
					
					$attribute['default']	= '\'' . ($column[4]?: '') . '\'';
					
					// Break
					
					break;
				
				
				case 'self::TYPE_DECIMAL':

					// Set column min and max
					
					if (isset ($columnMap[1]) && isset ($columnMap[2]))
					{
						
						// If the column is unsigned

						if (strpos ($dataType[4], 'unsigned') !== FALSE)
						{

							// Set min and max to unsigned

							$attribute['min']	= $columnMap[1] . '_UNSIGNED';
							$attribute['max']	= $columnMap[2] . '_UNSIGNED';

						}

						// Else the column is signed

						else
						{

							// Set min and max

							$attribute['min']	= $columnMap[1];
							$attribute['max']	= $columnMap[2];

						}
						
					}
					
					// If value constaints have been set
					
					if ($dataType[3])
					{
						
						// Break constraint

						$constraint	= explode (',', $dataType[3]);

						// If the column is unsigned

						if (strpos ($dataType[4], 'unsigned') !== FALSE)
						{

							// Set max

							$attribute['max']	= (float)('1' . str_repeat ('0', ($constraint[0] - $constraint[1])));
							
						}
						
						// Else signed value
						
						else
						{
							
							// Set min and max
							
							$attribute['min']	= (float)('-1' . str_repeat ('0', ($constraint[0] - $constraint[1])));
							$attribute['max']	= (float)('1' . str_repeat ('0', ($constraint[0] - $constraint[1])));
							
						}
						
					}
					
					// Set default
					
					$attribute['default']	= $column[4]?: 0;
					
					// Break
					
					break;
				
				
				case 'self::TYPE_ENUM':
					
					// Remove '' from values
					
//					$values	= substr (str_replace ('\',\'', ',', $dataType[3]), 1, -1);
					
					// Set values
					
					$attribute['values']	= $dataType[3];
					
					// Set column min and max
					
					if (isset ($columnMap[1]) && isset ($columnMap[2]))
					{

						$attribute['min']	= $columnMap[1];
						$attribute['max']	= $columnMap[2];
						
					}
					
					// Set default
					
					$attribute['default']	= '\'' . (isset ($column[4])? $column[4] : '') . '\'';
					
					// Break
					
					break;
				
				
				default:
					
					// Set column min and max
					
					if (isset ($columnMap[1]) && isset ($columnMap[2]))
					{

						$attribute['min']	= $columnMap[1];
						$attribute['max']	= $columnMap[2];
						
					}
					
					// Set default
					
					$attribute['default']	= '\'' . ($column[4]?: '') . '\'';
					
					// Break
					
					break;
				
				
			}

			// If the column is the primary key
			
			if ($column[3] == 'PRI')
			{

				// Set min to 1 (required)

				$attribute['min']		= 1;

			}
			
			// Set NULL

			if ($column[2] == 'YES')
			{
				
				$attribute['null']		= 'TRUE';

				if (!isset ($attribute['default']) || !$attribute['default'] || $attribute['default'] == '\'\'')
				{
					$attribute['default']	= 'NULL';
				}

			}
			
		}
		
		// Return attribute array
		
		return $attribute;
		
	}