common::Error SsdbDriver::commandCreateImpl(CommandCreateKey* command,
                                            std::string* cmdstring) const {
  if (!command || !cmdstring) {
    return common::make_error_value("Invalid input argument", common::ErrorValue::E_ERROR);
  }

  char patternResult[1024] = {0};
  NDbKValue key = command->key();
  NValue val = command->value();
  common::Value* rval = val.get();
  std::string key_str = key.keyString();
  std::string value_str = common::convertToString(rval, " ");
  common::Value::Type t = key.type();
  if (t == common::Value::TYPE_ARRAY) {
    common::SNPrintf(patternResult, sizeof(patternResult), SET_KEY_LIST_PATTERN_2ARGS_SS,
                     key_str, value_str);
  } else if (t == common::Value::TYPE_SET) {
    common::SNPrintf(patternResult, sizeof(patternResult), SET_KEY_SET_PATTERN_2ARGS_SS,
                     key_str, value_str);
  } else if (t == common::Value::TYPE_ZSET) {
    common::SNPrintf(patternResult, sizeof(patternResult), SET_KEY_ZSET_PATTERN_2ARGS_SS,
                     key_str, value_str);
  } else if (t == common::Value::TYPE_HASH) {
    common::SNPrintf(patternResult, sizeof(patternResult), SET_KEY_HASH_PATTERN_2ARGS_SS,
                     key_str, value_str);
  } else {
    common::SNPrintf(patternResult, sizeof(patternResult), SET_KEY_PATTERN_2ARGS_SS,
                     key_str, value_str);
  }

  *cmdstring = patternResult;
  return common::Error();
}
Example #2
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();
}
Example #3
0
TEST_F(TableTupleTest, ComputeNonInlinedMemory)
{
    UniqueEngine engine = UniqueEngineBuilder().build();
    Pool *pool = ExecutorContext::getTempStringPool();

    // Make sure that inlined strings are actually inlined
    int32_t maxInlinableLength = UNINLINEABLE_OBJECT_LENGTH/MAX_BYTES_PER_UTF8_CHARACTER - 1;
    ScopedTupleSchema allInlineSchema{Tools::buildSchema(VALUE_TYPE_BIGINT,
                                                         std::make_pair(VALUE_TYPE_VARCHAR, maxInlinableLength))};
    PoolBackedTupleStorage tupleStorage;
    tupleStorage.init(allInlineSchema.get(), pool);
    tupleStorage.allocateActiveTuple();
    TableTuple inlineTuple = tupleStorage;

    Tools::setTupleValues(&inlineTuple, int64_t(0), "dude");
    EXPECT_EQ(0, inlineTuple.getNonInlinedMemorySizeForPersistentTable());

    // Now check that an non-inlined schema returns the right thing.
    int32_t nonInlinableLength = UNINLINEABLE_OBJECT_LENGTH + 10000;
    ScopedTupleSchema nonInlinedSchema{Tools::buildSchema(VALUE_TYPE_BIGINT,
                                                         std::make_pair(VALUE_TYPE_VARCHAR, nonInlinableLength))};
    tupleStorage.init(nonInlinedSchema.get(), pool);
    tupleStorage.allocateActiveTuple();
    TableTuple nonInlinedTuple = tupleStorage;

    NValue nonInlinedString = Tools::nvalueFromNative("123456");
    Tools::setTupleValues(&nonInlinedTuple, int64_t(0), nonInlinedString);
    EXPECT_EQ(nonInlinedString.getAllocationSizeForObjectInPersistentStorage(),
              nonInlinedTuple.getNonInlinedMemorySizeForPersistentTable());
}
Example #4
0
TEST_F(TableTupleTest, VolatileStandAloneTuple) {
    UniqueEngine engine = UniqueEngineBuilder().build();

    // A schema with
    //    - one fixed size column
    //    - one inlined variable-length column
    //    - one non-inlined variable-length column
    ScopedTupleSchema schema{Tools::buildSchema(VALUE_TYPE_BIGINT,
                                                std::make_pair(VALUE_TYPE_VARCHAR, 12),
                                                std::make_pair(VALUE_TYPE_VARCHAR, 256))};
    StandAloneTupleStorage standAloneTuple{schema.get()};
    TableTuple tuple = standAloneTuple.tuple();
    Tools::setTupleValues(&tuple, int64_t(0), "foo", "foo bar");

    // Stand alone tuples are similar to pool-backed tuples.
    ASSERT_TRUE(tuple.inlinedDataIsVolatile());
    ASSERT_FALSE(tuple.nonInlinedDataIsVolatile());

    NValue nv = tuple.getNValue(0);
    ASSERT_FALSE(nv.getVolatile());

    nv = tuple.getNValue(1);
    ASSERT_TRUE(nv.getVolatile());

    nv = tuple.getNValue(2);
    ASSERT_FALSE(nv.getVolatile());
}
Example #5
0
 static std::string peekStringCopy(const NValue value) {
     assert((value.getValueType() == VALUE_TYPE_VARCHAR) ||
            (value.getValueType() == VALUE_TYPE_VARBINARY));
     std::string result(reinterpret_cast<const char*>(value.getObjectValue()),
                                                      value.getObjectLength());
     return result;
 }
