이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 보려고 할 수 있습니다현재버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

54.2. 확장 성

SP-Gist인터페이스를 제공합니다 높은 수준의 추상화로 액세스 방법이 필요합니다. 주어진 데이터에 특정한 방법 만 구현하는 개발자 유형. 그만큼SP-Gist코어는 효율적인 디스크 매핑 및 트리 검색을 담당합니다 구조. 또한 동시성과 로깅을 처리합니다 고려 사항.

leaf tuples ofSP-Gist트리에는 인덱스 열과 동일한 데이터 유형의 값이 포함되어 있습니다. 루트 레벨의 잎 윈 토토에는 항상 원본이 포함됩니다. 인덱싱 된 데이터 값이지만 낮은 레벨의 잎 윈 토토에는 접미사와 같은 압축 된 표현 만. 이 경우 운영자 클래스 지원 기능은 재구성 할 수 있어야합니다. 내부에서 축적 된 정보를 사용한 원래 값 잎 수준에 도달하기 위해 통과 된 윈 토토.

내부 윈 토토은 분기점이기 때문에 더 복잡합니다. 검색 트리에서. 각각의 내부 윈 토토에는 하나의 세트가 포함되어 있습니다 더노드, 그룹을 대표합니다 비슷한 잎 값. 노드에는 다운 링크가 포함되어 있습니다 다른, 하위 수준 내부 튜플 또는 짧은 잎 목록 모두 같은 색인 페이지에있는 튜플. 각 노드에는에레이블예를 들어, 접미사 트리 노드 레이블이 다음 문자 일 수 있습니다. 문자열 값. 선택적으로, 내부 튜플은 a를 가질 수 있습니다.prefix모든 회원을 설명하는 값. a 접미사 트리 이것은 표현의 일반적인 접두사 일 수 있습니다. 문자열. 접두사 값은 반드시 접두사 일 필요는 없지만 운영자 클래스가 필요한 데이터 일 수 있습니다. 예를 들어, a 쿼드 트리 4 사분면이있는 중심점을 저장할 수 있습니다. 관련하여 측정됩니다. 그런 다음 쿼드 트리 내부 튜플이 될 것입니다 또한 주위의 사분면에 해당하는 4 개의 노드가 포함되어 있습니다 이 중심점.

일부 트리 알고리즘은 레벨 (또는 깊이)에 대한 지식이 필요합니다. 현재 튜플, 그래서SP-Gist코어는 가능성을 제공합니다 내림차순으로 레벨 카운팅을 관리하는 운영자 클래스 나무. 또한 점진적으로 재구성을 지원합니다 필요할 때 대표 값.

참고 :theSP-Gist103PostgreSQL : 문서 : 9.2 : Extensibility99SP-Gist인덱스는 색인 된 열의 널에 대한 저장 항목이 있습니다. 인덱스 연산자 클래스 코드에서 숨겨져 있습니다. 항목 또는 검색 조건은 운영자 클래스 방법. (SP-Gist운영자는 엄격합니다 NULL 값에 대해서는 성공할 수 없습니다.) 따라서 NULL 값이 있습니다 여기서 더 이상 논의되지 않았습니다.

인덱스 운영자가 5 가지 사용자 정의 방법이 있습니다 클래스SP-Gist제공하다. 5 명 모두 2 개를 수락하는 협약을 따릅니다내부인수, 첫 번째는 a 지지를위한 입력 값을 포함하는 C 구조물에 대한 포인터 두 번째 인수는 C 구조물에 대한 포인터입니다. 출력 값을 배치 해야하는 경우. 4 가지 방법은 그냥 반품void, 모든 결과가 나타나기 때문에 출력 구조물에서; 하지만Leaf_consistent추가로 반환부울결과. 메소드는 수정해서는 안됩니다 입력 구조의 모든 필드. 모든 경우에 출력 사용자 정의를 호출하기 전에 구조물은 0으로 초기화됩니다 방법.

5 가지 사용자 정의 방법은 다음과 같습니다.

config

지수에 대한 정적 정보를 반환합니다 접두사의 데이터 유형 OID를 포함한 구현 및 노드 레이블 데이터 유형.

