Repository navigation
Conversation
Signed-off-by: Martin Tzvetanov Grigorov <mgrigorov@apache.org>
…t wait for cluster
…ategy This way they are applicable for Scylla too
Removed 'libsqliteodbc' from ODBC & Sqlite installation commands. Signed-off-by: Martin Grigorov <martin-g@users.noreply.github.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note: This PR is based on top of #753
Add a Cassandra table provider
Adds
datafusion-table-providers-cassandra, a DataFusionTableProviderfor Apache Cassandra. It is built on the ScyllaDB Rust driver (scylla1.9), so it also works with ScyllaDB. The crate is exposed fromdatafusion-table-providersbehind the newcassandrafeature.Features
Connection pool (
CassandraConnectionPool)Session, which manages its own connections.CassandraConnectionis a cheap handle to it.hosts: comma-separated contact points, optionally ashost:port.hostis accepted as an alias.port: defaults to9042.keyspace: the keyspace unqualified table names are resolved in.user/passwordlocal_datacenter: the datacenter to prefer when routing requests.connection_timeout_msCassandraConnectionPool::from_sessionbuilds a pool from an existing driver session.TableReference -> SchemaRefmap, which skips schema inference.schemas()) and tables (tables()) fromsystem_schema.UndefinedTableerror.Reading (
CassandraTableFactory::table_provider)SELECT *, so no table data is read to infer it.tableorkeyspace.table. Identifiers are always quoted.CassandraExec. The results are streamed from Cassandra's pages and converted to Arrow record batches.EXPLAINshows the CQL that is run, e.g.CassandraExec cql=SELECT "name" FROM "ks"."users" WHERE "id" IN (1, 3) LIMIT 10.Pushdown
CQL has no joins or aggregations, and without
ALLOW FILTERINGit can only filter on key columns. So only these are pushed down to Cassandra:SELECT count(*)selects a single key column.LIMIT.LIMIT 0doesn't query Cassandra at all.WHEREclause. These are reported asTableProviderFilterPushDown::Exact:=orINon every partition key column. A shortINlist that DataFusion rewrote toa = 1 OR a = 2is also accepted.=on the leading clustering columns, and optionally a range (<,<=,>,>=) on the next one.uuid/timeuuidsupport only=, with the canonical lowercase value.asciicolumn, are left to DataFusion.Unsupportedand evaluated by DataFusion: non-key columns, partial partition keys,!=,NOT IN, duplicate restrictions on the same column.scan()receives filters that together don't form a validWHEREclause, it checks them again. DataFusion decides on filters separately in each optimizer pass, so this can happen. The filters that can't be pushed down are applied by aFilterExecover the scan.Type mapping
ascii,text/varcharUtf8tinyint,smallint,int,bigint,counterInt8,Int16,Int32,Int64float,doubleFloat32,Float64booleanBooleanblobBinarydateDate32timeTime64(Nanosecond)timestampTimestamp(Millisecond, "UTC")durationInterval(MonthDayNano)decimal,varint,uuid,timeuuid,inetUtf8(no exact Arrow equivalent)list<T>,set<T>Listmap<K, V>Mapvector<T, n>FixedSizeListtuple<...>, user-defined typesStructAll fields are nullable, because Cassandra returns
nullfor any regular column without a value.Writing (
CassandraTableFactory::read_write_table_provider)INSERT INTOruns a prepared CQLINSERTper row, with up to 64 statements in flight. As in CQL, inserting a row whose primary key already exists replaces that row (an upsert).INSERT OVERWRITEtruncates the table first. The truncation happens only after theINSERTwas prepared successfully, so an invalid insert leaves the table untouched.FixedSizeBinary(16).countercolumns are rejected, because they can only be changed withUPDATE.Federation (
federationfeature, enabled by default)CassandraTableimplementsSQLExecutor, andtable_provider()returns aFederatedTableProviderAdaptor.LIMIT, and DataFusion evaluates the rest.JoinPushDown::Disallow).Testing
core/tests/cassandra) cover:FilterExecfallbackcount(*)andEXPLAININSERT INTO/INSERT OVERWRITEcassandra:5.0by default. SetCASSANDRA_DOCKER_IMAGEto use another image. ScyllaDB images (scylladb/scylla) are configured through entrypoint arguments instead of environment variables. The test container starts as a single node that doesn't wait for gossip.cassandra:5.0runs in the integration-test jobScyllaDB Integration Testsjob runs the same tests againstscylladb/scylla:2026.3.3cargo run -p datafusion-table-providers --example cassandra --features cassandra) and a README section.🤖 Generated with Claude Code