| 포스트그레SQL | ||
|---|---|---|
| 이전 | 31장. SQL 확장: 스포츠 토토 | 다음 |
내부적으로 Postgres는 기본 유형을 "메모리 덩어리"로 간주합니다. 유형에 대해 차례로 정의하는 사용자 정의 스포츠 토토 Postgres가 작동할 수 있는 방식을 정의합니다. 즉, 포스트그레스 디스크에서만 데이터를 저장 및 검색하고 데이터를 입력, 처리, 출력하는 사용자 정의 스포츠 토토입니다. 베이스 유형은 세 가지 내부 형식 중 하나를 가질 수 있습니다.
값 전달, 고정 길이
참조로 전달, 고정 길이
참조로 전달, 가변 길이
값 기준 유형은 길이가 1, 2 또는 4바이트만 될 수 있습니다. 컴퓨터는 다른 크기의 값별 유형을 지원합니다. 포스트그레스 자체적으로는 정수 유형만 값으로 전달합니다. 주의해야 할 점 동일한 크기(바이트 단위)가 되도록 유형을 정의하십시오. 모든 아키텍처에서. 예를 들어 롱타입은 위험해요 일부 시스템에서는 4바이트이고 다른 시스템에서는 8바이트이기 때문에 반면 int 유형은 대부분의 UNIX 시스템에서 4바이트입니다(그러나 UNIX 시스템에서는 그렇지 않음). 대부분의 개인용 컴퓨터). int4의 합리적인 구현 UNIX 시스템의 유형은 다음과 같습니다.
/* 4바이트 정수, 값으로 전달됨 */
typedef int int4;
반면에, 어떤 크기의 고정 길이 유형도 전달될 수 있습니다 참조로. 예를 들어, 다음은 포스트그레스 char16 유형:
/* 참조로 전달된 16바이트 구조 */
형식 정의 구조체
문자 데이터[16];
문자16;
이러한 유형에 대한 포인터만 전달할 때 사용할 수 있으며 Postgres 기능에서 벗어났습니다. 마지막으로 모든 가변 길이 유형은 또한 참조로 전달됩니다. 모든 가변 길이 유형은 시작되어야 합니다. 정확히 4바이트의 길이 필드와 저장될 모든 데이터 해당 유형 내의 항목은 즉시 메모리에 위치해야 합니다. 해당 길이 필드를 따릅니다. 길이 필드는 전체 길이입니다. 구조의 (즉, 길이 필드의 크기를 포함합니다. 자체). 다음과 같이 텍스트 유형을 정의할 수 있습니다.
typedef 구조체
int4 길이;
문자 데이터[1];
텍스트;
분명히 데이터 필드는 모든 데이터를 담을 만큼 길지 않습니다. 가능한 문자열 - 이러한 구조를 선언하는 것은 불가능합니다. C. 가변 길이 유형을 조작할 때 주의해야 할 사항은 다음과 같습니다. 올바른 양의 메모리를 할당하고 길이를 초기화하십시오. 필드. 예를 들어 텍스트에 40바이트를 저장하려는 경우 구조에 따라 다음과 같은 코드 조각을 사용할 수 있습니다.
#include "postgres.h"
#include "utils/palloc.h"
...
문자 버퍼[40]; /* 소스 데이터 */
...
텍스트 *목적지 = (텍스트 *) palloc(VARHDRSZ + 40);
대상-길이 = VARHDRSZ + 40;
memmove(대상-데이터, 버퍼, 40);
...
이제 우리는 기지의 가능한 모든 구조를 검토했습니다. 유형에 따라 실제 스포츠 토토의 몇 가지 예를 보여줄 수 있습니다. 가정funcs.c다음과 같습니다:
#include <string.h
#include "postgres.h" /* char16 등의 경우 */
#include "utils/palloc.h" /* palloc의 경우 */
정수
add_one(int 인수)
return(인수 + 1);
문자16 *
concat16(char16 *arg1, char16 *arg2)
char16 *new_c16 = (char16 *) palloc(sizeof(char16));
memset((void *) new_c16, 0, sizeof(char16));
(공허) strncpy(new_c16, arg1, 16);
return (char16 *)(strncat(new_c16, arg2, 16));
텍스트 *
카피텍스트(텍스트 *t)
/*
* VARSIZE는 구조체의 총 크기(바이트)입니다.
*/
text *new_t = (text *) palloc(VARSIZE(t));
memset(new_t, 0, VARSIZE(t));
VARSIZE(new_t) = VARSIZE(t);
/*
* VARDATA는 구조체의 데이터 영역에 대한 포인터입니다.
*/
memcpy((void *) VARDATA(new_t), /* 대상 */
(void *) VARDATA(t), /* 소스 */
VARSIZE(t)-VARHDRSZ); /* 몇 바이트 */
return(new_t);
OSF/1에서는 다음을 입력합니다:
스포츠 토토 생성 add_one(int4) 반환 int4
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
스포츠 토토 생성 concat16(char16, char16)은 char16을 반환합니다.
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
CREATE FUNCTION copytext(text) 텍스트를 반환합니다.
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
다른 시스템에서는 파일 이름을 .sl로 끝내야 할 수도 있습니다. (공유 라이브러리임을 나타냅니다.)
복합 유형에는 C 구조와 같은 고정 레이아웃이 없습니다. 복합 유형의 인스턴스에는 null 필드가 포함될 수 있습니다. 또한, 상속 계층의 일부인 복합 유형은 다음을 가질 수 있습니다. 동일한 상속의 다른 멤버와 다른 필드 계층 구조. 따라서 Postgres는 다음을 위한 절차적 인터페이스를 제공합니다. C에서 복합 유형의 필드에 액세스합니다. Postgres가 인스턴스 집합, 각 인스턴스가 함수에 전달됩니다. TUPLE 유형의 불투명 구조입니다. 우리가 쿼리에 응답하는 함수
* SELECT 이름, c_overpaid(EMP, 1500) AS 초과 지불
EMP에서
WHERE 이름 = 'Bill' 또는 이름 = 'Sam';위 쿼리에서 c_overpaid를 다음과 같이 정의할 수 있습니다.#include "postgres.h" /* char16 등의 경우 */
#include "libpq-fe.h" /* TUPLE의 경우 */
부울
c_overpaid(TUPLE t,/* EMP의 현재 인스턴스 */
int4 제한)
부울 isnull = false;
int4 급여;
급여 = (int4) GetAttributeByName(t, "급여", &isnull);
만약 (isnull)
반환(거짓);
return(급여 한도);
GetAttributeByName은 다음을 반환하는 Postgres 시스템 함수입니다. 현재 인스턴스의 속성입니다. 여기에는 세 가지 인수가 있습니다. 함수에 전달된 TUPLE 유형의 인수, 원하는 속성 및 여부를 설명하는 반환 매개변수 속성이 null입니다. GetAttributeByName은 데이터를 올바르게 정렬합니다. 따라서 반환 값을 원하는 유형으로 캐스팅할 수 있습니다. 예를 들어, char16 유형의 속성 이름이 있는 경우 GetAttributeByName 호출은 다음과 같습니다.
char *str;
...
str = (char *) GetAttributeByName(t, "name", &isnull)
다음 쿼리는 Postgres에 c_overpaid에 대해 알립니다. 기능:
* 스포츠 토토 생성 c_overpaid(EMP, int4) RETURNS bool
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
새 인스턴스를 구성하거나 수정하는 방법이 있지만 C 스포츠 토토 내의 기존 인스턴스는 너무 멀습니다. 이 매뉴얼에서 논의하기에는 복잡합니다.
이제 우리는 프로그래밍 작성이라는 더 어려운 작업으로 넘어갑니다. 언어 기능. 주의하세요: 매뉴얼의 이 섹션은 그렇지 않습니다. 너를 프로그래머로 만들어라. C에 대한 이해가 좋아야 합니다. (포인터 및 malloc 메모리 관리자 사용 포함) Postgres와 함께 사용할 C 함수를 작성하기 전에. 그러는 동안 C 이외의 언어로 작성된 함수를 로드하는 것이 가능할 수도 있습니다. Postgres에서는 이것이 종종 어렵습니다(가능한 경우). FORTRAN이나 Pascal과 같은 다른 언어는 종종 그렇지 않기 때문입니다. C와 동일한 "호출 규칙"을 따릅니다. 즉, 다른 언어는 함수 간에 인수와 반환 값을 전달하지 마십시오. 같은 방식으로. 이러한 이유로 우리는 귀하의 프로그래밍이 언어 함수는 C로 작성됩니다. C를 구축하기 위한 기본 규칙 기능은 다음과 같습니다:
Postgres에 대한 대부분의 헤더(포함) 파일은 이미 설치되어 있습니다.PGROOT/포함(그림 2 참조). 당신은해야 항상 포함
-I$PGROOT/포함cc 명령줄에. 때때로, 당신은 당신이 서버 소스 자체에 있는 헤더 파일이 필요합니다(예: include에 설치하지 않은 파일이 필요합니다). 그런 경우에는 다음 중 하나 이상을 추가해야 할 수도 있습니다.
-I$PGROOT/src/백엔드
-I$PGROOT/src/백엔드/포함
-I$PGROOT/src/백엔드/포트/<PORTNAME
-I$PGROOT/src/백엔드/obj(여기서 <PORTNAME은 포트 이름입니다. 예: alpha
또는 스파크).메모리를 할당할 때 Postgres 루틴 palloc 및 해당 C 라이브러리 루틴 malloc 대신 pfree 그리고 무료. palloc에 의해 할당된 메모리가 해제됩니다. 각 트랜잭션이 끝날 때 자동으로 메모리를 방지합니다. 누출.
항상 memset을 사용하여 구조의 바이트를 0으로 설정하거나 비제로. 여러 루틴(예: 해시 액세스 방법, 해시 조인 및 정렬 알고리즘) 원시 비트의 스포츠 토토를 계산합니다. 귀하의 구조에 포함되어 있습니다. 모든 필드를 초기화해도 구조에 몇 바이트의 정렬이 있을 수 있습니다. 쓰레기를 포함할 수 있는 패딩(구조물의 구멍) 값.
대부분의 내부 Postgres 유형은 다음에서 선언됩니다. postgres.h이므로 일반적으로 해당 파일을 다음과 같이 포함하는 것이 좋습니다. 음.
객체 코드를 컴파일하고 로드하는 중입니다. Postgres에 동적으로 로드하려면 항상 특수 플래그가 필요합니다. 이를 수행하는 방법에 대한 자세한 설명은 부록 A를 참조하십시오. 귀하의 특정 운영 체제.
| 이전 | 집 | 다음 |
| SQL 확장: 스포츠 토토 | 위로 | SQL 확장: 유형 |