theSQL선언 함수는 다음과 같아야합니다.

함수 만들기 my_config (내부, 내부) 반환 void ...

첫 번째 인수는 A에 대한 포인터입니다.SPGCONFIGINC 입력을 포함하는 구조 기능에 대한 데이터. 두 번째 논쟁은 포인터입니다 에이SPGCONFIGOUTc 구조 함수는 결과 데이터로 채워야합니다.

typedef struct spgconfigin

    Oid Atttype;        / * 색인화 할 데이터 유형 */
 spgconfigin;

typedef struct spgconfigout

    OID PREFIXTYPE;     / * 내부 튜플 접두사의 데이터 유형 */
    OID LABELTYPE;      / * 내부 튜플 노드 레이블의 데이터 유형 */
    BOOL CANRETURNDATA;  / * opclass는 원본 데이터를 재구성 할 수 있습니다 */
    BOOL LONGVALUESOK;   / * opclass는 값에 대처할 수 있습니다 1 페이지 */
 spgconfigout;

atttype순서대로 전달됩니다 다형성 인덱스 연산자 클래스를 지원하기 위해; 평범한 고정 데이터 유형 운영자 클래스는 항상 있습니다 동일한 값과 무시할 수 있습니다.

접두사를 사용하지 않는 운영자 클래스의 경우PrefixType로 설정할 수 있습니다voidoid. 마찬가지로 운영자를 위해 노드 레이블을 사용하지 않는 클래스,labelType로 설정할 수 있습니다voidoid. CanreturnData운영자 클래스는 재구성 할 수 있습니다 원래 보관 된 인덱스 값.Lo윈 토토Valuesok는 맞아야합니다 때atttype가변 길이와 연산자 클래스가 가능합니다 반복 된 접미사로 긴 값을 분할 ( 참조)섹션 54.3.1).

선택

새 값을 내부에 삽입하는 메소드를 선택합니다. 튜플.

theSQL선언 함수는 다음과 같아야합니다.

함수 생성 my_choose (내부, 내부) 반환 void ...

첫 번째 인수는 A에 대한 포인터입니다.SpgchooseinC 구조물, 입력을 포함합니다 기능에 대한 데이터. 두 번째 논쟁은 포인터입니다 에이spgchooseoutc 구조 함수는 결과 데이터로 채워야합니다.

typedef struct spgchoosein

    데이텀 데이텀;          / * 색인화 될 원본 데이텀 */
    데이텀 리프 듀다;      / * 잎에 저장 될 전류 데이텀 */
    int 레벨;          / * 현재 레벨 (0에서 계산) */

    / * 현재 내부 튜플의 데이터 */
    BOOL ALLTHESAME;     /* 튜플은 모든 것이 표시되어 있습니까? */
    BOOL HASPREFIX;      /* 튜플에는 접두사가 있습니까? */
    Datum Prefixdatum;    / * 그렇다면 접두사 값 */
    int nnodes;         / * 내부 튜플의 노드 수 */
    Datum *Nodelabels;     / * 노드 레이블 값 (null이 없음) */
 spgchoosein;

typedef enum spgchooseresulttype

    spgmatchnode = 1, / * 기존 노드로 내려갑니다 * /
    spgaddnode, / * 내부 튜플에 노드를 추가하십시오 * /
    spgsplittuple / * 분할 내부 튜플 (접두사 변경) * /
 spgchooseresulttype;

typedef struct spgchooseout

    spgchooseresulttype resulttype;     / * 액션 코드, 위 참조 */
    노동 조합

        spgmatchnode * /struct / * 결과 * /

            int noden;      / *이 노드로 내려갑니다 (0에서 index) */
            int levelAdd;   / *이 정도의 증분 레벨 */
            데이텀리스트 덤;  / * 새로운 잎 기준 */
         matchNode;
        spgaddnode * /struct / * 결과 * /

            데이텀 노 델라벨;  / * 새 노드 레이블 */
            int noden;      / * 삽입 할 위치 (0에서 색인) */
         addnode;
        spgsplittuple에 대한 struct / * 결과 * /

            / * 하나의 노드로 새로운 내부 튜플을 형성하는 정보 */
            부울 접두사 hasprefix;    /* 튜플은 접두사가 있어야합니까? */
            Datum PrefixprefixDatum;  / * 그렇다면 그 가치 */
            데이텀 노 델라벨;          / * 노드 레이블 */

            / * 모든 오래된 노드와 함께 새로운 하위 수준 내부 튜플을 형성하는 정보 */
            bool postfixhasprefix;   /* 튜플은 접두사가 있어야합니까? */
            Datum postfixprefixdatum; / * 그렇다면 그 가치 */
         splittuple;
               결과;
 spgchooseout;

