void fix_result_types()

in driver/utility.cc [145:332]


void fix_result_types(STMT *stmt)
{
  uint i;
  MYSQL_RES *result= stmt->result;
  DESCREC *irrec;
  MYSQL_FIELD *field;
  int capint32= stmt->dbc->ds.opt_COLUMN_SIZE_S32 ? 1 : 0;

  stmt->state= ST_EXECUTED;  /* Mark set found */

  /* Populate the IRD records */
  size_t f_count = stmt->field_count();
  for (i= 0; i < f_count; ++i)
  {
    irrec= desc_get_rec(stmt->ird, i, TRUE);
    /* TODO function for this */
    field= result->fields + i;

    irrec->row.field= field;
    irrec->type= get_sql_data_type(stmt, field, NULL);
    irrec->concise_type= get_sql_data_type(stmt, field,
                                           (char *)irrec->row.type_name);
    switch (irrec->concise_type)
    {
    case SQL_DATE:
    case SQL_TYPE_DATE:
    case SQL_TIME:
    case SQL_TYPE_TIME:
    case SQL_TIMESTAMP:
    case SQL_TYPE_TIMESTAMP:
      irrec->type= SQL_DATETIME;
      break;
    default:
      irrec->type= irrec->concise_type;
      break;
    }
    irrec->datetime_interval_code=
      get_dticode_from_concise_type(irrec->concise_type);
    irrec->type_name= (SQLCHAR *) irrec->row.type_name;
    irrec->length= get_column_size(stmt, field);
    irrec->octet_length= get_transfer_octet_length(stmt, field);
    irrec->display_size= get_display_size(stmt, field);
    /* According ODBC specs(http://msdn.microsoft.com/en-us/library/ms713558%28v=VS.85%29.aspx)
      "SQL_DESC_OCTET_LENGTH ... For variable-length character or binary types,
      this is the maximum length in bytes. This value does not include the null
      terminator" Thus there is no need to add 1 to octet_length for char types */
    irrec->precision= 0;
    /* Set precision for all non-char/blob types */
    switch (irrec->type)
    {
    case SQL_BINARY:
    case SQL_BIT:
    case SQL_CHAR:
    case SQL_WCHAR:
    case SQL_VARBINARY:
    case SQL_VARCHAR:
    case SQL_WVARCHAR:
    case SQL_LONGVARBINARY:
    case SQL_LONGVARCHAR:
    case SQL_WLONGVARCHAR:
      break;
    default:
      irrec->precision= (SQLSMALLINT) irrec->length;
      break;
    }
    irrec->scale= myodbc_max(0, get_decimal_digits(stmt, field));
    if ((field->flags & NOT_NULL_FLAG) &&
        !(field->type == MYSQL_TYPE_TIMESTAMP) &&
        !(field->flags & AUTO_INCREMENT_FLAG))
      irrec->nullable= SQL_NO_NULLS;
    else
      irrec->nullable= SQL_NULLABLE;
    irrec->table_name= (SQLCHAR *)field->table;
    irrec->name= (SQLCHAR *)field->name;
    irrec->label= (SQLCHAR *)field->name;
    if (field->flags & AUTO_INCREMENT_FLAG)
      irrec->auto_unique_value= SQL_TRUE;
    else
      irrec->auto_unique_value= SQL_FALSE;
    /* We need support from server, when aliasing is there */
    irrec->base_column_name= (SQLCHAR *)field->org_name;
    irrec->base_table_name= (SQLCHAR *)field->org_table;
    if (field->flags & BINARY_FLAG) /* TODO this doesn't cut it anymore */
      irrec->case_sensitive= SQL_TRUE;
    else
      irrec->case_sensitive= SQL_FALSE;

    if (field->db && *field->db)
    {
        irrec->catalog_name= (SQLCHAR *)field->db;
    }
    else
    {
      irrec->catalog_name= (SQLCHAR *)(stmt->dbc->database.c_str());
    }

    irrec->fixed_prec_scale= SQL_FALSE;
    switch (field->type)
    {
    case MYSQL_TYPE_LONG_BLOB:
    case MYSQL_TYPE_TINY_BLOB:
    case MYSQL_TYPE_MEDIUM_BLOB:
    case MYSQL_TYPE_BLOB:
    case MYSQL_TYPE_VAR_STRING:
    case MYSQL_TYPE_STRING:
    case MYSQL_TYPE_JSON:
      if (field->charsetnr == BINARY_CHARSET_NUMBER)
      {
        irrec->literal_prefix= (SQLCHAR *) "0x";
        irrec->literal_suffix= (SQLCHAR *) "";
        // The charset number must be only changed for JSON
        if (field->type == MYSQL_TYPE_JSON)
          field->charsetnr = UTF8_CHARSET_NUMBER;
        break;
      }
      /* FALLTHROUGH */

    case MYSQL_TYPE_DATE:
    case MYSQL_TYPE_DATETIME:
    case MYSQL_TYPE_NEWDATE:
    case MYSQL_TYPE_TIMESTAMP:
    case MYSQL_TYPE_TIME:
    case MYSQL_TYPE_YEAR:
      irrec->literal_prefix= (SQLCHAR *) "'";
      irrec->literal_suffix= (SQLCHAR *) "'";
      break;

    case MYSQL_TYPE_VECTOR:
      irrec->literal_prefix = (SQLCHAR *) "";
      irrec->literal_suffix = (SQLCHAR *) "";
      break;

    default:
      irrec->literal_prefix= (SQLCHAR *) "";
      irrec->literal_suffix= (SQLCHAR *) "";
    }
    switch (field->type) {
    case MYSQL_TYPE_SHORT:
    case MYSQL_TYPE_LONG:
    case MYSQL_TYPE_LONGLONG:
    case MYSQL_TYPE_INT24:
    case MYSQL_TYPE_TINY:
    case MYSQL_TYPE_DECIMAL:
      irrec->num_prec_radix= 10;
      break;

    /* overwrite irrec->precision set above */
    case MYSQL_TYPE_FLOAT:
      irrec->num_prec_radix= 2;
      irrec->precision= 23;
      break;

    case MYSQL_TYPE_DOUBLE:
      irrec->num_prec_radix= 2;
      irrec->precision= 53;
      break;

    default:
      irrec->num_prec_radix= 0;
      break;
    }
    irrec->schema_name= (SQLCHAR *) "";
    /*
      We limit BLOB/TEXT types to SQL_PRED_CHAR due an oversight in ADO
      causing problems with updatable cursors.
    */
    switch (irrec->concise_type)
    {
      case SQL_LONGVARBINARY:
      case SQL_LONGVARCHAR:
      case SQL_WLONGVARCHAR:
        irrec->searchable= SQL_PRED_CHAR;
        break;
      default:
        irrec->searchable= SQL_SEARCHABLE;
        break;
    }
    irrec->unnamed= SQL_NAMED;
    if (field->flags & UNSIGNED_FLAG)
      irrec->is_unsigned= SQL_TRUE;
    else
      irrec->is_unsigned= SQL_FALSE;
    if (field->table && *field->table)
      irrec->updatable= SQL_ATTR_READWRITE_UNKNOWN;
    else
      irrec->updatable= SQL_ATTR_READONLY;
  }
}