| /** | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| */ | |
| #include "catch.hpp" | |
| #include "Session.h" | |
| #include <memory> | |
| #include <vector> | |
| using namespace std; | |
| TEST_CASE("Session query rejects states without an open connection", "[utils]") { | |
| SECTION("before open") { | |
| Session session("127.0.0.1", 6667); | |
| REQUIRE_THROWS_AS(session.executeQueryStatement("SHOW VERSION"), IoTDBConnectionException); | |
| } | |
| SECTION("after failed open") { | |
| Session session("127.0.0.1", 1); | |
| REQUIRE_THROWS_AS(session.open(), IoTDBException); | |
| REQUIRE_THROWS_AS(session.executeQueryStatement("SHOW VERSION"), IoTDBConnectionException); | |
| } | |
| } | |
| TEST_CASE("SessionUtils filterNullColumns keeps only non-null FIELD columns", "[utils]") { | |
| vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32}, | |
| {"s2", TSDataType::INT64}, | |
| {"s3", TSDataType::FLOAT}, | |
| {"s4", TSDataType::DOUBLE}, | |
| {"s5", TSDataType::BOOLEAN}}; | |
| Tablet tablet("root.sg.d1", schemas, 1); | |
| tablet.timestamps[0] = 1000L; | |
| tablet.rowSize = 1; | |
| tablet.addValue("s1", 0, 1); | |
| tablet.addValue("s3", 0, 1.5f); | |
| tablet.bitMaps[1].mark(0); | |
| tablet.bitMaps[3].mark(0); | |
| tablet.bitMaps[4].mark(0); | |
| std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet); | |
| REQUIRE(filtered != nullptr); | |
| REQUIRE(filtered.get() != &tablet); | |
| REQUIRE(filtered.use_count() == 1); | |
| REQUIRE(filtered->schemas.size() == 2); | |
| REQUIRE(filtered->schemas[0].first == "s1"); | |
| REQUIRE(filtered->schemas[1].first == "s3"); | |
| REQUIRE(((int*)filtered->values[0])[0] == 1); | |
| REQUIRE(((float*)filtered->values[1])[0] == Approx(1.5f)); | |
| } | |
| TEST_CASE("SessionUtils filterNullColumns returns original when nothing to drop", "[utils]") { | |
| vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32}}; | |
| Tablet tablet("root.sg.d1", schemas, 1); | |
| tablet.timestamps[0] = 1L; | |
| tablet.rowSize = 1; | |
| tablet.addValue("s1", 0, 1); | |
| std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet); | |
| REQUIRE(filtered.get() == &tablet); | |
| } | |
| TEST_CASE( | |
| "SessionUtils filterNullColumns returns nullptr when tree-model FIELD columns are all null", | |
| "[utils]") { | |
| vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32}, | |
| {"s2", TSDataType::INT64}}; | |
| Tablet tablet("root.sg.d1", schemas, 1); | |
| tablet.timestamps[0] = 2000L; | |
| tablet.rowSize = 1; | |
| tablet.bitMaps[0].mark(0); | |
| tablet.bitMaps[1].mark(0); | |
| std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet); | |
| REQUIRE(filtered == nullptr); | |
| } | |
| TEST_CASE("SessionUtils filterNullColumns keeps TAG when table-model FIELD columns are all null", | |
| "[utils]") { | |
| vector<pair<string, TSDataType::TSDataType>> schemas = { | |
| {"tag1", TSDataType::TEXT}, {"s1", TSDataType::INT32}, {"s2", TSDataType::INT64}}; | |
| vector<ColumnCategory> columnTypes = {ColumnCategory::TAG, ColumnCategory::FIELD, | |
| ColumnCategory::FIELD}; | |
| Tablet tablet("table1", schemas, columnTypes, 1); | |
| tablet.timestamps[0] = 3000L; | |
| tablet.rowSize = 1; | |
| tablet.addValue("tag1", 0, string("d1")); | |
| tablet.bitMaps[1].mark(0); | |
| tablet.bitMaps[2].mark(0); | |
| std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet); | |
| REQUIRE(filtered != nullptr); | |
| REQUIRE(filtered.get() != &tablet); | |
| REQUIRE(filtered->schemas.size() == 1); | |
| REQUIRE(filtered->schemas[0].first == "tag1"); | |
| REQUIRE(filtered->columnTypes.size() == 1); | |
| REQUIRE(filtered->columnTypes[0] == ColumnCategory::TAG); | |
| } | |
| TEST_CASE("SessionUtils filterNullColumns checks active rows when bitmap is maxRowNumber-sized", | |
| "[utils]") { | |
| vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32}, | |
| {"s2", TSDataType::INT64}}; | |
| Tablet tablet("root.sg.d1", schemas, 10); | |
| tablet.timestamps[0] = 1000L; | |
| tablet.rowSize = 1; | |
| tablet.addValue("s1", 0, 1); | |
| tablet.bitMaps[1].mark(0); | |
| std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet); | |
| REQUIRE(filtered != nullptr); | |
| REQUIRE(filtered->schemas.size() == 1); | |
| REQUIRE(filtered->schemas[0].first == "s1"); | |
| } | |
| TEST_CASE("BitMap isRangeAllMarked matches per-bit scan and rejects OOB", "[utils]") { | |
| BitMap bitMap(20); | |
| for (size_t i = 0; i < 20; i++) { | |
| if (i % 4 != 2) { | |
| bitMap.mark(i); | |
| } | |
| } | |
| for (size_t start = 0; start <= 20; start++) { | |
| for (size_t length = 0; length <= 20 - start; length++) { | |
| bool allMarked = true; | |
| for (size_t i = start; i < start + length; i++) { | |
| allMarked = allMarked && bitMap.isMarked(i); | |
| } | |
| REQUIRE(bitMap.isRangeAllMarked(start, length) == allMarked); | |
| } | |
| } | |
| REQUIRE(bitMap.isRangeAllMarked(0, 0)); | |
| REQUIRE_FALSE(bitMap.isRangeAllMarked(0, 21)); | |
| REQUIRE_FALSE(bitMap.isRangeAllMarked(21, 0)); | |
| BitMap empty; | |
| REQUIRE(empty.isAllMarked()); | |
| BitMap full(8); | |
| full.markAll(); | |
| REQUIRE(full.isAllMarked()); | |
| full.unmark(7); | |
| REQUIRE_FALSE(full.isAllMarked()); | |
| REQUIRE(full.isRangeAllMarked(0, 7)); | |
| } |