Example #6
0
NValue NValue::opDivideDecimals(const NValue lhs, const NValue rhs) const {
    if ((lhs.getValueType() != VALUE_TYPE_DECIMAL) ||
        (rhs.getValueType() != VALUE_TYPE_DECIMAL))
    {
        throw SQLException(SQLException::dynamic_sql_error, "No decimal NValue in decimal subtract");
    }

    if (lhs.isNull() || rhs.isNull()) {
        TTInt retval;
        retval.SetMin();
        return getDecimalValue( retval );
    }

    TTLInt calc;
    calc.FromInt(lhs.getDecimal());
    calc *= NValue::kMaxScaleFactor;
    if (calc.Div(rhs.getDecimal())) {
        char message[4096];
        snprintf( message, 4096, "Attempted to divide %s by %s causing overflow/underflow (or divide by zero)",
                lhs.createStringFromDecimal().c_str(), rhs.createStringFromDecimal().c_str());
        throw SQLException(SQLException::data_exception_numeric_value_out_of_range,
                           message);
    }
    TTInt retval;
    if (retval.FromInt(calc)  || retval > NValue::s_maxDecimal || retval < s_minDecimal) {
        char message[4096];
        snprintf( message, 4096, "Attempted to divide %s by %s causing overflow. Unscaled result was %s",
                lhs.createStringFromDecimal().c_str(), rhs.createStringFromDecimal().c_str(),
                calc.ToString(10).c_str());
        throw SQLException(SQLException::data_exception_numeric_value_out_of_range,
                           message);
    }
    return getDecimalValue(retval);
}
        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);
            }

        }
