Skip to content
Open
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ build-qc-wasm: build-qc-wasm-fast build-qc-wasm-small

build-qc-gz-%: build-qc-wasm-%
@cd query-compiler/query-compiler-wasm/pkg && \
for provider in postgresql mysql sqlite sqlserver cockroachdb; do \
for provider in postgresql mysql sqlite sqlserver cockroachdb surrealdb; do \
gzip -knc $$provider/query_compiler_$*_bg.wasm > $${provider}_$*.gz; \
done;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Expand Down Expand Up @@ -436,7 +436,7 @@ measure-qc-wasm: measure-qc-wasm-fast measure-qc-wasm-small

measure-qc-wasm-%: build-qc-gz-%
@cd query-compiler/query-compiler-wasm/pkg; \
for provider in postgresql mysql sqlite sqlserver cockroachdb; do \
for provider in postgresql mysql sqlite sqlserver cockroachdb surrealdb; do \
echo "$${provider}_$*_qc_size=$$(cat $$provider/query_compiler_$*_bg.wasm | wc -c | tr -d ' ')" >> $(ENGINE_SIZE_OUTPUT); \
echo "$${provider}_$*_qc_size_gz=$$(cat $${provider}_$*.gz | wc -c | tr -d ' ')" >> $(ENGINE_SIZE_OUTPUT); \
done;
Expand Down
1 change: 1 addition & 0 deletions psl/psl-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mysql = []
cockroachdb = ["postgresql"]
mssql = []
mongodb = []
surrealdb = []

[dependencies]
diagnostics.workspace = true
Expand Down
7 changes: 7 additions & 0 deletions psl/psl-core/src/builtin_connectors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ mod native_type_definition;
mod postgres_datamodel_connector;
#[cfg(feature = "sqlite")]
mod sqlite_datamodel_connector;
#[cfg(feature = "surrealdb")]
mod surrealdb_datamodel_connector;
mod utils;
pub use capabilities_support::{can_have_capability, can_support_relation_load_strategy, has_capability};

Expand All @@ -47,6 +49,9 @@ pub const MSSQL: &'static dyn crate::datamodel_connector::Connector =
&mssql_datamodel_connector::MsSqlDatamodelConnector;
#[cfg(feature = "mongodb")]
pub const MONGODB: &'static dyn crate::datamodel_connector::Connector = &mongodb::MongoDbDatamodelConnector;
#[cfg(feature = "surrealdb")]
pub const SURREALDB: &'static dyn crate::datamodel_connector::Connector =
&surrealdb_datamodel_connector::SurrealDbDatamodelConnector;

pub static BUILTIN_CONNECTORS: ConnectorRegistry<'static> = &[
#[cfg(feature = "postgresql")]
Expand All @@ -61,4 +66,6 @@ pub static BUILTIN_CONNECTORS: ConnectorRegistry<'static> = &[
COCKROACH,
#[cfg(feature = "mongodb")]
MONGODB,
#[cfg(feature = "surrealdb")]
SURREALDB,
];
128 changes: 128 additions & 0 deletions psl/psl-core/src/builtin_connectors/surrealdb_datamodel_connector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use std::borrow::Cow;

use crate::{
ValidatedSchema,
datamodel_connector::{
Connector, ConnectorCapabilities, ConnectorCapability, ConstraintScope, Flavour, NativeTypeConstructor,
NativeTypeInstance,
},
diagnostics::{DatamodelError, Diagnostics, Span},
parser_database::ReferentialAction,
};
use enumflags2::BitFlags;
use parser_database::{ExtensionTypes, ScalarFieldType};

const NATIVE_TYPE_CONSTRUCTORS: &[NativeTypeConstructor] = &[];
const CONSTRAINT_SCOPES: &[ConstraintScope] = &[ConstraintScope::GlobalKeyIndex];

pub const CAPABILITIES: ConnectorCapabilities = enumflags2::make_bitflags!(ConnectorCapability::{
AnyId |
CompoundIds |
RelationFieldsInArbitraryOrder |
UpdateableId |
DecimalType |
BackwardCompatibleQueryRaw |
NativeUpsert |
FilteredInlineChildNestedToOneDisconnect |
InsertReturning |
DeleteReturning |
UpdateReturning |
SupportsFiltersOnRelationsWithoutJoins |
CreateMany |
Json |
AdvancedJsonNullability
});

pub struct SurrealDbDatamodelConnector;

impl Connector for SurrealDbDatamodelConnector {
fn provider_name(&self) -> &'static str {
"surrealdb"
}

fn name(&self) -> &str {
"SurrealDB"
}

fn capabilities(&self) -> ConnectorCapabilities {
CAPABILITIES
}

fn max_identifier_length(&self) -> usize {
// SurrealDB does not impose a specific identifier length limit
10000
}

fn foreign_key_referential_actions(&self) -> BitFlags<ReferentialAction> {
// SurrealDB does not support foreign key constraints natively
BitFlags::empty()
}

