Mutations
Insert, update, connect, validate, and transact across related tables.
Inserts
mutation {
users(insert: $data) {
id
email
}
}Example_insert
tests/insert_test.go:16Bulk and nested inserts
GraphJin can insert multiple rows and insert across related tables. PostgreSQL uses atomic CTE chains; other dialects use the dialect-appropriate mutation strategy.
mutation {
products(insert: [
{ id: 5001, name: "Desk", price: 199.00 }
{ id: 5002, name: "Lamp", price: 39.00 }
]) {
id
name
}
}mutation {
users(insert: $user) {
id
products(insert: $products) {
id
name
}
}
}Example_insertInlineBulk
tests/insert_test.go:148Example_insertIntoMultipleRelatedTables
tests/insert_test.go:278Connect to existing rows
Use connect operations when a mutation should link to existing related records instead of creating new ones.
mutation {
products(insert: $product) {
id
categories(connect: { id: { in: [1, 2] } }) {
id
name
}
}
}Example_insertIntoTableAndConnectToRelatedTables
tests/insert_test.go:531Validation and presets
Mutation validation supports required fields, formats, min/max constraints, comparisons, and conditional requirements. Presets can inject server-controlled values.
Example_insertInlineWithValidation
tests/insert_test.go:105Example_insertWithPresets
tests/insert_test.go:184Validation belongs in GraphJin config, not client code. Presets are useful for server-controlled fields such as owner_id, created_at, tenant IDs, or role-derived account IDs.
Updates
mutation {
products(update: $data, where: { id: { eq: $id } }) {
id
name
}
}Example_update
tests/update_test.go:61Deletes
Deletes require a where clause. Do not expose unconstrained deletes.
mutation DeleteProduct($id: ID!) {
products(delete: true, where: { id: { eq: $id } }) {
id
}
}TestMultiAliasDelete
tests/update_test.go:422Read-only and production controls
Mutations run through the same role, source, and production policy gates as queries:
- read-only databases or sources reject writes,
- table-level permissions can block insert/update/upsert/delete separately,
- production mode should use saved operations,
- source-mode capabilities should come from
core/sourcecap, - and MCP mutation access should be explicit.
TestReadOnlyDB_WithRolesAndTables
tests/readonly_test.go:102TestSourceModeHTTPRuntimeDenialEventsAreRedacted
serv/source_mode_http_test.go:113Dialect mutation strategies
The compiler lowers writes differently by dialect. PostgreSQL can use CTE-heavy nested mutation plans; MySQL, MariaDB, SQLite, SQL Server, Oracle, Snowflake, and other backends use dialect-specific linear or fallback strategies where needed. Shared mutation changes should be validated against relevant dialect scripts.