이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
당신은 다음과 같은 페이지를 보고 싶을 수도 있습니다.PostgreSQL : 문서 : 17 : 36.13. 사용자 정의 토토 캔버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

34.11. 사용자 정의 범퍼카 토토

설명에 따라PostgreSQL : 문서 : 8.3 : PostgreSQL 배트맨 토토 시스템, 포스트그레SQL될 수 있습니다 새로운 데이터 유형을 지원하도록 확장되었습니다. 이 섹션에서는 다음 방법을 설명합니다. 아래에 정의된 데이터 유형인 새로운 기본 유형을 정의합니다. 수준SQL언어. 새로운 기본 유형을 생성하려면 다음을 수행하는 함수를 구현해야 합니다. 일반적으로 C와 같은 저수준 언어로 유형을 조작합니다.

이 섹션의 예는 다음에서 찾을 수 있습니다.복잡한.sql그리고복잡한.c에서src/튜토리얼소스 디렉토리 유통. 참조README파일 있음 예제 실행에 대한 지침은 해당 디렉토리를 참조하세요.

사용자 정의 범퍼카 토토에는 항상 입력과 출력 함수.이 기능은 다음 방법을 결정합니다. 유형은 문자열로 나타납니다(사용자가 입력하고 사용자) 및 유형이 메모리에서 구성되는 방식. 입력 기능 null로 끝나는 문자열을 인수로 사용하고 유형의 내부(메모리 내) 표현을 반환합니다. 는 출력 함수는 유형의 내부 표현을 다음과 같이 사용합니다. 인수를 입력하고 null로 끝나는 문자열을 반환합니다. 만약 우리가 단순히 저장하는 것 이상으로 유형에 대해 더 많은 작업을 수행하고 싶습니다. 무엇이든 구현하려면 추가 기능을 제공해야 합니다. 해당 유형에 대해 갖고 싶은 작업입니다.

범퍼카 토토을 정의하고 싶다고 가정복잡한복소수를 나타냅니다. 표현하는 자연스러운 방법 메모리의 복소수는 다음과 같은 C 구조입니다.

typedef 구조체 복합체 
    더블엑스;
    이중 y;
 복잡;

우리는 이것을 참조에 의한 전달 범퍼카 토토으로 만들어야 합니다. 너무 커서 한 장에 들어갈 수 없습니다.데이텀값.

범퍼카 토토의 외부 문자열 표현으로 우리는 형식의 문자열(x,y).

입력 및 출력 함수는 일반적으로 작성하기 어렵지 않습니다. 특히 출력 기능. 그러나 외부를 정의할 때 유형의 문자열 표현을 사용하려면 다음을 수행해야 한다는 점을 기억하세요. 결국에는 이에 대한 완전하고 강력한 파서를 작성합니다. 입력 기능으로 표현합니다. 예를 들어:

PG_FUNCTION_INFO_V1(콤플렉스인);

데이텀
complex_in(PG_FUNCTION_ARGS)

    char *str = PG_GETARG_CSTRING(0);
    더블 엑스,
                와이;
    복잡한 *결과;

    if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
        ereport(오류,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("복합체에 대한 잘못된 입력 구문: \"%s\"",
                        str)));

    결과 = (복소수 *) palloc(sizeof(복소수));
    결과-x = x;
    결과-y = y;
    PG_RETURN_POINTER(결과);

출력 기능은 간단하게 다음과 같습니다:

PG_FUNCTION_INFO_V1(complex_out);

데이텀
complex_out(PG_FUNCTION_ARGS)

    복잡한 *복잡한 = (복잡한 *) PG_GETARG_POINTER(0);
    문자 *결과;

    결과 = (char *) palloc(100);
    snprintf(결과, 100, "(%g,%g)", 복합체-x, 복합체-y);
    PG_RETURN_CSTRING(결과);

입력 및 출력 기능을 만드는 데 주의해야 합니다. 서로 반대. 그렇지 않으면 심각한 일이 생길 것입니다. 데이터를 파일로 덤프해야 할 때 문제가 발생합니다. 다시 읽어보세요. 이는 특히 다음과 같은 경우에 흔히 발생하는 문제입니다. 부동 소수점 숫자가 포함됩니다.

선택적으로 사용자 정의 범퍼카 토토은 바이너리 입력을 제공할 수 있으며 출력 루틴. 바이너리 I/O는 일반적으로 더 빠르지만 이식성이 떨어집니다. 텍스트 I/O보다 텍스트 I/O와 마찬가지로 정의하는 것은 사용자의 몫입니다. 정확히 외부 이진 표현이 무엇인지. 대부분의 내장 데이터 범퍼카 토토은 기계 독립적인 바이너리를 제공하려고 합니다. 표현. 에 대한복잡한, 그럴게요 범퍼카 토토에 대한 바이너리 I/O 변환기에 피기백float8:

PG_FUNCTION_INFO_V1(complex_recv);

데이텀
complex_recv(PG_FUNCTION_ARGS)

    StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
    복잡한 *결과;

    결과 = (복소수 *) palloc(sizeof(복소수));
    결과-x = pq_getmsgfloat8(buf);
    결과-y = pq_getmsgfloat8(buf);
    PG_RETURN_POINTER(결과);

PG_FUNCTION_INFO_V1(complex_send);