fn emulated_referential_actions(&self) -> BitFlags<ReferentialAction> {
use ReferentialAction::*;

Restrict | SetNull | Cascade
}

fn scalar_type_for_native_type(
&self,
_native_type: &NativeTypeInstance,
_extension_types: &dyn ExtensionTypes,
) -> Option<ScalarFieldType> {
// Unreachable: parse_native_type() always returns None and
// available_native_type_constructors() is empty, so the validation
// pipeline in fields.rs never calls this method for SurrealDB.
unreachable!("No native types on SurrealDB");
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

fn default_native_type_for_scalar_type(
&self,
_scalar_type: &ScalarFieldType,
_schema: &ValidatedSchema,
) -> Option<NativeTypeInstance> {
None
}

fn native_type_to_parts<'t>(&self, _native_type: &'t NativeTypeInstance) -> (&'t str, Cow<'t, [String]>) {
unreachable!()
}

fn constraint_violation_scopes(&self) -> &'static [ConstraintScope] {
CONSTRAINT_SCOPES
}

fn available_native_type_constructors(&self) -> &'static [NativeTypeConstructor] {
NATIVE_TYPE_CONSTRUCTORS
}

fn parse_native_type(
&self,
_name: &str,
_args: &[String],
span: Span,
diagnostics: &mut Diagnostics,
) -> Option<NativeTypeInstance> {
diagnostics.push_error(DatamodelError::new_native_types_not_supported(
self.name().to_owned(),
span,
));
None
}

