From adc4e5724c926cac4ecb8dc3a58a5f9b4d1b9b81 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 28 Sep 2026 04:51:16 +0100 Subject: Take a view's arguments from the request's query GET /views/name?argument=value gives a view that takes arguments its arguments: the query as it came is kept on the request's work slot (it outlives the connection, which may go before the view is shown), and when the view is shown, on the connection thread from a snapshot or by the owner, its pairs (values %XX decoded) are laid out as a payload of the arguments' shape and given before the view is evaluated. from and count still page a table. An argument missing, unknown, given twice, not of its type or badly escaped answers 400 invalid. A registered query takes its view's arguments the same way (GET /queries/name?k=4). An arguments input is not an input to post to. server_arguments opens 200 accounts, then asks 83 times against a model: balances by key (404 no_value for a key not there), counts above an argument, texts with &, =, % and non-ASCII shown back, a table filtered by two arguments whose column folds with one, paged, counts by an owner's name, a registered query with an argument, and six refusals. The format's document (008) describes arguments. --- docs/design/008-module-format.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'docs/design/008-module-format.md') diff --git a/docs/design/008-module-format.md b/docs/design/008-module-format.md index 4b9855c..0e503cf 100644 --- a/docs/design/008-module-format.md +++ b/docs/design/008-module-format.md @@ -14,8 +14,8 @@ v4는 **레코드**, 레코드의 **리스트** 상태, 리스트의 **인덱스 v5는 값을 가진 채 합류하는 분기(조건식)와, 리스트 항목마다 행을 내는 **표 보기**, 한 번 계산한 값을 여러 번 쓰게 하는 스택 복사(PICK·SLIDE, 툴체인의 함수 인라인용)를 더한다. 이전 판은 받지 않는다(생산자는 aup 하나다). v5에는 뒤에 집계(FOLD), 걸러진 표, 마크, 그리고 **키 있는 리스트**와 text 비교가 더해졌다. 그 뒤 핸들러에서 리스트를 -도는 **걷기**(EACH)와 **메시지의 행**(레코드의 리스트인 메시지 필드와, 그 행을 담는 행 목록 상태)이 더해졌다. 모두 전의 -v5 모듈이 그대로 유효하도록 더한 것이다(새 명령과 이전에 0이던 자리의 값). +도는 **걷기**(EACH)와 **메시지의 행**(레코드의 리스트인 메시지 필드와, 그 행을 담는 행 목록 상태), 그리고 **인자를 받는 +보기**가 더해졌다. 모두 전의 v5 모듈이 그대로 유효하도록 더한 것이다(새 명령, 새 종류, 이전에 0이던 자리의 값). ## 바이트 배치 @@ -30,7 +30,7 @@ v5 모듈이 그대로 유효하도록 더한 것이다(새 명령과 이전에 | 32 | u32 상수 블롭 바이트 수, u16 레코드 필드, u16 0 | | 40 | 상태 × 16 B: u32 이름, u32 타입(0 수, 1 text, 2 커서, 3 리스트, 4 인덱스), 8 B 값: 수는 f64 초기값, text는 u32 초기 상수, 커서는 u32 대상 text 상태와 u32 플래그(1이면 마크: 그 자리에 넣은 글 앞에 남는다), 리스트는 u32 레코드와 u32 키(0이면 없음, 아니면 키 필드 + 1, 256이면 메시지의 행 목록: 이름은 그 필드의 경로 `입력.필드`이고 키가 없다), 인덱스는 u32 대상 리스트 상태 | | | 컬렉션 × 12 B: u32 이름, u32 1(바이트), u32 1(키별) | -| | 입력 × 16 B: u32 이름, u8 종류(1 키, 2 메시지, 3 text, 4 타이머, 5 출력: 앱이 보내는 메시지, 모양은 메시지와 같고 핸들러가 없다), u8 키별 여부, u16 0, u32 키 이름(키 입력)·주기(타이머, 1 ms–24시간을 ms로) 또는 0, u16 첫 필드, u16 필드 수 | +| | 입력 × 16 B: u32 이름, u8 종류(1 키, 2 메시지, 3 text, 4 타이머, 5 출력: 앱이 보내는 메시지, 모양은 메시지와 같고 핸들러가 없다, 6 인자: 한 보기가 받는 인자, 모양은 메시지와 같고 핸들러가 없으며 이름은 `보기.args`), u8 키별 여부, u16 0, u32 키 이름(키 입력)·주기(타이머, 1 ms–24시간을 ms로)·보기 번호(인자) 또는 0, u16 첫 필드, u16 필드 수 | | | 필드 × 8 B: u32 이름(식별자, 또는 그룹 안의 필드면 점으로 이은 경로 `user.name`), u32 타입(1 u32le, 2 바이트, 3 수(binary64), 4 text, 5 행: 비트 8–23에 그 행이 채우는 행 목록 상태). 페이로드는 접두부와 가변 필드의 바이트다. 접두부에는 선언 순서로 고정 필드의 값과 가변 필드(바이트·text)의 u32 길이가 들어가는데, 마지막 가변 필드는 길이 없이 나머지를 차지한다. 가변 필드의 바이트는 접두부 뒤에 선언 순서로 이어진다(가변 필드가 하나면 예전의 "바이트 꼬리"와 같다) | | | 상수 × 8 B: u32 블롭 오프셋, u32 길이 (UTF-8) | | | 레코드 × 8 B: u32 이름, u16 첫 레코드 필드, u16 필드 수(1–16) | @@ -61,7 +61,7 @@ v5 모듈이 그대로 유효하도록 더한 것이다(새 명령과 이전에 | 20 | STORE | n → | 상태 `인자`. 핸들러 전용 | | 21 | JZ | n → | 0이면 `인자`로 | | 22 | JMP | | `인자`로 | -| 23 | FIELD | → n, b 또는 t | 메시지 필드 `인자`(u32·수는 n, 바이트는 b, text는 t). 메시지 핸들러 전용. 도착할 때 길이가 페이로드를 넘거나 text가 UTF-8이 아니거나 수가 유한하지 않으면 메시지가 `limit`·`encoding`·`non_finite`로 실패한다 | +| 23 | FIELD | → n, b 또는 t | 메시지 필드 `인자`(u32·수는 n, 바이트는 b, text는 t). 메시지 핸들러와 그 안의 집계, 그리고 인자를 받는 보기(그 표의 열과 필터, 그 안의 집계)에서 인자를 읽는다. 도착할 때 길이가 페이로드를 넘거나 text가 UTF-8이 아니거나 수가 유한하지 않으면 메시지가 `limit`·`encoding`·`non_finite`로 실패한다 | | 24 | DOC | → b | 컬렉션 `인자`의 메시지 키 문서. 없으면 `not_found`. 키별 메시지 핸들러 전용 | | 25 | DOC_SIZE | → n | 그 문서의 바이트 수(없으면 0) | | 26 | LEN | b → n | 바이트 값의 길이 | @@ -148,6 +148,9 @@ v5 모듈이 그대로 유효하도록 더한 것이다(새 명령과 이전에 블록 안으로 들어오지 못한다. 걷는 리스트는 줄기만 하므로 한 걷기는 시작할 때의 항목 수 × 블록 길이를 넘지 않는다. - 행 필드(타입 5)는 메시지 입력에만 있고(출력은 행을 보내지 않는다), 가리키는 상태는 행 목록이며 그 이름이 `입력 이름.필드 경로`와 같다. 그래서 행 목록 하나는 필드 하나가 채운다. FIELD는 행 필드를 읽지 않는다(행은 리스트로 읽는다). +- 인자(종류 6)는 열이 아닌 보기 하나를 가리키고, 보기마다 하나이며, 이름이 `보기 이름.args`다. 핸들러를 갖지 않는다. 그 + 보기와(표라면 그 열과 필터도) 그 안의 집계는 FIELD로 인자를 읽는다. 집계 블록은 둘레 블록의 메시지나 인자를 읽을 수 있다 + (읽기뿐: 응답과 문서 연산은 핸들러 자신의 코드에만 있다). - 표는 리스트 상태를 가리키고 열은 앞에 나온 표를 가리킨다. 표 밖의 이름은 한 이름공간이고, 열 이름은 표 안에서만 유일하다. @@ -174,6 +177,11 @@ text, 끝이 맞지 않는 바이트는 메시지를 `limit`으로 실패시킨 읽고(걷기, 집계, `count`), 한 이벤트 안의 임시 표로 쓸 수도 있다. 한 메시지의 모든 행은 한 트랜잭션이다. 행 하나가 실패하면 (없는 키, `require`) 어느 행도 적용되지 않는다. +**인자를 받는 보기.** 호스트가 보기의 인자를 메시지 페이로드처럼 주면(`pure_app_arguments`: 고정 필드는 접두부, text와 바이트는 +그 뒤) 그 보기와 열, 행이 다시 줄 때까지 그것을 읽는다. 주지 않은 보기는 값이 없다. 걸러진 표의 행은 준 인자마다 다시 거른다. +인자는 잎 단위 실행에서 모두에 같은 값이고, 한 번의 통과로 답하는 열의 집계(PureShape)에서는 행이 주는 키 쪽에만 올 수 있다 +(통과는 인자에 따라 달라지지 않는다). + **걷기.** EACH는 걷는 항목의 위치를 인덱스처럼 들고 블록을 항목마다 돌린다. 블록이 걷는 리스트에서 항목을 지우면(LIST_REMOVE) 그 위치가 걷는 항목 앞이면 한 칸 당기고, 걷는 항목 자신이면 다음 차례에 같은 위치(곧 다음 항목)를 돈다. 블록은 걷는 리스트에 넣을 수 없으므로 걷기는 시작할 때 있던 항목 가운데 차례가 올 때까지 남은 것을 한 번씩, 순서대로 돈다. 블록이 실패하면 이벤트가 @@ -309,6 +317,7 @@ text·리스트가 남을 때만 위치를 유지한다. |---|---| | `GET /views/이름` | 보기의 값. 수는 가장 짧은 왕복 10진수, text는 UTF-8 그대로(`text/plain`). text 상태를 그대로 보이는 보기(`view page = note`)는 저장된 익스텐트를 빌려준다([079](../research/079-lent-views.md)) | | `GET /views/표?from=N&count=M` | 표의 행: `{"rows":전체,"from":N,"items":[{열: 값}…]}`(`application/json`). 요청한 행의 칸만 계산한다. 값이 없는 칸은 `null` | +| `GET /views/이름?인자=값…` | 인자를 받는 보기(표라면 `from`·`count`와 함께). 값은 `%XX`를 풀어 읽고, 고정 필드는 메시지의 쿼리 필드와 같다. 빠진 고정 인자, 모르는 이름, 두 번 준 인자, 타입이 다른 값은 400 `invalid`. 등록한 질의도 같다(`GET /queries/이름?인자=값`) | | `POST /inputs/이름` | 이벤트. text 입력은 본문이 text, 키 입력은 누름(down 뒤 up). 메시지는 고정 필드(u32, 수)를 쿼리(`?points=3`, 그룹 안이면 `?to.zip=7`)로, 가변 필드 하나를 본문으로 받거나, `Content-Type: application/json` 본문의 객체로 필드를 받는다(문자열은 바이트·text, 수는 u32·수, 그룹은 안의 객체). 응답 본문은 핸들러의 `reply`(메시지 필드) | | `POST /inputs/이름` + `X-Pure-Source`·`X-Pure-Sequence` | 다른 앱의 출력에서 전해진 메시지(`pure_app_deliver`): 번호마다 한 번 적용하고, 이미 들은 번호는 200. 답에 `X-Pure-Batch: 256`을 싣고, `X-Pure-Count: N`이면 본문은 N개 객체의 JSON 배열(연속 번호, 한 묶음에서 차례로 적용) | | `GET`·`PUT /objects/키` | 모듈에 키별 메시지 `show`·`edit`가 있으면 기존 문서 서버(`server.c`)와 같은 계약. `GET`은 `show`, `PUT`(`If-Match`/`If-None-Match`)은 `edit` | -- cgit v1.2.3