項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���ޥ�ɤ������Ȥ��Ƥ���������