fn validate_url(&self, url: &str) -> Result<(), String> {
// surrealdb:// is the canonical scheme; http(s):// accepted for direct HTTP API access.
if url.starts_with("surrealdb://") || url.starts_with("http://") || url.starts_with("https://") {
Ok(())
} else {
Err("must start with the protocol `surrealdb://`, `http://`, or `https://`.".to_string())
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

fn flavour(&self) -> Flavour {
Flavour::SurrealDb
}

fn can_assume_strict_equality_in_joins(&self) -> bool {
true
}
}
1 change: 1 addition & 0 deletions psl/psl-core/src/datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ pub enum Flavour {
Mysql,
Postgres,
Sqlite,
SurrealDb,
}

impl Flavour {
Expand Down
3 changes: 2 additions & 1 deletion psl/psl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ mysql = ["psl-core/mysql"]
cockroachdb = ["psl-core/cockroachdb", "postgresql"]
mssql = ["psl-core/mssql"]
mongodb = ["psl-core/mongodb"]
all = ["postgresql", "sqlite", "mysql", "cockroachdb", "mssql", "mongodb"]
surrealdb = ["psl-core/surrealdb"]
all = ["postgresql", "sqlite", "mysql", "cockroachdb", "mssql", "mongodb", "surrealdb"]

[dependencies]
psl-core.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions quaint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ pooled = ["dep:mobc"]
sqlite-native = ["sqlite", "rusqlite/bundled", "tokio/sync"]
sqlite = []

surrealdb = []

fmt-sql = ["dep:sqlformat"]

[dependencies]
Expand Down
24 changes: 24 additions & 0 deletions quaint/src/connector/connection_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ pub enum SqlFamily {
Sqlite,
#[cfg(feature = "mssql")]
Mssql,
#[cfg(feature = "surrealdb")]
SurrealDb,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

impl SqlFamily {
Expand All @@ -428,6 +430,8 @@ impl SqlFamily {
SqlFamily::Sqlite => "sqlite",
#[cfg(feature = "mssql")]
SqlFamily::Mssql => "mssql",
#[cfg(feature = "surrealdb")]
SqlFamily::SurrealDb => "surrealdb",
}
}

Expand All @@ -440,6 +444,8 @@ impl SqlFamily {
"postgres" | "postgresql" => Some(SqlFamily::Postgres),
#[cfg(feature = "mysql")]
"mysql" => Some(SqlFamily::Mysql),
#[cfg(feature = "surrealdb")]
"surrealdb" | "ws" | "wss" => Some(SqlFamily::SurrealDb),
_ => None,
}
}
Expand All @@ -455,6 +461,8 @@ impl SqlFamily {
SqlFamily::Sqlite => Some(999),
#[cfg(feature = "mssql")]
SqlFamily::Mssql => Some(1000),
#[cfg(feature = "surrealdb")]
SqlFamily::SurrealDb => None,
}
}

Expand Down Expand Up @@ -501,6 +509,10 @@ impl SqlFamily {
SqlFamily::Sqlite => 999,
#[cfg(feature = "mssql")]
SqlFamily::Mssql => 2098,
// SurrealDB has no documented parameter limit; this is a conservative
// transport-based fallback (HTTP/WebSocket body size dependent).
#[cfg(feature = "surrealdb")]
SqlFamily::SurrealDb => 32766,
Comment on lines +514 to +515
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

SurrealDB maximum query parameters bind values limit

💡 Result:

SurrealDB does not document a hard limit on the number of query parameters or bind values. Official documentation on parameters (SurrealQL parameters page) describes usage but specifies no maximum count. Environment variables include a "Limits config" section, but no specific parameter or bind limit is detailed. Related limits exist in storage (e.g., SurrealKV key size, increased in recent fixes for vectors) and HTTP (e.g., Python SDK URL query length ~65KB, request body 16KiB configurable via future args). Client-side issues like WebSocket max size (default 1MB, configurable) affect large binds indirectly. For production, practical limits depend on transport (HTTP/WS body size, memory) rather than a fixed parameter count; use SDK bind methods to avoid injection and size issues.

Citations:


SurrealDB has no documented maximum parameter limit; reconsider the hardcoded value.

SurrealDB does not document a hard limit on query parameters or bind values. The current value of 32766 is borrowed from PostgreSQL but may not be appropriate for SurrealDB, which relies on transport-level constraints (HTTP/WebSocket body size, memory) rather than a fixed parameter count. Either use a more appropriate value for SurrealDB or document why this limit was chosen.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@quaint/src/connector/connection_info.rs` around lines 512 - 513, The
hardcoded PostgreSQL-derived value for SurrealDB in the SqlFamily match
(SqlFamily::SurrealDb => 32766) should be removed or made explicit/justified;
replace the 32766 with a conservative, documented fallback (for example 1024) or
return a sentinel/None if your API supports Option (so callers know the limit is
transport-dependent), and add a brief inline comment explaining that SurrealDB
has no documented parameter limit and that the chosen value is a conservative
transport/body-size-based fallback; update the match arm for
SqlFamily::SurrealDb accordingly and ensure any callers that rely on this value
handle the new fallback/Option behavior.

}
}

Expand Down Expand Up @@ -556,6 +568,18 @@ impl SqlFamily {
pub fn is_mssql(&self) -> bool {
false
}

/// True, if family is SurrealDB.
#[cfg(feature = "surrealdb")]
pub fn is_surrealdb(&self) -> bool {
matches!(self, SqlFamily::SurrealDb)
}

/// True, if family is SurrealDB.
#[cfg(not(feature = "surrealdb"))]
pub fn is_surrealdb(&self) -> bool {
false
}
}

impl fmt::Display for SqlFamily {
Expand Down
8 changes: 8 additions & 0 deletions quaint/src/connector/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ pub enum AdapterProvider {
#[cfg(feature = "mssql")]
#[cfg_attr(target_arch = "wasm32", serde(rename = "sqlserver"))]
SqlServer,
#[cfg(feature = "surrealdb")]
SurrealDb,
}

impl AdapterProvider {
Expand All @@ -73,6 +75,8 @@ impl AdapterProvider {
Self::Sqlite => "sqlite",
#[cfg(feature = "mssql")]
Self::SqlServer => "mssql",
#[cfg(feature = "surrealdb")]
Self::SurrealDb => "surrealdb",
}
}
}
Expand All @@ -90,6 +94,8 @@ impl FromStr for AdapterProvider {
"sqlite" => Ok(Self::Sqlite),
#[cfg(feature = "mssql")]
"sqlserver" => Ok(Self::SqlServer),
#[cfg(feature = "surrealdb")]
"surrealdb" => Ok(Self::SurrealDb),
_ => Err(format!("Unsupported adapter flavour: {s:?}")),
}
}
Expand All @@ -106,6 +112,8 @@ impl From<&AdapterProvider> for SqlFamily {
AdapterProvider::Sqlite => SqlFamily::Sqlite,
#[cfg(feature = "mssql")]
AdapterProvider::SqlServer => SqlFamily::Mssql,
#[cfg(feature = "surrealdb")]
AdapterProvider::SurrealDb => SqlFamily::SurrealDb,
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions quaint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@
// TODO: remove once `quaint` is no longer a transitive dependency of `mongodb-schema-connector`.
#![allow(dead_code)]

#[cfg(not(any(feature = "sqlite", feature = "postgresql", feature = "mysql", feature = "mssql")))]
compile_error!("one of 'sqlite', 'postgresql', 'mysql' or 'mssql' features must be enabled");
#[cfg(not(any(feature = "sqlite", feature = "postgresql", feature = "mysql", feature = "mssql", feature = "surrealdb")))]
compile_error!("one of 'sqlite', 'postgresql', 'mysql', 'mssql' or 'surrealdb' features must be enabled");

#[macro_use]
mod macros;
Expand Down
4 changes: 4 additions & 0 deletions quaint/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ mod mysql;
mod postgres;
#[cfg(feature = "sqlite")]
mod sqlite;
#[cfg(feature = "surrealdb")]
mod surrealdb;

// Generic query writer, used for all SQL flavors
mod query_writer;
Expand All @@ -26,6 +28,8 @@ pub use self::mysql::Mysql;
pub use self::postgres::Postgres;
#[cfg(feature = "sqlite")]
pub use self::sqlite::Sqlite;
#[cfg(feature = "surrealdb")]
pub use self::surrealdb::SurrealDb;

use crate::ast::*;
use query_template::QueryTemplate;
Expand Down
Loading