Datum는 원래 데이텀입니다 그것은 색인에 삽입되어야했다.Leafdatum처음에는와 동일합니다.Datum그러나 낮은 곳에서 변경 될 수 있습니다 트리의 레벨 인 경우선택또는picksplit메소드를 변경합니다. 언제 삽입 검색은 잎 페이지에 도달합니다.Leafdatum새로 생성 된 잎 윈 토토에 저장됩니다.레벨는 현재 내부 튜플입니다 레벨, 루트 레벨의 경우 0에서 시작합니다.Allthesame현재 내부 인 경우 참입니다 튜플은 여러 동등한 노드를 포함하는 것으로 표시됩니다 (보다섹션 54.3.3).hasprefix사실입니다 전류 내부 튜플에 접두사가 포함 된 경우; 그렇다면,prefixdatum값입니다.nnodes는 자녀의 수입니다 내부 튜플에 포함 된 노드 및Nodelabels는 레이블의 배열입니다 레이블이없는 경우 값 또는 NULL.

the선택함수는 할 수 있습니다 새로운 값이 하나와 일치하는지 결정하십시오. 기존 자식 노드 또는 새 하위 노드가 추가되었거나 새 값이 튜플과 일치하지 않습니다. 접두사 및 따라서 내부 튜플을 분할하여 덜 제한적인 접두사.

새 가치가 기존 자녀 중 하나와 일치하는 경우 노드, setresulttypetoSPGMATCHNODE. 세트Noden그 인덱스 (제로)로 노드 어레이의 노드. 세트levelAdd증분으로레벨그로 인해 내림차순으로 인한 노동 레벨을 사용합니다. 세트RestdatumTO 동일한Datum운영자 인 경우 클래스 그렇지 않으면로 사용할 수정 된 값으로 설정하십시오.Leafdatum다음 수준.

새 하위 노드를 추가 해야하는 경우resultTypetoSpgaddnode. 세트Nodelabel사용되는 레이블에 새 노드 및 setNodenTO 노드를 노드 어레이. 노드가 추가 된 후선택함수가 다시 호출됩니다 변형 된 내부 튜플; 그 전화는를 초래해야합니다.SPGMATCHNODE결과.

새 값이 윈 토토 접두사와 일치하지 않는 경우, 세트resulttypetospgsplittuple. 이 행동은 모든 것을 움직입니다 기존 노드는 새로운 하위 수준의 내부 튜플로, 그리고 기존 내부 튜플을 튜플로 대체합니다. 새로운 하위 레벨 내부 튜플에 연결되는 단일 노드. 세트prefixhasprefixTO 새로운 상부 윈 토토에 접두사가 있어야하는지 여부를 나타냅니다. 그리고 그렇게 설정된 경우prefixprefixDatum접두사 값으로. 이 새로운 접두사 값은 충분히 덜 제한적이어야합니다 인덱싱 할 새 값을 수락하려는 원본보다 그리고 그것은 더 이상 원래 접두사보다 더 이상 아니어야합니다. 세트Nodelabel라벨에 새로운 하위 레벨을 가리킬 노드에 사용 내부 튜플. 세트PostFixHaspRefix새로운 하위 수준의 내부 튜플은 접두사가 있어야합니다. 세트PostFixPrefixDatum접두사 값. 이 두 접두사의 조합 추가 레이블은 원본과 동일한 의미를 가져야합니다. 노드를 변경할 기회가 없기 때문에 접두사 새로운 하위 수준 튜플로 이동하거나 자식 색인 항목을 변경하십시오. 노드 후 분할,선택함수 교체 내부 튜플로 다시 호출됩니다. 저것 통화는 일반적으로를 초래합니다.Spgaddnode아마도 노드이기 때문에 결과 분할 단계에 추가 된 레이블은 새 값과 일치하지 않습니다. 그 후, 마지막으로 세 번째 전화가있을 것입니다. 보고SPGMATCHNODE잎 수준으로 내려 가려는 삽입.

