Commit 16fc4db1 authored by unknown's avatar unknown
Browse files

Bug#26899 ndb_restore cannot restore selected tables and databases

Bug#26900 ndb_restore printout option does not give structured data
- add data stucturing options
- add database and table selection options


ndb/include/ndbapi/NdbRecAttr.hpp:
  add formatting option to ndb recattr printing
ndb/include/util/OutputStream.hpp:
  getter for FILE*
ndb/src/ndbapi/NdbRecAttr.cpp:
  add formatting option to ndb recattr printing
ndb/tools/restore/Restore.cpp:
  add formatting option to restore printing
  adoption to 5.1 source code
ndb/tools/restore/Restore.hpp:
  restore adoption to 5.1
ndb/tools/restore/consumer_printer.cpp:
  add formatting option to restore printing
ndb/tools/restore/restore_main.cpp:
  added option to restore only selected databases and tables
  added option to get CSV printout to file and stdout
  add formatting option to restore printing
  adoption to 5.1 source code
parent a58b9b05
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -441,6 +441,25 @@ NdbRecAttr::isNULL() const

class NdbOut& operator <<(class NdbOut&, const NdbRecAttr &);

class NdbRecordPrintFormat
{
public:
  NdbRecordPrintFormat();
  virtual ~NdbRecordPrintFormat();
  const char *lines_terminated_by;
  const char *fields_terminated_by;
  const char *start_array_enclosure;
  const char *end_array_enclosure;
  const char *fields_enclosed_by;
  const char *fields_optionally_enclosed_by;
  const char *hex_prefix;
  const char *null_string;
  int hex_format;
};
NdbOut&
ndbrecattr_print_formatted(NdbOut& out, const NdbRecAttr &r,
                           const NdbRecordPrintFormat &f);

#endif // ifndef DOXYGEN_SHOULD_SKIP_INTERNAL

