¾�ΥС�������ʸ�� �� 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

34.11. �桼������η�

項34.2�˽Ҥ٤��Ƥ���褦�ˡ�PostgreSQL�ϡ����������򥵥ݡ��Ȥ���褦�˳�ĥ���뤳�Ȥ��Ǥ��ޤ��� ����Ǥϡ�SQL����ʲ��Υ�٥����������ǡ������Ǥ�����ܷ��򿷤������������ˡ�ˤĤ����������ޤ��� ���������ܷ��κ����ˤϡ����٥���졢�̾�C�Ǻ������줿��������ؿ��μ�����ɬ�פǤ���

����ǻ��Ѥ�����ϡ�����������ʪ���src/tutorial�ǥ��쥯�ȥ��complex.sql��complex.c�Ȥ���̾�����֤��Ƥ���ޤ��� �ºݤ����¹Ԥ��������ϥǥ��쥯�ȥ����README�򻲾Ȥ��Ƥ���������

�桼������ǡ������Ǥ�ɬ�����ϴؿ��Ƚ��ϴؿ���ɬ�פǤ��� �����δؿ��ϡ������ʥ桼���ˤ�����Ϥȥ桼���ؤν��ϤΤ���Ρ�ʸ������ˤɤΤ褦�ʷ�����ɽ������뤫�ȡ����η���������Ǥɤ���������뤫����ꤷ�ޤ��� ���ϴؿ��ϰ����Ȥ���NULL��üʸ������ꡢ���η��Ρʥ�����Ρ�����ɽ�����֤��ޤ��� ���ϴؿ��ϰ����Ȥ��Ƥ��η�������ɽ�����ꡢNULL��üʸ������֤��ޤ��� ñ�˳�Ǽ��������ǤϤʤ������η�������ä������ΤǤ���С����η��˻������������Ƥ�������������ؿ��򤵤���󶡤��ʤ���Фʤ�ޤ���

�㤨�С�ʣ�ǿ���ɽ������complex����������뤳�Ȥ�ͤ��ޤ��� �����餯�����Τ褦��C��¤�Τ�ʣ�ǿ���������ɽ�����뤳�Ȥ�������������ˡ�Ǥ���

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

ñ���Datum�ͤǰ����ˤ��礭�᤮��Τǡ�����ϻ����Ϥ����ˤ��ʤ���Фʤ�ޤ���

���η��γ���ʸ����ɽ���Ȥ���(x,y)������ʸ�������Ѥ��뤳�Ȥ����򤷤ޤ���

�����ϴؿ����ä˽��ϴؿ��򵭽Ҥ���ΤϺ���ǤϤ���ޤ��� �������ʤ��顢���η��γ���ɽ��ʸ�������������������ɽ���Τ���δ����Ƿ�ϴ�ʥѡ��������ϴؿ��Ȥ��ƽ񤫤ʤ���Фʤ�ޤ��� �ʲ�����򼨤��ޤ���

>
PG_FUNCTION_INFO_V1(complex_in);

Datum
complex_in(PG_FUNCTION_ARGS)
{
    char       *str = PG_GETARG_CSTRING(0);
    double      x,
                y;
    Complex    *result;

    if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for complex: \"%s\"",
                        str)));

    result = (Complex *) palloc(sizeof(Complex));
    result->x = x;
    result->y = y;
    PG_RETURN_POINTER(result);
}

���ϴؿ��ϰʲ��Τ褦�˴�ñ�ˤǤ��ޤ���

>

PG_FUNCTION_INFO_V1(complex_out);

Datum
complex_out(PG_FUNCTION_ARGS)
{
    Complex    *complex = (Complex *) PG_GETARG_POINTER(0);
    char       *result;

    result = (char *) palloc(100);
    snprintf(result, 100, "(%g,%g)", complex->x, complex->y);
    PG_RETURN_CSTRING(result);
}

