Skip to content

Commit ba3e94f

Browse files
author
longshan.lu
committed
feat: Revamp Makefile for streamlined development workflow and enhance test utilities with new macros and schema handling
1 parent 4f6bcf1 commit ba3e94f

File tree

29 files changed

+894
-179
lines changed

29 files changed

+894
-179
lines changed

Makefile

Lines changed: 173 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,174 @@
1-
check:
2-
cargo check --all-features
1+
# Qurious Makefile
2+
# Simplified development workflow
3+
CARGO = cargo
4+
RUSTFMT = rustfmt
5+
DOCKER = docker
6+
PROJECT_NAME = qurious
7+
TPCH_DATA_DIR = qurious/tests/tpch/data
8+
TPCH_DOCKER_IMAGE = ghcr.io/scalytics/tpch-docker:main
39

4-
make tpch:
5-
mkdir -p qurious/tests/tpch/data
6-
docker run -it -v "$(realpath qurious/tests/tpch/data)":/data ghcr.io/scalytics/tpch-docker:main -vf -s 0.01
10+
# Default target
11+
.PHONY: help
12+
help:
13+
@echo "Qurious Development Tools"
14+
@echo "========================"
15+
@echo ""
16+
@echo "Available commands:"
17+
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
18+
19+
# Code checking
20+
.PHONY: check
21+
check: ## Check code syntax and dependencies
22+
$(CARGO) check --all-features
23+
24+
.PHONY: check-all
25+
check-all: ## Check all workspace members
26+
$(CARGO) check --workspace --all-features
27+
28+
# Build
29+
.PHONY: build
30+
build: ## Build project (debug mode)
31+
$(CARGO) build
32+
33+
.PHONY: build-release
34+
build-release: ## Build project (release mode)
35+
$(CARGO) build --release
36+
37+
.PHONY: build-all
38+
build-all: ## Build all workspace members
39+
$(CARGO) build --workspace
40+
41+
.PHONY: test
42+
test: ## Run unit tests
43+
INCLUDE_TPCH=true $(CARGO) test
44+
45+
# Code formatting
46+
.PHONY: fmt
47+
fmt: ## Check code formatting
48+
$(CARGO) fmt -- --check
49+
50+
.PHONY: fmt-fix
51+
fmt-fix: ## Format code and auto-fix
52+
$(CARGO) fmt
53+
54+
# Code quality
55+
.PHONY: clippy
56+
clippy: ## Run clippy code checks
57+
$(CARGO) clippy --all-features -- -D warnings
58+
59+
.PHONY: clippy-fix
60+
clippy-fix: ## Run clippy and auto-fix
61+
$(CARGO) clippy --fix --all-features
62+
63+
# Clean
64+
.PHONY: clean
65+
clean: ## Clean build artifacts
66+
$(CARGO) clean
67+
68+
.PHONY: clean-all
69+
clean-all: clean ## Clean all build artifacts and temp files
70+
rm -rf target/
71+
find . -name "*.orig" -delete
72+
find . -name "*.rej" -delete
73+
74+
# TPC-H data generation
75+
.PHONY: tpch-data
76+
tpch-data: ## Generate TPC-H test data
77+
mkdir -p $(TPCH_DATA_DIR)
78+
$(DOCKER) run -it -v "$(realpath $(TPCH_DATA_DIR))":/data $(TPCH_DOCKER_IMAGE) -vf -s 0.01
79+
80+
.PHONY: tpch-data-small
81+
tpch-data-small: ## Generate small TPC-H test data
82+
mkdir -p $(TPCH_DATA_DIR)
83+
$(DOCKER) run -it -v "$(realpath $(TPCH_DATA_DIR))":/data $(TPCH_DOCKER_IMAGE) -vf -s 0.001
84+
85+
.PHONY: tpch-data-large
86+
tpch-data-large: ## Generate large TPC-H test data
87+
mkdir -p $(TPCH_DATA_DIR)
88+
$(DOCKER) run -it -v "$(realpath $(TPCH_DATA_DIR))":/data $(TPCH_DOCKER_IMAGE) -vf -s 0.1
89+
90+
# Development workflow
91+
.PHONY: dev-setup
92+
dev-setup: ## Setup development environment
93+
rustup component add rustfmt
94+
rustup component add clippy
95+
$(CARGO) install cargo-watch
96+
97+
.PHONY: dev
98+
dev: ## Development mode: watch files and run tests
99+
cargo watch -x check -x test
100+
101+
.PHONY: dev-test
102+
dev-test: ## Development mode: watch files and run tests
103+
cargo watch -x test
104+
105+
# Documentation
106+
.PHONY: doc
107+
doc: ## Generate documentation
108+
$(CARGO) doc --no-deps
109+
110+
.PHONY: doc-open
111+
doc-open: ## Generate and open documentation
112+
$(CARGO) doc --no-deps --open
113+
114+
# Benchmark
115+
.PHONY: bench
116+
bench: ## Run benchmarks
117+
$(CARGO) bench
118+
119+
# Dependency management
120+
.PHONY: update
121+
update: ## Update dependencies
122+
$(CARGO) update
123+
124+
.PHONY: audit
125+
audit: ## Check dependency security vulnerabilities
126+
$(CARGO) audit
127+
128+
# Release preparation
129+
.PHONY: release-check
130+
release-check: check-all clippy test-all ## Pre-release checks
131+
@echo "All checks passed, ready to release!"
132+
133+
.PHONY: release-build
134+
release-build: ## Build release version
135+
$(CARGO) build --release
136+
@echo "Release build completed: target/release/$(PROJECT_NAME)"
137+
138+
# Database
139+
.PHONY: db-start
140+
db-start: ## Start database services
141+
$(DOCKER) compose up -d
142+
143+
.PHONY: db-stop
144+
db-stop: ## Stop database services
145+
$(DOCKER) compose down
146+
147+
.PHONY: db-reset
148+
db-reset: ## Reset database
149+
$(DOCKER) compose down -v
150+
$(DOCKER) compose up -d
151+
152+
# Utilities
153+
.PHONY: size
154+
size: build-release ## Show binary file size
155+
@echo "Binary file size:"
156+
@ls -lh target/release/$(PROJECT_NAME)
157+
158+
.PHONY: deps-tree
159+
deps-tree: ## Show dependency tree
160+
$(CARGO) tree
161+
162+
.PHONY: outdated
163+
outdated: ## Check outdated dependencies
164+
$(CARGO) install-update -a
165+
166+
# Quick development command combinations
167+
.PHONY: quick-check
168+
quick-check: fmt clippy test ## Quick check: format, clippy, test
169+
170+
.PHONY: full-check
171+
full-check: fmt clippy test-all audit ## Full check: format, clippy, all tests, security audit
172+
173+
# Default goal
174+
.DEFAULT_GOAL := help