Example #8
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();
}
Example #9
0
void NValue::castAndSortAndDedupArrayForInList(const ValueType outputType, std::vector<NValue> &outList) const
{
    int size = arrayLength();

    // make a set to eliminate unique values in O(nlogn) time
    std::set<StlFriendlyNValue> uniques;

    // iterate over the array of values and build a sorted set of unique
    // values that don't overflow or violate unique constaints
    // (n.b. sorted set means dups are removed)
    for (int i = 0; i < size; i++) {
        NValue value = itemAtIndex(i);
        // cast the value to the right type and catch overflow/cast problems
        try {
            StlFriendlyNValue stlValue;
            stlValue = value.castAs(outputType);
            std::pair<std::set<StlFriendlyNValue>::iterator, bool> ret;
            ret = uniques.insert(stlValue);
        }
        // cast exceptions mean the in-list test is redundant
        // don't include these values in the materialized table
        // TODO: make this less hacky
        catch (SQLException &sqlException) {}
    }

    // insert all items in the set in order
    std::set<StlFriendlyNValue>::const_iterator iter;
    for (iter = uniques.begin(); iter != uniques.end(); iter++) {
        outList.push_back(*iter);
    }
}
void MaterializedViewMetadata::processTupleDelete(TableTuple &oldTuple) {
    // don't change the view if this tuple doesn't match the predicate
    if (m_filterPredicate && (m_filterPredicate->eval(&oldTuple, NULL).isFalse()))
        return;

    // this will assert if the tuple isn't there as param expected is true
    findExistingTuple(oldTuple, true);

    // clear the tuple that will be built to insert or overwrite
    memset(m_updatedTupleBackingStore, 0, m_target->schema()->tupleLength() + 1);

    //printf("  Existing tuple: %s.\n", m_existingTuple.debugNoHeader().c_str());
    //fflush(stdout);

    // set up the first column, which is a count
    NValue count = m_existingTuple.getNValue(m_groupByColumnCount).op_decrement();

    //printf("  Count is: %d.\n", (int)(m_existingTuple.getSlimValue(m_groupByColumnCount).getBigInt()));
    //fflush(stdout);

    // check if we should remove the tuple
    if (count.isZero()) {
        m_target->deleteTuple(m_existingTuple, true);
        return;
    }
    // assume from here that we're just updating the existing row

    int colindex = 0;
    // set up the first n columns, based on group-by columns
    for (colindex = 0; colindex < m_groupByColumnCount; colindex++) {
        m_updatedTuple.setNValue(colindex, oldTuple.getNValue(m_groupByColumns[colindex]));
    }

    m_updatedTuple.setNValue(colindex, count);
    colindex++;

    // set values for the other columns
    for (int i = colindex; i < m_outputColumnCount; i++) {
        NValue oldValue = oldTuple.getNValue(m_outputColumnSrcTableIndexes[i]);
        NValue existingValue = m_existingTuple.getNValue(i);

        if (m_outputColumnAggTypes[i] == EXPRESSION_TYPE_AGGREGATE_SUM) {
            m_updatedTuple.setNValue(i, existingValue.op_subtract(oldValue));
        }
        else if (m_outputColumnAggTypes[i] == EXPRESSION_TYPE_AGGREGATE_COUNT) {
            m_updatedTuple.setNValue(i, existingValue.op_decrement());
        }
        else {
            throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                          "Error in materialized view table"
                                          " update.");
        }
    }

    // update the row
    // shouldn't need to update indexes as this shouldn't ever change the key
    m_target->updateTuple(m_updatedTuple, m_existingTuple, false);
}
void MaterializedViewMetadata::processTupleInsert(TableTuple &newTuple) {
    // don't change the view if this tuple doesn't match the predicate
    if (m_filterPredicate
        && (m_filterPredicate->eval(&newTuple, NULL).isFalse()))
        return;

    bool exists = findExistingTuple(newTuple);
    if (!exists) {
        // create a blank tuple
        m_existingTuple.move(m_emptyTupleBackingStore);
    }

    // clear the tuple that will be built to insert or overwrite
    memset(m_updatedTupleBackingStore, 0, m_target->schema()->tupleLength() + 1);

    int colindex = 0;
    // set up the first n columns, based on group-by columns
    for (colindex = 0; colindex < m_groupByColumnCount; colindex++) {
        m_updatedTuple.setNValue(colindex,
                                 newTuple.getNValue(m_groupByColumns[colindex]));
    }

    // set up the next column, which is a count
    m_updatedTuple.setNValue(colindex,
                             m_existingTuple.getNValue(colindex).op_increment());
    colindex++;

    // set values for the other columns
    for (int i = colindex; i < m_outputColumnCount; i++) {
        NValue newValue = newTuple.getNValue(m_outputColumnSrcTableIndexes[i]);
        NValue existingValue = m_existingTuple.getNValue(i);

        if (m_outputColumnAggTypes[i] == EXPRESSION_TYPE_AGGREGATE_SUM) {
            m_updatedTuple.setNValue(i, newValue.op_add(existingValue));
        }
        else if (m_outputColumnAggTypes[i] == EXPRESSION_TYPE_AGGREGATE_COUNT) {
            m_updatedTuple.setNValue(i, existingValue.op_increment());
        }
        else {
            char message[128];
            sprintf(message, "Error in materialized view table update for"
                    " col %d. Expression type %d", i, m_outputColumnAggTypes[i]);
            throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                          message);
        }
    }

    // update or insert the row
    if (exists) {
        // shouldn't need to update indexes as this shouldn't ever change the
        // key
        m_target->updateTuple(m_updatedTuple, m_existingTuple, false);
    }
    else {
        m_target->insertTuple(m_updatedTuple);
    }
}
bool MaterializedScanExecutor::p_execute(const NValueArray &params) {
    MaterializedScanPlanNode* node = dynamic_cast<MaterializedScanPlanNode*>(m_abstractNode);
    assert(node);

    // output table has one column
    Table* output_table = node->getOutputTable();
    TableTuple& tmptup = output_table->tempTuple();
    assert(output_table);
    assert ((int)output_table->columnCount() == 1);

    // get the output type
    const TupleSchema::ColumnInfo *columnInfo = output_table->schema()->getColumnInfo(0);
    ValueType outputType = columnInfo->getVoltType();
    bool outputCantBeNull = !columnInfo->allowNull;

    AbstractExpression* rowsExpression = node->getTableRowsExpression();
    assert(rowsExpression);

    // get array nvalue
    NValue arrayNValue = rowsExpression->eval();

    SortDirectionType sort_direction = node->getSortDirection();

    // make a set to eliminate unique values in O(nlogn) time
    std::vector<NValue> sortedUniques;

    // iterate over the array of values and build a sorted/deduped set of
    // values that don't overflow or violate unique constaints
    arrayNValue.castAndSortAndDedupArrayForInList(outputType, sortedUniques);

    // insert all items in the set in order
    if (sort_direction != SORT_DIRECTION_TYPE_DESC) {
        std::vector<NValue>::const_iterator iter;
        for (iter = sortedUniques.begin(); iter != sortedUniques.end(); iter++) {
            if ((*iter).isNull() && outputCantBeNull) {
                continue;
            }
            tmptup.setNValue(0, *iter);
            output_table->insertTuple(tmptup);
        }
    } else {
        std::vector<NValue>::reverse_iterator reverse_iter;
        for (reverse_iter = sortedUniques.rbegin(); reverse_iter != sortedUniques.rend(); reverse_iter++) {
            if ((*reverse_iter).isNull() && outputCantBeNull) {
                continue;
            }
            tmptup.setNValue(0, *reverse_iter);
            output_table->insertTuple(tmptup);
        }
    }

    VOLT_TRACE("\n%s\n", output_table->debug().c_str());
    VOLT_DEBUG("Finished Materializing a Table");

    return true;
}
Example #13
0
bool CoveringCellIndex::getPolygonFromTuple(const TableTuple *tuple, Polygon *poly) const {
    NValue nval = tuple->getNValue(m_columnIndex);
    if (! nval.isNull()) {
        const GeographyValue gv = ValuePeeker::peekGeographyValue(nval);
        poly->initFromGeography(gv);
        return true;
    }

    return false;
}
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();
}
 NValue compare(const NValue& nvalue) const
 {
     assert(m_tuple.getSchema()->columnCount() == 1);
     NValue lvalue = m_tuple.getNValue(0);
     if (lvalue.isNull()) {
         return NValue::getNullValue(VALUE_TYPE_BOOLEAN);
     }
     if (nvalue.isNull()) {
         return NValue::getNullValue(VALUE_TYPE_BOOLEAN);
     }
     return OP::compare_withoutNull(lvalue, nvalue);
 }