�����ϴؿ��ϡ��ơ��εմؿ��ˤʤ�褦�ˤ���٤��Ǥ��� �������ʤ��ȡ��ǡ�����ե�����˥���פ���������ɤ��᤽���Ȥ���ݤˡ���������꤬ȯ������Ǥ��礦�� ����ϡ���ư�������ط�����ݤˤ褯ȯ����������Ǥ���

���ץ����Ȥ��ơ��桼��������ϡ��Х��ʥ������ϴؿ����󶡤��뤳�Ȥ��Ǥ��ޤ��� �Х��ʥ������Ϥ��̾��®�Ǥ������ƥ����������Ϥ��ܿ���������ޤ��� �ƥ����������Ϥ�Ʊ�ͤˡ������Х��ʥ�ɽ�������Τ�������뤳�ȤϺ����Ԥ���Ǥ�Ǥ��� �ۤȤ�ɤ��Ȥ߹��ߥǡ������ϡ��ޥ���˰�¸���ʤ��Х��ʥ�ɽ�����󶡤��褦�Ȥ��Ƥ��ޤ��� complex���Ǥϡ�float8���ΥХ��ʥ������ϥ���С����򸵤ˤ��ޤ���

>
PG_FUNCTION_INFO_V1(complex_recv);

Datum
complex_recv(PG_FUNCTION_ARGS)
{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    Complex    *result;

    result = (Complex *) palloc(sizeof(Complex));
    result->x = pq_getmsgfloat8(buf);
    result->y = pq_getmsgfloat8(buf);
    PG_RETURN_POINTER(result);
}

PG_FUNCTION_INFO_V1(complex_send);

Datum
complex_send(PG_FUNCTION_ARGS)
{
    Complex    *complex = (Complex *) 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));
}

�����ϴؿ����������ͭ�饤�֥����˥���ѥ��뤹��С�SQL��complex����������뤳�Ȥ��Ǥ��ޤ��� �ޤ������뷿�Ȥ���������ޤ���

CREATE TYPE complex;

����ϥץ졼���ۥ���Ȥ���ư��������ϴؿ������������ˤ��η��򻲾Ȥ��뤳�Ȥ��Ǥ��ޤ��� ���θ�ʲ��Τ褦�ˡ������ϴؿ���������뤳�Ȥ��Ǥ��ޤ���

CREATE FUNCTION complex_in(cstring)
    RETURNS complex
    AS 'filename'
    LANGUAGE C IMMUTABLE STRICT;

CREATE FUNCTION complex_out(complex)
    RETURNS cstring
    AS 'filename'
    LANGUAGE C IMMUTABLE STRICT;

CREATE FUNCTION complex_recv(internal)
   RETURNS complex
   AS 'filename'
   LANGUAGE C IMMUTABLE STRICT;

CREATE FUNCTION complex_send(complex)
   RETURNS bytea
   AS 'filename'
   LANGUAGE C IMMUTABLE STRICT;

�Ǹ�ˡ��ǡ������δ�����������󶡤��뤳�Ȥ��Ǥ��ޤ���

CREATE TYPE complex (
   internallength = 16, 
   input = complex_in,
   output = complex_out,
   receive = complex_recv,
   send = complex_send,
   alignment = double
);

���������ܷ����������ȡ�PostgreSQL�ϼ�ưŪ�ˤ��η�������Υ��ݡ��Ȥ��󶡤��ޤ��� ���󷿤��̾���ܷ���̾�������˥������������ʸ��_���դ���̾���ˤʤ�ޤ���

�ǡ�������¸�ߤ���褦�ˤʤ�ȡ�����ˤ��Υǡ��������Ф���ͭ�Ѥ������󶡤���ؿ���������뤳�Ȥ��Ǥ��ޤ��� �����ơ����δؿ�����Ѥ���黻�Ҥ�����Ǥ��ޤ��� �ޤ���ɬ�פ˱����ơ����Υǡ������ѤΥ���ǥå����򥵥ݡ��Ȥ��뤿��˱黻�ҥ��饹�������ǽ�Ǥ��� ���������ɲ��ؤˤĤ��Ƥϸ������������ޤ���

�ǡ��������ͤ������������ǡ˥���������ư�����硢���Υǡ�������TOAST��ǽ�Ȥ��ʤ���Фʤ�ޤ��� ��項53.2�򻲾Ȥ��Ƥ����������� �إå��Υ����С��إåɤ򸺤餹���Ȥǡ�TOAST�Ͼ����ʥǡ������Ф��Ƥ����̤��ޤ��뤳�Ȥ��Ǥ��ޤ��Τǡ��ǡ�������˰��̤������˳�Ǽ����ˤϾ����᤮����Ǥ⡢�����Ԥ�ʤ���Фʤ�ޤ���

���Τ���ˤϡ�����ɽ��������Ĺ�ǡ�����ɸ��쥤�����Ȥ˽��äƤ��ʤ���Фʤ�ޤ��� ��Ƭ��4�Х��Ȥ�char[4]�ե�����ɤǡ�ľ�ܥ�����������뤳�ȤϷ褷�Ƥ���ޤ���ʴ���Ū��vl_len_�ȸƤФ�ޤ��ˡ� SET_VARSIZE()����Ѥ���datum�Υ������򤳤Υե�����ɤ˳�Ǽ����VARSIZE()����Ѥ��Ƽ��Ф��ʤ���Фʤ�ޤ��� ���Υǡ������򰷤�C�ؿ��ϡ�PG_DETOAST_DATUM����Ѥ��ơ��Ϥ��줿TOAST���ͤ����տ���Ÿ�����ʤ���Фʤ�ޤ��� ���̾�ܺ٤Ϸ��ȼ���GETARG_DATATYPE_P�ޥ�����������Ʊ��ä��ޤ��ˡ� ���θ塢CREATE TYPE���ޥ�ɤ�¹Ԥ���ݤˡ�variable������Ĺ����ꤷ���ޤ���Ŭ������¸���ץ��������򤷤Ƥ���������

���󤬡�ñ�ʤ�����δؿ�������ǡ���������˥Х���ñ�̤�������ꤷ�Ƥ��뤿��˽��פǤʤ���硢PG_DETOAST_DATUM�Υ����Хإåɤΰ�����ʤ����Ȥ��Ǥ��ޤ��� �����PG_DETOAST_DATUM_PACKED����Ѥ��Ƥ����������̾��PG_DETOAST_DATUM_PACKED�ޥ�����������뤳�ȤDZ��ä���ޤ��ˡ� �����ơ�VARSIZE_ANY_EXHDR�����VARDATA_ANY�ޥ�������Ѥ��ơ����̤���Ƥ����ǽ��������datam�˥����������Ƥ��������� �����֤��ޤ����������Υޥ��������֤����ǡ����ϡ����Ȥ��ǡ����������������ꤷ�Ƥ����Ȥ��Ƥ⡢���󤵤�ޤ��� ���󤬽��פǤ���С��̾��PG_DETOAST_DATUM���󥿥ե�������𤷤Ƽ¹Ԥ��Ƥ���������

注意: �Ť�Υ����ɤǤϤ��Ф���vl_len_��char[4]�ǤϤʤ�int32�Ȥ���������Ƥ��ޤ��� ���ι�¤����������ʤ��Ȥ�int32�����󤵤줿�ե�����ɤ���äƤ���¤ꡢ��������ꤢ��ޤ��� �����������󤵤�Ƥ��ʤ���ǽ��������datum���갷�����ˡ�����������¤���������Ѥ��뤳�Ȥϴ����Ǥ��� datum���ºݤ����󤵤�Ƥ���Ȳ��ꤹ�뤳�Ȥ򥳥�ѥ���ε�§�Ȥ��Ƥ��뤫�⤷�줺�����ξ�硢����˸�̩�ʥ������ƥ�����Ǥϥ�������פ��Ƥ��ޤ��ޤ���

�ܺ٤ˤĤ��Ƥ�CREATE TYPE���ޥ�ɤ������򻲾Ȥ��Ƥ���������