Example #1
0
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, 
                                        const char *name, bool& info)
  {
  int  buftyp[] = {TYPE_STRING, TYPE_SHORT,  TYPE_STRING, TYPE_INT,
                   TYPE_INT,    TYPE_SHORT,  TYPE_SHORT,  TYPE_SHORT,
                   TYPE_STRING, TYPE_STRING, TYPE_STRING};
  XFLD fldtyp[] = {FLD_NAME,   FLD_TYPE,  FLD_TYPENAME, FLD_PREC,
                   FLD_LENGTH, FLD_SCALE, FLD_RADIX,    FLD_NULL,
                   FLD_REM,    FLD_NO,    FLD_CHARSET};
  unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
  char        *fld, *colname, *chset, *fmt, v;
  int          i, n, ncol = sizeof(buftyp) / sizeof(int);
  int          prec, len, type, scale;
  int          zconv = GetConvSize();
  bool         mysql;
  TABLE_SHARE *s = NULL;
  Field*      *field;
  Field       *fp;
  PQRYRES      qrp;
  PCOLRES      crp;

  if (!info) {
    if (!(s = GetTableShare(g, thd, db, name, mysql))) {
      return NULL;
    } else if (s->is_view) {
      strcpy(g->Message, "Use MYSQL type to see columns from a view");
      info = true;       // To tell caller name is a view
      free_table_share(s);
      return NULL;
    } else
      n = s->fieldnames.count;

  } else {
    n = 0;
    length[0] = 128;
  } // endif info

  /**********************************************************************/
  /*  Allocate the structures used to refer to the result set.          */
  /**********************************************************************/
  if (!(qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
                             buftyp, fldtyp, length, false, true)))
    return NULL;

  // Some columns must be renamed
  for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
    switch (++i) {
      case  2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
      case 10: crp->Name = "Date_fmt";  break;
      case 11: crp->Name = "Collation"; break;
      } // endswitch i

  if (info)
    return qrp;

  /**********************************************************************/
  /*  Now get the results into blocks.                                  */
  /**********************************************************************/
  for (i = 0, field= s->field; *field; field++) {
    fp= *field;

    // Get column name
    crp = qrp->Colresp;                    // Column_Name
    colname = (char *)fp->field_name;
    crp->Kdata->SetValue(colname, i);

    chset = (char *)fp->charset()->name;
    v = (!strcmp(chset, "binary")) ? 'B' : 0;

    if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) {
      if (v == 'K') {
        // Skip this column
        sprintf(g->Message, "Column %s skipped (unsupported type)", colname);
        push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
        continue;
        } // endif v

      sprintf(g->Message, "Column %s unsupported type", colname);
      qrp = NULL;
      break;
      } // endif type

      if (v == 'X') {
        len = zconv;
        sprintf(g->Message, "Column %s converted to varchar(%d)",
                colname, len);
        push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
        } // endif v

    crp = crp->Next;                       // Data_Type
    crp->Kdata->SetValue(type, i);

    if (fp->flags & ZEROFILL_FLAG)
      crp->Nulls[i] = 'Z';
    else if (fp->flags & UNSIGNED_FLAG)
      crp->Nulls[i] = 'U';
    else                  // X means TEXT field
      crp->Nulls[i] = (v == 'X') ? 'V' : v;

    crp = crp->Next;                       // Type_Name
    crp->Kdata->SetValue(GetTypeName(type), i);
    fmt = NULL;

    if (type == TYPE_DATE) {
      // When creating tables we do need info about date columns
      if (mysql) {
        fmt = MyDateFmt(fp->type());
        prec = len = strlen(fmt);
      } else {
        fmt = (char*)fp->option_struct->dateformat;
        prec = len = fp->field_length;
      } // endif mysql

    } else if (v != 'X') {
      if (type == TYPE_DECIM)
        prec = ((Field_new_decimal*)fp)->precision;
      else
        prec = fp->field_length;
//      prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length;

      len = fp->char_length();
    } else
      prec = len = zconv;

    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(prec, i);

    crp = crp->Next;                       // Length
    crp->Kdata->SetValue(len, i);

    crp = crp->Next;                       // Scale
    scale = (type == TYPE_DOUBLE || type == TYPE_DECIM) ? fp->decimals()
                                                        : 0;
    crp->Kdata->SetValue(scale, i);

    crp = crp->Next;                       // Radix
    crp->Kdata->SetValue(0, i);

    crp = crp->Next;                       // Nullable
    crp->Kdata->SetValue((fp->null_ptr != 0) ? 1 : 0, i);

    crp = crp->Next;                       // Remark

    // For Valgrind
    if (fp->comment.length > 0 && (fld = fp->comment.str))
      crp->Kdata->SetValue(fld, fp->comment.length, i);
    else
      crp->Kdata->Reset(i);

    crp = crp->Next;                       // New (date format)
    crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);

    crp = crp->Next;                       // New (charset)
    fld = (char *)fp->charset()->name;
    crp->Kdata->SetValue(fld, i);

    // Add this item
    qrp->Nblin++;
    i++;                                   // Can be skipped
    } // endfor field

  /**********************************************************************/
  /*  Return the result pointer for use by GetData routines.            */
  /**********************************************************************/
  if (s)
	  free_table_share(s);
	  
  return qrp;
  } // end of TabColumns
