diff --git a/core/ledger/kvledger/txmgmt/statedb/commontests/test_common.go b/core/ledger/kvledger/txmgmt/statedb/commontests/test_common.go index 93cd6f42fe1..8b056b2ed9d 100644 --- a/core/ledger/kvledger/txmgmt/statedb/commontests/test_common.go +++ b/core/ledger/kvledger/txmgmt/statedb/commontests/test_common.go @@ -208,20 +208,22 @@ func TestQuery(t *testing.T, dbProvider statedb.VersionedDBProvider) { batch.Put("ns1", "key9", []byte(jsonValue9), version.NewHeight(1, 9)) jsonValue10 := "{\"asset_name\": \"marble10\",\"color\": \"green\",\"size\": 10,\"owner\": \"mary\"}" batch.Put("ns1", "key10", []byte(jsonValue10), version.NewHeight(1, 10)) + jsonValue11 := "{\"asset_name\": \"marble11\",\"color\": \"cyan\",\"size\": 1000007,\"owner\": \"joe\"}" + batch.Put("ns1", "key11", []byte(jsonValue11), version.NewHeight(1, 11)) //add keys for a separate namespace - batch.Put("ns2", "key1", []byte(jsonValue1), version.NewHeight(1, 11)) - batch.Put("ns2", "key2", []byte(jsonValue2), version.NewHeight(1, 12)) - batch.Put("ns2", "key3", []byte(jsonValue3), version.NewHeight(1, 13)) - batch.Put("ns2", "key4", []byte(jsonValue4), version.NewHeight(1, 14)) - batch.Put("ns2", "key5", []byte(jsonValue5), version.NewHeight(1, 15)) - batch.Put("ns2", "key6", []byte(jsonValue6), version.NewHeight(1, 16)) - batch.Put("ns2", "key7", []byte(jsonValue7), version.NewHeight(1, 17)) - batch.Put("ns2", "key8", []byte(jsonValue8), version.NewHeight(1, 18)) - batch.Put("ns2", "key9", []byte(jsonValue9), version.NewHeight(1, 19)) - batch.Put("ns2", "key10", []byte(jsonValue10), version.NewHeight(1, 20)) - - savePoint := version.NewHeight(2, 21) + batch.Put("ns2", "key1", []byte(jsonValue1), version.NewHeight(1, 12)) + batch.Put("ns2", "key2", []byte(jsonValue2), version.NewHeight(1, 13)) + batch.Put("ns2", "key3", []byte(jsonValue3), version.NewHeight(1, 14)) + batch.Put("ns2", "key4", []byte(jsonValue4), version.NewHeight(1, 15)) + batch.Put("ns2", "key5", []byte(jsonValue5), version.NewHeight(1, 16)) + batch.Put("ns2", "key6", []byte(jsonValue6), version.NewHeight(1, 17)) + batch.Put("ns2", "key7", []byte(jsonValue7), version.NewHeight(1, 18)) + batch.Put("ns2", "key8", []byte(jsonValue8), version.NewHeight(1, 19)) + batch.Put("ns2", "key9", []byte(jsonValue9), version.NewHeight(1, 20)) + batch.Put("ns2", "key10", []byte(jsonValue10), version.NewHeight(1, 21)) + + savePoint := version.NewHeight(2, 22) db.ApplyUpdates(batch, savePoint) // query for owner=jerry, use namespace "ns1" @@ -435,4 +437,25 @@ func TestQuery(t *testing.T, dbProvider statedb.VersionedDBProvider) { testutil.AssertNoError(t, err, "") testutil.AssertNil(t, queryResult1) + // query with integer with digit-count equals 7 and response received is also received + // with same digit-count and there is no float transformation + itr, err = db.ExecuteQuery("ns1", "{\"selector\":{\"$and\":[{\"size\":{\"$eq\": 1000007}}]}}") + testutil.AssertNoError(t, err, "") + + // verify one jerry result + queryResult1, err = itr.Next() + testutil.AssertNoError(t, err, "") + testutil.AssertNotNil(t, queryResult1) + versionedQueryRecord = queryResult1.(*statedb.VersionedQueryRecord) + stringRecord = string(versionedQueryRecord.Record) + bFoundRecord = strings.Contains(stringRecord, "joe") + testutil.AssertEquals(t, bFoundRecord, true) + bFoundRecord = strings.Contains(stringRecord, "1000007") + testutil.AssertEquals(t, bFoundRecord, true) + + // verify no more results + queryResult2, err = itr.Next() + testutil.AssertNoError(t, err, "") + testutil.AssertNil(t, queryResult2) + } diff --git a/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper.go b/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper.go index d03a8f65d9a..8cea9aa11cd 100644 --- a/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper.go +++ b/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper.go @@ -17,6 +17,7 @@ limitations under the License. package statecouchdb import ( + "bytes" "encoding/json" "fmt" "reflect" @@ -66,7 +67,9 @@ func ApplyQueryWrapper(namespace, queryString string, queryLimit, querySkip int) jsonQueryMap := make(map[string]interface{}) //unmarshal the selected json into the generic map - err := json.Unmarshal([]byte(queryString), &jsonQueryMap) + decoder := json.NewDecoder(bytes.NewBuffer([]byte(queryString))) + decoder.UseNumber() + err := decoder.Decode(&jsonQueryMap) if err != nil { return "", err } @@ -167,6 +170,10 @@ func processAndWrapQuery(jsonQueryMap map[string]interface{}) { //intercept the float64 case and prevent the []interface{} case from //incorrectly processing the float64 + case json.Number: + //intercept the Number case and prevent the []interface{} case from + //incorrectly processing the float64 + //if the type is an array, then iterate through the items case []interface{}: diff --git a/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper_test.go b/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper_test.go index aee0744feeb..fd4f0dc3335 100644 --- a/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper_test.go +++ b/core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper_test.go @@ -366,3 +366,18 @@ func TestQueryWithUseDesignDocAndIndexName(t *testing.T) { testutil.AssertEquals(t, strings.Count(wrappedQuery, "\"use_index\":[\"_design/testDoc\",\"testIndexName\"]"), 1) } + +//TestQueryWithLargeInteger tests query with large integer +func TestQueryWithLargeInteger(t *testing.T) { + + rawQuery := []byte(`{"selector":{"$and":[{"size":{"$eq": 1000007}}]}}`) + + wrappedQuery, err := ApplyQueryWrapper("ns1", string(rawQuery), 10000, 0) + + //Make sure the query did not throw an exception + testutil.AssertNoError(t, err, "Unexpected error thrown when for query JSON") + + //check to make sure the default selector is added + testutil.AssertEquals(t, strings.Count(wrappedQuery, "{\"$eq\":1000007}"), 1) + +} diff --git a/core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb.go b/core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb.go index 07748b7fd75..f7764c9dc1a 100644 --- a/core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb.go +++ b/core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb.go @@ -144,7 +144,9 @@ func removeDataWrapper(wrappedValue []byte, attachments []couchdb.Attachment) ([ jsonResult := make(map[string]interface{}) //unmarshal the selected json into the generic map - json.Unmarshal(wrappedValue, &jsonResult) + decoder := json.NewDecoder(bytes.NewBuffer(wrappedValue)) + decoder.UseNumber() + _ = decoder.Decode(&jsonResult) // handle binary or json data if jsonResult[dataWrapper] == nil && attachments != nil { // binary attachment diff --git a/core/ledger/util/couchdb/couchdb.go b/core/ledger/util/couchdb/couchdb.go index c46d2338f87..6d95d0ceafd 100644 --- a/core/ledger/util/couchdb/couchdb.go +++ b/core/ledger/util/couchdb/couchdb.go @@ -504,8 +504,11 @@ func createAttachmentPart(couchDoc *CouchDoc, defaultBoundary string) (bytes.Buf //create a generic map genericMap := make(map[string]interface{}) + //unmarshal the data into the generic map - json.Unmarshal(couchDoc.JSONValue, &genericMap) + decoder := json.NewDecoder(bytes.NewBuffer(couchDoc.JSONValue)) + decoder.UseNumber() + decoder.Decode(&genericMap) //add all key/values to the attachmentJSONMap for jsonKey, jsonValue := range genericMap {