8. 확장 SQL : 형 (Type)

앞에서 살펴보았지만, POSTGRES 에는 두 종류의 데이터 형이 있다. 기본(base)형 (프로그래밍 언어에 정의되어 있는 형)과 복합(composite)형(인스턴스)가 있다. 여기에 나오는 예제들은 complex.sql 과 complex.c 에 나와있다. 복합 예제는 funcs.sql 에 나와있다.

8.1 사용자 정의 형

사용자 정의 형은 반드시 input, output 함수를 가지고 있어야 한다. 이러한 함수 는 형이 (사용자가 입력하고 사용자에게 출력되는)문자열에 어떻게 나타나는 지와 해당 형이 메모리에 어떻게 편재되는지를 검사한다. 입력함수는 널로 끝나는 문자 열을 입력으로 받아들여서 해당 형의 내부적인 표현을 반환한다. 출력함수는 해당 형의 내부적인 표현을 받아들여서 널로 끝나는 문자열을 반환한다.

복합 숫자를 표현하는 complex 데이터 형을 정의해보자. 이 복합형을 메모리에 표 현하기 위해 자연스럽게 다음의 C 구조체를 선택할 것이다.

    typedef struct Complex { double x; double y; } Complex;

(x,y) 형태의 문자열은 외부적인 문자열로 표현된다.

이러한함수는 보통 작성하기가 쉬우며, 특히 출력함수는 더 쉽다. 그러나, 여기에서 기억해야 할 몇가지 사항이 있다.

(1) 외부적인 (문자열) 표현을 정의할 때, 최종적으로 입력함수가 해당 표현을 잘 받아들이는 완벽하고 튼튼한 분석기가 되도록 해야 한다는 점을 기억하자!

    Complex * complex_in(char *str)
    {
        double x, y;
        Complex *result;

        if (sscanf(str, " ( %1f , %1f )", &x, &y) != 2)
        {
            elog(WARN, "complex_in: error in parsing \"%s\"", str);
            return NULL;
        }
        result = (Complex *) palloc(sizeof(Complex));
        result->x = x;
        result->y = y;
        return (result);
    }

출력함수는 더욱 간단하게 만들 수 있다.

    char * complex_out(Complex *complex)
    {
        char *result;
        if (complex == NULL) return(NULL);
        result = (char *) palloc(60);
        sprintf(result, "(%g,%g)", complex->x, complex->y);
        return(result);
    }

(2) 입력, 출력 함수를 만들 때 서로 역으로 만들어 보는 것을 시도해보아야 한다. 만일 이렇게 하지 않을 경우에는, 해당 데이터를 파일에 덤프하거나 (다른 시 스템상의 어떤 다른 데이터베이스로) 거꾸로 읽어들일 때 여러가지 문제가 발 생할 것이다. 특히 부동 소수점을 포함할 때 공통적인 문제로 나타난다.

complex 형을 만들려면, 해당 형을 만들기 이전에 complex_in 과 complex_out 의 두가지 사용자 정의 함수를 만들어야 한다.

    CREATE FUNCTION complex_in(opaque) RETURNS complex AS '/usr/local/postgres95/tutorial/obj/complex.so' LANGUAGE 'c';
    CREATE FUNCTION complex_out(opaque) RETURNS opaque AS '/usr/local/postgres95/tutorial/obj/complex.so' LANGUAGE 'c';
    CREATE TYPE complex ( internallength = 16, input = complex_in, output = complex_out );

앞에서도 말했지만, POSTGRES 는 기본형의 배열을 풍족하게 제공한다. 아울러, POSTGRES 는 사용자 정의 형의 배열도 잘 제공한다. 형을 정의할 때, POSTGRES 는 자동적으로 해당 형의 배열을 제공한다. 전통적으로, 배열형의 이름은 사용자 정의 형의 명칭앞에 밑줄 문자 '_' 가 앞에 위치하는 형태가 된다.

복합형은 어떠한 함수도 필요하지 않다. 시스템은 이미 이들 내부를 이해하기 때문 이다.

8.1.2 대형 객체

지금까지 논의한 형은 모두 "소형(small)" 객체이며 8KB (주7) 보다 작은 것들이다. 문서화 시스템이나 비트맵 저장 시스템과 같은 대형 형이 필요하다면, POSTGRES 대형객체 (large object) 인터페이스를 사용할 필요가 있을 것이다.

주7) 8 * 1024 는 8192 바이트이다. POSTGRES 의 tuple 과 페이지 오버헤드는 이러한 8KB 한계에 적합해야 하기 때문에 실제로 하나의 형은 8192 바이트보다 작게 고려되어야 한다. 이에 적합한 실제 값은 해당 기계의 아키텍쳐에 의존 적이다.