extern "C" bool NValueLess(void* l, void* r) {
  /*
   *  bool* ret_bool;
   *  NValue* lnv = l;
   *  NValue* rnv = r;
   *  *ret_bool = lnv->op_less(rnv);
   *  return ret_bool;
   */
  NValue* lvalue = (NValue*) l;
  NValue* rvalue = (NValue*) r;

  return lvalue->op_less(*rvalue);
}
Example #17
0
 virtual void advance(const NValue& val)
 {
     if (val.isNull())
     {
         return;
     }
     if (!m_haveAdvanced)
     {
         m_value = val;
         if (m_value.getVolatile()) {
             // In serial aggregation, the NValue may be backed by
             // a row that is reused and updated for each row
             // produced by a child node.  Because NValue's copy
             // constructor only does a shallow copy, this can lead
             // wrong answers when the Agg's NValue changes
             // unexpectedly.  To avoid this, copy the
             // incoming NValue to its own storage.
             m_value.allocateObjectFromPool(m_memoryPool);
             m_inlineCopiedToNonInline = true;
         }
         m_haveAdvanced = true;
     }
     else
     {
         m_value = m_value.op_max(val);
         if (m_value.getVolatile()) {
             m_value.allocateObjectFromPool(m_memoryPool);
         }
     }
 }
