Пример #1
0
TEST_F(TableTupleTest, HiddenColumns)
{
    TupleSchemaBuilder builder(2, 2);
    builder.setColumnAtIndex(0, VALUE_TYPE_BIGINT);
    builder.setColumnAtIndex(1, VALUE_TYPE_VARCHAR, 256);
    builder.setHiddenColumnAtIndex(0, VALUE_TYPE_BIGINT);
    builder.setHiddenColumnAtIndex(1, VALUE_TYPE_VARCHAR, 10);
    ScopedTupleSchema schema(builder.build());

    StandAloneTupleStorage autoStorage(schema.get());
    const TableTuple& tuple = autoStorage.tuple();

    NValue nvalVisibleBigint = ValueFactory::getBigIntValue(999);
    NValue nvalVisibleString = ValueFactory::getStringValue("catdog");
    NValue nvalHiddenBigint = ValueFactory::getBigIntValue(1066);
    NValue nvalHiddenString = ValueFactory::getStringValue("platypus");

    tuple.setNValue(0, nvalVisibleBigint);
    tuple.setNValue(1, nvalVisibleString);
    tuple.setHiddenNValue(0, nvalHiddenBigint);
    tuple.setHiddenNValue(1, nvalHiddenString);

    EXPECT_EQ(0, tuple.getNValue(0).compare(nvalVisibleBigint));
    EXPECT_EQ(0, tuple.getNValue(1).compare(nvalVisibleString));
    EXPECT_EQ(0, tuple.getHiddenNValue(0).compare(nvalHiddenBigint));
    EXPECT_EQ(0, tuple.getHiddenNValue(1).compare(nvalHiddenString));

    nvalVisibleString.free();
    nvalHiddenString.free();
}
Пример #2
0
TEST_F(TableTupleTest, ToJsonArray)
{
    TupleSchemaBuilder builder(3, 2);
    builder.setColumnAtIndex(0, VALUE_TYPE_BIGINT);
    builder.setColumnAtIndex(1, VALUE_TYPE_VARCHAR, 256);
    builder.setColumnAtIndex(2, VALUE_TYPE_VARCHAR, 256);
    builder.setHiddenColumnAtIndex(0, VALUE_TYPE_BIGINT);
    builder.setHiddenColumnAtIndex(1, VALUE_TYPE_VARCHAR, 10);
    ScopedTupleSchema schema(builder.build());

    StandAloneTupleStorage autoStorage(schema.get());
    const TableTuple& tuple = autoStorage.tuple();

    NValue nvalVisibleBigint = ValueFactory::getBigIntValue(999);
    NValue nvalVisibleString = ValueFactory::getStringValue("数据库");
    NValue nvalHiddenBigint = ValueFactory::getBigIntValue(1066);
    NValue nvalHiddenString = ValueFactory::getStringValue("platypus");

    tuple.setNValue(0, nvalVisibleBigint);
    tuple.setNValue(1, nvalVisibleString);
    tuple.setNValue(2, ValueFactory::getNullValue());
    tuple.setHiddenNValue(0, nvalHiddenBigint);
    tuple.setHiddenNValue(1, nvalHiddenString);

    EXPECT_EQ(0, strcmp(tuple.toJsonArray().c_str(), "[\"999\",\"数据库\",\"null\"]\n"));

    nvalHiddenString.free();
    nvalVisibleString.free();
}
TEST_F(PersistentTableLogTest, LookupTupleUsingTempTupleTest) {
    initNarrowTable();

    // Create three tuple with a variable length VARCHAR column, then call
    // lookupTupleForUndo() to look each tuple up from wide to narrower column.
    // It will use the memcmp() code path for the comparison, which should all
    // succeed because there is no uninlined stuff.

    NValue wideStr = ValueFactory::getStringValue("a long string");
    NValue narrowStr = ValueFactory::getStringValue("a");
    NValue nullStr = ValueFactory::getNullStringValue();

    TableTuple wideTuple(m_tableSchema);
    wideTuple.move(new char[wideTuple.tupleLength()]);
    ::memset(wideTuple.address(), 0, wideTuple.tupleLength());
    wideTuple.setNValue(0, ValueFactory::getBigIntValue(1));
    wideTuple.setNValue(1, wideStr);
    m_table->insertTuple(wideTuple);
    delete[] wideTuple.address();

    TableTuple narrowTuple(m_tableSchema);
    narrowTuple.move(new char[narrowTuple.tupleLength()]);
    ::memset(narrowTuple.address(), 0, narrowTuple.tupleLength());
    narrowTuple.setNValue(0, ValueFactory::getBigIntValue(2));
    narrowTuple.setNValue(1, narrowStr);
    m_table->insertTuple(narrowTuple);
    delete[] narrowTuple.address();

    TableTuple nullTuple(m_tableSchema);
    nullTuple.move(new char[nullTuple.tupleLength()]);
    ::memset(nullTuple.address(), 0, nullTuple.tupleLength());
    nullTuple.setNValue(0, ValueFactory::getBigIntValue(3));
    nullTuple.setNValue(1, nullStr);
    m_table->insertTuple(nullTuple);
    delete[] nullTuple.address();

    TableTuple tempTuple = m_table->tempTuple();
    tempTuple.setNValue(0, ValueFactory::getBigIntValue(1));
    tempTuple.setNValue(1, wideStr);
    TableTuple result = m_table->lookupTupleForUndo(tempTuple);
    ASSERT_FALSE(result.isNullTuple());

    tempTuple = m_table->tempTuple();
    tempTuple.setNValue(0, ValueFactory::getBigIntValue(2));
    tempTuple.setNValue(1, narrowStr);
    result = m_table->lookupTupleForUndo(tempTuple);
    ASSERT_FALSE(result.isNullTuple());

    tempTuple = m_table->tempTuple();
    tempTuple.setNValue(0, ValueFactory::getBigIntValue(3));
    tempTuple.setNValue(1, nullStr);
    result = m_table->lookupTupleForUndo(tempTuple);
    ASSERT_FALSE(result.isNullTuple());

    wideStr.free();
    narrowStr.free();
    nullStr.free();
}
TEST_F(PersistentTableLogTest, InsertUpdateThenUndoOneTest) {
    initTable();
    tableutil::addRandomTuples(m_table, 1);
    voltdb::TableTuple tuple(m_tableSchema);

    tableutil::getRandomTuple(m_table, tuple);
    //std::cout << "Retrieved random tuple " << std::endl << tuple.debugNoHeader() << std::endl;

    ASSERT_FALSE( m_table->lookupTupleForUndo(tuple).isNullTuple());

    /*
     * A backup copy of what the tuple looked like before updates
     */
    voltdb::TableTuple tupleBackup(m_tableSchema);
    tupleBackup.move(new char[tupleBackup.tupleLength()]);
    tupleBackup.copyForPersistentInsert(tuple);

    /*
     * A copy of the tuple to modify and use as a source tuple when updating the new tuple.
     */
    voltdb::TableTuple tupleCopy(m_tableSchema);
    tupleCopy.move(new char[tupleCopy.tupleLength()]);
    tupleCopy.copyForPersistentInsert(tuple);

    m_engine->setUndoToken(INT64_MIN + 2);

    // this next line is a testing hack until engine data is
    // de-duplicated with executorcontext data
    m_engine->updateExecutorContextUndoQuantumForTest();

    /*
     * Update a few columns
     */
    tupleCopy.setNValue(0, ValueFactory::getBigIntValue(5));
    NValue newStringValue = ValueFactory::getStringValue("foo");
    tupleCopy.setNValue(7, newStringValue);
    NValue oldStringValue = tupleCopy.getNValue(6);
    tupleCopy.setNValue(6, ValueFactory::getStringValue("bar"));

    m_table->updateTuple(tuple, tupleCopy);

    ASSERT_TRUE( m_table->lookupTupleForUndo(tupleBackup).isNullTuple());
    ASSERT_FALSE( m_table->lookupTupleForUndo(tupleCopy).isNullTuple());
    m_engine->undoUndoToken(INT64_MIN + 2);

    ASSERT_FALSE(m_table->lookupTupleForUndo(tuple).isNullTuple());
    ASSERT_TRUE( m_table->lookupTupleForUndo(tupleCopy).isNullTuple());
    tupleBackup.freeObjectColumns();
    tupleCopy.freeObjectColumns();
    delete [] tupleBackup.address();
    delete [] tupleCopy.address();
    newStringValue.free();
    oldStringValue.free();
}
        TableSerializeTest() {
            this->database_id = 1000;

            columnNames = new std::string[NUM_OF_COLUMNS];
            std::vector<voltdb::ValueType> columnTypes;
            std::vector<int32_t> columnSizes;
            std::vector<bool> columnAllowNull(NUM_OF_COLUMNS, false);
            for (int ctr = 0; ctr < NUM_OF_COLUMNS; ctr++) {
                char name[16];
                if (ctr == 0) ::snprintf(name, 16, "id");
                else ::snprintf(name, 16, "val%02d", ctr);
                columnNames[ctr] = name;
                int size = (col_types[ctr] != VALUE_TYPE_VARCHAR ? 8 : 20);
                columnSizes.push_back(static_cast<int32_t>(size));
                columnTypes.push_back(col_types[ctr]);
            }
            voltdb::TupleSchema *schema = voltdb::TupleSchema::createTupleSchema(columnTypes, columnSizes, columnAllowNull, true);
            table_ = TableFactory::getTempTable(this->database_id, "temp_table", schema, columnNames, NULL);

            for (int64_t i = 1; i <= TUPLES; ++i) {
                TableTuple &tuple = table_->tempTuple();
                tuple.setNValue(0, ValueFactory::getTinyIntValue(static_cast<int8_t>(i)));
                tuple.setNValue(1, ValueFactory::getBigIntValue(static_cast<int16_t>(i % 2)));
                tuple.setNValue(2, ValueFactory::getBigIntValue(static_cast<int32_t>(i % 3)));
                tuple.setNValue(3, ValueFactory::getBigIntValue(static_cast<int64_t>(i % 5)));
                ostringstream str;
                str << "varchar string:" << (i % 7);
                NValue stringValue = ValueFactory::getStringValue(str.str());
                tuple.setNValueAllocateForObjectCopies(4, stringValue, NULL);
                stringValue.free();
                tuple.setNValue(5, ValueFactory::getDoubleValue(3.14f * static_cast<double>(i)));
                table_->insertTuple(tuple);
            }

        }