qurious/src/common/table_relation.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl TableRelation {
7676
}
7777

7878
/// Return the fully qualified name of the table
79-
pub fn to_quanlify_name(&self) -> String {
79+
pub fn to_qualified_name(&self) -> String {
8080
if self.is_file_source {
8181
let identify = self.identify.as_ref().expect("should have identify");
8282
return format!("tmp_table({})", &identify[..7]);
@@ -96,7 +96,7 @@ impl TableRelation {
9696

9797
impl Display for TableRelation {
9898
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99-
self.to_quanlify_name().fmt(f)
99+
self.to_qualified_name().fmt(f)
100100
}
101101
}
102102

@@ -144,18 +144,18 @@ mod tests {
144144
#[test]
145145
fn test_table_relation() {
146146
let table = TableRelation::from("table".to_string());
147-
assert_eq!(table.to_quanlify_name(), "table");
147+
assert_eq!(table.to_qualified_name(), "table");
148148

149149
let table = TableRelation::from("schema.table".to_string());
150-
assert_eq!(table.to_quanlify_name(), "schema.table");
150+
assert_eq!(table.to_qualified_name(), "schema.table");
151151

152152
let table = TableRelation::from("catalog.schema.table".to_string());
153-
assert_eq!(table.to_quanlify_name(), "catalog.schema.table");
153+
assert_eq!(table.to_qualified_name(), "catalog.schema.table");
154154
}
155155

156156
#[test]
157157
fn test_parse_file_path() {
158158
let table = TableRelation::parse_file_path("./tests/testdata/file/case1.csv");
159-
assert_eq!(table.to_quanlify_name(), "tmp_table(b563e59)");
159+
assert_eq!(table.to_qualified_name(), "tmp_table(b563e59)");
160160
}
161161
}

qurious/src/common/table_schema.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
internal_err,
77
logical::expr::Column,
88
};
9-
use arrow::datatypes::{Field, FieldRef, Schema, SchemaRef};
9+
use arrow::datatypes::{DataType, Field, FieldRef, Schema, SchemaRef};
1010

1111
pub type TableSchemaRef = Arc<TableSchema>;
1212

@@ -73,6 +73,21 @@ impl TableSchema {
7373
.zip(self.schema.fields().iter())
7474
.map(|(q, f)| (q.as_ref(), f))
7575
}
76+
77+
pub fn data_type_and_nullable(&self, relation: Option<&TableRelation>, name: &str) -> Result<(DataType, bool)> {
78+
let index = self
79+
.schema
80+
.index_of(name)
81+
.map_err(|e| Error::InternalError(format!("Field [{}] not found in schema, error: {}", name, e)))?;
82+
83+
if self.field_qualifiers[index].as_ref() != relation {
84+
return internal_err!("Field [{}] is not qualified with [{}]", name, relation.unwrap());
85+
}
86+
87+
let field = self.schema.field(index);
88+
89+
Ok((field.data_type().clone(), field.is_nullable()))
90+
}
7691
}
7792

7893
impl TableSchema {

qurious/src/datatypes/operator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub enum Operator {
88
GtEq,
99
Lt,
1010
LtEq,
11-
11+
1212
And,
1313
Or,
1414

qurious/src/datatypes/scalar.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::error::{Error, Result};
22
use arrow::{
33
array::{
4-
new_null_array, Array, ArrayRef, ArrowPrimitiveType, BooleanArray, Decimal128Array, Decimal256Array, Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array, LargeStringArray, PrimitiveArray, StringArray, UInt16Array, UInt32Array, UInt64Array, UInt8Array
4+
new_null_array, Array, ArrayRef, ArrowPrimitiveType, BooleanArray, Decimal128Array, Decimal256Array,
5+
Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array, LargeStringArray, PrimitiveArray,
6+
StringArray, UInt16Array, UInt32Array, UInt64Array, UInt8Array,
57
},
68
datatypes::{i256, DataType, Field},
79
};

qurious/src/execution/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub mod session;
22

33
mod config;
4+
mod information_schema;
45
mod providers;
5-
mod information_schema;

qurious/src/execution/session.rs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ impl ExecuteSession {
195195
.table(table.table())
196196
.ok_or(Error::InternalError(format!(
197197
"failed to resolve table: {}",
198-
table.to_quanlify_name()
198+
table.to_qualified_name()
199199
)))
200200
}
201201

@@ -204,12 +204,12 @@ impl ExecuteSession {
204204
.catalog(table.catalog().unwrap_or(&self.config.default_catalog))
205205
.ok_or(Error::InternalError(format!(
206206
"failed to resolve catalog: {}",
207-
table.to_quanlify_name()
207+
table.to_qualified_name()
208208
)))?
209209
.schema(table.schema().unwrap_or(&self.config.default_schema))
210210
.ok_or(Error::PlanError(format!(
211211
"failed to resolve schema: {}",
212-
table.to_quanlify_name()
212+
table.to_qualified_name()
213213
)))
214214
}
215215

@@ -237,7 +237,7 @@ impl ExecuteSession {
237237
} else {
238238
Err(Error::PlanError(format!(
239239
"Drop table failed, table not found: {}",
240-
table.to_quanlify_name()
240+
table.to_qualified_name()
241241
)))
242242
}
243243
}
@@ -380,31 +380,54 @@ mod tests {
380380
// session.sql("INSERT INTO test VALUES (1, 1), (2, 2), (3, 3), (3, 5), (NULL, NULL);")?;
381381
// session.sql("select a, b, c, d from x join y on a = c")?;
382382
println!("++++++++++++++");
383-
let batch = session.sql(
384-
"select
385-
l_orderkey,
386-
sum(l_extendedprice * (1 - l_discount)) as revenue,
387-
o_orderdate,
388-
o_shippriority
383+
let batch = session
384+
.sql(
385+
"select
386+
s_acctbal,
387+
s_name,
388+
n_name,
389+
p_partkey,
390+
p_mfgr,
391+
s_address,
392+
s_phone,
393+
s_comment
389394
from
390-
customer,
391-
orders,
392-
lineitem
395+
part,
396+
supplier,
397+
partsupp,
398+
nation,
399+
region
393400
where
394-
c_mktsegment = 'BUILDING'
395-
and c_custkey = o_custkey
396-
and l_orderkey = o_orderkey
397-
and o_orderdate < date '1995-03-15'
398-
and l_shipdate > date '1995-03-15'
399-
group by
400-
l_orderkey,
401-
o_orderdate,
402-
o_shippriority
401+
p_partkey = ps_partkey
402+
and s_suppkey = ps_suppkey
403+
and p_size = 15
404+
and p_type like '%BRASS'
405+
and s_nationkey = n_nationkey
406+
and n_regionkey = r_regionkey
407+
and r_name = 'EUROPE'
408+
and ps_supplycost = (
409+
select
410+
min(ps_supplycost)
411+
from
412+
partsupp,
413+
supplier,
414+
nation,
415+
region
416+
where
417+
p_partkey = ps_partkey
418+
and s_suppkey = ps_suppkey
419+
and s_nationkey = n_nationkey
420+
and n_regionkey = r_regionkey
421+
and r_name = 'EUROPE'
422+
)
403423
order by
404-
revenue desc,
405-
o_orderdate
406-
limit 10;",
407-
)?;
424+
s_acctbal desc,
425+
n_name,
426+
s_name,
427+
p_partkey
428+
limit 10;",
429+
)
430+
.unwrap();
408431

409432
// let batch = session.sql("select avg(l_quantity) as count_order from lineitem")?;
410433

0 commit comments

Comments
 (0)