Repository navigation
Conversation
A conforming server may refuse PRAGMA or reads of its system tables, and a SELECT response carries column names only, so a client had no portable way to learn a table's shape. The describe request asks the server for the columns, declared types and primary key from its own catalogue. It is optional; a server without it answers bad_request, and a client must not assume it. A table that does not exist or that the token cannot see answers the registered permission_error (403), one response for both. Section 6.1 now says columns is required for a SELECT that matches no rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
A client that keeps two databases in step has to learn each table's columns and primary key, and today http-sql gives it no portable way to do that. The spec is transport, not policy (section 10.1), so a conforming server may refuse
PRAGMAor reads of its system tables, and a single-statement response carries column names only. This edit adds an optionaldescriberequest so the server answers from its own catalogue and the client sends no engine-specific SQL. It also says outright that a SELECT matching no rows still returns its column names. It is an additive edit, numbered 0.0.2.Acceptance criteria mapping
1. Section 4 admits three request shapes; section 4.3 defines describe
The opening rule of section 4 now names
sql,batchanddescribeand rejects a body with more than one of them, or none. New section 4.3 defines the request. The table name is never executed as SQL: a server that builds a catalogue query from it must bind or quote it. The server answers from its own catalogue, so a server whose policy refusesPRAGMAcan still answer. A describe cannot appear inside a batch.Evidence: SPEC.md:53 (section 4 rule), SPEC.md:110-124 (section 4.3), SPEC.md:120 (answered from the server's catalogue)
2. Section 6.3 defines the describe success response
The response is a
columnsarray in declared order, the orderSELECT *produces. Each column object carriesname,typeandkey.typeis the declared type, or null for a column declared without one, and the server must not map it onto another type system.keyis the 1-based position in the primary key, so a composite key keeps its declared order. A table-levelgeneratedKeyis true when the database assigns the key itself; the examples given are SQLite's rowid alias, PostgreSQL serial or identity columns, and MySQL AUTO_INCREMENT.Evidence: SPEC.md:230-251 (section 6.3), SPEC.md:249 (
generatedKey)3. A missing or hidden table returns one registered error
No registered code means "not found."
permission_error(403) fits a table the token cannot see, and because the response for a missing table must be identical, that case getspermission_errortoo, so describe does not reveal whether a hidden table exists. The section 7 row's meaning widens to cover it, and no new code is registered.sql_errorwas the other candidate, and it is what a SELECT against a missing table returns (checks S-5). It was passed over because a describe carries no SQL. Section 12 repeats the identical-response rule for security readers.Evidence: SPEC.md:124 (section 4.3 error rule), SPEC.md:279 (section 7 table row), the section 12 describe bullet
4. Section 6.1 requires columns for an empty SELECT
The
columnsfield description now says that a SELECT produces a result set even when it matches no rows, socolumnsmust carry its names whilerowsis empty. The old text implied this, so the new sentence makes it explicit and contradicts nothing.Evidence: SPEC.md:177
5. Section 10.1 lets servers implement describe and says how to decline
The server MAY list gains a describe bullet. A server that implements describe answers with the section 6.3 envelope and with
permission_errorfor a table it will not describe. A server that does not must reject the request withbad_request(400). Section 4 already gives that code to a body with no recognized field, and section 4 now says a server without describe treats such a request that way.Evidence: SPEC.md:331, plus the second paragraph of section 4
6. Section 10.2 forbids clients from assuming describe
Client MUST item 2 now lists describe among the request fields. A new item 7 says a client must not assume describe exists. It also says a
bad_requestin answer to a well-formed describe means the server lacks the request, and the client must not read that error as an empty table.Evidence: SPEC.md:339, SPEC.md:344
7. The version moves to 0.0.2, with a history entry
The title, the status line, the
Http-Sql-VersionandHttp-Sql-Accept-Versionexamples in section 9, and the opening of section 11 now read 0.0.2. The new version-history entry lists the additions and says what a 0.0.1 server must change, consistent with section 11's rule that the patch number moves on any edit while the major is 0.Evidence: SPEC.md:1, SPEC.md:5, SPEC.md:298, SPEC.md:353, SPEC.md:359
8. curl.md has a describe example
A new "Describe a table" section shows the curl request, a success response, and the 403
permission_errorfor a table that does not exist or that the token cannot see. It also notes that a server without describe answers 400.Evidence: examples/curl.md:77
Not done
README.md, checks/README.md (H-1, H-2) and the example servers still say 0.0.1. The Cloudflare D1 example (
examples/cloudflare-worker-to-d1/src/index.ts:119) returnscolumns: []for a SELECT with zero rows, because D1 gives no column names when there are no rows. That breaks the clarified section 6.1. The example servers stay at 0.0.1 until they are fixed and the checks gain describe cases. Neither change was part of this issue.Closes #31
🤖 Generated with Claude Code