@ -26,10 +26,10 @@
/* FTS operator priorities, see ts_type.h */
const int tsearch_op_priority [ OP_COUNT ] =
{
3 , /* OP_NOT */
4 , /* OP_NOT */
2 , /* OP_AND */
1 , /* OP_OR */
4 /* OP_PHRASE */
3 /* OP_PHRASE */
} ;
struct TSQueryParserStateData
@ -430,6 +430,40 @@ pushStop(TSQueryParserState state)
# define STACKDEPTH 32
typedef struct OperatorElement {
int8 op ;
int16 distance ;
} OperatorElement ;
static void
pushOpStack ( OperatorElement * stack , int * lenstack , int8 op , int16 distance )
{
if ( * lenstack = = STACKDEPTH ) /* internal error */
elog ( ERROR , " tsquery stack too small " ) ;
stack [ * lenstack ] . op = op ;
stack [ * lenstack ] . distance = distance ;
( * lenstack ) + + ;
}
static void
cleanOpStack ( TSQueryParserState state ,
OperatorElement * stack , int * lenstack , int8 op )
{
int opPriority = OP_PRIORITY ( op ) ;
while ( * lenstack )
{
if ( opPriority > OP_PRIORITY ( stack [ * lenstack - 1 ] . op ) )
break ;
( * lenstack ) - - ;
pushOperator ( state , stack [ * lenstack ] . op ,
stack [ * lenstack ] . distance ) ;
}
}
/*
* Make polish ( prefix ) notation of query .
*
@ -444,11 +478,7 @@ makepol(TSQueryParserState state,
ts_tokentype type ;
int lenval = 0 ;
char * strval = NULL ;
struct
{
int8 op ;
int16 distance ;
} opstack [ STACKDEPTH ] ;
OperatorElement opstack [ STACKDEPTH ] ;
int lenstack = 0 ;
int16 weight = 0 ;
bool prefix ;
@ -462,49 +492,16 @@ makepol(TSQueryParserState state,
{
case PT_VAL :
pushval ( opaque , state , strval , lenval , weight , prefix ) ;
while ( lenstack & & ( opstack [ lenstack - 1 ] . op = = OP_AND | |
opstack [ lenstack - 1 ] . op = = OP_PHRASE | |
opstack [ lenstack - 1 ] . op = = OP_NOT ) )
{
lenstack - - ;
pushOperator ( state ,
opstack [ lenstack ] . op ,
opstack [ lenstack ] . distance ) ;
}
break ;
case PT_OPR :
if ( lenstack & & operator = = OP_OR )
pushOperator ( state , OP_OR , 0 ) ;
else
{
if ( lenstack = = STACKDEPTH ) /* internal error */
elog ( ERROR , " tsquery stack too small " ) ;
opstack [ lenstack ] . op = operator ;
opstack [ lenstack ] . distance = weight ;
lenstack + + ;
}
cleanOpStack ( state , opstack , & lenstack , operator ) ;
pushOpStack ( opstack , & lenstack , operator , weight ) ;
break ;
case PT_OPEN :
makepol ( state , pushval , opaque ) ;
while ( lenstack & & ( opstack [ lenstack - 1 ] . op = = OP_AND | |
opstack [ lenstack - 1 ] . op = = OP_PHRASE | |
opstack [ lenstack - 1 ] . op = = OP_NOT ) )
{
lenstack - - ;
pushOperator ( state ,
opstack [ lenstack ] . op ,
opstack [ lenstack ] . distance ) ;
}
break ;
case PT_CLOSE :
while ( lenstack )
{
lenstack - - ;
pushOperator ( state ,
opstack [ lenstack ] . op ,
opstack [ lenstack ] . distance ) ;
} ;
cleanOpStack ( state , opstack , & lenstack , OP_OR /* lowest */ ) ;
return ;
case PT_ERR :
default :
@ -514,13 +511,8 @@ makepol(TSQueryParserState state,
state - > buffer ) ) ) ;
}
}
while ( lenstack )
{
lenstack - - ;
pushOperator ( state ,
opstack [ lenstack ] . op ,
opstack [ lenstack ] . distance ) ;
}
cleanOpStack ( state , opstack , & lenstack , OP_OR /* lowest */ ) ;
}
static void
@ -750,7 +742,7 @@ while( ( (inf)->cur - (inf)->buf ) + (addsize) + 1 >= (inf)->buflen ) \
* print it in infix ( human - readable ) form
*/
static void
infix ( INFIX * in , int parentPriority )
infix ( INFIX * in , int parentPriority , bool rightPhraseOp )
{
/* since this function recurses, it could be driven to stack overflow. */
check_stack_depth ( ) ;
@ -819,7 +811,7 @@ infix(INFIX *in, int parentPriority)
}
else if ( in - > curpol - > qoperator . oper = = OP_NOT )
{
int priority = PRINT _PRIORITY( in - > curpol ) ;
int priority = QO _PRIORITY( in - > curpol ) ;
if ( priority < parentPriority )
{
@ -833,7 +825,7 @@ infix(INFIX *in, int parentPriority)
* ( in - > cur ) = ' \0 ' ;
in - > curpol + + ;
infix ( in , priority ) ;
infix ( in , priority , false ) ;
if ( priority < parentPriority )
{
RESIZEBUF ( in , 2 ) ;
@ -844,17 +836,15 @@ infix(INFIX *in, int parentPriority)
else
{
int8 op = in - > curpol - > qoperator . oper ;
int priority = PRINT _PRIORITY( in - > curpol ) ;
int priority = QO _PRIORITY( in - > curpol ) ;
int16 distance = in - > curpol - > qoperator . distance ;
INFIX nrm ;
bool needParenthesis = false ;
in - > curpol + + ;
if ( priority < parentPriority | |
( op = = OP_PHRASE & &
( priority = = parentPriority | | /* phrases are not
* commutative ! */
parentPriority = = OP_PRIORITY ( OP_AND ) ) ) )
/* phrase operator depends on order */
( op = = OP_PHRASE & & rightPhraseOp ) )
{
needParenthesis = true ;
RESIZEBUF ( in , 2 ) ;
@ -868,11 +858,11 @@ infix(INFIX *in, int parentPriority)
nrm . cur = nrm . buf = ( char * ) palloc ( sizeof ( char ) * nrm . buflen ) ;
/* get right operand */
infix ( & nrm , priority ) ;
infix ( & nrm , priority , ( op = = OP_PHRASE ) ) ;
/* get & print left operand */
in - > curpol = nrm . curpol ;
infix ( in , priority ) ;
infix ( in , priority , false ) ;
/* print operator & right operand */
RESIZEBUF ( in , 3 + ( 2 + 10 /* distance */ ) + ( nrm . cur - nrm . buf ) ) ;
@ -924,7 +914,7 @@ tsqueryout(PG_FUNCTION_ARGS)
nrm . cur = nrm . buf = ( char * ) palloc ( sizeof ( char ) * nrm . buflen ) ;
* ( nrm . cur ) = ' \0 ' ;
nrm . op = GETOPERAND ( query ) ;
infix ( & nrm , - 1 /* lowest priority */ ) ;
infix ( & nrm , - 1 /* lowest priority */ , false ) ;
PG_FREE_IF_COPY ( query , 0 ) ;
PG_RETURN_CSTRING ( nrm . buf ) ;
@ -1151,7 +1141,7 @@ tsquerytree(PG_FUNCTION_ARGS)
nrm . cur = nrm . buf = ( char * ) palloc ( sizeof ( char ) * nrm . buflen ) ;
* ( nrm . cur ) = ' \0 ' ;
nrm . op = GETOPERAND ( query ) ;
infix ( & nrm , tru e) ;
infix ( & nrm , - 1 , fals e) ;
res = cstring_to_text_with_len ( nrm . buf , nrm . cur - nrm . buf ) ;
pfree ( q ) ;
}