#endif
+2 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ class FileOutputStream : public OutputStream {
  FILE * f;
public:
  FileOutputStream(FILE * file = stdout);
  FILE *getFile() { return f; }

  int print(const char * fmt, ...);
  int println(const char * fmt, ...);
+103 −24
Original line number Diff line number Diff line
@@ -140,8 +140,24 @@ NdbRecAttr::receive_data(const Uint32 * data, Uint32 sz){
  return false;
}

NdbRecordPrintFormat::NdbRecordPrintFormat()
{
  fields_terminated_by= ";";
  start_array_enclosure= "[";
  end_array_enclosure= "]";
  fields_enclosed_by= "";
  fields_optionally_enclosed_by= "\"";
  lines_terminated_by= "\n";
  hex_prefix= "H'";
  null_string= "[NULL]";
  hex_format= 0;
}
NdbRecordPrintFormat::~NdbRecordPrintFormat() {};
static const NdbRecordPrintFormat default_print_format;

static void
ndbrecattr_print_string(NdbOut& out, const char *type,
ndbrecattr_print_string(NdbOut& out, const NdbRecordPrintFormat &f,
                        const char *type, bool is_binary,
			const char *aref, unsigned sz)
{
  const unsigned char* ref = (const unsigned char*)aref;
@@ -150,6 +166,25 @@ ndbrecattr_print_string(NdbOut& out, const char *type,
  for (i=sz-1; i >= 0; i--)
    if (ref[i] == 0) sz--;
    else break;
  if (!is_binary)
  {
    // trailing spaces are not printed
    for (i=sz-1; i >= 0; i--)
      if (ref[i] == 32) sz--;
      else break;
  }
  if (is_binary && f.hex_format)
  {
    if (sz == 0)
    {
      out.print("0x0");
      return;
    }
    out.print("0x");
    for (len = 0; len < (int)sz; len++)
      out.print("%02X", (int)ref[len]);
    return;
  }
  if (sz == 0) return; // empty

  for (len=0; len < (int)sz && ref[i] != 0; len++)
@@ -170,37 +205,56 @@ ndbrecattr_print_string(NdbOut& out, const char *type,
    for (i= len+1; ref[i] != 0; i++)
    out.print("%u]",len-i);
    assert((int)sz > i);
    ndbrecattr_print_string(out,type,aref+i,sz-i);
    ndbrecattr_print_string(out,f,type,is_binary,aref+i,sz-i);
  }
}

NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
NdbOut&
ndbrecattr_print_formatted(NdbOut& out, const NdbRecAttr &r,
                           const NdbRecordPrintFormat &f)
{
  if (r.isNULL())
  {
    out << "[NULL]";
    out << f.null_string;
    return out;
  }
  
  const NdbDictionary::Column* c = r.getColumn();
  uint length = c->getLength();
  if (length > 1)
    out << "[";

  for (Uint32 j = 0; j < length; j++) 
  {
    if (j > 0)
      out << " ";

    const char *fields_optionally_enclosed_by;
    if (f.fields_enclosed_by[0] == '\0')
      fields_optionally_enclosed_by=
        f.fields_optionally_enclosed_by;
    else
      fields_optionally_enclosed_by= "";
    out << f.fields_enclosed_by;
    Uint32 j;
    switch(r.getType()){
    case NdbDictionary::Column::Bigunsigned:
      out << r.u_64_value();
      break;
    case NdbDictionary::Column::Bit:
      out << hex << "H'" << r.u_32_value() << dec;
      for (j = (length-1)/32 + 1; j > 0; j--)
        if (*((Uint32*)r.aRef() + j - 1))
          break;
      if (j == 0)
      {
        out << "0x0";
        break;
      }
      out << f.hex_prefix << "0x";
      for (; j > 0; j--)
        out.print("%X", *((Uint32*)r.aRef() + j - 1));
      break;
    case NdbDictionary::Column::Unsigned:
      out << r.u_32_value();
      if (length > 1)
        out << f.start_array_enclosure;
      out << *(Uint32*)r.aRef();
      for (j = 1; j < length; j++)
        out << " " << *((Uint32*)r.aRef() + j);
      if (length > 1)
        out << f.end_array_enclosure;
      break;
    case NdbDictionary::Column::Smallunsigned:
      out << r.u_short_value();
@@ -221,25 +275,37 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
      out << (int) r.char_value();
      break;
    case NdbDictionary::Column::Binary:
      if (!f.hex_format)
        out << fields_optionally_enclosed_by;
      j = r.arraySize();
      ndbrecattr_print_string(out,"Binary", r.aRef(), j);
      ndbrecattr_print_string(out,f,"Binary", true, r.aRef(), j);
      if (!f.hex_format)
        out << fields_optionally_enclosed_by;
      break;
    case NdbDictionary::Column::Char:
      out << fields_optionally_enclosed_by;
      j = length;
      ndbrecattr_print_string(out,"Char", r.aRef(), r.arraySize());
      ndbrecattr_print_string(out,f,"Char", false, r.aRef(), r.arraySize());
      out << fields_optionally_enclosed_by;
      break;
    case NdbDictionary::Column::Varchar:
    {
      out << fields_optionally_enclosed_by;
      unsigned len = *(const unsigned char*)r.aRef();
      ndbrecattr_print_string(out,"Varchar", r.aRef()+1,len);
      ndbrecattr_print_string(out,f,"Varchar", false, r.aRef()+1,len);
      j = length;
      out << fields_optionally_enclosed_by;
    }
    break;
    case NdbDictionary::Column::Varbinary:
    {
      if (!f.hex_format)
        out << fields_optionally_enclosed_by;
      unsigned len = *(const unsigned char*)r.aRef();
      ndbrecattr_print_string(out,"Varbinary", r.aRef()+1,len);
      ndbrecattr_print_string(out,f,"Varbinary", true, r.aRef()+1,len);
      j = length;
      if (!f.hex_format)
        out << fields_optionally_enclosed_by;
    }
    break;
    case NdbDictionary::Column::Float:
@@ -368,16 +434,28 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
    break;
    case NdbDictionary::Column::Longvarchar:
    {
      out << fields_optionally_enclosed_by;
      unsigned len = uint2korr(r.aRef());
      ndbrecattr_print_string(out,"Longvarchar", r.aRef()+2,len);
      ndbrecattr_print_string(out,f,"Longvarchar", false, r.aRef()+2,len);
      j = length;
      out << fields_optionally_enclosed_by;
    }
    break;
    case NdbDictionary::Column::Longvarbinary:
    {
      if (!f.hex_format)
        out << fields_optionally_enclosed_by;
      unsigned len = uint2korr(r.aRef());
      ndbrecattr_print_string(out,f,"Longvarbinary", true, r.aRef()+2,len);
      j = length;
      if (!f.hex_format)
        out << fields_optionally_enclosed_by;
    }
    break;

    case NdbDictionary::Column::Undefined:
    case NdbDictionary::Column::Mediumint:
    case NdbDictionary::Column::Mediumunsigned:
    case NdbDictionary::Column::Longvarbinary:
    unknown:
    //default: /* no print functions for the rest, just print type */
    out << (int) r.getType();
@@ -386,14 +464,15 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
      out << " " << j << " times";
    break;
    }
    out << f.fields_enclosed_by;
  }

  if (length > 1)
  {
    out << "]";
  return out;
}

  return out;
NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
{
  return ndbrecattr_print_formatted(out, r, default_print_format);
}

Int64
+54 −6
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <SimpleProperties.hpp>
#include <signaldata/DictTabInfo.hpp>

extern NdbRecordPrintFormat g_ndbrecord_print_format;

Uint16 Twiddle16(Uint16 in); // Byte shift 16-bit data
Uint32 Twiddle32(Uint32 in); // Byte shift 32-bit data
Uint64 Twiddle64(Uint64 in); // Byte shift 64-bit data
@@ -118,6 +120,8 @@ RestoreMetaData::loadContent()
      return 0;
    }
  }
  if (! markSysTables())
    return 0;
  if(!readGCPEntry())
    return 0;

@@ -175,6 +179,49 @@ RestoreMetaData::readMetaTableDesc() {
  return parseTableDescriptor((Uint32*)ptr, len);	     
}

bool
RestoreMetaData::markSysTables()
{
  Uint32 i;
  for (i = 0; i < getNoOfTables(); i++) {
    TableS* table = allTables[i];
    table->m_local_id = i;
    const char* tableName = table->getTableName();
    if ( // XXX should use type
        strcmp(tableName, "SYSTAB_0") == 0 ||
        strcmp(tableName, "NDB$EVENTS_0") == 0 ||
        strcmp(tableName, "sys/def/SYSTAB_0") == 0 ||
        strcmp(tableName, "sys/def/NDB$EVENTS_0") == 0)
      table->isSysTable = true;
  }
  for (i = 0; i < getNoOfTables(); i++) {
    TableS* blobTable = allTables[i];
    const char* blobTableName = blobTable->getTableName();
    // yet another match blob
    int cnt, id1, id2;
    char buf[256];
    cnt = sscanf(blobTableName, "%[^/]/%[^/]/NDB$BLOB_%d_%d",
                 buf, buf, &id1, &id2);
    if (cnt == 4) {
      Uint32 j;
      for (j = 0; j < getNoOfTables(); j++) {
        TableS* table = allTables[j];
        if (table->getTableId() == (Uint32) id1) {
          if (table->isSysTable)
            blobTable->isSysTable = true;
          blobTable->m_main_table = table;
          break;
        }
      }
      if (j == getNoOfTables()) {
        err << "Restore: Bad primary table id in " << blobTableName << endl;
        return false;
      }
    }
  }
  return true;
}

bool
RestoreMetaData::readGCPEntry() {

@@ -259,6 +306,8 @@ TableS::TableS(Uint32 version, NdbTableImpl* tableImpl)
  m_max_auto_val= 0;
  m_noOfRecords= 0;
  backupVersion = version;
  isSysTable = false;
  m_main_table = NULL;
  
  for (int i = 0; i < tableImpl->getNoOfColumns(); i++)
    createAttr(tableImpl->getColumn(i));
@@ -704,6 +753,7 @@ bool RestoreDataIterator::readFragmentHeader(int & ret)
    return false;
  }

  info.setLevel(254);
  info << "_____________________________________________________" << endl
       << "Processing data in table: " << m_currentTable->getTableName() 
       << "(" << Header.TableId << ") fragment " 
@@ -924,13 +974,13 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){

  if (data.null)
  {
    ndbout << "<NULL>";
    ndbout << g_ndbrecord_print_format.null_string;
    return ndbout;
  }
  
  NdbRecAttr tmprec(0);
  tmprec.setup(desc.m_column, (char *)data.void_value);
  ndbout << tmprec;
  ndbrecattr_print_formatted(ndbout, tmprec, g_ndbrecord_print_format);

  return ndbout;
}
@@ -939,17 +989,15 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){
NdbOut& 
operator<<(NdbOut& ndbout, const TupleS& tuple)
{
  ndbout << tuple.getTable()->getTableName() << "; ";
  for (int i = 0; i < tuple.getNoOfAttributes(); i++) 
  {
    if (i > 0)
      ndbout << g_ndbrecord_print_format.fields_terminated_by;
    AttributeData * attr_data = tuple.getData(i);
    const AttributeDesc * attr_desc = tuple.getDesc(i);
    const AttributeS attr = {attr_desc, *attr_data};
    debug << i << " " << attr_desc->m_column->getName();
    ndbout << attr;
    
    if (i != (tuple.getNoOfAttributes() - 1))
      ndbout << delimiter << " ";
  } // for
  return ndbout;
}
+16 −2
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@
#include <ndb_version.h>
#include <version.h>

static const char * delimiter = ";"; // Delimiter in file dump

const int FileNameLenC = 256;
const int TableNameLenC = 256;
const int AttrNameLenC = 256;
@@ -143,6 +141,10 @@ class TableS {

  int pos;

  bool isSysTable;
  TableS *m_main_table;
  Uint32 m_local_id;

  Uint64 m_noOfRecords;
  Vector<FragmentInfo *> m_fragmentInfo;

@@ -156,6 +158,9 @@ public:
  Uint32 getTableId() const { 
    return m_dictTable->getTableId(); 
  }
  Uint32 getLocalId() const { 
    return m_local_id; 
  }
  Uint32 getNoOfRecords() const { 
    return m_noOfRecords; 
  }
@@ -235,6 +240,14 @@ public:
    return allAttributesDesc[attributeId]; 
  }

  bool getSysTable() const {
    return isSysTable;
  }

  const TableS *getMainTable() const {
    return m_main_table;
  }

  TableS& operator=(TableS& org) ; 
}; // TableS;

@@ -285,6 +298,7 @@ class RestoreMetaData : public BackupFile {
  Vector<TableS *> allTables;
  bool readMetaFileHeader();
  bool readMetaTableDesc();
  bool markSysTables();
		
  bool readGCPEntry();
  bool readFragmentInfo();
Loading