提交 eebdfcdb 编写于 作者: T Teodor Sigaev

1 Minimize memory allocation for void (but not null) value.

2 Add silly ordering for ts_vector to aim grouping, union, except etc. Don't use BTree opclass (tsvector_ops).
上级 457ad392
......@@ -247,3 +247,9 @@ Upon a woman s face. E. J. Pratt (1882 1964)
--check debug
select * from ts_debug('Tsearch module for PostgreSQL 7.3.3');
--check ordering
drop trigger tsvectorupdate on test_tsvector;
insert into test_tsvector values (null, null);
select a is null, a from test_tsvector order by a;
......@@ -702,6 +702,112 @@ where
c.oid=show_curcfg()
' language 'SQL' with(isstrict);
--compare functions
CREATE FUNCTION tsvector_cmp(tsvector,tsvector)
RETURNS int4
AS 'MODULE_PATHNAME'
LANGUAGE 'C' WITH (isstrict,iscachable);
CREATE FUNCTION tsvector_lt(tsvector,tsvector)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' WITH (isstrict,iscachable);
CREATE FUNCTION tsvector_le(tsvector,tsvector)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' WITH (isstrict,iscachable);
CREATE FUNCTION tsvector_eq(tsvector,tsvector)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' WITH (isstrict,iscachable);
CREATE FUNCTION tsvector_ge(tsvector,tsvector)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' WITH (isstrict,iscachable);
CREATE FUNCTION tsvector_gt(tsvector,tsvector)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' WITH (isstrict,iscachable);
CREATE FUNCTION tsvector_ne(tsvector,tsvector)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' WITH (isstrict,iscachable);
CREATE OPERATOR < (
LEFTARG = tsvector,
RIGHTARG = tsvector,
PROCEDURE = tsvector_lt,
COMMUTATOR = '>',
NEGATOR = '>=',
RESTRICT = contsel,
JOIN = contjoinsel
);
CREATE OPERATOR <= (
LEFTARG = tsvector,
RIGHTARG = tsvector,
PROCEDURE = tsvector_le,
COMMUTATOR = '>=',
NEGATOR = '>',
RESTRICT = contsel,
JOIN = contjoinsel
);
CREATE OPERATOR >= (
LEFTARG = tsvector,
RIGHTARG = tsvector,
PROCEDURE = tsvector_ge,
COMMUTATOR = '<=',
NEGATOR = '<',
RESTRICT = contsel,
JOIN = contjoinsel
);
CREATE OPERATOR > (
LEFTARG = tsvector,
RIGHTARG = tsvector,
PROCEDURE = tsvector_gt,
COMMUTATOR = '<',
NEGATOR = '<=',
RESTRICT = contsel,
JOIN = contjoinsel
);
CREATE OPERATOR = (
LEFTARG = tsvector,
RIGHTARG = tsvector,
PROCEDURE = tsvector_eq,
COMMUTATOR = '=',
NEGATOR = '<>',
RESTRICT = eqsel,
JOIN = eqjoinsel,
SORT1 = '<',
SORT2 = '<'
);
CREATE OPERATOR <> (
LEFTARG = tsvector,
RIGHTARG = tsvector,
PROCEDURE = tsvector_ne,
COMMUTATOR = '<>',
NEGATOR = '=',
RESTRICT = neqsel,
JOIN = neqjoinsel
);
CREATE OPERATOR CLASS tsvector_ops
DEFAULT FOR TYPE tsvector USING btree AS
OPERATOR 1 < ,
OPERATOR 2 <= ,
OPERATOR 3 = ,
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 tsvector_cmp(tsvector, tsvector);
--example of ISpell dictionary
--update pg_ts_dict set dict_initoption='DictFile="/usr/local/share/ispell/russian.dict" ,AffFile ="/usr/local/share/ispell/russian.aff", StopFile="/usr/local/share/ispell/russian.stop"' where dict_id=4;
......
......@@ -451,6 +451,8 @@ tsvector_in(PG_FUNCTION_ARGS)
if (len > 0)
len = uniqueentry(arr, len, tmpbuf, &buflen);
else
buflen=0;
totallen = CALCDATASIZE(len, buflen);
in = (tsvector *) palloc(totallen);
memset(in, 0, totallen);
......@@ -932,3 +934,91 @@ tsearch2(PG_FUNCTION_ARGS)
return PointerGetDatum(rettuple);
}
static int
silly_cmp_tsvector(const tsvector *a, const tsvector *b) {
if ( a->len < b->len )
return -1;
else if ( a->len > b->len )
return 1;
else if ( a->size < b->size )
return -1;
else if ( a->size > b->size )
return 1;
else {
unsigned char *aptr=(unsigned char *)(a->data) + DATAHDRSIZE;
unsigned char *bptr=(unsigned char *)(b->data) + DATAHDRSIZE;
while( aptr - ( (unsigned char *)(a->data) ) < a->len ) {
if ( *aptr != *bptr )
return ( *aptr < *bptr ) ? -1 : 1;
aptr++; bptr++;
}
}
return 0;
}
PG_FUNCTION_INFO_V1(tsvector_cmp);
PG_FUNCTION_INFO_V1(tsvector_lt);
PG_FUNCTION_INFO_V1(tsvector_le);
PG_FUNCTION_INFO_V1(tsvector_eq);
PG_FUNCTION_INFO_V1(tsvector_ne);
PG_FUNCTION_INFO_V1(tsvector_ge);
PG_FUNCTION_INFO_V1(tsvector_gt);
Datum tsvector_cmp(PG_FUNCTION_ARGS);
Datum tsvector_lt(PG_FUNCTION_ARGS);
Datum tsvector_le(PG_FUNCTION_ARGS);
Datum tsvector_eq(PG_FUNCTION_ARGS);
Datum tsvector_ne(PG_FUNCTION_ARGS);
Datum tsvector_ge(PG_FUNCTION_ARGS);
Datum tsvector_gt(PG_FUNCTION_ARGS);
#define RUNCMP \
tsvector *a = (tsvector *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));\
tsvector *b = (tsvector *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));\
int res = silly_cmp_tsvector(a,b); \
PG_FREE_IF_COPY(a,0); \
PG_FREE_IF_COPY(b,1); \
Datum
tsvector_cmp(PG_FUNCTION_ARGS) {
RUNCMP
PG_RETURN_INT32(res);
}
Datum
tsvector_lt(PG_FUNCTION_ARGS) {
RUNCMP
PG_RETURN_BOOL((res < 0) ? true : false);
}
Datum
tsvector_le(PG_FUNCTION_ARGS) {
RUNCMP
PG_RETURN_BOOL((res <= 0) ? true : false);
}
Datum
tsvector_eq(PG_FUNCTION_ARGS) {
RUNCMP
PG_RETURN_BOOL((res == 0) ? true : false);
}
Datum
tsvector_ge(PG_FUNCTION_ARGS) {
RUNCMP
PG_RETURN_BOOL((res >= 0) ? true : false);
}
Datum
tsvector_gt(PG_FUNCTION_ARGS) {
RUNCMP
PG_RETURN_BOOL((res > 0) ? true : false);
}
Datum
tsvector_ne(PG_FUNCTION_ARGS) {
RUNCMP
PG_RETURN_BOOL((res != 0) ? true : false);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册