00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/test/TestBase.h"
00026 #include "fennel/tuple/TupleDescriptor.h"
00027 #include "fennel/tuple/TupleData.h"
00028 #include "fennel/tuple/TupleAccessor.h"
00029 #include "fennel/tuple/TuplePrinter.h"
00030 #include "fennel/tuple/AttributeAccessor.h"
00031 #include "fennel/tuple/UnalignedAttributeAccessor.h"
00032 #include "fennel/tuple/StandardTypeDescriptor.h"
00033 #include "fennel/common/TraceSource.h"
00034
00035 #include <boost/test/test_tools.hpp>
00036 #include <boost/scoped_array.hpp>
00037 #include <limits>
00038
00039 using namespace fennel;
00040
00041 class TupleTest : virtual public TestBase, public TraceSource
00042 {
00043 static const uint MAX_WIDTH = 512;
00044
00045 TupleDescriptor tupleDesc;
00046 TupleAccessor tupleAccessor;
00047
00048 void writeMinData(TupleDatum &datum,uint typeOrdinal);
00049 void writeMaxData(TupleDatum &datum,uint typeOrdinal);
00050 void writeSampleData(TupleDatum &datum,uint typeOrdinal);
00051 uint testMarshal(TupleData const &tupleDataFixed);
00052 void checkData(TupleData const &tupleData1,TupleData const &tupleData2);
00053 void checkAlignment(
00054 TupleAttributeDescriptor const &desc, PConstBuffer pBuf);
00055
00056 void testStandardTypesNullable();
00057 void testStandardTypesNotNull();
00058 void testStandardTypesNetworkNullable();
00059 void testStandardTypesNetworkNotNull();
00060 void testStandardTypes(TupleFormat,bool nullable);
00061 void testZeroByteTuple();
00062 void testDebugAccess();
00063 void testLoadStoreUnaligned();
00064 void loadStore8ByteInts(int64_t initialValue, uint8_t nextByte);
00065 void loadAndStore8ByteInt(int64_t intVal);
00066 void loadStore2ByteLenData(uint dataLen);
00067 void loadStoreNullData(uint typeOrdinal, uint len);
00068
00069 void traceTuple(TupleData const &tupleData)
00070 {
00071 std::ostringstream oss;
00072 TuplePrinter tuplePrinter;
00073 tuplePrinter.print(oss,tupleDesc,tupleData);
00074 std::string s = oss.str();
00075 FENNEL_TRACE(TRACE_FINE,s);
00076 }
00077
00078 public:
00079 explicit TupleTest()
00080 : TraceSource(shared_from_this(),"TupleTest")
00081 {
00082 FENNEL_UNIT_TEST_CASE(TupleTest,testStandardTypesNotNull);
00083 FENNEL_UNIT_TEST_CASE(TupleTest,testStandardTypesNullable);
00084 FENNEL_UNIT_TEST_CASE(TupleTest,testStandardTypesNetworkNotNull);
00085 FENNEL_UNIT_TEST_CASE(TupleTest,testStandardTypesNetworkNullable);
00086 FENNEL_UNIT_TEST_CASE(TupleTest,testZeroByteTuple);
00087 FENNEL_UNIT_TEST_CASE(TupleTest,testLoadStoreUnaligned);
00088
00089
00090
00091 FENNEL_EXTRA_UNIT_TEST_CASE(TupleTest,testDebugAccess);
00092 }
00093
00094 virtual ~TupleTest()
00095 {
00096 }
00097 };
00098
00099 void TupleTest::testStandardTypesNullable()
00100 {
00101 testStandardTypes(TUPLE_FORMAT_STANDARD,true);
00102 }
00103
00104 void TupleTest::testStandardTypesNotNull()
00105 {
00106 testStandardTypes(TUPLE_FORMAT_STANDARD,false);
00107 }
00108
00109 void TupleTest::testStandardTypesNetworkNullable()
00110 {
00111 testStandardTypes(TUPLE_FORMAT_NETWORK,true);
00112 }
00113
00114 void TupleTest::testStandardTypesNetworkNotNull()
00115 {
00116 testStandardTypes(TUPLE_FORMAT_NETWORK,false);
00117 }
00118
00119 void TupleTest::testStandardTypes(
00120 TupleFormat format,bool nullable)
00121 {
00122 StandardTypeDescriptorFactory typeFactory;
00123 uint cbMin = 0;
00124 tupleDesc.clear();
00125 for (uint i = STANDARD_TYPE_MIN; i < STANDARD_TYPE_END; ++i) {
00126 StoredTypeDescriptor const &typeDesc = typeFactory.newDataType(i);
00127 uint cbFixed = typeDesc.getFixedByteCount();
00128 if (cbFixed) {
00129 cbMin += cbFixed;
00130 } else {
00131 cbMin += typeDesc.getMinByteCount(MAX_WIDTH);
00132 }
00133 tupleDesc.push_back(
00134 TupleAttributeDescriptor(
00135 typeDesc,
00136 nullable,
00137 cbFixed ? 0 : MAX_WIDTH));
00138 }
00139
00140 tupleAccessor.compute(tupleDesc,format);
00141 BOOST_CHECK(tupleAccessor.getMinByteCount() >= cbMin);
00142 BOOST_CHECK(tupleAccessor.getMaxByteCount() > cbMin);
00143
00144 TupleAccessor tupleAccessorFixed;
00145 tupleAccessorFixed.compute(
00146 tupleDesc,
00147 TUPLE_FORMAT_ALL_FIXED);
00148
00149 boost::scoped_array<FixedBuffer> pTupleBufFixed(
00150 new FixedBuffer[tupleAccessor.getMaxByteCount()]);
00151 tupleAccessorFixed.setCurrentTupleBuf(pTupleBufFixed.get(), false);
00152
00153 TupleData tupleDataFixed(tupleDesc);
00154 tupleAccessorFixed.unmarshal(tupleDataFixed);
00155
00156 TupleData::iterator pDatum = tupleDataFixed.begin();
00157 for (uint i = STANDARD_TYPE_MIN; i < STANDARD_TYPE_END; ++i) {
00158 writeMinData(*pDatum,i);
00159 ++pDatum;
00160 }
00161 FENNEL_TRACE(TRACE_FINE,"testMarshal(MinData)");
00162 uint cbMinData = testMarshal(tupleDataFixed);
00163 BOOST_CHECK(cbMinData >= tupleAccessor.getMinByteCount());
00164 BOOST_CHECK(cbMinData < tupleAccessor.getMaxByteCount());
00165
00166 pDatum = tupleDataFixed.begin();
00167 for (uint i = STANDARD_TYPE_MIN; i < STANDARD_TYPE_END; ++i) {
00168 writeMaxData(*pDatum,i);
00169 ++pDatum;
00170 }
00171 FENNEL_TRACE(TRACE_FINE,"testMarshal(MaxData)");
00172 uint cbMaxData = testMarshal(tupleDataFixed);
00173 BOOST_CHECK(cbMaxData > cbMinData);
00174 BOOST_CHECK(cbMaxData <= tupleAccessor.getMaxByteCount());
00175
00176 pDatum = tupleDataFixed.begin();
00177 for (uint i = STANDARD_TYPE_MIN; i < STANDARD_TYPE_END; ++i) {
00178 writeSampleData(*pDatum,i);
00179 ++pDatum;
00180 }
00181 FENNEL_TRACE(TRACE_FINE,"testMarshal(SampleData)");
00182 uint cbSampleData = testMarshal(tupleDataFixed);
00183 BOOST_CHECK(cbSampleData >= tupleAccessor.getMinByteCount());
00184 BOOST_CHECK(cbSampleData <= tupleAccessor.getMaxByteCount());
00185
00186 if (nullable) {
00187 pDatum = tupleDataFixed.begin();
00188 for (uint i = STANDARD_TYPE_MIN; i < STANDARD_TYPE_END; ++i) {
00189 pDatum->pData = NULL;
00190 ++pDatum;
00191 }
00192 FENNEL_TRACE(TRACE_FINE,"testMarshal(NullData)");
00193 uint cbNullData = testMarshal(tupleDataFixed);
00194 BOOST_CHECK(cbNullData >= tupleAccessor.getMinByteCount());
00195 BOOST_CHECK(cbNullData < tupleAccessor.getMaxByteCount());
00196 }
00197 }
00198
00199 uint TupleTest::testMarshal(TupleData const &tupleDataFixed)
00200 {
00201 FENNEL_TRACE(TRACE_FINE,"reference tuple:");
00202 traceTuple(tupleDataFixed);
00203 boost::scoped_array<FixedBuffer> pTupleBufVar(
00204 new FixedBuffer[tupleAccessor.getMaxByteCount()]);
00205
00206 uint cbTuple = tupleAccessor.getByteCount(tupleDataFixed);
00207 tupleAccessor.marshal(tupleDataFixed,pTupleBufVar.get());
00208 BOOST_CHECK_EQUAL(cbTuple,tupleAccessor.getCurrentByteCount());
00209
00210 TupleData tupleDataTogether(tupleDesc);
00211 tupleAccessor.unmarshal(tupleDataTogether);
00212 FENNEL_TRACE(TRACE_FINE,"unmarshalled tuple (together):");
00213 traceTuple(tupleDataTogether);
00214 BOOST_CHECK_EQUAL(cbTuple,tupleAccessor.getByteCount(tupleDataTogether));
00215 checkData(tupleDataFixed,tupleDataTogether);
00216
00217 TupleData tupleDataIndividual(tupleDesc);
00218 for (uint i = 0; i < tupleDataIndividual.size(); ++i) {
00219 tupleAccessor.getAttributeAccessor(i).unmarshalValue(
00220 tupleAccessor,tupleDataIndividual[i]);
00221 }
00222 FENNEL_TRACE(TRACE_FINE,"unmarshalled tuple (individual):");
00223 traceTuple(tupleDataIndividual);
00224 BOOST_CHECK_EQUAL(cbTuple,tupleAccessor.getByteCount(tupleDataIndividual));
00225 checkData(tupleDataFixed,tupleDataIndividual);
00226
00227 return tupleAccessor.getCurrentByteCount();
00228 }
00229
00230 void TupleTest::checkData(
00231 TupleData const &tupleData1,TupleData const &tupleData2)
00232 {
00233 for (uint i = 0; i < tupleData1.size(); ++i) {
00234 TupleDatum const &datum1 = tupleData1[i];
00235 TupleDatum const &datum2 = tupleData2[i];
00236 if (!datum1.pData || !datum2.pData) {
00237 BOOST_CHECK_EQUAL(
00238 static_cast<void const *>(datum1.pData),
00239 static_cast<void const *>(datum2.pData));
00240 continue;
00241 }
00242 checkAlignment(tupleDesc[i], datum1.pData);
00243 checkAlignment(tupleDesc[i], datum2.pData);
00244 BOOST_CHECK_EQUAL(datum1.cbData,datum2.cbData);
00245 BOOST_CHECK_EQUAL_COLLECTIONS(
00246 datum1.pData,
00247 datum1.pData + datum1.cbData,
00248 datum2.pData,
00249 datum2.pData + datum2.cbData);
00250 }
00251 }
00252
00253 void TupleTest::checkAlignment(
00254 TupleAttributeDescriptor const &desc, PConstBuffer pBuf)
00255 {
00256 uint iAlign = desc.pTypeDescriptor->getAlignmentByteCount(
00257 desc.cbStorage);
00258 switch (iAlign) {
00259 case 1:
00260 return;
00261 case 2:
00262 BOOST_CHECK_EQUAL(0, uintptr_t(pBuf) & 1);
00263 break;
00264 case 4:
00265 BOOST_CHECK_EQUAL(0, uintptr_t(pBuf) & 3);
00266 break;
00267 case 8:
00268 BOOST_CHECK_EQUAL(0, uintptr_t(pBuf) & 7);
00269 break;
00270 }
00271 }
00272
00273 void TupleTest::writeMinData(TupleDatum &datum,uint typeOrdinal)
00274 {
00275 PBuffer pData = const_cast<PBuffer>(datum.pData);
00276 switch (typeOrdinal) {
00277 case STANDARD_TYPE_BOOL:
00278 *(reinterpret_cast<bool *>(pData)) = false;
00279 break;
00280 case STANDARD_TYPE_INT_8:
00281 *(reinterpret_cast<int8_t *>(pData)) =
00282 std::numeric_limits<int8_t>::min();
00283 break;
00284 case STANDARD_TYPE_UINT_8:
00285 *(reinterpret_cast<uint8_t *>(pData)) =
00286 std::numeric_limits<uint8_t>::min();
00287 break;
00288 case STANDARD_TYPE_INT_16:
00289 *(reinterpret_cast<int16_t *>(pData)) =
00290 std::numeric_limits<int16_t>::min();
00291 break;
00292 case STANDARD_TYPE_UINT_16:
00293 *(reinterpret_cast<uint16_t *>(pData)) =
00294 std::numeric_limits<uint16_t>::min();
00295 break;
00296 case STANDARD_TYPE_INT_32:
00297 *(reinterpret_cast<int32_t *>(pData)) =
00298 std::numeric_limits<int32_t>::min();
00299 break;
00300 case STANDARD_TYPE_UINT_32:
00301 *(reinterpret_cast<uint32_t *>(pData)) =
00302 std::numeric_limits<uint32_t>::min();
00303 break;
00304 case STANDARD_TYPE_INT_64:
00305 *(reinterpret_cast<int64_t *>(pData)) =
00306 std::numeric_limits<int64_t>::min();
00307 break;
00308 case STANDARD_TYPE_UINT_64:
00309 *(reinterpret_cast<uint64_t *>(pData)) =
00310 std::numeric_limits<uint64_t>::min();
00311 break;
00312 case STANDARD_TYPE_REAL:
00313 *(reinterpret_cast<float *>(pData)) =
00314 std::numeric_limits<float>::min();
00315 break;
00316 case STANDARD_TYPE_DOUBLE:
00317 *(reinterpret_cast<double *>(pData)) =
00318 std::numeric_limits<double>::min();
00319 break;
00320 case STANDARD_TYPE_BINARY:
00321 memset(pData,0,datum.cbData);
00322 break;
00323 case STANDARD_TYPE_CHAR:
00324 memset(pData,'A',datum.cbData);
00325 break;
00326 case STANDARD_TYPE_UNICODE_CHAR:
00327 {
00328 Ucs2Buffer pStr =
00329 reinterpret_cast<Ucs2Buffer>(pData);
00330 uint nChars = (datum.cbData >> 1);
00331 for (uint i = 0; i < nChars; ++i) {
00332 pStr[i] = 'A';
00333 }
00334 }
00335 break;
00336 case STANDARD_TYPE_VARCHAR:
00337 case STANDARD_TYPE_VARBINARY:
00338 case STANDARD_TYPE_UNICODE_VARCHAR:
00339 datum.cbData = 0;
00340 break;
00341 default:
00342 permAssert(false);
00343 }
00344 }
00345
00346 void TupleTest::writeMaxData(TupleDatum &datum,uint typeOrdinal)
00347 {
00348 PBuffer pData = const_cast<PBuffer>(datum.pData);
00349 switch (typeOrdinal) {
00350 case STANDARD_TYPE_BOOL:
00351 *(reinterpret_cast<bool *>(pData)) = true;
00352 break;
00353 case STANDARD_TYPE_INT_8:
00354 *(reinterpret_cast<int8_t *>(pData)) =
00355 std::numeric_limits<int8_t>::max();
00356 break;
00357 case STANDARD_TYPE_UINT_8:
00358 *(reinterpret_cast<uint8_t *>(pData)) =
00359 std::numeric_limits<uint8_t>::max();
00360 break;
00361 case STANDARD_TYPE_INT_16:
00362 *(reinterpret_cast<int16_t *>(pData)) =
00363 std::numeric_limits<int16_t>::max();
00364 break;
00365 case STANDARD_TYPE_UINT_16:
00366 *(reinterpret_cast<uint16_t *>(pData)) =
00367 std::numeric_limits<uint16_t>::max();
00368 break;
00369 case STANDARD_TYPE_INT_32:
00370 *(reinterpret_cast<int32_t *>(pData)) =
00371 std::numeric_limits<int32_t>::max();
00372 break;
00373 case STANDARD_TYPE_UINT_32:
00374 *(reinterpret_cast<uint32_t *>(pData)) =
00375 std::numeric_limits<uint32_t>::max();
00376 break;
00377 case STANDARD_TYPE_INT_64:
00378 *(reinterpret_cast<int64_t *>(pData)) =
00379 std::numeric_limits<int64_t>::max();
00380 break;
00381 case STANDARD_TYPE_UINT_64:
00382 *(reinterpret_cast<uint64_t *>(pData)) =
00383 std::numeric_limits<uint64_t>::max();
00384 break;
00385 case STANDARD_TYPE_REAL:
00386 *(reinterpret_cast<float *>(pData)) =
00387 std::numeric_limits<float>::max();
00388 break;
00389 case STANDARD_TYPE_DOUBLE:
00390 *(reinterpret_cast<double *>(pData)) =
00391 std::numeric_limits<double>::max();
00392 break;
00393 case STANDARD_TYPE_UNICODE_CHAR:
00394 case STANDARD_TYPE_BINARY:
00395 memset(pData,0xFF,datum.cbData);
00396 break;
00397 case STANDARD_TYPE_CHAR:
00398 memset(pData,'z',datum.cbData);
00399 break;
00400 case STANDARD_TYPE_VARCHAR:
00401 datum.cbData = MAX_WIDTH;
00402 memset(pData,'z',datum.cbData);
00403 break;
00404 case STANDARD_TYPE_UNICODE_VARCHAR:
00405 case STANDARD_TYPE_VARBINARY:
00406 datum.cbData = MAX_WIDTH;
00407 memset(pData,0xFF,datum.cbData);
00408 break;
00409 default:
00410 permAssert(false);
00411 }
00412 }
00413
00414 void TupleTest::writeSampleData(TupleDatum &datum,uint typeOrdinal)
00415 {
00416
00417 std::subtractive_rng randomNumberGenerator(time(NULL));
00418 PBuffer pData = const_cast<PBuffer>(datum.pData);
00419 switch (typeOrdinal) {
00420 case STANDARD_TYPE_BOOL:
00421 if (randomNumberGenerator(2)) {
00422 *(reinterpret_cast<bool *>(pData)) = true;
00423 } else {
00424 *(reinterpret_cast<bool *>(pData)) = false;
00425 }
00426 break;
00427 case STANDARD_TYPE_INT_8:
00428 *(reinterpret_cast<int8_t *>(pData)) = 0x28;
00429 break;
00430 case STANDARD_TYPE_UINT_8:
00431 *(reinterpret_cast<uint8_t *>(pData)) = 0x54;
00432 break;
00433 case STANDARD_TYPE_INT_16:
00434 *(reinterpret_cast<int16_t *>(pData)) = 0xfedc;
00435 break;
00436 case STANDARD_TYPE_UINT_16:
00437 *(reinterpret_cast<uint16_t *>(pData)) = 0x1234;
00438 break;
00439 case STANDARD_TYPE_INT_32:
00440 *(reinterpret_cast<int32_t *>(pData)) = 0xfedcba98;
00441 break;
00442 case STANDARD_TYPE_REAL:
00443 case STANDARD_TYPE_UINT_32:
00444 *(reinterpret_cast<uint32_t *>(pData)) = 0x12345678;
00445 break;
00446 case STANDARD_TYPE_INT_64:
00447 *(reinterpret_cast<int64_t *>(pData)) = 0xfedcba0987654321LL;
00448 break;
00449 case STANDARD_TYPE_DOUBLE:
00450 case STANDARD_TYPE_UINT_64:
00451 *(reinterpret_cast<uint64_t *>(pData)) = 0x1234567890abcdefLL;
00452 break;
00453 case STANDARD_TYPE_UNICODE_CHAR:
00454 case STANDARD_TYPE_BINARY:
00455 for (int i = 0; i < datum.cbData; i++) {
00456 pData[i] = i % 256;
00457 }
00458 break;
00459 case STANDARD_TYPE_CHAR:
00460 for (int i = 0; i < datum.cbData; i++) {
00461 pData[i] = i % ('z' - ' ') + ' ';
00462 }
00463 break;
00464 case STANDARD_TYPE_VARCHAR:
00465 datum.cbData = randomNumberGenerator(MAX_WIDTH);
00466 for (int i = 0; i < datum.cbData; i++) {
00467 pData[i] = i % ('z' - ' ') + ' ';
00468 }
00469 break;
00470 case STANDARD_TYPE_UNICODE_VARCHAR:
00471 case STANDARD_TYPE_VARBINARY:
00472 datum.cbData = randomNumberGenerator(MAX_WIDTH);
00473 if (typeOrdinal == STANDARD_TYPE_UNICODE_VARCHAR) {
00474 if (datum.cbData & 1) {
00475
00476 datum.cbData--;
00477 }
00478 }
00479 for (int i = 0; i < datum.cbData; i++) {
00480 pData[i] = i % 256;
00481 }
00482 break;
00483 default:
00484 assert(false);
00485 }
00486 }
00487
00488 void TupleTest::testDebugAccess()
00489 {
00490 StandardTypeDescriptorFactory typeFactory;
00491
00492
00493 testStandardTypesNullable();
00494
00495 boost::scoped_array<FixedBuffer> buf(
00496 new FixedBuffer[tupleAccessor.getMaxByteCount()]);
00497 memset(buf.get(), 0, tupleAccessor.getMaxByteCount());
00498
00499
00500
00501 tupleAccessor.setCurrentTupleBuf(buf.get());
00502 }
00503
00504 void TupleTest::testZeroByteTuple()
00505 {
00506 StandardTypeDescriptorFactory typeFactory;
00507 tupleDesc.clear();
00508 tupleDesc.push_back(
00509 TupleAttributeDescriptor(
00510 typeFactory.newDataType(STANDARD_TYPE_CHAR),
00511 false,
00512 0));
00513 TupleAccessor tupleAccessor;
00514 tupleAccessor.compute(tupleDesc);
00515
00516
00517
00518 BOOST_CHECK(tupleAccessor.getMinByteCount());
00519 BOOST_CHECK(tupleAccessor.getMaxByteCount());
00520 BOOST_CHECK_EQUAL(
00521 tupleAccessor.getMinByteCount(),
00522 tupleAccessor.getMaxByteCount());
00523 }
00524
00525 void TupleTest::testLoadStoreUnaligned()
00526 {
00527
00528 loadStore8ByteInts(0, 0xff);
00529 loadStore8ByteInts(0x80, 0);
00530
00531
00532 loadAndStore8ByteInt(0);
00533
00534
00535 loadStore2ByteLenData(128);
00536 loadStore2ByteLenData(129);
00537 loadStore2ByteLenData(255);
00538 loadStore2ByteLenData(256);
00539 loadStore2ByteLenData(257);
00540 loadStore2ByteLenData(510);
00541 loadStore2ByteLenData(511);
00542 loadStore2ByteLenData(512);
00543
00544
00545 loadStore2ByteLenData(0);
00546
00547
00548 loadStoreNullData(STANDARD_TYPE_INT_64, 8);
00549 loadStoreNullData(STANDARD_TYPE_INT_32, 4);
00550
00551
00552 TupleDatum tupleDatum;
00553 tupleDatum.cbData = 2;
00554 int16_t intVal = 43981;
00555 tupleDatum.pData = (PConstBuffer) &intVal;
00556 FixedBuffer storageBuf[4];
00557 StandardTypeDescriptorFactory stdTypeFactory;
00558 TupleAttributeDescriptor attrDesc_int16(
00559 stdTypeFactory.newDataType(STANDARD_TYPE_INT_16));
00560 UnalignedAttributeAccessor accessor_int16(attrDesc_int16);
00561 accessor_int16.storeValue(tupleDatum, storageBuf);
00562 uint len = accessor_int16.getStoredByteCount(storageBuf);
00563 BOOST_REQUIRE(len == 2);
00564
00565 FixedBuffer loadBuf[4];
00566 tupleDatum.cbData = 0xff;
00567 tupleDatum.pData = loadBuf;
00568 accessor_int16.loadValue(tupleDatum, storageBuf);
00569
00570 BOOST_REQUIRE(tupleDatum.cbData == 2);
00571 bool rc = (intVal == *reinterpret_cast<int16_t const *> (tupleDatum.pData));
00572 BOOST_REQUIRE(rc);
00573
00574
00575 tupleDatum.cbData = 3;
00576 FixedBuffer data[3];
00577 data[0] = 0xba;
00578 data[0] = 0xdc;
00579 data[0] = 0xfe;
00580 tupleDatum.pData = data;
00581 TupleAttributeDescriptor attrDesc_varBinary(
00582 stdTypeFactory.newDataType(STANDARD_TYPE_VARBINARY),
00583 true,
00584 4);
00585 UnalignedAttributeAccessor accessor_varBinary(attrDesc_varBinary);
00586 accessor_varBinary.storeValue(tupleDatum, storageBuf);
00587 len = accessor_varBinary.getStoredByteCount(storageBuf);
00588 BOOST_REQUIRE(len == 4);
00589
00590 tupleDatum.cbData = 0xff;
00591 tupleDatum.pData = loadBuf;
00592 accessor_varBinary.loadValue(tupleDatum, storageBuf);
00593
00594 BOOST_REQUIRE(tupleDatum.cbData == 3);
00595 BOOST_REQUIRE(memcmp(tupleDatum.pData, data, 3) == 0);
00596 }
00597
00598 void TupleTest::loadStore8ByteInts(int64_t initialValue, uint8_t nextByte)
00599 {
00600
00601
00602
00603
00604
00605 int64_t intVal = initialValue;
00606 for (int i = 0; i < 8; i++) {
00607 intVal <<= 8;
00608 intVal |= nextByte;
00609
00610 intVal--;
00611 loadAndStore8ByteInt(intVal);
00612 loadAndStore8ByteInt(-intVal);
00613
00614 intVal++;
00615 loadAndStore8ByteInt(intVal);
00616 loadAndStore8ByteInt(-intVal);
00617
00618 intVal++;
00619 loadAndStore8ByteInt(intVal);
00620 loadAndStore8ByteInt(-intVal);
00621
00622 intVal--;
00623 }
00624 }
00625
00626 void TupleTest::loadAndStore8ByteInt(int64_t intVal)
00627 {
00628 TupleDatum tupleDatum;
00629
00630 FixedBuffer storageBuf[9];
00631 FixedBuffer loadBuf[9];
00632
00633
00634
00635
00636 tupleDatum.cbData = 8;
00637 tupleDatum.pData = (PConstBuffer) &intVal;
00638 StandardTypeDescriptorFactory stdTypeFactory;
00639 TupleAttributeDescriptor attrDesc(
00640 stdTypeFactory.newDataType(STANDARD_TYPE_INT_64));
00641 UnalignedAttributeAccessor accessor(attrDesc);
00642 accessor.storeValue(tupleDatum, storageBuf);
00643
00644
00645
00646 tupleDatum.cbData = 0;
00647 tupleDatum.pData = loadBuf;
00648 accessor.loadValue(tupleDatum, storageBuf);
00649 bool rc = (intVal == *reinterpret_cast<int64_t const *> (tupleDatum.pData));
00650 BOOST_REQUIRE(rc);
00651 BOOST_REQUIRE(tupleDatum.cbData == 8);
00652 }
00653
00654 void TupleTest::loadStore2ByteLenData(uint dataLen)
00655 {
00656
00657 TupleDatum tupleDatum;
00658 tupleDatum.cbData = dataLen;
00659 boost::scoped_array<FixedBuffer> dataBuf(new FixedBuffer[dataLen + 2]);
00660 for (int i = 0; i < dataLen; i++) {
00661 dataBuf[i] = i;
00662 }
00663 tupleDatum.pData = dataBuf.get();
00664
00665
00666 boost::scoped_array<FixedBuffer> storageBuf(new FixedBuffer[dataLen + 2]);
00667 StandardTypeDescriptorFactory stdTypeFactory;
00668 TupleAttributeDescriptor attrDesc(
00669 stdTypeFactory.newDataType(STANDARD_TYPE_BINARY), true, dataLen);
00670 UnalignedAttributeAccessor accessor(attrDesc);
00671 accessor.storeValue(tupleDatum, storageBuf.get());
00672 uint len = accessor.getStoredByteCount(storageBuf.get());
00673 BOOST_REQUIRE(len == dataLen + 2);
00674
00675
00676 boost::scoped_array<FixedBuffer> loadBuf(new FixedBuffer[dataLen + 2]);
00677 tupleDatum.cbData = 0;
00678 tupleDatum.pData = loadBuf.get();
00679 accessor.loadValue(tupleDatum, storageBuf.get());
00680 BOOST_REQUIRE(tupleDatum.cbData == dataLen);
00681 BOOST_REQUIRE(memcmp(tupleDatum.pData, dataBuf.get(), dataLen) == 0);
00682 }
00683
00684 void TupleTest::loadStoreNullData(uint typeOrdinal, uint dataLen)
00685 {
00686 FixedBuffer storageBuf[2];
00687 TupleDatum tupleDatum;
00688 tupleDatum.cbData = 0;
00689 tupleDatum.pData = 0;
00690
00691 StandardTypeDescriptorFactory stdTypeFactory;
00692 TupleAttributeDescriptor attrDesc(
00693 stdTypeFactory.newDataType(typeOrdinal),
00694 true,
00695 dataLen);
00696 UnalignedAttributeAccessor accessor(attrDesc);
00697
00698 accessor.storeValue(tupleDatum, storageBuf);
00699 uint len = accessor.getStoredByteCount(storageBuf);
00700 BOOST_REQUIRE(len == 1);
00701
00702 FixedBuffer loadBuf[2];
00703 tupleDatum.cbData = 0xff;
00704 tupleDatum.pData = loadBuf;
00705 accessor.loadValue(tupleDatum, storageBuf);
00706
00707 BOOST_REQUIRE(tupleDatum.pData == NULL);
00708 }
00709
00710 FENNEL_UNIT_TEST_SUITE(TupleTest);
00711
00712
00713