picksplit

​​세트에 새 윈 토토을 만드는 방법 결정 잎 윈 토토.

theSQL선언 함수는 다음과 같아야합니다.

함수 생성 my_picksplit (내부, 내부) 반환 void ...

첫 번째 인수는 a에 대한 포인터입니다.SPGPICKSPLITINc 입력을 포함하는 구조 기능에 대한 데이터. 두 번째 논쟁은 포인터입니다 에이SPGPICKSPLITOUTC 구조, 함수가 결과 데이터로 채워야합니다.

typedef struct spgpicksplitin

    int ntuples;        / * 잎 튜플 수 */
    데이텀 *데이텀;         / * 그들의 데이텀 (길이의 배열 ntuples) */
    int 레벨;          / * 현재 레벨 (0에서 계산) */
 spgpicksplitin;

typedef struct spgpicksplitout

    BOOL HASPREFIX;      /* 새로운 내부 튜플이 접두사가 있어야합니까? */
    Datum Prefixdatum;    / * 그렇다면 그 가치 */

    int nnodes;         / * 새 내부 튜플에 대한 노드 수 */
    Datum *Nodelabels;     / * 레이블 (또는 레이블 없음) */

    int *maptuplestonodes;   / * 각 잎에 대한 노드 인덱스 */
    데이텀 *리프트 수스 룸;    / * 각각의 새로운 잎 튜플에 보관할 데이 텀 */
 spgpicksplitout;

ntuples는 수입니다 제공된 잎 윈 토토.Datums는 데이텀 값의 배열입니다.레벨는 모든 수준입니다 잎 튜플이 공유하며, 새로운 수준이 될 것입니다. 내부 튜플.

SEThasprefix새로운 내부 튜플에 접두사가 있어야하는지 여부, 그렇다면 세트PrefixDatum접두사에 값. 세트nnodes새로운 내부 튜플에 포함 할 노드 수, 그리고 setNodelabels배열로 그들의 레이블 값의. (노드에 레이블이 필요하지 않은 경우 세트Nodelabels보다섹션 54.3.2자세한 내용.) SETMaptuplestonodes제공되는 배열 각 잎이 튜플 인 노드의 인덱스 (0에서) 할당해야합니다. 세트Leaftupledatums의 배열에 새로운 잎 윈 토토에 저장 될 값 (이것들은 입력과 동일Datums운영자 클래스가 한 레벨에서 기준을 수정하지 않는 경우 다음으로).picksplit함수는 palloc'ing theNodelabels, MaptuplestonodesandLeaftupledatums배열.

둘 이상의 잎 윈 토토이 제공되면 예상됩니다. 그게picksplit함수 둘 이상의 노드로 분류합니다. 그렇지 않으면 잎 튜플을 여러 건에 쪼개는 것은 불가능합니다 이 작업의 궁극적 인 목적입니다. 따라서이면picksplit함수는 모든 잎 튜플을 동일하게 배치하게됩니다. 노드, Core SP-Gist 코드는 해당 결정을 무시하고 잎 튜플이있는 내부 튜플을 생성합니다. 무작위로 여러 동일하게 표지 된 노드에 할당됩니다. 그러한 튜플은 표시되어 있습니다Allthesame이것이 일어났다는 것을 나타냅니다. 그만큼선택andInner_consistent함수는 가져와야합니다 그러한 내부 튜플에 적합한 관리. 보다섹션 54.3.3자세한 내용은

picksplit를 적용 할 수 있습니다 단일 잎 윈 토토에만config함수 세트Lo윈 토토Valuesoktrue and a 페이지보다 큰 입력 값이 제공되었습니다. 이것에서 사례 작업 지점은 접두사를 벗기는 것입니다. 새롭고 짧은 잎 기준 값을 생성합니다. 전화가 의지합니다 잎 기준이 짧아 질 때까지 반복됩니다. 페이지가 생성되었습니다. 보다섹션 54.3.1자세한 내용은

