@ -48,6 +48,12 @@
# include "utils/rel.h"
# include "utils/rel.h"
# include "utils/syscache.h"
# include "utils/syscache.h"
/* Single entry of List returned by getTokenTypes() */
typedef struct
{
int num ; /* token type number */
char * name ; /* token type name */
} TSTokenTypeItem ;
static void MakeConfigurationMapping ( AlterTSConfigurationStmt * stmt ,
static void MakeConfigurationMapping ( AlterTSConfigurationStmt * stmt ,
HeapTuple tup , Relation relMap ) ;
HeapTuple tup , Relation relMap ) ;
@ -1192,22 +1198,45 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
}
}
/*
/*
* Translate a list of token type names to an array of token type numbers
* Check whether a token type name is a member of a TSTokenTypeItem list .
*/
static bool
tstoken_list_member ( char * token_name , List * tokens )
{
ListCell * c ;
bool found = false ;
foreach ( c , tokens )
{
TSTokenTypeItem * ts = ( TSTokenTypeItem * ) lfirst ( c ) ;
if ( strcmp ( token_name , ts - > name ) = = 0 )
{
found = true ;
break ;
}
}
return found ;
}
/*
* Translate a list of token type names to a list of unique TSTokenTypeItem .
*
* Duplicated entries list are removed from tokennames .
*/
*/
static int *
static Lis t *
getTokenTypes ( Oid prsId , List * tokennames )
getTokenTypes ( Oid prsId , List * tokennames )
{
{
TSParserCacheEntry * prs = lookup_ts_parser_cache ( prsId ) ;
TSParserCacheEntry * prs = lookup_ts_parser_cache ( prsId ) ;
LexDescr * list ;
LexDescr * list ;
int * res ,
List * result = NIL ;
i ,
int ntoken ;
ntoken ;
ListCell * tn ;
ListCell * tn ;
ntoken = list_length ( tokennames ) ;
ntoken = list_length ( tokennames ) ;
if ( ntoken = = 0 )
if ( ntoken = = 0 )
return NULL ;
return NIL ;
res = ( int * ) palloc ( sizeof ( int ) * ntoken ) ;
if ( ! OidIsValid ( prs - > lextypeOid ) )
if ( ! OidIsValid ( prs - > lextypeOid ) )
elog ( ERROR , " method lextype isn't defined for text search parser %u " ,
elog ( ERROR , " method lextype isn't defined for text search parser %u " ,
@ -1217,19 +1246,26 @@ getTokenTypes(Oid prsId, List *tokennames)
list = ( LexDescr * ) DatumGetPointer ( OidFunctionCall1 ( prs - > lextypeOid ,
list = ( LexDescr * ) DatumGetPointer ( OidFunctionCall1 ( prs - > lextypeOid ,
( Datum ) 0 ) ) ;
( Datum ) 0 ) ) ;
i = 0 ;
foreach ( tn , tokennames )
foreach ( tn , tokennames )
{
{
String * val = lfirst_node ( String , tn ) ;
String * val = lfirst_node ( String , tn ) ;
bool found = false ;
bool found = false ;
int j ;
int j ;
/* Skip if this token is already in the result */
if ( tstoken_list_member ( strVal ( val ) , result ) )
continue ;
j = 0 ;
j = 0 ;
while ( list & & list [ j ] . lexid )
while ( list & & list [ j ] . lexid )
{
{
if ( strcmp ( strVal ( val ) , list [ j ] . alias ) = = 0 )
if ( strcmp ( strVal ( val ) , list [ j ] . alias ) = = 0 )
{
{
res [ i ] = list [ j ] . lexid ;
TSTokenTypeItem * ts = ( TSTokenTypeItem * ) palloc0 ( sizeof ( TSTokenTypeItem ) ) ;
ts - > num = list [ j ] . lexid ;
ts - > name = pstrdup ( strVal ( val ) ) ;
result = lappend ( result , ts ) ;
found = true ;
found = true ;
break ;
break ;
}
}
@ -1240,10 +1276,9 @@ getTokenTypes(Oid prsId, List *tokennames)
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( " token type \" %s \" does not exist " ,
errmsg ( " token type \" %s \" does not exist " ,
strVal ( val ) ) ) ) ;
strVal ( val ) ) ) ) ;
i + + ;
}
}
return res ;
return result ;
}
}
/*
/*
@ -1261,8 +1296,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
int i ;
int i ;
int j ;
int j ;
Oid prsId ;
Oid prsId ;
int * tokens ,
List * tokens = NIL ;
ntoken ;
int ntoken ;
Oid * dictIds ;
Oid * dictIds ;
int ndict ;
int ndict ;
ListCell * c ;
ListCell * c ;
@ -1273,15 +1308,17 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
prsId = tsform - > cfgparser ;
prsId = tsform - > cfgparser ;
tokens = getTokenTypes ( prsId , stmt - > tokentype ) ;
tokens = getTokenTypes ( prsId , stmt - > tokentype ) ;
ntoken = list_length ( stmt - > tokentype ) ;
ntoken = list_length ( tokens ) ;
if ( stmt - > override )
if ( stmt - > override )
{
{
/*
/*
* delete maps for tokens if they exist and command was ALTER
* delete maps for tokens if they exist and command was ALTER
*/
*/
for ( i = 0 ; i < ntoken ; i + + )
foreach ( c , tokens )
{
{
TSTokenTypeItem * ts = ( TSTokenTypeItem * ) lfirst ( c ) ;
ScanKeyInit ( & skey [ 0 ] ,
ScanKeyInit ( & skey [ 0 ] ,
Anum_pg_ts_config_map_mapcfg ,
Anum_pg_ts_config_map_mapcfg ,
BTEqualStrategyNumber , F_OIDEQ ,
BTEqualStrategyNumber , F_OIDEQ ,
@ -1289,7 +1326,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
ScanKeyInit ( & skey [ 1 ] ,
ScanKeyInit ( & skey [ 1 ] ,
Anum_pg_ts_config_map_maptokentype ,
Anum_pg_ts_config_map_maptokentype ,
BTEqualStrategyNumber , F_INT4EQ ,
BTEqualStrategyNumber , F_INT4EQ ,
Int32GetDatum ( tokens [ i ] ) ) ;
Int32GetDatum ( ts - > num ) ) ;
scan = systable_beginscan ( relMap , TSConfigMapIndexId , true ,
scan = systable_beginscan ( relMap , TSConfigMapIndexId , true ,
NULL , 2 , skey ) ;
NULL , 2 , skey ) ;
@ -1346,9 +1383,11 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
{
{
bool tokmatch = false ;
bool tokmatch = false ;
for ( j = 0 ; j < ntoken ; j + + )
foreach ( c , tokens )
{
{
if ( cfgmap - > maptokentype = = tokens [ j ] )
TSTokenTypeItem * ts = ( TSTokenTypeItem * ) lfirst ( c ) ;
if ( cfgmap - > maptokentype = = ts - > num )
{
{
tokmatch = true ;
tokmatch = true ;
break ;
break ;
@ -1401,8 +1440,10 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
/*
/*
* Insertion of new entries
* Insertion of new entries
*/
*/
for ( i = 0 ; i < ntoken ; i + + )
foreach ( c , tokens )
{
{
TSTokenTypeItem * ts = ( TSTokenTypeItem * ) lfirst ( c ) ;
for ( j = 0 ; j < ndict ; j + + )
for ( j = 0 ; j < ndict ; j + + )
{
{
ExecClearTuple ( slot [ slotCount ] ) ;
ExecClearTuple ( slot [ slotCount ] ) ;
@ -1411,7 +1452,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
slot [ slotCount ] - > tts_tupleDescriptor - > natts * sizeof ( bool ) ) ;
slot [ slotCount ] - > tts_tupleDescriptor - > natts * sizeof ( bool ) ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_mapcfg - 1 ] = ObjectIdGetDatum ( cfgId ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_mapcfg - 1 ] = ObjectIdGetDatum ( cfgId ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_maptokentype - 1 ] = Int32GetDatum ( tokens [ i ] ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_maptokentype - 1 ] = Int32GetDatum ( ts - > num ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_mapseqno - 1 ] = Int32GetDatum ( j + 1 ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_mapseqno - 1 ] = Int32GetDatum ( j + 1 ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_mapdict - 1 ] = ObjectIdGetDatum ( dictIds [ j ] ) ;
slot [ slotCount ] - > tts_values [ Anum_pg_ts_config_map_mapdict - 1 ] = ObjectIdGetDatum ( dictIds [ j ] ) ;
@ -1455,9 +1496,8 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
ScanKeyData skey [ 2 ] ;
ScanKeyData skey [ 2 ] ;
SysScanDesc scan ;
SysScanDesc scan ;
HeapTuple maptup ;
HeapTuple maptup ;
int i ;
Oid prsId ;
Oid prsId ;
int * tokens ;
List * tokens = NIL ;
ListCell * c ;
ListCell * c ;
tsform = ( Form_pg_ts_config ) GETSTRUCT ( tup ) ;
tsform = ( Form_pg_ts_config ) GETSTRUCT ( tup ) ;
@ -1466,10 +1506,9 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
tokens = getTokenTypes ( prsId , stmt - > tokentype ) ;
tokens = getTokenTypes ( prsId , stmt - > tokentype ) ;
i = 0 ;
foreach ( c , tokens )
foreach ( c , stmt - > tokentype )
{
{
String * val = lfirst_node ( String , c ) ;
TSTokenTypeItem * ts = ( TSTokenTypeItem * ) lfirst ( c ) ;
bool found = false ;
bool found = false ;
ScanKeyInit ( & skey [ 0 ] ,
ScanKeyInit ( & skey [ 0 ] ,
@ -1479,7 +1518,7 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
ScanKeyInit ( & skey [ 1 ] ,
ScanKeyInit ( & skey [ 1 ] ,
Anum_pg_ts_config_map_maptokentype ,
Anum_pg_ts_config_map_maptokentype ,
BTEqualStrategyNumber , F_INT4EQ ,
BTEqualStrategyNumber , F_INT4EQ ,
Int32GetDatum ( tokens [ i ] ) ) ;
Int32GetDatum ( ts - > num ) ) ;
scan = systable_beginscan ( relMap , TSConfigMapIndexId , true ,
scan = systable_beginscan ( relMap , TSConfigMapIndexId , true ,
NULL , 2 , skey ) ;
NULL , 2 , skey ) ;
@ -1499,17 +1538,15 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
ereport ( ERROR ,
ereport ( ERROR ,
( errcode ( ERRCODE_UNDEFINED_OBJECT ) ,
( errcode ( ERRCODE_UNDEFINED_OBJECT ) ,
errmsg ( " mapping for token type \" %s \" does not exist " ,
errmsg ( " mapping for token type \" %s \" does not exist " ,
strVal ( val ) ) ) ) ;
ts - > name ) ) ) ;
}
}
else
else
{
{
ereport ( NOTICE ,
ereport ( NOTICE ,
( errmsg ( " mapping for token type \" %s \" does not exist, skipping " ,
( errmsg ( " mapping for token type \" %s \" does not exist, skipping " ,
strVal ( val ) ) ) ) ;
ts - > name ) ) ) ;
}
}
}
}
i + + ;
}
}
EventTriggerCollectAlterTSConfig ( stmt , cfgId , NULL , 0 ) ;
EventTriggerCollectAlterTSConfig ( stmt , cfgId , NULL , 0 ) ;