Example #18
0
 virtual void advance(const NValue& val)
 {
     if (val.isNull())
     {
         return;
     }
     if (!m_haveAdvanced)
     {
         m_value = val;
         if (m_value.getSourceInlined()) {
             // see comment in MaxAgg above, regarding why we're
             // doing this.
             m_value.allocateObjectFromInlinedValue(m_memoryPool);
             m_inlineCopiedToOutline = true;
         }
         m_haveAdvanced = true;
     }
     else
     {
         m_value = m_value.op_min(val);
         if (m_value.getSourceInlined()) {
             m_value.allocateObjectFromInlinedValue(m_memoryPool);
         }
     }
 }
Example #19
0
 virtual void advance(const NValue& val)
 {
     if (val.isNull() || ifDistinct.excludeValue(val)) {
         return;
     }
     m_count++;
 }
Example #20
0
 virtual void advance(const NValue& val)
 {
     if (val.isNull())
     {
         return;
     }
     if (!m_haveAdvanced)
     {
         m_value = val;
         if (m_value.getSourceInlined()) {
             // If the incoming value is inlined, that means its
             // data really lives in a record somewhere.  In serial
             // aggregation, the NValue may be backed by a row that
             // is reused and updated for each row produced by a
             // child node.  Because NValue's copy constructor only
             // does a shallow copy, this can lead wrong answers
             // when the Agg's NValue changes unexpectedly.  To
             // avoid this, un-inline the incoming NValue to its
             // own storage.
             m_value.allocateObjectFromInlinedValue(m_memoryPool);
             m_inlineCopiedToOutline = true;
         }
         m_haveAdvanced = true;
     }
     else
     {
         m_value = m_value.op_max(val);
         if (m_value.getSourceInlined()) {
             m_value.allocateObjectFromInlinedValue(m_memoryPool);
         }
     }
 }