Inner_consistent

트리 중에 따라야 할 노드 세트 (분기) 세트를 반환합니다 찾다.

theSQL선언 함수는 다음과 같아야합니다.

함수 생성 my_inner_consistent (내부, 내부) 반환 void ...

첫 번째 인수는 A에 대한 포인터입니다.SpginnerConsistentinc 구조물, 포함 함수에 대한 입력 데이터. 두 번째 논쟁은 a A에 대한 포인터SpginnerConsistentOutC 구조 함수는 결과 데이터로 채워야합니다.

typedef struct spginnerconsistentin

    스캔 키 스캔 키;       / * 운영자 배열 및 비교 값 */
    int nkeys;          / * 배열 길이 */

    Datum ReconstructedValue;     / * 부모에게 재구성 된 값 */
    int 레벨;          / * 현재 레벨 (0에서 계산) */
    bool returndata;     /* 원본 데이터를 반환해야합니까? */

    / * 현재 내부 튜플의 데이터 */
    BOOL ALLTHESAME;     /* 튜플은 모든 것이 표시되어 있습니까? */
    BOOL HASPREFIX;      /* 튜플에는 접두사가 있습니까? */
    Datum Prefixdatum;    / * 그렇다면 접두사 값 */
    int nnodes;         / * 내부 튜플의 노드 수 */
    Datum *Nodelabels;     / * 노드 레이블 값 (null이 없음) */
 SpginnerConsistentin;

typedef struct spginnerconsistentout

    int nnodes;         / * 방문 할 어린이 노드 수 */
    int *nodenumbers;    / * 노드 어레이의 인덱스 */
    int *levelAdds;      / * 각 */에 대한 이거 화수율
    Datum *재구성 Values;    / * 관련 재구성 값 */
 spginnerConsistEntOut;

배열Scankeys, OF 길이nkeys, 색인 검색 조건. 이러한 조건이 결합되어 있습니다 그들과 함께 - 그들 모두를 만족시키는 인덱스 항목 만 흥미로운. (nkeys= 0은 모든 인덱스 항목이 쿼리를 만족 함을 의미합니다.) 일반적으로 일관된 함수는에만 관심이 있습니다.sk_strategyandsk_argument각 배열 항목의 필드, 각각 색인 가능한 연산자에게 제공합니다 비교 값. 특히 필요하지 않습니다 확인하다sk_flagsSP-Gist 핵심 코드이기 때문에 비교 값은 null입니다 그러한 조건을 필터링합니다.재구성 value값입니다 부모 윈 토토에 대해 재구성; 그것은(Datum) 0루트 레벨에서 또는Inner_consistent함수 부모 수준에서 값을 제공하지 않습니다.레벨는 현재 내부 튜플입니다 레벨, 루트 레벨의 경우 0에서 시작합니다.returnDataistrue재구성 된 데이터가 필요한 경우 이 쿼리; 이것은만큼 그렇게 될 것입니다config기능 주장CanreturnData. Allthesame현재 내부 인 경우 참입니다 튜플이 표시되어"All-the-Same"; 이 경우 모든 노드는 동일한 레이블 (있는 경우)을 가지고 있으며 그래서 그들 중 어느 것도 그들 중 전혀 쿼리와 일치합니다 (참조섹션 54.3.3).hasprefix사실입니다 전류 내부 튜플에 접두사가 포함 된 경우; 그렇다면,PrefixDatum값입니다.nnodes는 자녀의 수입니다 내부 튜플에 포함 된 노드 및Nodelabels는 레이블 배열입니다 노드에 레이블이없는 경우 값 또는 NULL.

