clickhouse.rs icon indicating copy to clipboard operation
clickhouse.rs copied to clipboard

Insert schema validation doesn't work with qualified table names

Open rfairfax opened this issue 2 months ago • 5 comments

Describe the bug

We have a Client instance that talks to tables across more than one database. We use fully qualified table names like mydb.mytable in our inserter usage to support this.

With validation turned on in CH 0.14 it appears it does not handle the qualified name and instead treats the table name as default.mydb.mytable, which causes it to locate an empty schema and fail.

There are some FIXME comments in get_insert_metadata that suggest this isn't fully handled today. Fixing this would remove a point of confusion and enable validation for these cases.

Steps to reproduce

  1. Create a table in a non-default database
  2. Create an inserter with a fully qualified table name
  3. Attempt to insert records

Expected behaviour

Insert succeeds

Error log

Note the error log shows no columns on the table:

While processing struct MyRow: database schema has no column named timestamp.
#### All struct fields:
- timestamp
- field1
#### All schema columns:

Query log

We can see the following query for schema, which is wrong:

SELECT name, type, default_kind FROM system.columns WHERE database = 'default' AND table = 'mydb.mytable'

Configuration

Environment

  • Client version: 0.14
  • OS: macOS

rfairfax avatar Oct 21 '25 15:10 rfairfax

Bump, same bug, want to see fix in next release please

VladTheJunior avatar Nov 24 '25 12:11 VladTheJunior

Is there a reason you can't do the following?

let db_name = "mydb";
let table_name = "some_table";

let mut insert = client
    .with_database(db_name)
    .insert::<Data>(table_name)
    .await
    .unwrap();

slvrtrn avatar Nov 24 '25 15:11 slvrtrn

I can, and now to let my app work I should create 2 clients for 2 different databases instead just one client

VladTheJunior avatar Nov 24 '25 16:11 VladTheJunior

I can, and now to let my app work I should create 2 clients for 2 different databases instead just one client

In the code snippet above, you use the main instance of your client with the db override. There is no need to create two (three, four) separate instances per db, just set the db ad-hoc when you run the insert in a different db.

slvrtrn avatar Nov 24 '25 17:11 slvrtrn

I can, and now to let my app work I should create 2 clients for 2 different databases instead just one client

You can clone the client and set the option on the new instance without affecting the old one. It's relatively cheap, though a few things (like the options map) get deep copied. We can introduce structural sharing (e.g. with a persistent hashmap or copy-on-write) if that's a performance concern.

abonander avatar Nov 24 '25 20:11 abonander