/**
  *
  * @param string $sql
  * @return \ArrayObject
  * @throws UnsupportedDatatypeException
  * @throws Exception\AmbiguousColumnException
  * @throws Exception\ConnectionException
  */
 protected function readColumnsMetadata($sql)
 {
     $metadata = new ArrayObject();
     $fields = $this->readFields($sql);
     $type_map = $this->getDatatypeMapping();
     foreach ($fields as $idx => $field) {
         $name = $field->orgname == '' ? $field->name : $field->orgname;
         $tableName = $field->orgtable;
         $schemaName = $field->db;
         $datatype = $field->type;
         //@codeCoverageIgnoreStart
         if (!$type_map->offsetExists($datatype)) {
             throw new UnsupportedDatatypeException("Datatype '{$datatype}' not yet supported by " . __CLASS__);
         }
         //@codeCoverageIgnoreEnd
         $datatype = $type_map->offsetGet($datatype);
         $column = Column\Type::createColumnDefinition($datatype['type'], $name, $tableName, $schemaName);
         /*
                     if ($field->name == 'min_time') {
                         var_dump($field);
                     //	var_dump($field->flags & MYSQLI_BLOB_FLAG);
                     //	var_dump($field->flags & MYSQLI_ENUM_FLAG);
                         die();
                     }*/
         /*
             MYSQLI_BINARY_FLAG
             MYSQLI_BLOB_FLAG
             MYSQLI_ENUM_FLAG
             MYSQLI_MULTIPLE_KEY_FLAG
             MYSQLI_GROUP_FLAG
             MYSQLI_SET_FLAG
             MYSQLI_UNIQUE_KEY_FLAG
             MYSQLI_ZEROFILL_FLAG
         */
         $column->setAlias($field->name);
         $column->setTableAlias($field->table);
         $column->setCatalog($field->catalog);
         $column->setOrdinalPosition($idx + 1);
         $column->setDataType($datatype['type']);
         $column->setIsNullable(!($field->flags & MYSQLI_NOT_NULL_FLAG) > 0 && $field->orgtable != '');
         $column->setIsPrimary(($field->flags & MYSQLI_PRI_KEY_FLAG) > 0);
         $column->setColumnDefault($field->def);
         if (($field->flags & MYSQLI_SET_FLAG) > 0) {
             $column->setNativeDataType('SET');
         } elseif (($field->flags & MYSQLI_ENUM_FLAG) > 0) {
             $column->setNativeDataType('ENUM');
         } else {
             $column->setNativeDataType($datatype['native']);
         }
         if ($field->table == '') {
             $column->setIsGroup(($field->flags & MYSQLI_GROUP_FLAG) > 0);
         }
         if ($column instanceof Column\Definition\NumericColumnInterface) {
             $column->setNumericUnsigned(($field->flags & MYSQLI_UNSIGNED_FLAG) > 0);
         }
         if ($column instanceof Column\Definition\IntegerColumn) {
             $column->setIsAutoIncrement(($field->flags & MYSQLI_AUTO_INCREMENT_FLAG) > 0);
         }
         if ($column instanceof Column\Definition\DecimalColumn) {
             // salary DECIMAL(5,2)
             // In this example, 5 is the precision and 2 is the scale.
             // Standard SQL requires that DECIMAL(5,2) be able to store any value
             // with five digits and two decimals, so values that can be stored in
             // the salary column range from -999.99 to 999.99.
             $column->setNumericScale($field->length - $field->decimals + 1);
             $column->setNumericPrecision($field->decimals);
         }
         if ($column instanceof Column\Definition\StringColumn) {
             $column->setCharacterMaximumLength($field->length);
         }
         if ($column instanceof Column\Definition\BlobColumn) {
             $column->setCharacterOctetLength($field->length);
         }
         $alias = $column->getAlias();
         if ($metadata->offsetExists($alias)) {
             $prev_column = $metadata->offsetGet($alias);
             $prev_def = $prev_column->toArray();
             $curr_def = $column->toArray();
             if ($prev_def['dataType'] != $curr_def['dataType'] || $prev_def['nativeDataType'] != $curr_def['nativeDataType']) {
                 throw new Exception\AmbiguousColumnException("Cannot get column metadata, non unique column found '{$alias}' in query with different definitions.");
             }
             // If the the previous definition, was a prev_def
             if ($prev_def['isPrimary']) {
                 $column = $prev_column;
             }
         }
         $metadata->offsetSet($alias, $column);
     }
     return $metadata;
 }
 /**
  *
  * @param string $sql
  * @return \ArrayObject
  * @throws UnsupportedDatatypeException
  * @throws Exception\AmbiguousColumnException
  * @throws Exception\ConnectionException
  */
 protected function readColumnsMetadata($sql)
 {
     $metadata = new ArrayObject();
     $fields = $this->readFields($sql);
     $type_map = $this->getDatatypeMapping();
     foreach ($fields as $idx => $field) {
         $name = $field['name'];
         $tableName = $field['table'];
         $datatype = strtoupper($field['native_type']);
         //@codeCoverageIgnoreStart
         if (!$type_map->offsetExists($datatype)) {
             throw new UnsupportedDatatypeException("Datatype '{$datatype}' not yet supported by " . __CLASS__);
         }
         //@codeCoverageIgnoreEnd
         $datatype = $type_map->offsetGet($datatype);
         $column = Column\Type::createColumnDefinition($datatype['type'], $name, $tableName, $schemaName = null);
         $alias = $field['name'];
         $column->setAlias($alias);
         $column->setTableAlias($field['table']);
         //$column->setCatalog($field->catalog);
         $column->setOrdinalPosition($idx + 1);
         $column->setDataType($datatype['type']);
         $column->setIsNullable(!in_array('not_null', $field['flags']));
         $column->setIsPrimary(in_array('primary_key', $field['flags']));
         //$column->setColumnDefault($field->def);
         $column->setNativeDataType($datatype['native']);
         /*
                     if ($column instanceof Column\Definition\NumericColumnInterface) {
                         $column->setNumericUnsigned(($field->flags & MYSQLI_UNSIGNED_FLAG) > 0);
                     }
         
                     if ($column instanceof Column\Definition\IntegerColumn) {
                         $column->setIsAutoIncrement(($field->flags & MYSQLI_AUTO_INCREMENT_FLAG) > 0);
                     }
         */
         if ($column instanceof Column\Definition\DecimalColumn) {
             // salary DECIMAL(5,2)
             // In this example, 5 is the precision and 2 is the scale.
             // Standard SQL requires that DECIMAL(5,2) be able to store any value
             // with five digits and two decimals, so values that can be stored in
             // the salary column range from -999.99 to 999.99.
             $column->setNumericUnsigned(false);
             $column->setNumericPrecision($field['precision']);
             $column->setNumericScale($field['len'] - $field['precision'] + 1);
         }
         if ($column instanceof Column\Definition\StringColumn) {
             $column->setCharacterMaximumLength($field['len']);
         }
         if ($column instanceof Column\Definition\BlobColumn) {
             $column->setCharacterOctetLength($field['len']);
         }
         if ($metadata->offsetExists($alias)) {
             $prev_column = $metadata->offsetGet($alias);
             $prev_def = $prev_column->toArray();
             $curr_def = $column->toArray();
             if ($prev_def['dataType'] != $curr_def['dataType'] || $prev_def['nativeDataType'] != $curr_def['nativeDataType']) {
                 throw new Exception\AmbiguousColumnException("Cannot get column metadata, non unique column found '{$alias}' in query with different definitions.");
             }
             // If the the previous definition, was a prev_def
             if ($prev_def['isPrimary']) {
                 $column = $prev_column;
             }
         }
         $metadata->offsetSet($alias, $column);
     }
     return $metadata;
 }