pub struct Executor<A: DatabaseAdapter> { /* private fields */ }Expand description
Query executor - executes compiled GraphQL queries.
This is the main entry point for runtime query execution. It coordinates matching, planning, execution, and projection.
§Type Parameters
A- The database adapter type (implementsDatabaseAdaptertrait)
§Ownership and Lifetimes
The executor holds owned references to schema and runtime data, with no borrowed pointers:
schema: OwnedCompiledSchema(immutable after construction)adapter: Shared viaArc<A>to allow multiple executors/tasks to use the same connection poolintrospection: Owned cached GraphQL schema responsesconfig: Owned runtime configuration
No explicit lifetimes required - all data is either owned or wrapped in Arc,
so the executor can be stored in long-lived structures without lifetime annotations or
borrow-checker issues.
§Concurrency
Executor<A> is Send + Sync when A is Send + Sync. It can be safely shared across
threads and tasks without cloning:
let executor = Arc::new(Executor::new(schema, adapter, config));
// Can be cloned into multiple tasks
let exec_clone = executor.clone();
tokio::spawn(async move {
let result = exec_clone.execute(query, vars).await;
});§Query Timeout
Queries are protected by the query_timeout_ms configuration in RuntimeConfig (default: 30s).
When a query exceeds this timeout, it returns FraiseQLError::Timeout without panicking.
Set query_timeout_ms to 0 to disable timeout enforcement.
Implementations§
Source§impl<A: DatabaseAdapter> Executor<A>
impl<A: DatabaseAdapter> Executor<A>
Sourcepub fn new(schema: CompiledSchema, adapter: Arc<A>) -> Self
pub fn new(schema: CompiledSchema, adapter: Arc<A>) -> Self
Sourcepub fn with_config(
schema: CompiledSchema,
adapter: Arc<A>,
config: RuntimeConfig,
) -> Self
pub fn with_config( schema: CompiledSchema, adapter: Arc<A>, config: RuntimeConfig, ) -> Self
Create new executor with custom configuration.
§Arguments
schema- Compiled schemaadapter- Database adapterconfig- Runtime configuration
Sourcepub async fn execute(
&self,
query: &str,
variables: Option<&Value>,
) -> Result<String>
pub async fn execute( &self, query: &str, variables: Option<&Value>, ) -> Result<String>
Execute a GraphQL query.
§Arguments
query- GraphQL query stringvariables- Query variables (optional)
§Returns
GraphQL response as JSON string
§Errors
Returns error if:
- Query is malformed
- Query references undefined operations
- Database execution fails
- Result projection fails
§Example
let query = r#"query { users { id name } }"#;
let result = executor.execute(query, None).await?;
println!("{}", result);Sourcepub async fn execute_with_scopes(
&self,
query: &str,
variables: Option<&Value>,
user_scopes: &[String],
) -> Result<String>
pub async fn execute_with_scopes( &self, query: &str, variables: Option<&Value>, user_scopes: &[String], ) -> Result<String>
Execute a GraphQL query with user context for field-level access control.
This method validates that the user has permission to access all requested
fields before executing the query. If field filtering is enabled in the
RuntimeConfig and the user lacks required scopes, this returns an error.
§Arguments
query- GraphQL query stringvariables- Query variables (optional)user_scopes- User’s scopes from JWT token (pass empty slice if unauthenticated)
§Returns
GraphQL response as JSON string, or error if access denied
§Example
let query = r#"query { users { id name salary } }"#;
let user_scopes = user.scopes.iter().map(|s| s.as_str()).collect::<Vec<_>>();
let result = executor.execute_with_scopes(query, None, &user_scopes).await?;Sourcepub async fn execute_with_context(
&self,
query: &str,
variables: Option<&Value>,
ctx: &ExecutionContext,
) -> Result<String>
pub async fn execute_with_context( &self, query: &str, variables: Option<&Value>, ctx: &ExecutionContext, ) -> Result<String>
Execute a GraphQL query with cancellation support via ExecutionContext.
This method allows graceful cancellation of long-running queries through a
cancellation token. If the token is cancelled during execution, the query
returns a FraiseQLError::Cancelled error.
§Arguments
query- GraphQL query stringvariables- Query variables (optional)ctx- ExecutionContext with cancellation token
§Returns
GraphQL response as JSON string, or error if cancelled or execution fails
§Example
let ctx = ExecutionContext::new("user-query-123".to_string());
let cancel_token = ctx.cancellation_token().clone();
// Spawn a task to cancel after 5 seconds
tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(5)).await;
cancel_token.cancel();
});
let result = executor.execute_with_context(query, None, &ctx).await;
match result {
Err(FraiseQLError::Cancelled { reason, .. }) => {
eprintln!("Query cancelled: {}", reason);
}
Ok(response) => println!("{}", response),
Err(e) => eprintln!("Error: {}", e),
}Sourcepub async fn execute_with_security(
&self,
query: &str,
variables: Option<&Value>,
security_context: &SecurityContext,
) -> Result<String>
pub async fn execute_with_security( &self, query: &str, variables: Option<&Value>, security_context: &SecurityContext, ) -> Result<String>
Execute a GraphQL query with row-level security (RLS) context.
This method applies RLS filtering based on the user’s SecurityContext before executing the query. If an RLS policy is configured in RuntimeConfig, it will be evaluated to determine what rows the user can access.
§Arguments
query- GraphQL query stringvariables- Query variables (optional)security_context- User’s security context (authentication + permissions)
§Returns
GraphQL response as JSON string, or error if access denied by RLS
§Example
let query = r#"query { posts { id title } }"#;
let context = SecurityContext {
user_id: "user1".to_string(),
roles: vec!["user".to_string()],
tenant_id: None,
scopes: vec![],
attributes: HashMap::new(),
request_id: "req-1".to_string(),
ip_address: None,
authenticated_at: Utc::now(),
expires_at: Utc::now() + Duration::hours(1),
issuer: None,
audience: None,
};
let result = executor.execute_with_security(query, None, &context).await?;Sourcepub fn check_field_access(
&self,
type_name: &str,
field_name: &str,
user_scopes: &[String],
) -> Result<(), FieldAccessError>
pub fn check_field_access( &self, type_name: &str, field_name: &str, user_scopes: &[String], ) -> Result<(), FieldAccessError>
Check if a specific field can be accessed with given scopes.
This is a convenience method for checking field access without executing a query.
§Arguments
type_name- The GraphQL type namefield_name- The field nameuser_scopes- User’s scopes from JWT token
§Returns
Ok(()) if access is allowed, Err(FieldAccessError) if denied
Sourcepub async fn execute_window_query(
&self,
query_json: &Value,
query_name: &str,
metadata: &FactTableMetadata,
) -> Result<String>
pub async fn execute_window_query( &self, query_json: &Value, query_name: &str, metadata: &FactTableMetadata, ) -> Result<String>
Execute a window query.
§Arguments
query_json- JSON representation of the window queryquery_name- GraphQL field name (e.g., “sales_window”)metadata- Fact table metadata
§Returns
GraphQL response as JSON string
§Errors
Returns error if:
- Query parsing fails
- Execution plan generation fails
- SQL generation fails
- Database execution fails
- Result projection fails
§Example
let query_json = json!({
"table": "tf_sales",
"select": [{"type": "measure", "name": "revenue", "alias": "revenue"}],
"windows": [{
"function": {"type": "row_number"},
"alias": "rank",
"partitionBy": [{"type": "dimension", "path": "category"}],
"orderBy": [{"field": "revenue", "direction": "DESC"}]
}]
});
let metadata = /* fact table metadata */;
let result = executor.execute_window_query(&query_json, "sales_window", &metadata).await?;Sourcepub async fn execute_json(
&self,
query: &str,
variables: Option<&Value>,
) -> Result<Value>
pub async fn execute_json( &self, query: &str, variables: Option<&Value>, ) -> Result<Value>
Execute a query and return parsed JSON.
Same as execute() but returns parsed serde_json::Value instead of string.
Sourcepub async fn execute_aggregate_query(
&self,
query_json: &Value,
query_name: &str,
metadata: &FactTableMetadata,
) -> Result<String>
pub async fn execute_aggregate_query( &self, query_json: &Value, query_name: &str, metadata: &FactTableMetadata, ) -> Result<String>
Execute an aggregate query.
§Arguments
query_json- JSON representation of the aggregate queryquery_name- GraphQL field name (e.g., “sales_aggregate”)metadata- Fact table metadata
§Returns
GraphQL response as JSON string
§Errors
Returns error if:
- Query parsing fails
- Execution plan generation fails
- SQL generation fails
- Database execution fails
- Result projection fails
§Example
let query_json = json!({
"table": "tf_sales",
"groupBy": { "category": true },
"aggregates": [{"count": {}}]
});
let metadata = /* fact table metadata */;
let result = executor.execute_aggregate_query(&query_json, "sales_aggregate", &metadata).await?;Sourcepub const fn schema(&self) -> &CompiledSchema
pub const fn schema(&self) -> &CompiledSchema
Get the compiled schema.
Sourcepub const fn config(&self) -> &RuntimeConfig
pub const fn config(&self) -> &RuntimeConfig
Get runtime configuration.