From 49f6ef078a16c0d1a4fa977e2993a8b7d9b7e6a9 Mon Sep 17 00:00:00 2001 From: knonomura Date: Fri, 22 Mar 2019 14:37:27 +0900 Subject: [PATCH 1/3] update for V4.1 --- utility/util/code.cpp | 69 +++++++++++++++++++++++++++++++++ utility/util/code.h | 89 +++++++++++++++++++++++++++++++++++++++++++ utility/util/type.h | 12 ++++++ 3 files changed, 170 insertions(+) diff --git a/utility/util/code.cpp b/utility/util/code.cpp index 9be1b7c..59f0e99 100644 --- a/utility/util/code.cpp +++ b/utility/util/code.cpp @@ -41,6 +41,7 @@ */ #include "util/code.h" #include "util/os.h" +#include #include #ifndef _WIN32 @@ -1010,4 +1011,72 @@ void StreamErrors::throwUnexpectedRemaining() { } +namespace detail { +void NameCoderImpl::initialize( + const char8_t **nameList, Entry *entryList, size_t count) { + + Entry *entryEnd = entryList + count; + const char8_t **nameIt = nameList; + for (const Entry *it = entryList; it != entryEnd; ++it, ++nameIt) { + *nameIt = it->first; + assert(it->second == it - entryList); + } + + std::sort(entryList, entryEnd, EntryPred()); +} + +const char8_t* NameCoderImpl::findName( + const char8_t *const *nameList, size_t count, int32_t id, + const char8_t *defaultName) { + if (id < 0 || static_cast(id) >= count) { + return defaultName; + } + + return nameList[id]; +} + +const NameCoderImpl::Entry* NameCoderImpl::findEntry( + const Entry *entryList, size_t count, const char8_t *name) { + assert(name != NULL); + + const Entry *entryEnd = entryList + count; + const Entry key(name, Entry::second_type()); + const std::pair &range = + std::equal_range( + entryList, entryEnd, key, EntryPred()); + + if (range.first == range.second) { + return NULL; + } + + return range.first; +} + +const char8_t* NameCoderImpl::removePrefix( + const char8_t *name, size_t prefixWordCount) { + + const char8_t *ret = name; + for (size_t i = prefixWordCount; i > 0; i--) { + const char8_t *found = strchr(ret, '_'); + if (found == NULL) { + assert(false); + break; + } + ret = found + 1; + } + + return ret; +} + +bool NameCoderImpl::EntryPred::operator()( + const Entry &entry1, const Entry &entry2) const { + if (entry1.first == NULL || entry2.first == NULL) { + return (entry1.first == NULL ? 0 : 1) < (entry2.first == NULL ? 0 : 1); + } + + return strcmp(entry1.first, entry2.first) < 0; +} +} + + } diff --git a/utility/util/code.h b/utility/util/code.h index 4137239..90769f5 100644 --- a/utility/util/code.h +++ b/utility/util/code.h @@ -675,6 +675,59 @@ struct StreamErrors { typedef ByteStream ArrayByteInStream; +namespace detail { +struct NameCoderImpl { + typedef std::pair Entry; + + struct EntryPred { + bool operator()(const Entry &entry1, const Entry &entry2) const; + }; + + static void initialize( + const char8_t **nameList, Entry *entryList, size_t count); + + static const char8_t* findName( + const char8_t *const *nameList, size_t count, int32_t id, + const char8_t *defaultName); + + static const Entry* findEntry( + const Entry *entryList, size_t count, const char8_t *name); + + static const char8_t* removePrefix( + const char8_t *name, size_t prefixWordCount); +}; +} + +template +struct NameCoderEntry { + const char8_t *name_; + T id_; +}; + +template +class NameCoder { +public: + typedef NameCoderEntry Entry; + + NameCoder(const Entry (&entryList)[Count], size_t prefixWordCount); + + const char8_t* operator()(T id, const char8_t *defaultName = NULL) const; + bool operator()(const char8_t *name, T &id) const; + +private: + typedef detail::NameCoderImpl Impl; + typedef Impl::Entry BaseEntry; + + const char8_t *nameList_[Count]; + BaseEntry entryList_[Count]; +}; + +#define UTIL_NAME_CODER_ENTRY_CUSTOM(name, id) { name, id } +#define UTIL_NAME_CODER_ENTRY(id) UTIL_NAME_CODER_ENTRY_CUSTOM(#id, id) +#define UTIL_NAME_CODER_NON_NAME_ENTRY(id) \ + UTIL_NAME_CODER_ENTRY_CUSTOM(NULL, id) + + namespace detail { @@ -1686,6 +1739,42 @@ inline ByteStream& ByteStream::put( } + +template +NameCoder::NameCoder( + const Entry (&entryList)[Count], size_t prefixWordCount) { + + const Entry *const end = entryList + Count; + BaseEntry *destIt = entryList_; + + for (const Entry *it = entryList; it != end; ++it, ++destIt) { + destIt->first = Impl::removePrefix(it->name_, prefixWordCount); + destIt->second = it->id_; + } + + Impl::initialize(nameList_, entryList_, Count); +} + +template +const char8_t* NameCoder::operator()( + T id, const char8_t *defaultName) const { + return Impl::findName(nameList_, Count, id, defaultName); +} + +template +bool NameCoder::operator()(const char8_t *name, T &id) const { + const BaseEntry *entry = Impl::findEntry(entryList_, Count, name); + + if (entry == NULL) { + id = T(); + return false; + } + + id = static_cast(entry->second); + return true; +} + + } #endif diff --git a/utility/util/type.h b/utility/util/type.h index 4e5a8ec..c740948 100644 --- a/utility/util/type.h +++ b/utility/util/type.h @@ -967,6 +967,18 @@ template struct IsSame { enum Value { VALUE = Type::VALUE }; }; +template +struct IsPointer { + typedef FalseType Type; + enum Value { VALUE = Type::VALUE }; +}; + +template +struct IsPointer { + typedef TrueType Type; + enum Value { VALUE = Type::VALUE }; +}; + } From e49c7509c28498ba7f54375eae76b77bb065205b Mon Sep 17 00:00:00 2001 From: knonomura Date: Fri, 22 Mar 2019 14:38:36 +0900 Subject: [PATCH 2/3] update for V4.1 --- client/c/client.cpp | 275 +++++++++++++++++++++---------- client/c/client.h | 55 +++++-- client/c/include/gridstore.h | 23 ++- client/c/include_org/gridstore.h | 196 +++++++++++++++++++--- 4 files changed, 425 insertions(+), 124 deletions(-) diff --git a/client/c/client.cpp b/client/c/client.cpp index 78d95de..c3666f8 100644 --- a/client/c/client.cpp +++ b/client/c/client.cpp @@ -1587,8 +1587,8 @@ GSColumnInfo RowMapper::getColumnSchema( columnInfo.type = toFullType(entry.elementType, isArrayColumn(entry)); columnInfo.indexTypeFlags = 0; - columnInfo.options = (entry.options & - (GS_TYPE_OPTION_NULLABLE | GS_TYPE_OPTION_NOT_NULL)); + columnInfo.options = + (entry.options & TypeOptionMask::MASK_GENERAL_SUPPORTED); return columnInfo; } @@ -1633,6 +1633,16 @@ bool RowMapper::hasAnyTypeColumn() const { return false; } +bool RowMapper::isDefaultValueSpecified() const { + for (size_t i = 0; i < binding_.entryCount; i++) { + const GSBindingEntry &entry = binding_.entries[i]; + if ((entry.options & TypeOptionMask::MASK_DEFAULT_VALUE) != 0) { + return true; + } + } + return false; +} + void RowMapper::exportSchema( XArrayByteOutStream &out, const Config &config) const { if (rowTypeCategory_ == CATEGORY_AGGREGATION_RESULT) { @@ -1737,6 +1747,9 @@ GSColumnInfo RowMapper::importColumnSchema( filterNullable( entry.options, 0, config.nullableAllowed_, entry.columnName); + const bool nullable = isOptionNullable(entry.options); + filterInitialValueNull(entry.options, nullable, entry.columnName); + if (config.anyTypeAllowed_ && strlen(entry.columnName) == 0) { entry.columnName = NULL; } @@ -2546,15 +2559,20 @@ GSType RowMapper::toNonNullable(GSType type) { return toNullable(type, false); } +bool RowMapper::isOptionNullable(GSTypeOption options) { + return ((options & GS_TYPE_OPTION_NULLABLE) != 0); +} + +bool RowMapper::isOptionInitialValueNull(GSTypeOption options) { + return ((options & GS_TYPE_OPTION_DEFAULT_VALUE_NULL) != 0); +} + GSTypeOption RowMapper::filterTypeOptions( const GSBindingEntry &entry, bool anyTypeAllowed, bool nullableAllowed) { GSTypeOption srcOptions = entry.options; - if ((srcOptions & ~static_cast( - GS_TYPE_OPTION_KEY | - GS_TYPE_OPTION_NULLABLE | - GS_TYPE_OPTION_NOT_NULL)) != 0) { + if ((srcOptions & ~TypeOptionMask::MASK_BINDING_SUPPORTED) != 0) { UTIL_THROW_ERROR( GS_ERROR_CC_UNKNOWN_ELEMENT_TYPE_OPTION, ""); } @@ -2575,22 +2593,20 @@ GSTypeOption RowMapper::filterTypeOptions( } const GSTypeOption nullableDefault = 0; - if (filterNullable( - srcOptions, nullableDefault, nullableAllowed, entry.columnName)) { - destOptions |= GS_TYPE_OPTION_NULLABLE; - } - else { - destOptions |= GS_TYPE_OPTION_NOT_NULL; - } + destOptions |= filterNullable( + srcOptions, nullableDefault, nullableAllowed, entry.columnName); + + const bool nullable = isOptionNullable(destOptions); + destOptions |= + filterInitialValueNull(srcOptions, nullable, entry.columnName); return destOptions; } -bool RowMapper::filterNullable( +GSTypeOption RowMapper::filterNullable( GSTypeOption options, GSTypeOption nullableDefault, bool nullableAllowed, const GSChar *columnName) { - const GSTypeOption mask = - (GS_TYPE_OPTION_NULLABLE | GS_TYPE_OPTION_NOT_NULL); + const GSTypeOption mask = TypeOptionMask::MASK_NULLABLE; const GSChar *filteredColumnName = (columnName == NULL ? "" : columnName); @@ -2601,7 +2617,7 @@ bool RowMapper::filterNullable( "column=" << filteredColumnName << ")"); } - if ((options & GS_TYPE_OPTION_NULLABLE) != 0) { + if (isOptionNullable(options)) { if (!nullableAllowed) { UTIL_THROW_ERROR( GS_ERROR_CC_ILLEGAL_SCHEMA, @@ -2617,17 +2633,51 @@ bool RowMapper::filterNullable( } } + bool nullable; if ((options & mask) == 0) { if ((options & GS_TYPE_OPTION_KEY) != 0) { - return false; + nullable = false; } - if ((nullableDefault & mask) != 0) { - return ((nullableDefault & GS_TYPE_OPTION_NULLABLE) != 0); + else if ((nullableDefault & mask) != 0) { + nullable = isOptionNullable(nullableDefault); + } + else { + nullable = nullableAllowed; } - return nullableAllowed; + } + else { + nullable = isOptionNullable(options); } - return ((options & GS_TYPE_OPTION_NULLABLE) != 0); + if (nullable) { + return GS_TYPE_OPTION_NULLABLE; + } + else { + return GS_TYPE_OPTION_NOT_NULL; + } +} + +GSTypeOption RowMapper::filterInitialValueNull( + GSTypeOption options, bool nullable, const GSChar *columnName) { + const GSTypeOption mask = TypeOptionMask::MASK_DEFAULT_VALUE; + const GSChar *filteredColumnName = + (columnName == NULL ? "" : columnName); + + if ((options & mask) == mask) { + UTIL_THROW_ERROR( + GS_ERROR_CC_ILLEGAL_SCHEMA, + "Both of default value null and not null option specified (" + "column=" << filteredColumnName << ")"); + } + + if (!nullable && (options & GS_TYPE_OPTION_DEFAULT_VALUE_NULL) != 0) { + UTIL_THROW_ERROR( + GS_ERROR_CC_ILLEGAL_SCHEMA, + "Default value null is not allowed (" + "column=" << filteredColumnName << ")"); + } + + return (options & mask); } const RowMapper::ContainerInfoRef RowMapper::toInfoRef( @@ -5903,8 +5953,8 @@ void NodeConnection::OptionalRequest::format( if (!clientId_.isEmpty()) { formatter.putType(CLIENT_ID); - reqOut.writeAll(clientId_.getUUID(), sizeof(uuid_t)); reqOut << clientId_.getSessionId(); + reqOut.writeAll(clientId_.getUUID(), sizeof(uuid_t)); } if (fetchBytesSize_ > 0) { @@ -7298,7 +7348,7 @@ bool GridStoreChannel::v40QueryCompatible_ = false; bool GridStoreChannel::v40ContainerHashCompatible_ = true; bool GridStoreChannel::v40SchemaCompatible_ = false; -const int32_t GridStoreChannel::FAILOVER_TIMEOUT_DEFAULT = 60 * 1000; +const int32_t GridStoreChannel::FAILOVER_TIMEOUT_DEFAULT = 2 * 60 * 1000; const int32_t GridStoreChannel::FAILOVER_RETRY_INTERVAL = 1 * 1000; const size_t GridStoreChannel::INITIAL_BUFFER_SIZE = 256; const size_t GridStoreChannel::MAPPER_CACHE_SIZE = 32; @@ -8799,11 +8849,10 @@ void GSGridStoreTag::close(GSGridStore **store, bool allRelated) throw() { } try { + ResourceSet &resourceSet = (**store).activeResources_; - ResourceList &resourceList = (**store).resourceList_; - - for (ResourceList::iterator it = resourceList.begin(); - it != resourceList.end(); ++it) { + for (ResourceSet::iterator it = resourceSet.begin(); + it != resourceSet.end(); ++it) { void *resource = *it; GSResourceType::Id type; @@ -8815,11 +8864,11 @@ void GSGridStoreTag::close(GSGridStore **store, bool allRelated) throw() { } } - if (allRelated && !resourceList.empty()) { + if (allRelated && !resourceSet.empty()) { size_t orgSize; do { - orgSize = resourceList.size(); - void *resource = *(--resourceList.end()); + orgSize = resourceSet.size(); + void *resource = *(--resourceSet.end()); GSResourceType::Id type; if (!GSResourceHeader::getType(resource, type)) { @@ -8851,8 +8900,8 @@ void GSGridStoreTag::close(GSGridStore **store, bool allRelated) throw() { } assert(referenceCount > 0); } - while (!resourceList.empty() && orgSize != resourceList.size()); - assert(resourceList.empty()); + while (!resourceSet.empty() && orgSize != resourceSet.size()); + assert(resourceSet.empty()); } } catch (...) { @@ -8874,8 +8923,6 @@ void GSGridStoreTag::close(GSGridStore **store, bool allRelated) throw() { } void GSGridStoreTag::createReference(void *resource) { - resourceList_.reserve(resourceList_.size() + 1); - GSResourceType::Id type; if (!GSResourceHeader::getType(resource, type)) { assert(false); @@ -8898,11 +8945,11 @@ void GSGridStoreTag::createReference(void *resource) { UTIL_THROW_ERROR(GS_ERROR_CC_INTERNAL_ERROR, ""); } + const ContainerKey *containerKey = NULL; if (pathKeyOperationEnabled_) { if (type == GSResourceType::CONTAINER) { GSContainer &container = *static_cast(resource); - const ContainerKey *containerKey = - container.getNormalizedContainerKey(); + containerKey = container.getNormalizedContainerKey(); if (containerKey != NULL) { containerMap_.insert( std::make_pair(*containerKey, &container)); @@ -8910,22 +8957,29 @@ void GSGridStoreTag::createReference(void *resource) { } } - resourceList_.insert(resource); + try { + activeResources_.insert(resource); + } + catch (...) { + if (containerKey != NULL) { + containerMap_.erase(*containerKey); + } + throw; + } referenceCount_++; } -void GSGridStoreTag::removeReference( - GSGridStore *&store, void *resource) { +void GSGridStoreTag::removeReference(GSGridStore *&store, void *resource) { if (store == NULL) { return; } try { { - ResourceList &resourceList = store->resourceList_; - ResourceList::iterator it = resourceList.find(resource); - if (it != resourceList.end()) { - resourceList.erase(it); + ResourceSet &resourceSet = store->activeResources_; + ResourceSet::iterator it = resourceSet.find(resource); + if (it != resourceSet.end()) { + resourceSet.erase(it); } else { assert(false); @@ -9264,7 +9318,6 @@ GSContainer* GSGridStoreTag::putContainer( } XArrayByteOutStream reqOut = channel_.getRequestOutStream(req_); - tryPutSystemOptionalRequest(reqOut, context_, true); RowMapper::Cache &mapperCache = RowMapper::getDefaultCache(); const RowMapper::RowTypeCategory category = @@ -9272,6 +9325,11 @@ GSContainer* GSGridStoreTag::putContainer( const RowMapper::Reference orgMapper( mapperCache, mapperCache.resolve( category, &binding, false, getRowMapperConfig())); + + const ContainerPropertiesOption &propsOption = + containerPropertiesToOption(*orgMapper); + tryPutSystemOptionalRequest(reqOut, context_, true, propsOption.get()); + const int32_t partitionId = channel_.resolvePartitionId(context_, key, keyConverter); @@ -9433,12 +9491,16 @@ GSContainer* GSGridStoreTag::putContainer( } XArrayByteOutStream reqOut = channel_.getRequestOutStream(req_); - tryPutSystemOptionalRequest(reqOut, context_, true); RowMapper::Cache &mapperCache = RowMapper::getDefaultCache(); const RowMapper::Reference orgMapper( mapperCache, mapperCache.resolve( containerInfoRef, getRowMapperConfig())); + + const ContainerPropertiesOption &propsOption = + containerPropertiesToOption(*orgMapper); + tryPutSystemOptionalRequest(reqOut, context_, true, propsOption.get()); + const int32_t partitionId = channel_.resolvePartitionId(context_, key, keyConverter); @@ -10164,6 +10226,18 @@ void GSGridStoreTag::tryPutSystemOptionalRequest( optionalRequest.format(reqOut); } +GSGridStore::ContainerPropertiesOption +GSGridStoreTag::containerPropertiesToOption(const RowMapper &mapper) { + ContainerPropertiesOption option; + if (mapper.isDefaultValueSpecified()) { + UTIL_THROW_ERROR( + GS_ERROR_CC_UNSUPPORTED_OPERATION, + "Default value can not specified for container " + "definition in the current version"); + } + return option; +} + void GSGridStoreTag::exportContainerProperties( XArrayByteOutStream &out, const GSContainerType type, const GSContainerInfo *info, const RowMapper &mapper) { @@ -11554,6 +11628,11 @@ bool GSGridStoreTag::MultiGetRequest::makeRequest( return true; } +const NodeConnection::OptionalRequestSource* +GSGridStoreTag::ContainerPropertiesOption::get() const { + return NULL; +} + const bool GSContainerTag::TIME_SERIES_UPDATE_ENABLED = true; bool GSContainerTag::queryStatementIdPreserved_ = false; @@ -11638,13 +11717,13 @@ void GSContainerTag::close(GSContainer **container, bool allRelated) throw() { size_t &referenceCount = (**container).referenceCount_; try { - ResourceList &resourceList = (**container).activeResources_; - if (allRelated && !resourceList.empty()) { + ResourceSet &resourceSet = (**container).activeResources_; + if (allRelated && !resourceSet.empty()) { referenceCount++; size_t orgSize; do { - orgSize = resourceList.size(); - void *resource = resourceList.back(); + orgSize = resourceSet.size(); + void *resource = *(--resourceSet.end()); GSResourceType::Id type; if (!GSResourceHeader::getType(resource, type)) { @@ -11686,8 +11765,8 @@ void GSContainerTag::close(GSContainer **container, bool allRelated) throw() { } assert(referenceCount > 0); } - while (!resourceList.empty() && orgSize != resourceList.size()); - assert(resourceList.empty()); + while (!resourceSet.empty() && orgSize != resourceSet.size()); + assert(resourceSet.empty()); if (referenceCount > 1) { --referenceCount; } @@ -11728,7 +11807,7 @@ void GSContainerTag::createReference(void *resource) { assert(false); UTIL_THROW_ERROR(GS_ERROR_CC_INTERNAL_ERROR, ""); } - activeResources_.push_back(resource); + activeResources_.insert(resource); referenceCount_++; } @@ -11739,10 +11818,10 @@ void GSContainerTag::removeReference( } try { - ResourceList &list = container->activeResources_; - ResourceList::iterator it = std::find(list.begin(), list.end(), resource); - if (it != list.end()) { - list.erase(it); + ResourceSet &set = container->activeResources_; + ResourceSet::iterator it = set.find(resource); + if (it != set.end()) { + set.erase(it); } else { assert(false); @@ -12272,7 +12351,8 @@ GSRowSet* GSContainerTag::acceptQueryResponse( } const QueryParameters &rowSetParameters = parameters.inherit( - forUpdate, (autoCommit_ ? 0 : transactionId_), executionStatus); + forUpdate, (autoCommit_ ? 0 : transactionId_), + transactionStarted_, executionStatus); int64_t rowCount; rowSetIn >> rowCount; @@ -12359,8 +12439,8 @@ void GSContainerTag::fetchRowSet( try { getChannel().checkActiveConnection(getContext(), partitionId_, connectionId); - ArrayByteInStream respIn = executeStatement( - Statement::FETCH_ROW_SET, STATEMENT_FAMILY_NONE); + ArrayByteInStream respIn = + executeStatement(Statement::FETCH_ROW_SET, family); respIn >> resultClosed; respIn >> varDataBaseOffset; respIn >> resultRowCount; @@ -12409,9 +12489,9 @@ void GSContainerTag::fetchRowSet( } void GSContainerTag::removeRow( - const RowMapper &resolvedMapper, - int64_t transactionId, int64_t rowId, const void *key) { - checkTransactionPreserved(true, transactionId, true); + const RowMapper &resolvedMapper, int64_t transactionId, + const bool *transactionStarted, int64_t rowId, const void *key) { + checkTransactionPreserved(true, transactionId, transactionStarted, true); if (&resolvedMapper != mapper_.get()) { UTIL_THROW_ERROR(GS_ERROR_CC_UNSUPPORTED_OPERATION, ""); @@ -12436,15 +12516,15 @@ void GSContainerTag::removeRow( } void GSContainerTag::updateRow( - const RowMapper &resolvedMapper, - int64_t transactionId, int64_t rowId, - const void *key, const void *rowObj) { + const RowMapper &resolvedMapper, int64_t transactionId, + const bool *transactionStarted, int64_t rowId, const void *key, + const void *rowObj) { if (resolvedMapper.getCategory() == RowMapper::CATEGORY_TIME_SERIES && !TIME_SERIES_UPDATE_ENABLED) { UTIL_THROW_ERROR(GS_ERROR_CC_UNSUPPORTED_OPERATION, ""); } - checkTransactionPreserved(true, transactionId, true); + checkTransactionPreserved(true, transactionId, transactionStarted, true); if (&resolvedMapper != mapper_.get()) { UTIL_THROW_ERROR(GS_ERROR_CC_UNSUPPORTED_OPERATION, ""); @@ -13520,7 +13600,7 @@ void GSContainerTag::closeAllSessions( void GSContainerTag::closeSubResources(bool silent, bool transactionalOnly) { assert(referenceCount_ > 0); - for (ResourceList::iterator it = activeResources_.begin(); + for (ResourceSet::iterator it = activeResources_.begin(); it != activeResources_.end(); ++it) { GSResourceType::Id type; if (!GSResourceHeader::getType(*it, type)) { @@ -13594,7 +13674,8 @@ GSContainer::StatementFamily GSContainerTag::prepareQuerySession( if (parameters.transactionIdSpecified_) { checkTransactionPreserved( - forUpdateActual, parameters.initialTransactionId_, true); + forUpdateActual, parameters.initialTransactionId_, + ¶meters.initialTransactionStarted_, true); } StatementFamily baseFamily; @@ -13685,7 +13766,8 @@ bool GSContainerTag::isResultRowIdIncluded(QueryResultType type) { } void GSContainerTag::checkTransactionPreserved( - bool forUpdate, int64_t transactionId, bool updatable) { + bool forUpdate, int64_t transactionId, const bool *transactionStarted, + bool updatable) { if (forUpdate && (transactionId == 0 || !updatable)) { UTIL_THROW_ERROR(GS_ERROR_CC_NOT_LOCKED, "Update option must be turned on"); @@ -13701,7 +13783,9 @@ void GSContainerTag::checkTransactionPreserved( } else { if (transactionId != transactionId_ || - !transactionStarted_ || autoCommit_) { + (transactionStarted != NULL && + (!(*transactionStarted)) != (!transactionStarted_)) || + autoCommit_) { UTIL_THROW_ERROR(GS_ERROR_CC_TRANSACTION_CLOSED, "Transaction expired"); } @@ -14091,6 +14175,7 @@ GSContainerTag::QueryParameters::QueryParameters(Statement::Id statement) : executionPartial_(false), forUpdate_(false), transactionIdSpecified_(false), + initialTransactionStarted_(false), initialTransactionId_(0) { } @@ -14147,17 +14232,20 @@ bool GSContainerTag::QueryParameters::isForUpdate(bool forUpdate) const { } GSContainerTag::QueryParameters GSContainerTag::QueryParameters::inherit( - bool forUpdate, int64_t transactionId, + bool forUpdate, int64_t transactionId, bool transactionStarted, const PartialExecutionStatus &executionStatus) const { QueryParameters dest = *this; dest.forUpdate_ = isForUpdate(forUpdate); - if (transactionIdSpecified_ && initialTransactionId_ != transactionId) { + if (transactionIdSpecified_ && + (initialTransactionId_ != transactionId || + (!initialTransactionStarted_) != (!transactionStarted))) { UTIL_THROW_ERROR(GS_ERROR_CC_INTERNAL_ERROR, ""); } dest.transactionIdSpecified_ = true; dest.initialTransactionId_ = transactionId; + dest.initialTransactionStarted_ = transactionStarted; dest.executionStatus_ = dest.executionStatus_.inherit(executionStatus); @@ -14451,9 +14539,15 @@ GSContainer* GSRowSetTag::getContainer() const { } int64_t GSRowSetTag::getTransactionId() const { + assert(queryParameters_.transactionIdSpecified_); return queryParameters_.initialTransactionId_; } +bool GSRowSetTag::isTransactionStarted() const { + assert(queryParameters_.transactionIdSpecified_); + return queryParameters_.initialTransactionStarted_; +} + int64_t GSRowSetTag::getRowId() const { checkOpened(); checkInRange(); @@ -14587,17 +14681,20 @@ void GSRowSetTag::remove() { checkOpened(); checkInRange(); + const bool &transactionStarted = isTransactionStarted(); container_->removeRow( - mapper_, getTransactionId(), cursor_.getLastRowID(), lastKey_); + mapper_, getTransactionId(), &transactionStarted, + cursor_.getLastRowID(), lastKey_); } void GSRowSetTag::update(const void *rowObj) { checkOpened(); checkInRange(); + const bool &transactionStarted = isTransactionStarted(); container_->updateRow( - mapper_, getTransactionId(), cursor_.getLastRowID(), lastKey_, - rowObj); + mapper_, getTransactionId(), &transactionStarted, + cursor_.getLastRowID(), lastKey_, rowObj); } void GSRowSetTag::getRowFixedPart(const uint8_t *&data, size_t &size) const { @@ -14963,8 +15060,9 @@ GSBinding GSRowTag::createBinding( entry.columnName = columnInfo.name; entry.elementType = elementType; - if ((columnInfo.options & ~static_cast( - GS_TYPE_OPTION_NULLABLE | GS_TYPE_OPTION_NOT_NULL)) != 0) { + typedef RowMapper::TypeOptionMask TypeOptionMask; + if ((columnInfo.options & + ~TypeOptionMask::MASK_GENERAL_SUPPORTED) != 0) { UTIL_THROW_ERROR(GS_ERROR_CC_ILLEGAL_SCHEMA, ""); } @@ -15240,6 +15338,10 @@ GSRowTag::GSRowTag( for (size_t i = 0; i < binding.entryCount; i++) { const GSBindingEntry &entry = binding.entries[i]; RowMapper::invokeTypedOperation(*this, initializer, entry); + + if (RowMapper::isOptionInitialValueNull(entry.options)) { + setNullDirect(static_cast(i), entry, true, false); + } } if (parentResource_ == NULL) { @@ -16261,7 +16363,9 @@ const GSChar *const* GSPartitionControllerTag::toAddressList( return resultList; } -#ifndef GS_CLIENT_UNIT_TEST +#ifdef GS_CLIENT_UNIT_TEST +namespace client_unit_test { +#endif void GS_API_CALL gsCloseFactory( @@ -19031,11 +19135,12 @@ GSResult GS_API_CALL gsExperimentalUpdateRowById( case RowMapper::CATEGORY_COLLECTION: container->updateRow( container->getMapper(), rowId->internal.transactionId, - rowId->internal.baseId, NULL, rowObj); + NULL, rowId->internal.baseId, NULL, rowObj); break; case RowMapper::CATEGORY_TIME_SERIES: container->updateRow( - container->getMapper(), rowId->internal.transactionId, 0, + container->getMapper(), rowId->internal.transactionId, + NULL, 0, &static_cast(rowId->internal.baseId), rowObj); break; @@ -19066,11 +19171,12 @@ GSResult GS_API_CALL gsExperimentalDeleteRowById( case RowMapper::CATEGORY_COLLECTION: container->removeRow( container->getMapper(), rowId->internal.transactionId, - rowId->internal.baseId, NULL); + NULL, rowId->internal.baseId, NULL); break; case RowMapper::CATEGORY_TIME_SERIES: container->removeRow( - container->getMapper(), rowId->internal.transactionId, 0, + container->getMapper(), rowId->internal.transactionId, + NULL, 0, &static_cast(rowId->internal.baseId)); break; default: @@ -19085,7 +19191,8 @@ GSResult GS_API_CALL gsExperimentalDeleteRowById( #endif -#else +#ifdef GS_CLIENT_UNIT_TEST +} GSResult GS_API_CALL gsGetContainerInfoV3_3( diff --git a/client/c/client.h b/client/c/client.h index 35c0e5f..d3d0c84 100644 --- a/client/c/client.h +++ b/client/c/client.h @@ -511,6 +511,19 @@ class RowMapper { static const GSType NULLABLE_MASK = ~static_cast((1U << (CHAR_BIT - 1)) - 1); + struct TypeOptionMask { + static const GSTypeOption MASK_NULLABLE = + GS_TYPE_OPTION_NULLABLE | GS_TYPE_OPTION_NOT_NULL; + static const GSTypeOption MASK_DEFAULT_VALUE = + GS_TYPE_OPTION_DEFAULT_VALUE_NULL | + GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL; + + static const GSTypeOption MASK_GENERAL_SUPPORTED = + MASK_NULLABLE | MASK_DEFAULT_VALUE; + static const GSTypeOption MASK_BINDING_SUPPORTED = + GS_TYPE_OPTION_KEY | MASK_GENERAL_SUPPORTED; + }; + struct Tool; struct KeyStorage; struct Config; @@ -584,6 +597,7 @@ class RowMapper { GSType getElementType(int32_t columnId) const; bool isArray(int32_t columnId) const; bool hasAnyTypeColumn() const; + bool isDefaultValueSpecified() const; static GSBinding importSchema( ArrayByteInStream &in, VarDataPool *varDataPool, @@ -719,12 +733,18 @@ class RowMapper { static GSType toNullable(GSType type, bool nullable = true); static GSType toNonNullable(GSType type); + static bool isOptionNullable(GSTypeOption options); + static bool isOptionInitialValueNull(GSTypeOption options); + static GSTypeOption filterTypeOptions( const GSBindingEntry &entry, bool anyTypeAllowed, bool nullableAllowed); - static bool filterNullable( + static GSTypeOption filterNullable( GSTypeOption options, GSTypeOption nullableDefault, bool nullableAllowed, const GSChar *columnName); + static GSTypeOption filterInitialValueNull( + GSTypeOption options, bool nullable, + const GSChar *columnName); static const ContainerInfoRef toInfoRef( const GSContainerInfo *info, const ClientVersion &version) throw(); @@ -2583,11 +2603,13 @@ struct GSGridStoreTag { int32_t protocolVersion); private: - typedef util::NormalSortedList ResourceList; + typedef std::set ResourceSet; typedef NodeConnection::OptionalRequestSource OptionalRequestSource; typedef GridStoreChannel::ContainerCache ContainerCache; typedef std::multimap ContainerMap; + struct ContainerPropertiesOption; + struct MultiQueryStatement { explicit MultiQueryStatement(GridStoreChannel::Context &context); static void check(GSQuery &query, GSGridStore &store); @@ -2697,6 +2719,9 @@ struct GSGridStoreTag { XArrayByteOutStream &reqOut, GridStoreChannel::Context &context, bool forCreationDDL, const OptionalRequestSource *source = NULL); + static ContainerPropertiesOption containerPropertiesToOption( + const RowMapper &mapper); + static void exportContainerProperties( XArrayByteOutStream &out, const GSContainerType type, const GSContainerInfo *info, const RowMapper &mapper); @@ -2764,11 +2789,14 @@ struct GSGridStoreTag { util::NormalXArray &req_; util::NormalXArray &resp_; RowMapper::VarDataPool varDataPool_; - ResourceList resourceList_; + ResourceSet activeResources_; ContainerMap containerMap_; ErrorStack stack_; }; +struct GSGridStoreTag::ContainerPropertiesOption { + const OptionalRequestSource* get() const; +}; struct GSContainerTag { public: @@ -2855,12 +2883,12 @@ struct GSContainerTag { GridStoreChannel::ConnectionId &connectionId); void removeRow( - const RowMapper &resolvedMapper, - int64_t transactionId, int64_t rowId, const void *key); + const RowMapper &resolvedMapper, int64_t transactionId, + const bool *transactionStarted, int64_t rowId, const void *key); void updateRow( - const RowMapper &resolvedMapper, - int64_t transactionId, int64_t rowId, - const void *key, const void *rowObj); + const RowMapper &resolvedMapper, int64_t transactionId, + const bool *transactionStarted, int64_t rowId, const void *key, + const void *rowObj); void abort(); void commit(); @@ -2910,7 +2938,7 @@ struct GSContainerTag { GSRow* createRow(); private: - typedef std::vector ResourceList; + typedef std::set ResourceSet; typedef NodeConnection::OptionalRequestSource OptionalRequestSource; typedef GridStoreChannel::ContainerCache ContainerCache; @@ -3051,7 +3079,8 @@ struct GSContainerTag { bool isResultRowIdIncluded(QueryResultType type); void checkTransactionPreserved( - bool forUpdate, int64_t transactionId, bool updatable); + bool forUpdate, int64_t transactionId, + const bool *transactionStarted, bool updatable); bool filterIndexInfo( const GSIndexInfo &info, bool forCreation, @@ -3072,7 +3101,7 @@ struct GSContainerTag { size_t referenceCount_; GSGridStore *store_; - ResourceList activeResources_; + ResourceSet activeResources_; RowMapper::Reference mapper_; const int32_t schemaVerId_; @@ -3155,7 +3184,7 @@ struct GSContainerTag::QueryParameters { bool isForUpdate(bool forUpdate) const; QueryParameters inherit( - bool forUpdate, int64_t transactionId, + bool forUpdate, int64_t transactionId, bool transactionStarted, const PartialExecutionStatus &executionStatus) const; Statement::Id statement_; @@ -3167,6 +3196,7 @@ struct GSContainerTag::QueryParameters { bool executionPartial_; bool forUpdate_; bool transactionIdSpecified_; + bool initialTransactionStarted_; int64_t initialTransactionId_; }; @@ -3264,6 +3294,7 @@ struct GSRowSetTag { GSContainer* getContainer() const; int64_t getTransactionId() const; + bool isTransactionStarted() const; int64_t getRowId() const; const void* getRowKey() const; diff --git a/client/c/include/gridstore.h b/client/c/include/gridstore.h index d66d070..fb6bdf7 100644 --- a/client/c/include/gridstore.h +++ b/client/c/include/gridstore.h @@ -1,5 +1,5 @@ /*------------------------------------------------------------------*/ -// Copyright (c) 2017 TOSHIBA Digital Solutions Corporation +// Copyright (c) 2017 TOSHIBA Digital Solutions Corporation. All Rights Reserved. /*------------------------------------------------------------------*/ @@ -23,7 +23,7 @@ #ifndef GS_CLIENT_VERSION_MINOR -#define GS_CLIENT_VERSION_MINOR 0 +#define GS_CLIENT_VERSION_MINOR 1 #endif @@ -161,6 +161,14 @@ extern "C" { #define GS_COMPATIBILITY_SUPPORT_4_0 0 #endif +#if !defined(GS_COMPATIBILITY_SUPPORT_4_1) && \ + (GS_CLIENT_VERSION_MAJOR > 4 || \ + (GS_CLIENT_VERSION_MAJOR == 4 && GS_CLIENT_VERSION_MINOR >= 1)) +#define GS_COMPATIBILITY_SUPPORT_4_1 1 +#else +#define GS_COMPATIBILITY_SUPPORT_4_1 0 +#endif + #endif @@ -557,7 +565,16 @@ enum GSTypeOptionTag { GS_TYPE_OPTION_NOT_NULL = 1 << 2, -#endif +#if GS_COMPATIBILITY_SUPPORT_4_1 + + GS_TYPE_OPTION_DEFAULT_VALUE_NULL = 1 << 3, + + + GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL = 1 << 4 + +#endif + +#endif }; diff --git a/client/c/include_org/gridstore.h b/client/c/include_org/gridstore.h index 750b69a..ff648f3 100644 --- a/client/c/include_org/gridstore.h +++ b/client/c/include_org/gridstore.h @@ -1,5 +1,5 @@ /*------------------------------------------------------------------*/ -// Copyright (c) 2017 TOSHIBA Digital Solutions Corporation +// Copyright (c) 2017 TOSHIBA Digital Solutions Corporation. All Rights Reserved. /*------------------------------------------------------------------*/ /*! @JP @@ -100,7 +100,7 @@ @ENDL */ -#define GS_CLIENT_VERSION_MINOR 0 +#define GS_CLIENT_VERSION_MINOR 1 #endif // C API @@ -238,6 +238,14 @@ extern "C" { #define GS_COMPATIBILITY_SUPPORT_4_0 0 #endif +#if !defined(GS_COMPATIBILITY_SUPPORT_4_1) && \ + (GS_CLIENT_VERSION_MAJOR > 4 || \ + (GS_CLIENT_VERSION_MAJOR == 4 && GS_CLIENT_VERSION_MINOR >= 1)) +#define GS_COMPATIBILITY_SUPPORT_4_1 1 +#else +#define GS_COMPATIBILITY_SUPPORT_4_1 0 +#endif + #endif // GS_INTERNAL_DEFINITION_VISIBLE /*! @@ -1186,7 +1194,7 @@ enum GSFetchOptionTag { 部分実行モードを有効にした場合に@ref GSRowSet に対して使用 できない操作や特有の挙動については、個別の定義を参照してください。 @par - サポートされる設定値の型は、@ref GSBool のみです。 + サポートされる設定値の型は、BOOLのみです。 部分実行モードを有効にするには、@ref GS_TRUE と一致する値を 指定します。現バージョンでは、未設定の場合には部分実行モードを有効に しません。 @@ -1234,7 +1242,7 @@ enum GSFetchOptionTag { individual definitions. @par The only supported type for this setting is - @ref GSBool. The value matching to @ref GS_TRUE + BOOL. The value matching to @ref GS_TRUE must be specified to activate this mode. In this version, the partial execution mode is not effective unless setting @@ -2386,9 +2394,11 @@ typedef GSEnum GSType; /*! @JP @brief カラムに関するオプション設定を示します。 + @see GSTypeOption @EN - @brief Indicates optional settings for Column + @brief Indicates optional settings for Column. + @see GSTypeOption @ENDL */ @@ -2426,7 +2436,36 @@ enum GSTypeOptionTag { */ GS_TYPE_OPTION_NOT_NULL = 1 << 2, -#endif +#if GS_COMPATIBILITY_SUPPORT_4_1 + /*! + @JP + @brief 初期値としてNULLを使用するカラムであることを示します。 + @since 4.1 + + @EN + @brief Indicates use of NULL for the initial value. + @since 4.1 + + @ENDL + */ + GS_TYPE_OPTION_DEFAULT_VALUE_NULL = 1 << 3, + + /*! + @JP + @brief 初期値としてNULLを使用しないカラムであることを示します。 + @since 4.1 + + @EN + @brief Indicates no use of NULL for the initial value. + @since 4.1 + + @ENDL + */ + GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL = 1 << 4 + +#endif // GS_COMPATIBILITY_SUPPORT_4_1 + +#endif // GS_COMPATIBILITY_SUPPORT_3_5 }; @@ -2434,21 +2473,56 @@ enum GSTypeOptionTag { @JP @brief カラムに関するオプション設定を示すフラグ値のビット和です。 @par - 次のフラグ値を共に含めた場合、矛盾したオプション設定であると - みなされます。また、いずれも含まれていない場合、NOT NULL制約に - 関して未設定状態であるとみなされます。 + ある設定項目について、対応するフラグ値が複数含まれていた場合に、 + オプション設定が矛盾しているとみなされるものが存在します。 + それらの設定項目のうち、対応するフラグ値が一つも含まれていないものは、 + 未設定状態であるとみなされます。この制約に該当する設定項目と + フラグ値との対応は次の通りです。 + + + + + + + + + + +
設定項目フラグ値
NOT NULL制約 - @ref GS_TYPE_OPTION_NULLABLE - @ref GS_TYPE_OPTION_NOT_NULL +
初期値でのNULL使用有無 + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NULL + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL +
@see GSTypeOptionTag @EN - @brief Sum of bits of value of the flag indicating the option setting for Column. + @brief Sum of bits of value of the flag indicating the option setting + for Column. @par - When both of the following flag values are included, the option setting - is considered inconsistent. When neither are included, the NOT NULL - constraint is considered to be in an unconfigured state. + There are setting items that when more than one flag values for a + setting item are included, the option setting is considered + inconsistent. A setting item that neither of corresponding flag values + is included is considered to be in an unconfigured state. Following + flag values related to the setting items have those restrictions. + + + + + + + + + + +
Setting itemFlag values
NOT NULL constraint state - @ref GS_TYPE_OPTION_NULLABLE - @ref GS_TYPE_OPTION_NOT_NULL +
Whether to use of NULL for the initial value + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NULL + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL +
@see GSTypeOptionTag @ENDL @@ -3072,18 +3146,24 @@ typedef struct GSColumnInfoTag { @JP @brief カラムに関するオプション設定を示すフラグ値のビット和です。 @par - 現バージョンでは、NOT NULL制約に関連する以下のフラグ値のみを含める - ことができます。 + 現バージョンでは、NOT NULL制約または初期値に関連する、以下の + フラグ値のみを含めることができます。 - @ref GS_TYPE_OPTION_NULLABLE - @ref GS_TYPE_OPTION_NOT_NULL + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NULL + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL @since 3.5 @EN - @brief Sum of bits of value of the flag indicating the option setting for Column. + @brief Sum of bits of value of the flag indicating the option setting + for Column. @par - In the current version, you can only include the following flag values for the NOT NULL constraint. + In the current version, it can only contain the following flag + values for the NOT NULL constraint or the initial value. - @ref GS_TYPE_OPTION_NULLABLE - @ref GS_TYPE_OPTION_NOT_NULL + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NULL + - @ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL @since 3.5 @ENDL @@ -5082,6 +5162,9 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsGetContainerInfoV3_3( カラム順序を無視するかどうかについては、無視しない状態に設定されます。 この設定は、@ref GSContainerInfo::columnOrderIgnorable を通じて 確認できます。 + @par + 現バージョンでは、初期値でのNULL使用有無は未設定状態で求まります。 + この設定は、@ref GSColumnInfo::options を通じて確認できます。 @attention カラム情報の列などの可変長データを格納するために、指定の@ref GSGridStore インスタンス上で管理される一時的なメモリ領域を使用します。 @@ -5118,6 +5201,10 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsGetContainerInfoV3_3( @par The column sequence is set to Do Not Ignore. This setting can be verified through @ref GSContainerInfo::columnOrderIgnorable. + @par + In the current version, whether to use of NULL for the initial value + is not set. Note that it may be set in the future version. This + information can be acquired through @ref GSColumnInfo::options. @attention In order to store the variable-length data such as the column of column information, it uses a temporary memory area which is managed by the @@ -5732,7 +5819,10 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsPutContainerGeneralV3_3( と同様の振る舞いとなる。 カラムレイアウト@c info @ref GSContainer にて規定された制約に合致するよう - @ref GSColumnInfo のリストならびにロウキーの有無を設定する。 + @ref GSColumnInfo のリストならびにロウキーの有無を設定する。 + ただし現バージョンでは、初期値でのNULL使用有無が設定された + @ref GSColumnInfo::options を持つ@ref GSColumnInfo を含めることは + できない。 カラム順序の無視@c info 無視する場合、同名の既存のコンテナのカラム順序と一致するかどうかを 検証しない。 @@ -5807,6 +5897,10 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsPutContainerGeneralV3_3( column layout@c info Set the @ref GSColumnInfo list and whether there is any Row key so as to conform to the restrictions stipulated in @ref GSContainer. + However, in the current version, it is not allowed that the list + includes one or more @ref GSColumnInfo which has option + whether to use of NULL for the initial value in + @ref GSColumnInfo::options. ignore column order@c info If ignored, no verification of the conformance with the column order @@ -6410,8 +6504,33 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsCreateRowByStoreV3_3( を呼び出したとしても、常に固定の値である@ref GS_CONTAINER_COLLECTION がコンテナ種別として設定された@ref GSContainerInfo が求まります。 @par - 作成された@ref GSRow の各フィールドには、@ref GSContainer にて定義 - されている空の値が初期値として設定されます。 + 作成された@ref GSRow の各フィールドには、@ref GSContainerInfo に + 含まれる各カラムの@ref GSColumnInfo に基づいた初期値が設定されます。 + 初期値として、@ref GSColumnInfo::options に含まれるオプションに応じた + 次の値が使用されます。 + + + + + + + + + + + + + + + + + + + + +
オプション初期値
@ref GS_TYPE_OPTION_DEFAULT_VALUE_NULLNULL。ただし制約に反するロウは作成できない。
@ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL空の値。@ref GSContainer の定義を参照。
(上記いずれも指定なし)現バージョンでは、@ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL + が指定された場合と同様。
(上記オプションを両方指定)@ref GSTypeOption の定義に基づき矛盾する設定と見なされ、ロウを作成 + できない。
@param [in] store 処理対象の@ref GSGridStore @param [in] info @@ -6442,6 +6561,35 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsCreateRowByStoreV3_3( @par Each existing field of the created @ref GSRow is initialized with the empty value defined by @ref GSContainer. + @par + Each field will be set to the initial value which is based on + @ref GSColumnInfo of each column in the specified + @ref GSContainerInfo. The initial value corresponding to the option in + @ref GSColumnInfo::options is selected by the following way. + + + + + + + + + + + + + + + + + + + + +
OptionInitial value
@ref GS_TYPE_OPTION_DEFAULT_VALUE_NULLNULL. However a row which violates constraints can not be + created.
@ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULLThe empty value. See the definition of @ref GSContainer.
(None of above)In the current version, same as + @ref GS_TYPE_OPTION_DEFAULT_VALUE_NOT_NULL.
(Both of above)According to definition of @ref GSTypeOption, a row can not be + created because of conflicted options.
@param [in] store @ref GSGridStore to be processed @param [in] info @@ -8563,8 +8711,6 @@ GS_DLL_PUBLIC GS_DEPRECATED_FUNC( 処理対象のロウキーが格納された変数へのポインタ値。 @ref GSContainer において定義されているコンテナ上のロウキーの型と この引数の型との関係は、@ref gsGetRow の場合と同様です。 - ロウキーに対応するカラムが存在しない場合、もしくは指定のロウオブジェクト内の - キーを用いる場合は@c NULL を指定します。 @param [out] exists 処理対象のロウが存在したかどうかを格納するためのブール型変数へのポインタ値。 実行結果として@ref GS_RESULT_OK 以外が返される場合、 @@ -8604,8 +8750,6 @@ GS_DLL_PUBLIC GS_DEPRECATED_FUNC( The relationship between the type of Row key in Container defined by @ref GSContainer and the type of argument is same as in the case of @ref gsGetRow. - @c NULL should be specified if the column corresponding to Row key is - not existed, or if Row key in specified Row object is used. @param [out] exists the pointer to a BOOL-type variable to store the value which can be used to identify whether the target Row exists or not. @@ -13348,6 +13492,7 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsFetch( -|- INTEGER | int32_t* LONG | int64_t* + BOOL | @ref GSBool* @param [in] valueType オプションの値の型 @return 実行結果のコード番号。次の場合、@ref GS_RESULT_OK 以外の値を返します。 @@ -13376,6 +13521,7 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsFetch( -|- INTEGER | int32_t* LONG | int64_t* + BOOL | @ref GSBool* @param [in] valueType a type of option value @return Return code of the execution result. It returns the value except @@ -16936,7 +17082,7 @@ GS_DLL_PUBLIC GSResult GS_API_CALL gsExperimentalDeleteRowById( @param type 対応関係の定義名。関数名の一部として使用されます。 @param entries - 構造体メンバとカラム定義との対応関係示す以下の定義の列を、 + 構造体メンバとカラム定義との対応関係を示す以下の定義の列を、 「,」で区切らず順に並べます。 - @ref GS_STRUCT_BINDING_NAMED_ELEMENT - @ref GS_STRUCT_BINDING_NAMED_KEY From 1a508f00a44ac533bdf50dc3e765a9bf494db7cc Mon Sep 17 00:00:00 2001 From: knonomura Date: Fri, 22 Mar 2019 14:40:15 +0900 Subject: [PATCH 3/3] change VERSION --- README.md | 2 +- README_ja.md | 2 +- client/c/configure.ac | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5f95373..23c4048 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Library building and program execution are checked in the environment below. OS: CentOS 7.3(x64) GCC: Version 4.8.5 - GridDB server: Version 4.0 CE(Community Edition) + GridDB server: Version 4.1 CE(Community Edition) ## Quick start diff --git a/README_ja.md b/README_ja.md index e172988..887de17 100644 --- a/README_ja.md +++ b/README_ja.md @@ -12,7 +12,7 @@ GridDB C OS: CentOS 7.3(x64) GCC: Version 4.8.5 - GridDB server: Version 4.0 CE(Community Edition) + GridDB server: Version 4.1 CE(Community Edition) ## NCbNX^[g diff --git a/client/c/configure.ac b/client/c/configure.ac index 2e7a294..0b28595 100644 --- a/client/c/configure.ac +++ b/client/c/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ(2.61) AC_INIT AC_CONFIG_AUX_DIR([.]) -AM_INIT_AUTOMAKE(c_client, 4.0.0) +AM_INIT_AUTOMAKE(c_client, 4.1.0) CF_ORG="$CFLAGS" CX_ORG="$CXXFLAGS"