데이텀
complex_send(PG_FUNCTION_ARGS)

    복잡한 *복잡한 = (복잡한 *) PG_GETARG_POINTER(0);
    StringInfoData buf;

    pq_begintypsend(&buf);
    pq_sendfloat8(&buf, complex-x);
    pq_sendfloat8(&buf, complex-y);
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));

I/O 함수를 작성하고 이를 다음으로 컴파일한 후에는 공유 라이브러리에서는 다음을 정의할 수 있습니다.복잡한SQL을 입력하세요. 먼저 이를 쉘 유형으로 선언합니다.

CREATE TYPE 콤플렉스;

이것은 우리가 다음을 참조할 수 있는 자리 표시자 역할을 합니다. I/O 기능을 정의하는 동안 입력합니다. 이제 I/O를 정의할 수 있습니다. 기능:

CREATE FUNCTION complex_in(cstring)
    반품 콤플렉스
    그대로 '파일 이름'
    언어 C 불변 STRICT;

CREATE FUNCTION complex_out(복잡한)
    반환 cstring
    그대로 '파일 이름'
    언어 C 불변 STRICT;

CREATE FUNCTION complex_recv(내부)
   반품 콤플렉스
   그대로 '파일 이름'
   언어 C 불변 STRICT;

CREATE FUNCTION complex_send(복잡한)
   반환 bytea
   그대로 '파일 이름'
   언어 C 불변 STRICT;

마지막으로 데이터의 완전한 정의를 제공할 수 있습니다. 범퍼카 토토:

CREATE TYPE 콤플렉스(
   내부 길이 = 16, 
   입력 = complex_in,
   출력 = complex_out,
   수신 = complex_recv,
   보내기 = complex_send,
   정렬 = 이중
);

새 기본 범퍼카 토토을 정의할 때,PostgreSQL자동으로 지원 제공 해당 유형의 배열의 경우.배열 범퍼카 토토은 일반적으로 기본 범퍼카 토토과 동일한 이름을 갖습니다. 밑줄 문자(_)가 앞에 붙습니다.

데이터 유형이 존재하면 추가 기능을 선언할 수 있습니다 데이터 유형에 대한 유용한 작업을 제공합니다. 그러면 운영자는 다음을 수행할 수 있습니다. 함수 위에 정의되고, 필요한 경우 연산자 클래스 데이터 유형의 인덱싱을 지원하기 위해 생성될 수 있습니다. 이것들 추가 레이어는 다음 섹션에서 논의됩니다.

당신의 가치가 데이터 범퍼카 토토의 크기(내부 형식)가 다양하므로 데이터 범퍼카 토토토스트-가능(참조섹션 53.2). 당신은해야합니다 이는 데이터가 항상 너무 작아서 압축할 수 없는 경우에도 마찬가지입니다. 외부에 저장되기 때문입니다.토스트작은 데이터에서도 공간을 절약할 수 있습니다. 헤더 오버헤드를 줄입니다.

이를 위해서는 내부 표현이 다음을 따라야 합니다. 가변 길이 데이터의 표준 레이아웃: 처음 4바이트 이어야 합니다.문자[4]절대 없는 필드 직접 액세스됨(관례적으로 이름 지정됨)vl_len_). 반드시 사용해야 합니다SET_VARSIZE()데이텀의 크기를 저장하려면 이 필드와VARSIZE()에 그것을 검색하십시오. 데이터 유형에 대해 작동하는 C 함수는 다음과 같아야 합니다. 항상 건네준 구운 값을 풀도록 주의하세요. 사용하여PG_DETOAST_DATUM. (이 세부 사항은 범퍼카 토토별로 정의하여 관례적으로 숨겨집니다.GETARG_DATATYPE_P매크로.) 그런 다음, 실행할 때범퍼카 토토 생성명령, 내부 길이를 다음과 같이 지정하십시오.변수적절한 저장 옵션을 선택하세요.

정렬이 중요하지 않은 경우(단지 특정 함수 또는 데이터 범퍼카 토토이 바이트 정렬을 지정하기 때문에 어쨌든) 그러면 일부 오버헤드를 피할 수 있습니다.PG_DETOAST_DATUM. 당신은 사용할 수 있습니다PG_DETOAST_DATUM_PACKED대신 (관습적으로 다음을 정의하여 숨겨집니다.GETARG_DATATYPE_PP매크로) 및 매크로 사용VARSIZE_ANY_EXHDR그리고VARDATA_ANY잠재적으로 포장된 항목에 액세스하려면 데이텀. 다시 말하지만, 이러한 매크로에 의해 반환된 데이터는 정렬되지 않습니다. 데이터 유형 정의가 정렬을 지정하더라도 마찬가지입니다. 만약 정렬이 중요하므로 정기적인 점검을 거쳐야 합니다.PG_DETOAST_DATUM인터페이스.

참고:이전 코드가 자주 선언됨vl_len_으로int32필드 대신문자[4]. 이것은 괜찮습니다 구조체 정의에 다음과 같은 다른 필드가 있는 한 최소한int32정렬. 하지만 그것은 작업할 때 그러한 구조체 정의를 사용하는 것은 위험합니다. 잠재적으로 정렬되지 않은 데이텀; 컴파일러는 그것을 다음과 같이 받아들일 수 있습니다. 데이텀이 실제로 정렬되어 있다고 가정할 수 있는 라이센스 엄격한 아키텍처의 코어 덤프 정렬.

자세한 내용은 다음 설명을 참조하세요.범퍼카 토토 생성명령.