Example #2
0
PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
                  const char *user, const char *pwd,
                  const char *table, const char *colpat,
                  int port, bool info)
  {
  int  buftyp[] = {TYPE_STRING, TYPE_SHORT,  TYPE_STRING, TYPE_INT,
                   TYPE_STRING, TYPE_SHORT,  TYPE_SHORT,  TYPE_SHORT,
                   TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING,
                   TYPE_STRING};
  XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,  FLD_TYPENAME, FLD_PREC,
                   FLD_KEY,  FLD_SCALE, FLD_RADIX,    FLD_NULL,
                   FLD_REM,  FLD_NO,    FLD_DEFAULT,  FLD_EXTRA,
                   FLD_CHARSET};
  unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
  char   *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16];
  int     i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
  int     len, type, prec, rc, k = 0;
  PQRYRES qrp;
  PCOLRES crp;
  MYSQLC  myc;

  if (!port)
    port = mysqld_port;

  if (!info) {
    /********************************************************************/
    /*  Open the connection with the MySQL server.                      */
    /********************************************************************/
    if (myc.Open(g, host, db, user, pwd, port))
      return NULL;

    /********************************************************************/
    /*  Do an evaluation of the result size.                            */
    /********************************************************************/
    STRING cmd(g, 64, "SHOW FULL COLUMNS FROM ");
    bool   b = cmd.Append((PSZ)table);

    b |= cmd.Append(" FROM ");
    b |= cmd.Append((PSZ)(db ? db : PlgGetUser(g)->DBName));

    if (colpat) {
      b |= cmd.Append(" LIKE ");
      b |= cmd.Append((PSZ)colpat);
      } // endif colpat

    if (b) {
      strcpy(g->Message, "Out of memory");
      return NULL;
      } // endif b

    if (trace)
      htrc("MyColumns: cmd='%s'\n", cmd.GetStr());

    if ((n = myc.GetResultSize(g, cmd.GetStr())) < 0) {
      myc.Close();
      return NULL;
      } // endif n

    /********************************************************************/
    /*  Get the size of the name and default columns.                   */
    /********************************************************************/
    length[0] = myc.GetFieldLength(0);
//  length[10] = myc.GetFieldLength(5);
  } else {
    n = 0;
    length[0] = 128;
  } // endif info

  /**********************************************************************/
  /*  Allocate the structures used to refer to the result set.          */
  /**********************************************************************/
  if (!(qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
                             buftyp, fldtyp, length, false, true)))
    return NULL;

  // Some columns must be renamed
  for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
    switch (++i) {
      case  2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
      case  4: crp->Name = "Length";    break;
      case  5: crp->Name = "Key";       break;
      case 10: crp->Name = "Date_fmt";  break;
      case 11: crp->Name = "Default";   break;
      case 12: crp->Name = "Extra";     break;
      case 13: crp->Name = "Collation"; break;
      } // endswitch i

  if (info)
    return qrp;

  /**********************************************************************/
  /*  Now get the results into blocks.                                  */
  /**********************************************************************/
  for (i = 0; i < n; /*i++*/) {
    if ((rc = myc.Fetch(g, -1)) == RC_FX) {
      myc.Close();
      return NULL;
    } else if (rc == RC_EF)
      break;

    // Get column name
    colname = myc.GetCharField(0);
    crp = qrp->Colresp;                    // Column_Name
    crp->Kdata->SetValue(colname, i);

    // Get type, type name, precision, unsigned and zerofill
    chset = myc.GetCharField(2);
    fld = myc.GetCharField(1);
    prec = 0;
    len = 0;
    v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
    *uns = 0;
    *zero = 0;

    switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) {
      case 3:
        nf = sscanf(fld, "%[^(](%d,%d) %s %s", buf, &len, &prec, uns, zero);
        break;
      case 2:
        nf = sscanf(fld, "%[^(](%d) %s %s", buf, &len, uns, zero) + 1;
        break;
      case 1:
        nf = sscanf(fld, "%s %s %s", buf, uns, zero) + 2;
        break;
      default:
        sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
        myc.Close();
        return NULL;
      } // endswitch nf

    if ((type = MYSQLtoPLG(buf, &v)) == TYPE_ERROR) {
      if (v == 'K') {
        // Skip this column
        sprintf(g->Message, "Column %s skipped (unsupported type %s)",
                colname, buf);
        PushWarning(g, thd);
        continue;
        } // endif v

      sprintf(g->Message, "Column %s unsupported type %s", colname, buf);
      myc.Close();
      return NULL;
    } else if (type == TYPE_STRING) {
      if (v == 'X') {
        len = GetConvSize();
        sprintf(g->Message, "Column %s converted to varchar(%d)",
                colname, len);
        PushWarning(g, thd);
        v = 'V';
      } else
        len = MY_MIN(len, 4096);

    } // endif type

    qrp->Nblin++;
    crp = crp->Next;                       // Data_Type
    crp->Kdata->SetValue(type, i);

    switch (nf) {
      case 5:  crp->Nulls[i] = 'Z'; break;
      case 4:  crp->Nulls[i] = 'U'; break;
      default: crp->Nulls[i] = v;   break;
      } // endswitch nf

    crp = crp->Next;                       // Type_Name
    crp->Kdata->SetValue(buf, i);

    if (type == TYPE_DATE) {
      // When creating tables we do need info about date columns
      fmt = MyDateFmt(buf);
      len = strlen(fmt);
    } else
      fmt = NULL;

    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(len, i);

    crp = crp->Next;                       // key (was Length)
    fld = myc.GetCharField(4);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // Scale
    crp->Kdata->SetValue(prec, i);

    crp = crp->Next;                       // Radix
    crp->Kdata->SetValue(0, i);

    crp = crp->Next;                       // Nullable
    fld = myc.GetCharField(3);
    crp->Kdata->SetValue((toupper(*fld) == 'Y') ? 1 : 0, i);

    crp = crp->Next;                       // Remark
    fld = myc.GetCharField(8);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // Date format
//  crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
    crp->Kdata->SetValue(fmt, i);

    crp = crp->Next;                       // New (default)
    fld = myc.GetCharField(5);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // New (extra)
    fld = myc.GetCharField(6);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // New (charset)
    fld = chset;
    crp->Kdata->SetValue(fld, i);

    i++;                                   // Can be skipped
    } // endfor i

#if 0
  if (k > 1) {
    // Multicolumn primary key
    PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata;

    for (i = 0; i < n; i++)
      if (vbp->GetIntValue(i))
        vbp->SetValue(k, i);

    } // endif k
#endif // 0

  /**********************************************************************/
  /*  Close MySQL connection.                                           */
  /**********************************************************************/
  myc.Close();

  /**********************************************************************/
  /*  Return the result pointer for use by GetData routines.            */
  /**********************************************************************/
  return qrp;
  } // end of MyColumns