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