nnodes방문 해야하는 자식 노드 수 검색 및Nodenumbers필수 인덱스 배열로 설정하십시오. 운영자 클래스 인 경우 레벨을 추적하고 설정levelAdds레벨의 배열로 각 노드로 내림차순이 필요합니다 방문. (종종 이러한 증분은 모두와 동일합니다 노드이지만 반드시 그렇지는 않기 때문에 배열은 중고.) 값 재구성이 필요한 경우재구성의 배열로 방문 할 각 어린이 노드에 대해 재구성 된 값; 그렇지 않으면 떠나재구성null로. 주목하십시오 그만큼Inner_consistent함수 palloc'ing the에 대한 책임이 있습니다.Nodenumbers, levelAddsand재구성배열.

Leaf_consistent

리프 튜플이 쿼리를 만족시키는 경우 true를 반환합니다.

theSQL선언 함수는 다음과 같아야합니다.

함수 만들기 my_leaf_consistent (내부, 내부) 반환 bool ...

첫 번째 인수는 A에 대한 포인터입니다spleafconsistentinc 구조물, 포함 함수에 대한 입력 데이터. 두 번째 논쟁은 a A에 대한 포인터spleafconsistentoutC 구조 함수는 결과 데이터로 채워야합니다.

typedef struct spleafconsistentin

    스캔 키 스캔 키;       / * 운영자 배열 및 비교 값 */
    int nkeys;          / * 배열 길이 */

    Datum ReconstructedValue;     / * 부모에게 재구성 된 값 */
    int 레벨;          / * 현재 레벨 (0에서 계산) */
    bool returndata;     /* 원본 데이터를 반환해야합니까? */

    데이텀 리프 듀다;      / * 잎 튜플의 데이텀 */
 spgleafconsistentin;

typedef struct spgleafconsistentout

    데이텀 리프 값;      / * 재구성 된 원본 데이터 */
    부울 재건;        / * 운영자를 다시 확인 해야하는 경우 true 설정 */
 spleafconsistentout;

배열Scankeys, OF 길이nkeys, 색인 검색 조건. 이러한 조건이 결합되어 있습니다 및 - 모든 것을 만족시키는 인덱스 항목 만 쿼리를 만족시킵니다. (nkeys= 0은 모든 인덱스 항목을 의미합니다 쿼리를 만족 시키십시오.) 일반적으로 일관된 기능 만sk_strategysk_argument각각의 필드 인덱스 가능한 연산자에게 각각 배열 항목 그리고 비교 값. 특히 필요하지 않습니다 확인하다sk_flagsSP-Gist 핵심 코드이기 때문에 비교 값은 null입니다 그러한 조건을 필터링합니다.재구성 value는 값입니다 부모 윈 토토에 대해 재구성; 그것은(Datum) 0루트 레벨에서 또는Inner_consistent함수는 부모 수준에서 값을 제공하지 않습니다.레벨현재 잎 튜플 레벨, 루트 레벨의 경우 0에서 시작합니다.returnDataistrue재구성 된 데이터가 필요한 경우 이 쿼리; 이것은만큼 그렇게 될 것입니다config기능 주장CanreturnData. Leafdatum에 저장된 주요 값입니다 현재 잎 튜플.

함수가 반환해야합니다true리프 윈 토토이 쿼리와 일치하는 경우거짓그렇지 않은 경우. 에서truecase, ifreturnDataistruetheLeafValue값으로 설정해야합니다 이 잎 윈 토토에 대해 원래 색인으로 공급되었습니다. 또한,다시 확인로 설정 될 수 있습니다true경기가 불확실한 경우 따라서 연산자는 실제 힙에 다시 적용되어야합니다. 경기를 확인하려면 윈 토토.

모든 SP-Gist 지원 방법은 일반적으로 단기간 메모리 컨텍스트; 즉,CurrentMemoryContext이후에 재설정됩니다 각 튜플의 처리. 따라서 그다지 중요하지 않습니다 당신이 palloc 모든 것을 pfree'i윈 토토에 대해 걱정하십시오. (그만큼config메소드는 예외입니다 메모리가 새는 것을 피하십시오. 그러나 보통config메소드는 할당하는 것 외에는 아무것도하지 않아야합니다 전달 된 매개 변수 구조물로의 상수.)

인덱스 된 열이 Collatable Data Type 인 경우 인덱스 Collation은 다음을 사용하여 모든 지원 방법으로 전달됩니다. 기준pg_get_collation ()메커니즘.