Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions .github/workflows/cppcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# 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.

name: Cppcheck

on:
push:
branches:
- develop
- iotdb
- rc/*
paths:
- '.github/workflows/cppcheck.yml'
- '.mvn/**'
- 'cpp/**'
- 'mvnw'
- 'pom.xml'
pull_request:
branches:
- develop
- dev/*
- iotdb
- rc/*
paths:
- '.github/workflows/cppcheck.yml'
- '.mvn/**'
- 'cpp/**'
- 'mvnw'
- 'pom.xml'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
CPPCHECK_VERSION: 2.17.1
CPPCHECK_SOURCE_SHA256: bfd681868248ec03855ca7c2aea7bcb1f39b8b18860d76aec805a92a967b966c
MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}

jobs:
cppcheck:
runs-on: ubuntu-24.04
timeout-minutes: 30

steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Set up JDK 17
uses: actions/setup-java@v5.6.0
with:
distribution: corretto
java-version: 17

- name: Cache Maven packages
uses: actions/cache@v6
with:
path: ~/.m2
key: ${{ runner.os }}-m2-cppcheck-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2-

- name: Cache Cppcheck
uses: actions/cache@v6
with:
path: ~/.cache/cppcheck/${{ env.CPPCHECK_VERSION }}
key: cppcheck-${{ runner.os }}-${{ runner.arch }}-${{ env.CPPCHECK_VERSION }}-${{ env.CPPCHECK_SOURCE_SHA256 }}

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y uuid-dev

- name: Install Cppcheck
shell: bash
run: |
set -euo pipefail

cppcheck_home="${HOME}/.cache/cppcheck/${CPPCHECK_VERSION}"
if [[ ! -x "${cppcheck_home}/bin/cppcheck" ]]; then
build_root="$(mktemp -d)"
archive="${build_root}/cppcheck.tar.gz"
source_dir="${build_root}/source"
build_dir="${build_root}/build"

mkdir -p "${source_dir}" "${build_dir}" "${cppcheck_home}"
curl --fail --location --retry 3 \
"https://github.com/cppcheck-opensource/cppcheck/archive/refs/tags/${CPPCHECK_VERSION}.tar.gz" \
--output "${archive}"
echo "${CPPCHECK_SOURCE_SHA256} ${archive}" | sha256sum --check -
tar -xzf "${archive}" --strip-components=1 -C "${source_dir}"

cmake -S "${source_dir}" -B "${build_dir}" \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_MATCHCOMPILER=ON \
-DBUILD_GUI=OFF \
-DBUILD_TESTS=OFF \
-DCMAKE_INSTALL_PREFIX="${cppcheck_home}"
cmake --build "${build_dir}" --parallel "$(nproc)"
cmake --install "${build_dir}"
fi

echo "${cppcheck_home}/bin" >> "${GITHUB_PATH}"
"${cppcheck_home}/bin/cppcheck" --version

- name: Generate compilation database with Maven
run: |
./mvnw -P with-cpp,with-cppcheck -pl cpp \
-Dbuild.test=OFF \
cmake:generate@cmake-generate-test-compile
test -s cpp/target/build/compile_commands.json

- name: Run Cppcheck
shell: bash
run: |
mkdir -p cpp/target/cppcheck

set +e
cppcheck \
--project=cpp/target/build/compile_commands.json \
--file-filter='*cpp/src/*' \
--file-filter='*cpp/tools/*' \
--file-filter='*cpp/examples/*' \
--enable=warning,performance,portability \
--check-level=exhaustive \
--inline-suppr \
--suppress=missingIncludeSystem \
--suppress=unusedFunction \
--suppress='*:*/third_party/*' \
--suppress='*:*/target/*' \
--suppress='*:*/parser/generated/*' \
--error-exitcode=2 \
--template=gcc \
--output-file=cpp/target/cppcheck/cppcheck.txt \
--quiet \
-j "$(nproc)"
cppcheck_status=$?
set -e

cat cpp/target/cppcheck/cppcheck.txt
exit "${cppcheck_status}"

- name: Upload Cppcheck report
if: always()
uses: actions/upload-artifact@v7
with:
name: cppcheck-report
path: cpp/target/cppcheck/cppcheck.txt
if-no-files-found: ignore
105 changes: 76 additions & 29 deletions cpp/examples/c_examples/demo_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,69 @@ static char* duplicate_string(const char* src) {
return dst;
}

static ERRNO cleanup_write_tsfile_resources(WriteFile* file,
TsFileWriter writer, Tablet* tablet,
TableSchema* table_schema,
ERRNO code) {
if (*tablet != NULL) {
free_tablet(tablet);
}

if (writer != NULL) {
ERRNO close_code = tsfile_writer_close(writer);
if (code == RET_OK) {
code = close_code;
}
}

if (table_schema->table_name != NULL ||
table_schema->column_schemas != NULL) {
free_table_schema(*table_schema);
}

if (*file != NULL) {
free_write_file(file);
}

if (code != RET_OK) {
printf("get err no: %d", code);
}
return code;
}

// This example shows you how to write tsfile.
ERRNO write_tsfile() {
ERRNO code = 0;
WriteFile file = NULL;
TsFileWriter writer = NULL;
Tablet tablet = NULL;
TableSchema table_schema = {0};

code = set_global_compression(TS_COMPRESSION_LZ4);
if (code != RET_OK) {
return code;
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, code);
}
code = set_datatype_encoding(TS_DATATYPE_INT32, TS_ENCODING_TS_2DIFF);
if (code != RET_OK) {
return code;
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, code);
}
char* table_name = "table1";

// Create table schema to describe a table in a tsfile.
TableSchema table_schema;
table_schema.table_name = duplicate_string(table_name);
table_schema.column_num = 3;
if (table_schema.table_name == NULL) {
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, RET_OOM);
}
table_schema.column_schemas =
(ColumnSchema*)malloc(sizeof(ColumnSchema) * 3);
(ColumnSchema*)calloc(3, sizeof(ColumnSchema));
if (table_schema.column_schemas == NULL) {
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, RET_OOM);
}
table_schema.column_num = 3;
table_schema.column_schemas[0] =
(ColumnSchema){.column_name = duplicate_string("id1"),
.data_type = TS_DATATYPE_STRING,
Expand All @@ -64,22 +108,37 @@ ERRNO write_tsfile() {
(ColumnSchema){.column_name = duplicate_string("s1"),
.data_type = TS_DATATYPE_INT32,
.column_category = FIELD};
if (table_schema.column_schemas[0].column_name == NULL ||
table_schema.column_schemas[1].column_name == NULL ||
table_schema.column_schemas[2].column_name == NULL) {
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, RET_OOM);
}

remove("test_c.tsfile");
// Create a file with specify path to write tsfile.
WriteFile file = write_file_new("test_c.tsfile", &code);
HANDLE_ERROR(code);
file = write_file_new("test_c.tsfile", &code);
if (code != RET_OK) {
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, code);
}

// Create tsfile writer with specify table schema.
TsFileWriter writer = tsfile_writer_new(file, &table_schema, &code);
HANDLE_ERROR(code);
writer = tsfile_writer_new(file, &table_schema, &code);
if (code != RET_OK) {
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, code);
}

// Create tablet to insert data.
Tablet tablet =
tablet_new((char*[]){"id1", "id2", "s1"},
(TSDataType[]){TS_DATATYPE_STRING, TS_DATATYPE_STRING,
TS_DATATYPE_INT32},
3, 5);
tablet = tablet_new((char*[]){"id1", "id2", "s1"},
(TSDataType[]){TS_DATATYPE_STRING, TS_DATATYPE_STRING,
TS_DATATYPE_INT32},
3, 5);
if (tablet == NULL) {
return cleanup_write_tsfile_resources(&file, writer, &tablet,
&table_schema, RET_OOM);
}

for (int row = 0; row < 5; row++) {
Timestamp timestamp = row;
Expand All @@ -92,19 +151,7 @@ ERRNO write_tsfile() {
}

// Write tablet data.
HANDLE_ERROR(tsfile_writer_write(writer, tablet));

// Free tablet.
free_tablet(&tablet);

// Free table schema we used before.
free_table_schema(table_schema);

// Close writer.
HANDLE_ERROR(tsfile_writer_close(writer));

// Close write file after closing writer.
free_write_file(&file);

return 0;
code = tsfile_writer_write(writer, tablet);
return cleanup_write_tsfile_resources(&file, writer, &tablet, &table_schema,
code);
}
26 changes: 26 additions & 0 deletions cpp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,32 @@
</plugins>
</build>
</profile>
<!--
Generate compile_commands.json for the standalone Cppcheck CI job.
This profile only changes the CMake configure step; it does not run
Cppcheck or add static analysis to normal C++ builds.
-->
<profile>
<id>with-cppcheck</id>
<build>
<plugins>
<plugin>
<groupId>com.googlecode.cmake-maven-project</groupId>
<artifactId>cmake-maven-plugin</artifactId>
<executions>
<execution>
<id>cmake-generate-test-compile</id>
<configuration>
<options combine.children="append">
<option>-DCMAKE_EXPORT_COMPILE_COMMANDS=ON</option>
</options>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>.java-9-and-above</id>
<activation>
Expand Down
5 changes: 2 additions & 3 deletions cpp/src/common/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ struct Path {

Path(std::string& device, std::string& measurement)
: measurement_(measurement),
device_id_(std::make_shared<StringArrayDeviceID>(device)) {
full_path_ = device + "." + measurement;
}
device_id_(std::make_shared<StringArrayDeviceID>(device)),
full_path_(device + "." + measurement) {}

Path(const std::string& path_sc, bool if_split = true) {
if (!path_sc.empty()) {
Expand Down
11 changes: 7 additions & 4 deletions cpp/src/common/row_record.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,24 +188,27 @@ FORCE_INLINE Field* make_null_literal() {

class RowRecord {
public:
explicit RowRecord(uint32_t col_num) : col_num_(col_num) {
fields_ = new std::vector<Field*>();
explicit RowRecord(uint32_t col_num)
: time_(0), col_num_(col_num), fields_(new std::vector<Field*>()) {
fields_->reserve(col_num);
for (uint32_t i = 0; i < col_num; ++i) {
Field* val = make_null_literal();
fields_->push_back(val);
}
}

RowRecord(int64_t time, uint32_t col_num) : time_(time), col_num_(col_num) {
fields_ = new std::vector<Field*>();
RowRecord(int64_t time, uint32_t col_num)
: time_(time), col_num_(col_num), fields_(new std::vector<Field*>()) {
fields_->reserve(col_num_);
for (uint32_t i = 0; i < col_num_; ++i) {
Field* val = make_null_literal();
fields_->push_back(val);
}
}

RowRecord(const RowRecord&) = delete;
RowRecord& operator=(const RowRecord&) = delete;

~RowRecord() {
if (fields_) {
int size = fields_->size();
Expand Down
Loading
Loading