// helper to make a schema, a tuple and calculate EL size
size_t
TableTupleExportTest::maxElSize(std::vector<uint16_t> &keep_offsets,
                             bool useNullStrings)
{
    TableTuple *tt;
    TupleSchema *ts;
    char buf[1024]; // tuple data

    ts = TupleSchema::createTupleSchema(m_schema, keep_offsets);
    tt = new TableTuple(buf, ts);

    // if the tuple includes strings, add some content
    // assuming all Export tuples were allocated for persistent
    // storage and choosing set* api accordingly here.
    if (ts->columnCount() > 6) {
        NValue nv = ValueFactory::getStringValue("ABCDEabcde"); // 10 char
        if (useNullStrings)
        {
            nv.free(); nv.setNull();
        }
        tt->setNValueAllocateForObjectCopies(6, nv, NULL);
        nv.free();
    }
    if (ts->columnCount() > 7) {
        NValue nv = ValueFactory::getStringValue("abcdeabcdeabcdeabcde"); // 20 char
        if (useNullStrings)
        {
            nv.free(); nv.setNull();
        }
        tt->setNValueAllocateForObjectCopies(7, nv, NULL);
        nv.free();
    }

    // The function under test!
    size_t sz = tt->maxExportSerializationSize();

    // and cleanup
    tt->freeObjectColumns();
    delete tt;
    TupleSchema::freeTupleSchema(ts);

    return sz;
}
Пример #7
0
TEST_F(TableTupleTest, HiddenColumns)
{
    UniqueEngine engine = UniqueEngineBuilder().build();

    TupleSchemaBuilder builder(2, 2);
    builder.setColumnAtIndex(0, VALUE_TYPE_BIGINT);
    builder.setColumnAtIndex(1, VALUE_TYPE_VARCHAR, 256);
    builder.setHiddenColumnAtIndex(0, VALUE_TYPE_BIGINT);
    builder.setHiddenColumnAtIndex(1, VALUE_TYPE_VARCHAR, 10);
    ScopedTupleSchema schema(builder.build());

    StandAloneTupleStorage autoStorage(schema.get());
    TableTuple& tuple = autoStorage.tuple();

    NValue nvalVisibleBigint = ValueFactory::getBigIntValue(999);
    NValue nvalVisibleString = ValueFactory::getStringValue("catdog");
    NValue nvalHiddenBigint = ValueFactory::getBigIntValue(1066);
    NValue nvalHiddenString = ValueFactory::getStringValue("platypus");

    tuple.setNValue(0, nvalVisibleBigint);
    tuple.setNValue(1, nvalVisibleString);
    tuple.setHiddenNValue(0, nvalHiddenBigint);
    tuple.setHiddenNValue(1, nvalHiddenString);

    EXPECT_EQ(0, tuple.getNValue(0).compare(nvalVisibleBigint));
    EXPECT_EQ(0, tuple.getNValue(1).compare(nvalVisibleString));
    EXPECT_EQ(0, tuple.getHiddenNValue(0).compare(nvalHiddenBigint));
    EXPECT_EQ(0, tuple.getHiddenNValue(1).compare(nvalHiddenString));

    EXPECT_EQ(8 + (4 + 6) + 8 + (4 + 8), tuple.maxDRSerializationSize());

    tuple.setHiddenNValue(1, ValueFactory::getNullStringValue());
    nvalHiddenString.free();

    // The hidden string is null, takes 0 serialized byte
    EXPECT_EQ(8 + (4 + 6) + 8, tuple.maxDRSerializationSize());

    nvalVisibleString.free();
}
// helper to make a schema, a tuple and serialize to a buffer
size_t
TableTupleExportTest::serElSize(std::vector<uint16_t> &keep_offsets,
                             uint8_t *nullArray, char *dataPtr, bool nulls)
{
    TableTuple *tt;
    TupleSchema *ts;
    char buf[1024]; // tuple data

    ts = TupleSchema::createTupleSchema(m_schema, keep_offsets);
    tt = new TableTuple(buf, ts);

    // assuming all Export tuples were allocated for persistent
    // storage and choosing set* api accordingly here.

    switch (ts->columnCount()) {
        // note my sophisticated and clever use of fall through
      case 8:
      {
          NValue nv = ValueFactory::getStringValue("abcdeabcdeabcdeabcde"); // 20 char
          if (nulls) { nv.free(); nv.setNull(); }
          tt->setNValueAllocateForObjectCopies(7, nv, NULL);
          nv.free();
      }
      case 7:
      {
          NValue nv = ValueFactory::getStringValue("ABCDEabcde"); // 10 char
          if (nulls) { nv.free(); nv.setNull(); }
          tt->setNValueAllocateForObjectCopies(6, nv, NULL);
          nv.free();
      }
      case 6:
      {
          NValue nv = ValueFactory::getDecimalValueFromString("-12.34");
          if (nulls) { nv.free(); nv.setNull(); }
          tt->setNValueAllocateForObjectCopies(5, nv, NULL);
          nv.free();
      }
      case 5:
      {
          NValue nv = ValueFactory::getTimestampValue(9999);
          if (nulls) nv.setNull();
          tt->setNValueAllocateForObjectCopies(4, nv, NULL);
          nv.free();
      }
      case 4:
      {
          NValue nv = ValueFactory::getBigIntValue(1024);
          if (nulls) nv.setNull();
          tt->setNValueAllocateForObjectCopies(3, nv, NULL);
          nv.free();
      }
      case 3:
      {
          NValue nv = ValueFactory::getIntegerValue(512);
          if (nulls) nv.setNull();
          tt->setNValueAllocateForObjectCopies(2, nv, NULL);
          nv.free();
      }
      case 2:
      {
          NValue nv = ValueFactory::getSmallIntValue(256);
          if (nulls) nv.setNull();
          tt->setNValueAllocateForObjectCopies(1, nv, NULL);
          nv.free();
      }
      case 1:
      {
          NValue nv = ValueFactory::getTinyIntValue(120);
          if (nulls) nv.setNull();
          tt->setNValueAllocateForObjectCopies(0, nv, NULL);
          nv.free();
      }
      break;

      default:
        // this is an error in the test fixture.
        EXPECT_EQ(0,1);
        break;
    }

    // The function under test!
    ExportSerializeOutput io(dataPtr, 2048);
    tt->serializeToExport(io, 0, nullArray);

    // and cleanup
    tt->freeObjectColumns();
    delete tt;
    TupleSchema::freeTupleSchema(ts);
    return io.position();
}