Broker 쿼리 API
Broker 쿼리 API (Broker Query API)
Pinot 쿼리 API 레퍼런스를 다루는 문서예요. Pinot는 단일 스테이지 실행, 다중 스테이지 실행, 파싱 전용 SQL 문법 검증, 쿼리 핑거프린트 생성을 위한 브로커 엔드포인트를 제공해요. 커서 기반 페이지네이션은 SQL 엔드포인트의 쿼리 파라미터로 사용할 수 있고, 응답 저장소(response-store) 수명주기는 쿼리를 실행한 브로커의 엔드포인트로 관리돼요.
출처: 문서
본문
Pinot는 단일 스테이지 실행, 다중 스테이지 실행, 파싱 전용 SQL 문법 검증, 쿼리 핑거프린트 생성을 위한 브로커 엔드포인트를 노출해요. 커서 기반 페이지네이션은 SQL 엔드포인트의 쿼리 파라미터로 사용할 수 있고, 응답 저장소 수명주기는 쿼리를 실행한 동일 브로커의 엔드포인트로 관리돼요.
POST /query/sql과 POST /query의 경우, 잘못된 형식의 JSON 요청 본문이나 필수 필드가 누락된 페이로드는 HTTP 400 Bad Request를 반환해요. 이 페이지의 헬퍼 엔드포인트들은 엔드포인트별 상태 처리를 가지며, 각 엔드포인트마다 문서화돼 있어요.
엔드포인트 (Endpoints)
| 메소드 | 엔드포인트 | 용도 |
|---|---|---|
POST |
/query/sql |
SQL을 브로커 쿼리 엔드포인트에 제출 |
POST |
/query |
다중 스테이지 엔드포인트로 SQL 제출 |
POST |
/query/sql/validateSyntax |
SQL을 파싱해 Pinot가 문법을 수용하는지 보고 |
POST |
/query/sql/queryFingerprint |
DQL 쿼리에 대한 정규화된 핑거프린트와 안정 해시 생성 |
POST |
/query/sql?getCursor=true |
쿼리 제출 및 커서 기반 첫 페이지 반환 |
GET |
/responseStore/{requestId}/results |
추가 커서 페이지 가져오기 |
GET |
/responseStore/{requestId} |
커서 메타데이터 가져오기 |
GET |
/responseStore |
활성 커서 저장소 나열 |
DELETE |
/responseStore/{requestId} |
커서 응답 저장소 삭제 |
쿼리 제출 (Query Submission)
curl -H "Content-Type: application/json" -X POST \
-d '{"sql":"select foo, count(*) from myTable group by foo limit 100"}' \
http://localhost:8099/query/sql
join이나 window 함수 같은 다중 스테이지 기능이 필요한 문장은 /query를 사용해요:
curl -H "Content-Type: application/json" -X POST \
-d '{"sql":"select count(*) from a JOIN b ON a.x = b.x"}' \
http://localhost:8099/query
POST /query/sql과 POST /query는 둘 다 최상위 sql 필드를 가진 JSON 요청 본문을 요구해요. 요청 본문이 잘못된 JSON이거나 sql 필드가 누락되면 브로커는 HTTP 400 Bad Request를 반환해요.
SQL 문법 검증 (SQL Syntax Validation)
Pinot의 Calcite 기반 파서가 SQL 텍스트를 수용하거나 거부하도록 하는 것만 원한다면 POST /query/sql/validateSyntax를 사용해요. 브로커는 문장을 파싱하지만 실행하거나, 테이블 메타데이터를 가져오거나, 의미론적 검증(semantic validation)을 수행하지는 않아요.
이 엔드포인트는 단일 스테이지와 다중 스테이지 SQL을 모두 수용하며, DQL, DML, DDL, DCL로 파싱되는 문장을 포함해요.
curl -H "Content-Type: application/json" -X POST \
-d '{"sql":"SELECT * FROM myTable WHERE id > 10"}' \
http://localhost:8099/query/sql/validateSyntax
유효한 문법은 valid=true와 파싱된 SQL 타입과 함께 HTTP 200 OK를 반환해요:
{
"valid": true,
"sqlType": "DQL"
}
유효하지 않은 문법도 valid=false와 파서 오류 텍스트와 함께 HTTP 200 OK를 반환해요:
{
"valid": false,
"errorMessage": "Encountered \"FROM\" at line 1, column 8."
}
JSON 페이로드에 sql 필드가 없으면 Pinot는 HTTP 400 Bad Request를 반환해요:
{
"error": "Payload is missing the query string field 'sql'"
}
잘못된 JSON과 기타 예상치 못한 서버 실패는 HTTP 500 Internal Server Error를 반환해요.
관련 헬퍼 엔드포인트와 비교하면:
POST /query/sql/queryFingerprint와 달리 이 엔드포인트는 핑거프린트나 쿼리 해시를 생성하지 않으며 DQL로 제한되지 않아요.- 컨트롤러
POST /validateMultiStageQuery와 달리 이 엔드포인트는 브로커 로컬이며 파싱 전용이에요. 테이블 메타데이터에 대해 쿼리를 컴파일하거나, 의미론을 검증하거나, 다중 스테이지 쿼리로 검증을 제한하지 않아요.
쿼리 핑거프린트 (Query Fingerprints)
DQL 쿼리를 실행하지 않고 정규화된 핑거프린트를 생성하려면 POST /query/sql/queryFingerprint를 사용해요. Pinot는 다음을 포함한 작은 JSON 객체를 반환해요:
queryHash: 정규화된 핑거프린트의 안정 해시fingerprint: 정규화된 SQL 형태
요청 본문에는 sql이 포함되어야 해요:
curl -H "Content-Type: application/json" -X POST \
-d '{"sql":"SELECT * FROM myTable WHERE id IN (1, 2, 3)"}' \
http://localhost:8099/query/sql/queryFingerprint
Pinot는 리터럴을 플레이스홀더로 정규화하므로, 위 예시에 대해 반환되는 핑거프린트는 다음과 같아요:
SELECT * FROM `myTable` WHERE `id` IN (?)
같은 엔드포인트는 다중 스테이지 쿼리도 수용해요. 예를 들어 SET useMultistageEngine=true;가 있는 쿼리도 문장을 실행하지 않고 정규화된 핑거프린트를 반환해요.
이 엔드포인트는 DQL 전용이에요. 잘못된 JSON, 누락된 sql 필드, 유효하지 않은 SQL, 또는 DQL이 아닌 문장은 모두 HTTP 400 Bad Request를 반환해요. 브로커 구성 pinot.broker.enable.query.fingerprinting과 달리, 이 헬퍼 엔드포인트는 정상 쿼리 실행에 대한 자동 핑거프린팅을 활성화하지 않고도 주문형 핑거프린트를 생성할 수 있어요.
커서 페이지네이션 (Cursor Pagination)
커서 기반 쿼리는 클라이언트가 이후 가져오기에 재사용해야 하는 메타데이터와 함께 첫 페이지를 반환해요. 가장 중요한 필드는 requestId, brokerHost, brokerPort, offset, numRows, numRowsResultSet, expirationTimeMs예요.
curl --request POST http://localhost:8099/query/sql?getCursor=true&numRows=1 \
--data '{"sql":"SELECT * FROM nation limit 100"}' | jq
numRows를 생략하거나 0으로 설정하면 Pinot는 pinot.broker.cursor.fetch.rows(기본 10000)를 사용해요. 다음 페이지를 가져오는 방법:
curl -X GET http://localhost:8099/responseStore/236490978000000006/results?offset=1&numRows=1 | jq
행 조각 없이 커서 메타데이터를 읽는 방법:
curl -X GET http://localhost:8099/responseStore/236490978000000006 | jq
운영 노트 (Operational Notes)
- 커서는 브로커 연관(affine)이에요. 후속 요청은 반드시 같은 브로커로 다시 가야 해요.
- 커서 결과는
pinot.broker.cursor.response.store.expiration에 따라 만료되며 결국 컨트롤러가 정리해요. GET /responseStore와DELETE /responseStore/{requestId}는 운영자 지향 응답 저장소 엔드포인트로, 일반적인 클라이언트 페이지네이션 흐름이 아니에요.
이 페이지에서 다룬 내용 (What this page covered)
- 브로커 쿼리 엔드포인트와 의도된 용도
- 파싱 전용 문법 검증 대 핑거프린트 생성·컨트롤러 측 검증
- 커서 기반 페이지네이션과 응답 저장소 수명주기 기초
- 주요 운영 제약: 후속 요청은 같은 브로커로 가야 함
다음 단계 (Next step)
SQL 의미론이 필요하다면 SQL 문법 페이지로, 쿼리 제출 너머의 엔드포인트 상세가 필요하다면 컨트롤러 또는 gRPC 레퍼런스로 이동하세요.