Example #21
0
TEST_F(DRBinaryLogTest, VerifyHiddenColumns) {
    ASSERT_FALSE(flush(98));

    // single row write transaction
    beginTxn(99, 99, 98, 70);
    TableTuple first_tuple = insertTuple(m_table, prepareTempTuple(m_table, 42, 55555, "349508345.34583", "a thing", "a totally different thing altogether", 5433));
    endTxn(true);

    flushAndApply(99);

    TableTuple tuple = m_tableReplica->lookupTupleByValues(first_tuple);
    NValue drTimestamp = tuple.getHiddenNValue(m_table->getDRTimestampColumnIndex());
    NValue drTimestampReplica = tuple.getHiddenNValue(m_tableReplica->getDRTimestampColumnIndex());
    EXPECT_EQ(ValuePeeker::peekAsBigInt(drTimestamp), 70);
    EXPECT_EQ(0, drTimestamp.compare(drTimestampReplica));
}
 NValue compare(const NValue& nvalue) const
 {
     if (m_value.isNull() && OP::isNullRejecting()) {
         return NValue::getNullValue(VALUE_TYPE_BOOLEAN);
     }
     if (nvalue.isNull() && OP::isNullRejecting()) {
         return NValue::getNullValue(VALUE_TYPE_BOOLEAN);
     }
     return OP::compare(m_value, nvalue);
 }
 NValue compare(const NValue& nvalue) const
 {
     if (m_value.isNull()) {
         return NValue::getNullValue(VALUE_TYPE_BOOLEAN);
     }
     if (nvalue.isNull()) {
         return NValue::getNullValue(VALUE_TYPE_BOOLEAN);
     }
     return OP::compare_withoutNull(m_value, nvalue);
 }
Example #24
0
/**
 * This NValue can be of any scalar value type.
 * @param rhs  a VALUE_TYPE_ARRAY NValue whose referent must be an NValueList.
 *             The NValue elements of the NValueList should be comparable to and ideally
 *             of exactly the same VALUE_TYPE as "this".
 * The planner and/or deserializer should have taken care of this with checks and
 * explicit cast operators and and/or constant promotions as needed.
 * @return a VALUE_TYPE_BOOLEAN NValue.
 */
bool NValue::inList(const NValue& rhs) const
{
    //TODO: research: does the SQL standard allow a null to match a null list element
    // vs. returning FALSE or NULL?
    const bool lhsIsNull = isNull();
    if (lhsIsNull) {
        return false;
    }

    const ValueType rhsType = rhs.getValueType();
    if (rhsType != VALUE_TYPE_ARRAY) {
        throwDynamicSQLException("rhs of IN expression is of a non-list type %s", rhs.getValueTypeString().c_str());
    }
    const NValueList* listOfNValues = (NValueList*)rhs.getObjectValue_withoutNull();
    const StlFriendlyNValue& value = *static_cast<const StlFriendlyNValue*>(this);
    //TODO: An O(ln(length)) implementation vs. the current O(length) implementation
    // such as binary search would likely require some kind of sorting/re-org of values
    // post-update/pre-lookup, and would likely require some sortable inequality method
    // (operator<()?) to be defined on StlFriendlyNValue.
    return std::find(listOfNValues->begin(), listOfNValues->end(), value) != listOfNValues->end();
}
Example #25
0
 virtual void advance(const NValue& val)
 {
     if (val.isNull() || ifDistinct.excludeValue(val)) {
         return;
     }
     if (m_count == 0) {
         m_value = val;
     }
     else {
         m_value = m_value.op_add(val);
     }
     ++m_count;
 }
Example #26
0
 virtual void advance(const NValue& val)
 {
     if (val.isNull() || ifDistinct.excludeValue(val)) {
         return;
     }
     if (!m_haveAdvanced) {
         m_value = val;
         m_haveAdvanced = true;
     }
     else {
         m_value = m_value.op_add(val);
     }
 }
Example #27
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();
}
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();
}
Example #29
0
void VCardFormatImpl::readNValue( ContentLine *cl, Addressee &a )
{
  NValue *v = (NValue *)cl->value();
  a.setFamilyName( QString::fromUtf8( v->family() ) );
  a.setGivenName( QString::fromUtf8( v->given() ) );
  a.setAdditionalName( QString::fromUtf8( v->middle() ) );
  a.setPrefix( QString::fromUtf8( v->prefix() ) );
  a.setSuffix( QString::fromUtf8( v->suffix() ) );
}
Example #30
0
 virtual void advance(const NValue& val)
 {
     if (val.isNull())
     {
         return;
     }
     if (!m_haveAdvanced)
     {
         m_value = val;
         m_haveAdvanced = true;
     }
     else
     {
         m_value = m_value.op_min(val);
     }
 }