Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
- Do not use cat, hexdump, perl, or sed. Always edit files directly.
- If attempting to use Cargo, use `nix-shell --command 'cargo ...'`
- If attempting to use Cargo, use `nix-shell --command 'cargo ...'`
- Public API specs live in sdks/api/fern/
- When modifying sdks/api/fern/, run ./scripts/fern/gen.sh to regenerate the related libraries
93 changes: 26 additions & 67 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/common/clickhouse-user-query/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors.workspace = true
license.workspace = true

[dependencies]
clickhouse = "0.12"
clickhouse = "0.11.2"
thiserror = "1.0"
serde = { version = "1.0", features = ["derive"] }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use clickhouse_user_query::*;

fn main() {
// Create a schema with string properties
let schema = Schema::new(vec![
Property::new("username".to_string(), false, PropertyType::String).unwrap(),
Property::new("email".to_string(), false, PropertyType::String).unwrap(),
Property::new("tags".to_string(), true, PropertyType::String).unwrap(),
])
.unwrap();

println!("=== Case Sensitivity Demo ===\n");

// Example 1: Case-sensitive string equality
println!("1. Case-sensitive equality:");
let query1 = QueryExpr::StringEqual {
property: "username".to_string(),
map_key: None,
value: "JohnDoe".to_string(),
case_sensitive: true,
};
let builder1 = UserDefinedQueryBuilder::new(&schema, &query1).unwrap();
println!(" Query: {}", builder1.where_expr());
println!(" -> Will match: 'JohnDoe'");
println!(" -> Won't match: 'johndoe', 'JOHNDOE'\n");

// Example 2: Case-insensitive string equality
println!("2. Case-insensitive equality:");
let query2 = QueryExpr::StringEqual {
property: "username".to_string(),
map_key: None,
value: "JohnDoe".to_string(),
case_sensitive: false,
};
let builder2 = UserDefinedQueryBuilder::new(&schema, &query2).unwrap();
println!(" Query: {}", builder2.where_expr());
println!(" -> Will match: 'JohnDoe', 'johndoe', 'JOHNDOE', 'jOhNdOe'\n");

// Example 3: Case-sensitive regex matching
println!("3. Case-sensitive regex:");
let query3 = QueryExpr::StringMatchRegex {
property: "email".to_string(),
map_key: None,
pattern: "^[A-Z].*@example\\.com$".to_string(),
case_sensitive: true,
};
let builder3 = UserDefinedQueryBuilder::new(&schema, &query3).unwrap();
println!(" Query: {}", builder3.where_expr());
println!(" Pattern: ^[A-Z].*@example\\.com$");
println!(" -> Will match: 'Admin@example.com'");
println!(" -> Won't match: 'admin@example.com'\n");

// Example 4: Case-insensitive regex matching
println!("4. Case-insensitive regex:");
let query4 = QueryExpr::StringMatchRegex {
property: "email".to_string(),
map_key: None,
pattern: "admin|support".to_string(),
case_sensitive: false,
};
let builder4 = UserDefinedQueryBuilder::new(&schema, &query4).unwrap();
println!(" Query: {}", builder4.where_expr());
println!(" Pattern: admin|support (with (?i) prefix)");
println!(" -> Will match: 'admin@test.com', 'ADMIN@test.com', 'Support@test.com'\n");

// Example 5: Case-insensitive IN clause
println!("5. Case-insensitive IN clause:");
let query5 = QueryExpr::StringIn {
property: "username".to_string(),
map_key: None,
values: vec!["Admin".to_string(), "Support".to_string()],
case_sensitive: false,
};
let builder5 = UserDefinedQueryBuilder::new(&schema, &query5).unwrap();
println!(" Query: {}", builder5.where_expr());
println!(" -> Will match: 'admin', 'ADMIN', 'support', 'SUPPORT'\n");

// Example 6: Complex query with mixed case sensitivity
println!("6. Complex query with mixed sensitivity:");
let query6 = QueryExpr::And {
exprs: vec![
QueryExpr::StringEqual {
property: "username".to_string(),
map_key: None,
value: "Admin".to_string(),
case_sensitive: false, // Case-insensitive username
},
QueryExpr::StringMatchRegex {
property: "tags".to_string(),
map_key: Some("role".to_string()),
pattern: "^(Admin|Manager)$".to_string(),
case_sensitive: true, // Case-sensitive role
},
],
};
let builder6 = UserDefinedQueryBuilder::new(&schema, &query6).unwrap();
println!(" Query: {}", builder6.where_expr());
println!(" -> Username matches 'admin' (any case)");
println!(" -> Role must be exactly 'Admin' or 'Manager' (case-sensitive)");
}
50 changes: 50 additions & 0 deletions packages/common/clickhouse-user-query/examples/group_by_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use clickhouse_user_query::*;

fn main() {
// Define a schema with properties that can be grouped by
let schema = Schema::new(vec![
Property::new("datacenter_id".to_string(), false, PropertyType::String)
.unwrap()
.with_group_by(true),
Property::new("tags".to_string(), true, PropertyType::String)
.unwrap()
.with_group_by(true),
Property::new("cpu_millicores".to_string(), false, PropertyType::Number)
.unwrap()
.with_group_by(false),
])
.unwrap();

// Example 1: Group by simple property
let query_expr = QueryExpr::NumberGreater {
property: "cpu_millicores".to_string(),
map_key: None,
value: 1000.0,
};

let key_path = KeyPath::new("datacenter_id".to_string());
let builder =
UserDefinedQueryBuilder::new_with_group_by(&schema, &query_expr, Some(&key_path)).unwrap();

println!("Simple property GROUP BY:");
println!("WHERE clause: {}", builder.where_expr());
println!("GROUP BY clause: {:?}", builder.group_by_expr());
println!();

// Example 2: Group by map property with key
let key_path = KeyPath::with_map_key("tags".to_string(), "region".to_string());
let builder =
UserDefinedQueryBuilder::new_with_group_by(&schema, &query_expr, Some(&key_path)).unwrap();

println!("Map property with key GROUP BY:");
println!("WHERE clause: {}", builder.where_expr());
println!("GROUP BY clause: {:?}", builder.group_by_expr());
println!();

// Example 3: No group by
let builder = UserDefinedQueryBuilder::new_with_group_by(&schema, &query_expr, None).unwrap();

println!("No GROUP BY:");
println!("WHERE clause: {}", builder.where_expr());
println!("GROUP BY clause: {:?}", builder.group_by_expr());
}
Loading
Loading