2003-08-04 08:43:34 +08:00
/*
* interface functions to tscfg
2003-07-21 18:27:44 +08:00
* Teodor Sigaev < teodor @ sigaev . ru >
*/
# include <errno.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <locale.h>
# include "postgres.h"
# include "fmgr.h"
# include "utils/array.h"
# include "catalog/pg_type.h"
# include "executor/spi.h"
# include "ts_cfg.h"
# include "dict.h"
# include "wparser.h"
# include "snmap.h"
# include "common.h"
# include "tsvector.h"
2003-11-25 21:33:15 +08:00
# define IGNORE_LONGLEXEME 1
2003-07-21 18:27:44 +08:00
/*********top interface**********/
2003-08-04 08:43:34 +08:00
static Oid current_cfg_id = 0 ;
2003-07-21 18:27:44 +08:00
void
2003-08-04 08:43:34 +08:00
init_cfg ( Oid id , TSCfgInfo * cfg )
{
2004-04-02 07:44:38 +08:00
Oid arg [ 2 ] ;
2003-08-04 08:43:34 +08:00
bool isnull ;
2004-04-02 07:44:38 +08:00
Datum pars [ 2 ] ;
2003-08-04 08:43:34 +08:00
int stat ,
i ,
j ;
text * ptr ;
text * prsname = NULL ;
2004-08-29 13:07:03 +08:00
char * nsp = get_namespace ( TSNSP_FunctionOid ) ;
char buf [ 1024 ] ;
2003-08-04 08:43:34 +08:00
MemoryContext oldcontext ;
2004-08-29 13:07:03 +08:00
void * plan ;
2003-08-04 08:43:34 +08:00
2004-04-02 07:44:38 +08:00
arg [ 0 ] = OIDOID ;
arg [ 1 ] = OIDOID ;
pars [ 0 ] = ObjectIdGetDatum ( id ) ;
pars [ 1 ] = ObjectIdGetDatum ( id ) ;
2003-08-04 08:43:34 +08:00
memset ( cfg , 0 , sizeof ( TSCfgInfo ) ) ;
2003-07-21 18:27:44 +08:00
SPI_connect ( ) ;
2004-06-01 00:51:56 +08:00
sprintf ( buf , " select prs_name from %s.pg_ts_cfg where oid = $1 " , nsp ) ;
2004-08-29 13:07:03 +08:00
plan = SPI_prepare ( buf , 1 , arg ) ;
2004-06-01 00:51:56 +08:00
if ( ! plan )
ts_error ( ERROR , " SPI_prepare() failed " ) ;
stat = SPI_execp ( plan , pars , " " , 1 ) ;
2003-08-04 08:43:34 +08:00
if ( stat < 0 )
ts_error ( ERROR , " SPI_execp return %d " , stat ) ;
if ( SPI_processed > 0 )
{
prsname = ( text * ) DatumGetPointer (
SPI_getbinval ( SPI_tuptable - > vals [ 0 ] , SPI_tuptable - > tupdesc , 1 , & isnull )
) ;
2003-07-21 18:27:44 +08:00
oldcontext = MemoryContextSwitchTo ( TopMemoryContext ) ;
2003-08-04 08:43:34 +08:00
prsname = ptextdup ( prsname ) ;
2003-07-21 18:27:44 +08:00
MemoryContextSwitchTo ( oldcontext ) ;
2003-08-04 08:43:34 +08:00
cfg - > id = id ;
}
else
2003-07-21 18:27:44 +08:00
ts_error ( ERROR , " No tsearch cfg with id %d " , id ) ;
2004-06-01 00:51:56 +08:00
SPI_freeplan ( plan ) ;
2003-08-04 08:43:34 +08:00
arg [ 0 ] = TEXTOID ;
2004-06-01 00:51:56 +08:00
sprintf ( buf , " select lt.tokid, map.dict_name from %s.pg_ts_cfgmap as map, %s.pg_ts_cfg as cfg, %s.token_type( $1 ) as lt where lt.alias = map.tok_alias and map.ts_name = cfg.ts_name and cfg.oid= $2 order by lt.tokid desc; " , nsp , nsp , nsp ) ;
2004-08-29 13:07:03 +08:00
plan = SPI_prepare ( buf , 2 , arg ) ;
2004-06-01 00:51:56 +08:00
if ( ! plan )
ts_error ( ERROR , " SPI_prepare() failed " ) ;
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
pars [ 0 ] = PointerGetDatum ( prsname ) ;
2004-06-01 00:51:56 +08:00
stat = SPI_execp ( plan , pars , " " , 0 ) ;
2003-08-04 08:43:34 +08:00
if ( stat < 0 )
ts_error ( ERROR , " SPI_execp return %d " , stat ) ;
if ( SPI_processed < = 0 )
2003-07-21 18:27:44 +08:00
ts_error ( ERROR , " No parser with id %d " , id ) ;
2003-08-04 08:43:34 +08:00
for ( i = 0 ; i < SPI_processed ; i + + )
{
int lexid = DatumGetInt32 ( SPI_getbinval ( SPI_tuptable - > vals [ i ] , SPI_tuptable - > tupdesc , 1 , & isnull ) ) ;
ArrayType * toasted_a = ( ArrayType * ) PointerGetDatum ( SPI_getbinval ( SPI_tuptable - > vals [ i ] , SPI_tuptable - > tupdesc , 2 , & isnull ) ) ;
ArrayType * a ;
if ( ! cfg - > map )
{
cfg - > len = lexid + 1 ;
cfg - > map = ( ListDictionary * ) malloc ( sizeof ( ListDictionary ) * cfg - > len ) ;
if ( ! cfg - > map )
2003-07-25 01:52:50 +08:00
ereport ( ERROR ,
( errcode ( ERRCODE_OUT_OF_MEMORY ) ,
errmsg ( " out of memory " ) ) ) ;
2003-08-04 08:43:34 +08:00
memset ( cfg - > map , 0 , sizeof ( ListDictionary ) * cfg - > len ) ;
2003-07-21 18:27:44 +08:00
}
if ( isnull )
continue ;
2003-08-04 08:43:34 +08:00
a = ( ArrayType * ) PointerGetDatum ( PG_DETOAST_DATUM ( DatumGetPointer ( toasted_a ) ) ) ;
if ( ARR_NDIM ( a ) ! = 1 )
ts_error ( ERROR , " Wrong dimension " ) ;
if ( ARRNELEMS ( a ) < 1 )
2003-07-21 18:27:44 +08:00
continue ;
2003-08-04 08:43:34 +08:00
cfg - > map [ lexid ] . len = ARRNELEMS ( a ) ;
cfg - > map [ lexid ] . dict_id = ( Datum * ) malloc ( sizeof ( Datum ) * cfg - > map [ lexid ] . len ) ;
2003-09-30 02:54:38 +08:00
if ( ! cfg - > map [ lexid ] . dict_id )
2004-08-29 13:07:03 +08:00
ts_error ( ERROR , " No memory " ) ;
2003-09-30 02:54:38 +08:00
2003-08-04 08:43:34 +08:00
memset ( cfg - > map [ lexid ] . dict_id , 0 , sizeof ( Datum ) * cfg - > map [ lexid ] . len ) ;
ptr = ( text * ) ARR_DATA_PTR ( a ) ;
2003-07-21 18:27:44 +08:00
oldcontext = MemoryContextSwitchTo ( TopMemoryContext ) ;
2003-08-04 08:43:34 +08:00
for ( j = 0 ; j < cfg - > map [ lexid ] . len ; j + + )
{
2003-07-21 18:27:44 +08:00
cfg - > map [ lexid ] . dict_id [ j ] = PointerGetDatum ( ptextdup ( ptr ) ) ;
2003-08-04 08:43:34 +08:00
ptr = NEXTVAL ( ptr ) ;
}
2003-07-21 18:27:44 +08:00
MemoryContextSwitchTo ( oldcontext ) ;
2003-08-04 08:43:34 +08:00
if ( a ! = toasted_a )
2003-07-21 18:27:44 +08:00
pfree ( a ) ;
}
2003-08-04 08:43:34 +08:00
2004-06-01 00:51:56 +08:00
SPI_freeplan ( plan ) ;
2003-07-21 18:27:44 +08:00
SPI_finish ( ) ;
2003-08-04 08:43:34 +08:00
cfg - > prs_id = name2id_prs ( prsname ) ;
2003-07-21 18:27:44 +08:00
pfree ( prsname ) ;
2004-06-01 00:51:56 +08:00
pfree ( nsp ) ;
2003-08-04 08:43:34 +08:00
for ( i = 0 ; i < cfg - > len ; i + + )
{
for ( j = 0 ; j < cfg - > map [ i ] . len ; j + + )
{
ptr = ( text * ) DatumGetPointer ( cfg - > map [ i ] . dict_id [ j ] ) ;
cfg - > map [ i ] . dict_id [ j ] = ObjectIdGetDatum ( name2id_dict ( ptr ) ) ;
2003-07-21 18:27:44 +08:00
pfree ( ptr ) ;
}
}
}
2003-08-04 08:43:34 +08:00
typedef struct
{
TSCfgInfo * last_cfg ;
int len ;
int reallen ;
TSCfgInfo * list ;
2003-07-21 18:27:44 +08:00
SNMap name2id_map ;
2003-08-04 08:43:34 +08:00
} CFGList ;
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
static CFGList CList = { NULL , 0 , 0 , NULL , { 0 , 0 , NULL } } ;
2003-07-21 18:27:44 +08:00
void
2003-08-04 08:43:34 +08:00
reset_cfg ( void )
{
freeSNMap ( & ( CList . name2id_map ) ) ;
if ( CList . list )
{
int i ,
j ;
for ( i = 0 ; i < CList . len ; i + + )
if ( CList . list [ i ] . map )
{
for ( j = 0 ; j < CList . list [ i ] . len ; j + + )
if ( CList . list [ i ] . map [ j ] . dict_id )
2003-07-21 18:27:44 +08:00
free ( CList . list [ i ] . map [ j ] . dict_id ) ;
2003-08-04 08:43:34 +08:00
free ( CList . list [ i ] . map ) ;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
free ( CList . list ) ;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
memset ( & CList , 0 , sizeof ( CFGList ) ) ;
2003-07-21 18:27:44 +08:00
}
static int
2003-08-04 08:43:34 +08:00
comparecfg ( const void * a , const void * b )
{
return ( ( TSCfgInfo * ) a ) - > id - ( ( TSCfgInfo * ) b ) - > id ;
2003-07-21 18:27:44 +08:00
}
TSCfgInfo *
2003-08-04 08:43:34 +08:00
findcfg ( Oid id )
{
2003-07-21 18:27:44 +08:00
/* last used cfg */
2003-08-04 08:43:34 +08:00
if ( CList . last_cfg & & CList . last_cfg - > id = = id )
2003-07-21 18:27:44 +08:00
return CList . last_cfg ;
/* already used cfg */
2003-08-04 08:43:34 +08:00
if ( CList . len ! = 0 )
{
TSCfgInfo key ;
key . id = id ;
2003-07-21 18:27:44 +08:00
CList . last_cfg = bsearch ( & key , CList . list , CList . len , sizeof ( TSCfgInfo ) , comparecfg ) ;
2003-08-04 08:43:34 +08:00
if ( CList . last_cfg ! = NULL )
2003-07-21 18:27:44 +08:00
return CList . last_cfg ;
}
/* last chance */
2003-08-04 08:43:34 +08:00
if ( CList . len = = CList . reallen )
{
TSCfgInfo * tmp ;
int reallen = ( CList . reallen ) ? 2 * CList . reallen : 16 ;
tmp = ( TSCfgInfo * ) realloc ( CList . list , sizeof ( TSCfgInfo ) * reallen ) ;
if ( ! tmp )
ts_error ( ERROR , " No memory " ) ;
CList . reallen = reallen ;
CList . list = tmp ;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
CList . last_cfg = & ( CList . list [ CList . len ] ) ;
2003-07-21 18:27:44 +08:00
init_cfg ( id , CList . last_cfg ) ;
CList . len + + ;
qsort ( CList . list , CList . len , sizeof ( TSCfgInfo ) , comparecfg ) ;
2003-08-04 08:43:34 +08:00
return findcfg ( id ) ; /* qsort changed order!! */ ;
2003-07-21 18:27:44 +08:00
}
Oid
2003-08-04 08:43:34 +08:00
name2id_cfg ( text * name )
{
2004-04-02 07:44:38 +08:00
Oid arg [ 1 ] ;
2003-08-04 08:43:34 +08:00
bool isnull ;
2004-04-02 07:44:38 +08:00
Datum pars [ 1 ] ;
2003-08-04 08:43:34 +08:00
int stat ;
Oid id = findSNMap_t ( & ( CList . name2id_map ) , name ) ;
2004-08-29 13:07:03 +08:00
void * plan ;
char * nsp ;
char buf [ 1024 ] ;
2003-08-04 08:43:34 +08:00
2004-04-02 07:44:38 +08:00
arg [ 0 ] = TEXTOID ;
pars [ 0 ] = PointerGetDatum ( name ) ;
2003-08-04 08:43:34 +08:00
if ( id )
2003-07-21 18:27:44 +08:00
return id ;
2003-08-04 08:43:34 +08:00
2004-08-29 13:07:03 +08:00
nsp = get_namespace ( TSNSP_FunctionOid ) ;
2003-07-21 18:27:44 +08:00
SPI_connect ( ) ;
2004-08-29 13:07:03 +08:00
sprintf ( buf , " select oid from %s.pg_ts_cfg where ts_name = $1 " , nsp ) ;
plan = SPI_prepare ( buf , 1 , arg ) ;
2004-06-01 00:51:56 +08:00
if ( ! plan )
/* internal error */
elog ( ERROR , " SPI_prepare() failed " ) ;
2003-07-21 18:27:44 +08:00
2004-06-01 00:51:56 +08:00
stat = SPI_execp ( plan , pars , " " , 1 ) ;
2003-08-04 08:43:34 +08:00
if ( stat < 0 )
2003-07-25 01:52:50 +08:00
/* internal error */
2003-08-04 08:43:34 +08:00
elog ( ERROR , " SPI_execp return %d " , stat ) ;
if ( SPI_processed > 0 )
{
id = DatumGetObjectId ( SPI_getbinval ( SPI_tuptable - > vals [ 0 ] , SPI_tuptable - > tupdesc , 1 , & isnull ) ) ;
if ( isnull )
2003-07-25 01:52:50 +08:00
ereport ( ERROR ,
( errcode ( ERRCODE_CONFIG_FILE_ERROR ) ,
errmsg ( " null id for tsearch config " ) ) ) ;
2003-08-04 08:43:34 +08:00
}
else
2003-07-25 01:52:50 +08:00
ereport ( ERROR ,
( errcode ( ERRCODE_CONFIG_FILE_ERROR ) ,
errmsg ( " no tsearch config " ) ) ) ;
2004-06-01 00:51:56 +08:00
SPI_freeplan ( plan ) ;
2003-07-21 18:27:44 +08:00
SPI_finish ( ) ;
2003-08-04 08:43:34 +08:00
addSNMap_t ( & ( CList . name2id_map ) , name , id ) ;
2003-07-21 18:27:44 +08:00
return id ;
}
2003-08-04 08:43:34 +08:00
void
parsetext_v2 ( TSCfgInfo * cfg , PRSTEXT * prs , char * buf , int4 buflen )
{
int type ,
lenlemm ,
i ;
char * lemm = NULL ;
2003-07-21 18:27:44 +08:00
WParserInfo * prsobj = findprs ( cfg - > prs_id ) ;
2003-08-04 08:43:34 +08:00
prsobj - > prs = ( void * ) DatumGetPointer (
FunctionCall2 (
& ( prsobj - > start_info ) ,
PointerGetDatum ( buf ) ,
Int32GetDatum ( buflen )
)
) ;
while ( ( type = DatumGetInt32 ( FunctionCall3 (
& ( prsobj - > getlexeme_info ) ,
PointerGetDatum ( prsobj - > prs ) ,
PointerGetDatum ( & lemm ) ,
PointerGetDatum ( & lenlemm ) ) ) ) ! = 0 )
{
2004-08-29 13:07:03 +08:00
if ( lenlemm > = MAXSTRLEN )
{
2003-11-25 21:33:15 +08:00
# ifdef IGNORE_LONGLEXEME
ereport ( NOTICE ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
errmsg ( " word is too long " ) ) ) ;
continue ;
2004-08-29 13:07:03 +08:00
# else
2003-07-25 01:52:50 +08:00
ereport ( ERROR ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
errmsg ( " word is too long " ) ) ) ;
2003-11-25 21:33:15 +08:00
# endif
}
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
if ( type > = cfg - > len ) /* skip this type of lexem */
continue ;
for ( i = 0 ; i < cfg - > map [ type ] . len ; i + + )
{
DictInfo * dict = finddict ( DatumGetObjectId ( cfg - > map [ type ] . dict_id [ i ] ) ) ;
char * * norms ,
* * ptr ;
norms = ptr = ( char * * ) DatumGetPointer (
FunctionCall3 (
& ( dict - > lexize_info ) ,
PointerGetDatum ( dict - > dictionary ) ,
PointerGetDatum ( lemm ) ,
PointerGetDatum ( lenlemm )
)
) ;
if ( ! norms ) /* dictionary doesn't know this lexem */
2003-07-21 18:27:44 +08:00
continue ;
2003-08-04 08:43:34 +08:00
prs - > pos + + ; /* set pos */
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
while ( * ptr )
{
if ( prs - > curwords = = prs - > lenwords )
{
2003-07-21 18:27:44 +08:00
prs - > lenwords * = 2 ;
2004-05-31 21:29:43 +08:00
prs - > words = ( TSWORD * ) repalloc ( ( void * ) prs - > words , prs - > lenwords * sizeof ( TSWORD ) ) ;
2003-07-21 18:27:44 +08:00
}
prs - > words [ prs - > curwords ] . len = strlen ( * ptr ) ;
prs - > words [ prs - > curwords ] . word = * ptr ;
prs - > words [ prs - > curwords ] . alen = 0 ;
prs - > words [ prs - > curwords ] . pos . pos = LIMITPOS ( prs - > pos ) ;
ptr + + ;
prs - > curwords + + ;
}
pfree ( norms ) ;
2003-08-04 08:43:34 +08:00
break ; /* lexem already normalized or is stop
* word */
2003-07-21 18:27:44 +08:00
}
}
FunctionCall1 (
2003-08-04 08:43:34 +08:00
& ( prsobj - > end_info ) ,
PointerGetDatum ( prsobj - > prs )
) ;
2003-07-21 18:27:44 +08:00
}
static void
2003-08-04 08:43:34 +08:00
hladdword ( HLPRSTEXT * prs , char * buf , int4 buflen , int type )
{
while ( prs - > curwords > = prs - > lenwords )
{
2003-07-21 18:27:44 +08:00
prs - > lenwords * = 2 ;
prs - > words = ( HLWORD * ) repalloc ( ( void * ) prs - > words , prs - > lenwords * sizeof ( HLWORD ) ) ;
}
2003-08-04 08:43:34 +08:00
memset ( & ( prs - > words [ prs - > curwords ] ) , 0 , sizeof ( HLWORD ) ) ;
prs - > words [ prs - > curwords ] . type = ( uint8 ) type ;
prs - > words [ prs - > curwords ] . len = buflen ;
2003-07-21 18:27:44 +08:00
prs - > words [ prs - > curwords ] . word = palloc ( buflen ) ;
memcpy ( prs - > words [ prs - > curwords ] . word , buf , buflen ) ;
2003-08-04 08:43:34 +08:00
prs - > curwords + + ;
2003-07-21 18:27:44 +08:00
}
static void
2003-08-04 08:43:34 +08:00
hlfinditem ( HLPRSTEXT * prs , QUERYTYPE * query , char * buf , int buflen )
{
int i ;
ITEM * item = GETQUERY ( query ) ;
2003-09-22 21:32:33 +08:00
HLWORD * word ;
2003-08-04 08:43:34 +08:00
while ( prs - > curwords + query - > size > = prs - > lenwords )
{
2003-07-21 18:27:44 +08:00
prs - > lenwords * = 2 ;
prs - > words = ( HLWORD * ) repalloc ( ( void * ) prs - > words , prs - > lenwords * sizeof ( HLWORD ) ) ;
}
2003-09-22 21:32:33 +08:00
word = & ( prs - > words [ prs - > curwords - 1 ] ) ;
2003-08-04 08:43:34 +08:00
for ( i = 0 ; i < query - > size ; i + + )
{
if ( item - > type = = VAL & & item - > length = = buflen & & strncmp ( GETOPERAND ( query ) + item - > distance , buf , buflen ) = = 0 )
{
if ( word - > item )
{
memcpy ( & ( prs - > words [ prs - > curwords ] ) , word , sizeof ( HLWORD ) ) ;
prs - > words [ prs - > curwords ] . item = item ;
prs - > words [ prs - > curwords ] . repeated = 1 ;
2003-07-21 18:27:44 +08:00
prs - > curwords + + ;
2003-08-04 08:43:34 +08:00
}
else
word - > item = item ;
2003-07-21 18:27:44 +08:00
}
item + + ;
}
}
2003-08-04 08:43:34 +08:00
void
hlparsetext ( TSCfgInfo * cfg , HLPRSTEXT * prs , QUERYTYPE * query , char * buf , int4 buflen )
{
int type ,
lenlemm ,
i ;
char * lemm = NULL ;
2003-07-21 18:27:44 +08:00
WParserInfo * prsobj = findprs ( cfg - > prs_id ) ;
2003-08-04 08:43:34 +08:00
prsobj - > prs = ( void * ) DatumGetPointer (
FunctionCall2 (
& ( prsobj - > start_info ) ,
PointerGetDatum ( buf ) ,
Int32GetDatum ( buflen )
)
) ;
while ( ( type = DatumGetInt32 ( FunctionCall3 (
& ( prsobj - > getlexeme_info ) ,
PointerGetDatum ( prsobj - > prs ) ,
PointerGetDatum ( & lemm ) ,
PointerGetDatum ( & lenlemm ) ) ) ) ! = 0 )
{
2004-08-29 13:07:03 +08:00
if ( lenlemm > = MAXSTRLEN )
{
2003-11-25 21:33:15 +08:00
# ifdef IGNORE_LONGLEXEME
ereport ( NOTICE ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
errmsg ( " word is too long " ) ) ) ;
continue ;
2004-08-29 13:07:03 +08:00
# else
2003-07-25 01:52:50 +08:00
ereport ( ERROR ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
errmsg ( " word is too long " ) ) ) ;
2003-11-25 21:33:15 +08:00
# endif
}
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
hladdword ( prs , lemm , lenlemm , type ) ;
if ( type > = cfg - > len )
continue ;
for ( i = 0 ; i < cfg - > map [ type ] . len ; i + + )
{
DictInfo * dict = finddict ( DatumGetObjectId ( cfg - > map [ type ] . dict_id [ i ] ) ) ;
char * * norms ,
* * ptr ;
norms = ptr = ( char * * ) DatumGetPointer (
FunctionCall3 (
& ( dict - > lexize_info ) ,
PointerGetDatum ( dict - > dictionary ) ,
PointerGetDatum ( lemm ) ,
PointerGetDatum ( lenlemm )
)
) ;
if ( ! norms ) /* dictionary doesn't know this lexem */
2003-07-21 18:27:44 +08:00
continue ;
2003-08-04 08:43:34 +08:00
while ( * ptr )
{
hlfinditem ( prs , query , * ptr , strlen ( * ptr ) ) ;
2003-07-21 18:27:44 +08:00
pfree ( * ptr ) ;
ptr + + ;
}
pfree ( norms ) ;
2003-08-04 08:43:34 +08:00
break ; /* lexem already normalized or is stop
* word */
2003-07-21 18:27:44 +08:00
}
}
FunctionCall1 (
2003-08-04 08:43:34 +08:00
& ( prsobj - > end_info ) ,
PointerGetDatum ( prsobj - > prs )
) ;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
text *
genhl ( HLPRSTEXT * prs )
{
text * out ;
int len = 128 ;
char * ptr ;
HLWORD * wrd = prs - > words ;
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
out = ( text * ) palloc ( len ) ;
ptr = ( ( char * ) out ) + VARHDRSZ ;
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
while ( wrd - prs - > words < prs - > curwords )
{
while ( wrd - > len + prs - > stopsellen + prs - > startsellen + ( ptr - ( ( char * ) out ) ) > = len )
{
int dist = ptr - ( ( char * ) out ) ;
len * = 2 ;
2003-07-21 18:27:44 +08:00
out = ( text * ) repalloc ( out , len ) ;
2003-08-04 08:43:34 +08:00
ptr = ( ( char * ) out ) + dist ;
2003-07-21 18:27:44 +08:00
}
2004-06-29 00:19:09 +08:00
if ( wrd - > in & & ! wrd - > repeated )
2003-08-04 08:43:34 +08:00
{
if ( wrd - > replace )
{
* ptr = ' ' ;
2003-07-21 18:27:44 +08:00
ptr + + ;
2003-08-04 08:43:34 +08:00
}
else
{
if ( wrd - > selected )
{
memcpy ( ptr , prs - > startsel , prs - > startsellen ) ;
ptr + = prs - > startsellen ;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
memcpy ( ptr , wrd - > word , wrd - > len ) ;
ptr + = wrd - > len ;
if ( wrd - > selected )
{
memcpy ( ptr , prs - > stopsel , prs - > stopsellen ) ;
ptr + = prs - > stopsellen ;
2003-07-21 18:27:44 +08:00
}
}
2004-08-29 13:07:03 +08:00
}
else if ( ! wrd - > repeated )
2003-07-21 18:27:44 +08:00
pfree ( wrd - > word ) ;
wrd + + ;
}
2003-08-04 08:43:34 +08:00
VARATT_SIZEP ( out ) = ptr - ( ( char * ) out ) ;
return out ;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
int
get_currcfg ( void )
{
Oid arg [ 1 ] = { TEXTOID } ;
2003-07-21 18:27:44 +08:00
const char * curlocale ;
2003-08-04 08:43:34 +08:00
Datum pars [ 1 ] ;
bool isnull ;
int stat ;
2004-08-29 13:07:03 +08:00
char buf [ 1024 ] ;
char * nsp ;
void * plan ;
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
if ( current_cfg_id > 0 )
2003-07-21 18:27:44 +08:00
return current_cfg_id ;
2004-08-29 13:07:03 +08:00
nsp = get_namespace ( TSNSP_FunctionOid ) ;
2003-07-21 18:27:44 +08:00
SPI_connect ( ) ;
2004-08-29 13:07:03 +08:00
sprintf ( buf , " select oid from %s.pg_ts_cfg where locale = $1 " , nsp ) ;
2004-06-01 00:51:56 +08:00
pfree ( nsp ) ;
plan = SPI_prepare ( buf , 1 , arg ) ;
if ( ! plan )
/* internal error */
elog ( ERROR , " SPI_prepare() failed " ) ;
2003-07-21 18:27:44 +08:00
curlocale = setlocale ( LC_CTYPE , NULL ) ;
2003-08-04 08:43:34 +08:00
pars [ 0 ] = PointerGetDatum ( char2text ( ( char * ) curlocale ) ) ;
2004-06-01 00:51:56 +08:00
stat = SPI_execp ( plan , pars , " " , 1 ) ;
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
if ( stat < 0 )
2003-07-25 01:52:50 +08:00
/* internal error */
2003-08-04 08:43:34 +08:00
elog ( ERROR , " SPI_execp return %d " , stat ) ;
if ( SPI_processed > 0 )
current_cfg_id = DatumGetObjectId ( SPI_getbinval ( SPI_tuptable - > vals [ 0 ] , SPI_tuptable - > tupdesc , 1 , & isnull ) ) ;
else
2003-07-25 01:52:50 +08:00
ereport ( ERROR ,
( errcode ( ERRCODE_CONFIG_FILE_ERROR ) ,
errmsg ( " could not find tsearch config by locale " ) ) ) ;
2003-07-21 18:27:44 +08:00
pfree ( DatumGetPointer ( pars [ 0 ] ) ) ;
2004-06-01 00:51:56 +08:00
SPI_freeplan ( plan ) ;
2003-07-21 18:27:44 +08:00
SPI_finish ( ) ;
return current_cfg_id ;
}
PG_FUNCTION_INFO_V1 ( set_curcfg ) ;
2003-08-04 08:43:34 +08:00
Datum set_curcfg ( PG_FUNCTION_ARGS ) ;
2003-07-21 18:27:44 +08:00
Datum
2003-08-04 08:43:34 +08:00
set_curcfg ( PG_FUNCTION_ARGS )
{
2004-08-29 13:07:03 +08:00
SET_FUNCOID ( ) ;
2003-08-04 08:43:34 +08:00
findcfg ( PG_GETARG_OID ( 0 ) ) ;
current_cfg_id = PG_GETARG_OID ( 0 ) ;
PG_RETURN_VOID ( ) ;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
2003-07-21 18:27:44 +08:00
PG_FUNCTION_INFO_V1 ( set_curcfg_byname ) ;
2003-08-04 08:43:34 +08:00
Datum set_curcfg_byname ( PG_FUNCTION_ARGS ) ;
2003-07-21 18:27:44 +08:00
Datum
2003-08-04 08:43:34 +08:00
set_curcfg_byname ( PG_FUNCTION_ARGS )
{
text * name = PG_GETARG_TEXT_P ( 0 ) ;
2004-08-29 13:07:03 +08:00
SET_FUNCOID ( ) ;
2003-08-04 08:43:34 +08:00
DirectFunctionCall1 (
set_curcfg ,
ObjectIdGetDatum ( name2id_cfg ( name ) )
) ;
PG_FREE_IF_COPY ( name , 0 ) ;
PG_RETURN_VOID ( ) ;
}
2003-07-21 18:27:44 +08:00
PG_FUNCTION_INFO_V1 ( show_curcfg ) ;
2003-08-04 08:43:34 +08:00
Datum show_curcfg ( PG_FUNCTION_ARGS ) ;
2003-07-21 18:27:44 +08:00
Datum
2003-08-04 08:43:34 +08:00
show_curcfg ( PG_FUNCTION_ARGS )
{
2004-08-29 13:07:03 +08:00
SET_FUNCOID ( ) ;
2003-08-04 08:43:34 +08:00
PG_RETURN_OID ( get_currcfg ( ) ) ;
2003-07-21 18:27:44 +08:00
}
PG_FUNCTION_INFO_V1 ( reset_tsearch ) ;
2003-08-04 08:43:34 +08:00
Datum reset_tsearch ( PG_FUNCTION_ARGS ) ;
2003-07-21 18:27:44 +08:00
Datum
2003-08-04 08:43:34 +08:00
reset_tsearch ( PG_FUNCTION_ARGS )
{
2004-08-29 13:07:03 +08:00
SET_FUNCOID ( ) ;
2003-08-04 08:43:34 +08:00
ts_error ( NOTICE , " TSearch cache cleaned " ) ;
PG_RETURN_VOID ( ) ;
2003-07-21 18:27:44 +08:00
}