| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // Package capabilities describes the SQL surface an engine build supports.
- //
- // The document is machine-readable and versioned separately from the engine
- // build. Clients should compare SchemaVersion when parsing it and use
- // EngineVersion to pin behavior to a specific PizzaSQL release. Keep this file
- // in sync with the tests it advertises: every claim here must be covered by an
- // engine test in the same repository.
- package capabilities
- import (
- "time"
- "github.com/danfragoso/pizzasql-next/pkg/version"
- )
- // SchemaVersion changes only when the document's shape or semantics change in a
- // way clients must handle. Additive fields do not require a bump.
- const SchemaVersion = 1
- // Feature reports whether a capability is supported and, when it is not,
- // whether the engine rejects the syntax or accepts it with different semantics.
- type Feature struct {
- Supported bool `json:"supported"`
- Status string `json:"status"`
- SQLState string `json:"sqlstate,omitempty"`
- Notes string `json:"notes,omitempty"`
- }
- // Document is the machine-readable capability description served by
- // GET /capabilities.
- type Document struct {
- SchemaVersion int `json:"schema_version"`
- Engine string `json:"engine"`
- EngineVersion string `json:"engine_version"`
- Commit string `json:"commit"`
- GeneratedAt string `json:"generated_at,omitempty"`
- Protocol Protocol `json:"protocol"`
- Constraints Constraints `json:"constraints"`
- DDL DDL `json:"ddl"`
- Transactions Transactions `json:"transactions"`
- Types Types `json:"types"`
- Parameters Parameters `json:"parameters"`
- JSON JSON `json:"json"`
- ErrorCodes map[string]string `json:"error_codes"`
- Documentation Documentation `json:"documentation"`
- }
- type Protocol struct {
- PostgresCompat string `json:"postgres_compat"`
- SQLiteCompat string `json:"sqlite_compat"`
- SimpleQuery bool `json:"simple_query"`
- ExtendedQuery bool `json:"extended_query"`
- TLS string `json:"tls"`
- }
- type Constraints struct {
- NotNull Feature `json:"not_null"`
- Unique Feature `json:"unique"`
- PrimaryKey Feature `json:"primary_key"`
- CompositePK Feature `json:"composite_primary_key"`
- ForeignKey Feature `json:"foreign_key"`
- Check Feature `json:"check"`
- DefaultValues Feature `json:"default_values"`
- }
- type DDL struct {
- AddColumn Feature `json:"add_column"`
- AddColumnBackfill Feature `json:"add_column_backfill"`
- DropColumn Feature `json:"drop_column"`
- RenameColumn Feature `json:"rename_column"`
- RenameColumnIndexes Feature `json:"rename_column_updates_indexes"`
- CreateTableIfNotExists bool `json:"create_table_if_not_exists"`
- AddColumnIfNotExists bool `json:"add_column_if_not_exists"`
- }
- type Transactions struct {
- Model string `json:"model"`
- Isolation string `json:"isolation"`
- SerializationCode string `json:"serialization_sqlstate"`
- RowLocks Feature `json:"row_locks"`
- Savepoints Feature `json:"savepoints"`
- RetryRecommended bool `json:"retry_recommended"`
- }
- type Types struct {
- Integer bool `json:"integer"`
- Bigint bool `json:"bigint"`
- Real bool `json:"real"`
- Text bool `json:"text"`
- Blob bool `json:"blob"`
- Boolean bool `json:"boolean"`
- DateTime bool `json:"datetime"`
- JSONText bool `json:"json_as_text"`
- JSONB Feature `json:"jsonb"`
- Arrays Feature `json:"arrays"`
- RowID Feature `json:"rowid"`
- }
- type Parameters struct {
- Positional bool `json:"positional"`
- MaxOID string `json:"max_oid"`
- Arrays Feature `json:"arrays"`
- BinaryNumeric bool `json:"binary_numeric"`
- }
- type JSON struct {
- Storage string `json:"storage"`
- Functions string `json:"functions"`
- ArrowOperators Feature `json:"arrow_operators"`
- InvalidInput string `json:"invalid_input"`
- }
- type Documentation struct {
- Compatibility string `json:"compatibility"`
- Isolation string `json:"isolation"`
- }
- // Current returns the capability document for this build.
- func Current() *Document {
- return &Document{
- SchemaVersion: SchemaVersion,
- Engine: "pizzasql",
- EngineVersion: version.String(),
- Commit: version.Commit,
- GeneratedAt: time.Now().UTC().Format(time.RFC3339),
- Protocol: Protocol{
- PostgresCompat: "14.0",
- SQLiteCompat: "3.35.0",
- SimpleQuery: true,
- ExtendedQuery: true,
- TLS: "terminated by the managed pgproxy, not the engine listener",
- },
- Constraints: Constraints{
- NotNull: Feature{Supported: true, Status: "enforced"},
- Unique: Feature{Supported: true, Status: "enforced", SQLState: "23505", Notes: "unique indexes, INLINE UNIQUE, and ON CONFLICT are enforced atomically"},
- PrimaryKey: Feature{Supported: true, Status: "enforced", Notes: "single-column only"},
- CompositePK: Feature{Supported: false, Status: "rejected", SQLState: "0A000", Notes: "declare a single-column primary key"},
- ForeignKey: Feature{Supported: false, Status: "rejected", SQLState: "0A000", Notes: "inline and table-level FOREIGN KEY are rejected; enforce referential integrity in the application, cascades are not implemented"},
- Check: Feature{Supported: false, Status: "rejected", SQLState: "0A000", Notes: "inline and table-level CHECK are rejected; enforce the rule in the application"},
- DefaultValues: Feature{Supported: true, Status: "constant_only", SQLState: "0A000", Notes: "non-constant defaults (CURRENT_TIMESTAMP, function calls) are rejected instead of being frozen at DDL time"},
- },
- DDL: DDL{
- AddColumn: Feature{Supported: true, Status: "metadata_only"},
- AddColumnBackfill: Feature{Supported: false, Status: "no_backfill", Notes: "existing rows read NULL; a DEFAULT applies to later INSERTs only"},
- DropColumn: Feature{Supported: true, Status: "rewrites_rows"},
- RenameColumn: Feature{Supported: true, Status: "rewrites_rows"},
- RenameColumnIndexes: Feature{Supported: false, Status: "stale_index_metadata", Notes: "drop and recreate indexes that reference a renamed column"},
- CreateTableIfNotExists: true,
- AddColumnIfNotExists: true,
- },
- Transactions: Transactions{
- Model: "optimistic compare-batch commit; no MVCC or snapshots",
- Isolation: "serializable-equivalent for single-row compare-batch commits; write skew is possible across independent rows",
- SerializationCode: "40001",
- RowLocks: Feature{Supported: false, Status: "rejected", SQLState: "0A000", Notes: "SELECT ... FOR UPDATE/SHARE and NOWAIT/SKIP LOCKED are rejected"},
- Savepoints: Feature{Supported: true, Status: "enforced"},
- RetryRecommended: true,
- },
- Types: Types{
- Integer: true,
- Bigint: true,
- Real: true,
- Text: true,
- Blob: true,
- Boolean: true,
- DateTime: true,
- JSONText: true,
- JSONB: Feature{Supported: false, Status: "type_name_alias", Notes: "JSONB is accepted as a column type name with no native semantics; values are stored as text and reported as TEXT over the wire"},
- Arrays: Feature{Supported: false, Status: "rejected", SQLState: "0A000"},
- RowID: Feature{Supported: true, Status: "auto_assigned", Notes: "rowid/oid/_rowid_ are BIGINT over the wire; monotonic when the engine assigns the rowid, stable across UPDATE, not monotonic for client-assigned descending INTEGER PRIMARY KEY values"},
- },
- Parameters: Parameters{
- Positional: true,
- MaxOID: "int8/text/bool/bytea/float; arrays are rejected",
- Arrays: Feature{Supported: false, Status: "rejected", SQLState: "0A000", Notes: "id = ANY($1) is rejected; expand to IN (...) with individual parameters"},
- BinaryNumeric: true,
- },
- JSON: JSON{
- Storage: "TEXT (JSON and JSONB type names are accepted without native semantics; insert JSON as text)",
- Functions: "json, json_extract, json_set, json_insert, json_replace, json_remove, json_valid, json_type, json_array, json_object, json_quote, json_group_array",
- ArrowOperators: Feature{Supported: false, Status: "rejected", SQLState: "42601", Notes: "-> and ->> are not implemented; use json_extract"},
- InvalidInput: "json_extract/json_set throw 'malformed JSON'; json_valid returns 0",
- },
- ErrorCodes: map[string]string{
- "23505": "unique_violation",
- "40001": "serialization_failure",
- "0A000": "feature_not_supported",
- "42601": "syntax_error",
- "25P02": "in_failed_sql_transaction",
- "08P01": "protocol_violation (managed proxy: TLS required)",
- "53300": "too_many_connections (managed proxy: organization quota)",
- "XX000": "internal_error",
- },
- Documentation: Documentation{
- Compatibility: "https://docs.database.pizza/sql-reference/compatibility/",
- Isolation: "https://docs.database.pizza/engine/concurrency/",
- },
- }
- }
|