1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

Re-run pgindent, fixing a problem where comment lines after a blank

comment line where output as too long, and update typedefs for /lib
directory.  Also fix case where identifiers were used as variable names
in the backend, but as typedefs in ecpg (favor the backend for
indenting).

Backpatch to 8.1.X.
This commit is contained in:
Bruce Momjian
2005-11-22 18:17:34 +00:00
parent e196eedd8a
commit 436a2956d8
264 changed files with 4403 additions and 4097 deletions

View File

@ -60,9 +60,9 @@
typedef struct remoteConn
{
PGconn *conn; /* Hold the remote connection */
PGconn *conn; /* Hold the remote connection */
int openCursorCount; /* The number of open cursors */
bool newXactForCursor; /* Opened a transaction for a cursor */
bool newXactForCursor; /* Opened a transaction for a cursor */
} remoteConn;
/*
@ -85,8 +85,8 @@ static Oid get_relid_from_relname(text *relname_text);
static char *generate_relation_name(Oid relid);
/* Global */
static remoteConn *pconn = NULL;
static HTAB *remoteConnHash = NULL;
static remoteConn *pconn = NULL;
static HTAB *remoteConnHash = NULL;
/*
* Following is list that holds multiple remote connections.
@ -347,7 +347,7 @@ dblink_open(PG_FUNCTION_ARGS)
else
conn = rconn->conn;
/* If we are not in a transaction, start one */
/* If we are not in a transaction, start one */
if (PQtransactionStatus(conn) == PQTRANS_IDLE)
{
res = PQexec(conn, "BEGIN");
@ -1505,7 +1505,7 @@ get_text_array_contents(ArrayType *array, int *numitems)
else
{
values[i] = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(ptr)));
PointerGetDatum(ptr)));
ptr = att_addlength(ptr, typlen, PointerGetDatum(ptr));
ptr = (char *) att_align(ptr, typalign);
}
@ -1717,7 +1717,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
key = -1;
if (key > -1)
val = tgt_pkattvals[key] ? pstrdup(tgt_pkattvals[key]) : NULL;
val = tgt_pkattvals[key] ? pstrdup(tgt_pkattvals[key]) : NULL;
else
val = SPI_getvalue(tuple, tupdesc, i + 1);
@ -1744,7 +1744,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
if (tgt_pkattvals != NULL)
val = tgt_pkattvals[i] ? pstrdup(tgt_pkattvals[i]) : NULL;
val = tgt_pkattvals[i] ? pstrdup(tgt_pkattvals[i]) : NULL;
else
val = SPI_getvalue(tuple, tupdesc, pkattnum);

View File

@ -39,7 +39,7 @@ g_int_consistent(PG_FUNCTION_ARGS)
if (strategy == BooleanSearchStrategy)
PG_RETURN_BOOL(execconsistent((QUERYTYPE *) query,
(ArrayType *) DatumGetPointer(entry->key),
GIST_LEAF(entry)));
GIST_LEAF(entry)));
/* XXX are we sure it's safe to scribble on the query object here? */
/* XXX what about toasted input? */
@ -97,7 +97,7 @@ g_int_union(PG_FUNCTION_ARGS)
for (i = 0; i < entryvec->n; i++)
{
ArrayType *ent = GETENTRY(entryvec, i);
ArrayType *ent = GETENTRY(entryvec, i);
CHECKARRVALID(ent);
totlen += ARRNELEMS(ent);
@ -108,8 +108,8 @@ g_int_union(PG_FUNCTION_ARGS)
for (i = 0; i < entryvec->n; i++)
{
ArrayType *ent = GETENTRY(entryvec, i);
int nel;
ArrayType *ent = GETENTRY(entryvec, i);
int nel;
nel = ARRNELEMS(ent);
memcpy(ptr, ARRPTR(ent), nel * sizeof(int4));
@ -143,10 +143,10 @@ g_int_compress(PG_FUNCTION_ARGS)
CHECKARRVALID(r);
PREPAREARR(r);
if (ARRNELEMS(r)>= 2 * MAXNUMRANGE)
elog(NOTICE,"Input array is too big (%d maximum allowed, %d current), use gist__intbig_ops opclass instead",
2 * MAXNUMRANGE - 1, ARRNELEMS(r));
if (ARRNELEMS(r) >= 2 * MAXNUMRANGE)
elog(NOTICE, "Input array is too big (%d maximum allowed, %d current), use gist__intbig_ops opclass instead",
2 * MAXNUMRANGE - 1, ARRNELEMS(r));
retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
@ -154,12 +154,14 @@ g_int_compress(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(retval);
}
/* leaf entries never compress one more time, only when entry->leafkey ==true,
so now we work only with internal keys */
/*
* leaf entries never compress one more time, only when entry->leafkey
* ==true, so now we work only with internal keys
*/
r = (ArrayType *) PG_DETOAST_DATUM(entry->key);
CHECKARRVALID(r);
if (ARRISVOID(r))
if (ARRISVOID(r))
{
if (r != (ArrayType *) DatumGetPointer(entry->key))
pfree(r);

View File

@ -1,5 +1,5 @@
/*
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.45 2005/10/29 19:38:07 tgl Exp $
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.46 2005/11/22 18:17:04 momjian Exp $
*
* pgbench: a simple benchmark program for PostgreSQL
* written by Tatsuo Ishii
@ -1110,7 +1110,8 @@ main(int argc, char **argv)
fprintf(stderr, "Use limit/ulimt to increase the limit before using pgbench.\n");
exit(1);
}
#endif /* #if !(defined(__CYGWIN__) || defined(__MINGW32__)) */
#endif /* #if !(defined(__CYGWIN__) ||
* defined(__MINGW32__)) */
break;
case 'C':
is_connect = 1;

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-decrypt.c,v 1.6 2005/10/15 02:49:06 momjian Exp $
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-decrypt.c,v 1.7 2005/11/22 18:17:04 momjian Exp $
*/
#include "postgres.h"
@ -269,14 +269,14 @@ prefix_init(void **priv_p, void *arg, PullFilter * src)
* The original purpose of the 2-byte check was to show user a
* friendly "wrong key" message. This made following possible:
*
* "An Attack on CFB Mode Encryption As Used By OpenPGP" by Serge Mister
* and Robert Zuccherato
* "An Attack on CFB Mode Encryption As Used By OpenPGP" by Serge
* Mister and Robert Zuccherato
*
* To avoid being 'oracle', we delay reporting, which basically means we
* prefer to run into corrupt packet header.
* To avoid being 'oracle', we delay reporting, which basically means
* we prefer to run into corrupt packet header.
*
* We _could_ throw PXE_PGP_CORRUPT_DATA here, but there is possibility
* of attack via timing, so we don't.
* We _could_ throw PXE_PGP_CORRUPT_DATA here, but there is
* possibility of attack via timing, so we don't.
*/
ctx->corrupt_prefix = 1;
}

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.6 2005/10/15 02:49:06 momjian Exp $
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.7 2005/11/22 18:17:04 momjian Exp $
*/
#include "postgres.h"
@ -125,8 +125,8 @@ add_entropy(text *data1, text *data2, text *data3)
/*
* Try to make the feeding unpredictable.
*
* Prefer data over keys, as it's rather likely that key is same in several
* calls.
* Prefer data over keys, as it's rather likely that key is same in
* several calls.
*/
/* chance: 7/8 */

View File

@ -547,8 +547,8 @@ crosstab(PG_FUNCTION_ARGS)
* Get the next category item value, which is alway
* attribute number three.
*
* Be careful to sssign the value to the array index based on
* which category we are presently processing.
* Be careful to sssign the value to the array index based
* on which category we are presently processing.
*/
values[1 + i] = SPI_getvalue(spi_tuple, spi_tupdesc, 3);
@ -870,8 +870,8 @@ get_crosstab_tuplestore(char *sql,
/*
* The provided SQL query must always return at least three columns:
*
* 1. rowname the label for each row - column 1 in the final result 2.
* category the label for each value-column in the final result 3.
* 1. rowname the label for each row - column 1 in the final result
* 2. category the label for each value-column in the final result 3.
* value the values used to populate the value-columns
*
* If there are more than three columns, the last two are taken as

View File

@ -178,7 +178,7 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, int2
state->state = WAITOPERATOR;
return VAL;
}
else if ( state->state == WAITFIRSTOPERAND )
else if (state->state == WAITFIRSTOPERAND)
return END;
else
ereport(ERROR,
@ -206,13 +206,13 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, int2
return ERR;
break;
case WAITSINGLEOPERAND:
if ( *(state->buf) == '\0' )
if (*(state->buf) == '\0')
return END;
*strval = state->buf;
*lenval = strlen( state->buf );
state->buf += strlen( state->buf );
*lenval = strlen(state->buf);
state->buf += strlen(state->buf);
state->count++;
return VAL;
return VAL;
default:
return ERR;
break;
@ -600,7 +600,7 @@ findoprnd(ITEM * ptr, int4 *pos)
* input
*/
static QUERYTYPE *
queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int, int2), int cfg_id, bool isplain)
queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int, int2), int cfg_id, bool isplain)
{
QPRS_STATE state;
int4 i;
@ -637,12 +637,13 @@ queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int, int2), int c
/* parse query & make polish notation (postfix, but in reverse order) */
makepol(&state, pushval);
pfree(state.valstate.word);
if (!state.num) {
if (!state.num)
{
elog(NOTICE, "Query doesn't contain lexem(s)");
query = (QUERYTYPE*)palloc( HDRSIZEQT );
query = (QUERYTYPE *) palloc(HDRSIZEQT);
query->len = HDRSIZEQT;
query->size = 0;
return query;
return query;
}
/* make finish struct */
@ -928,9 +929,9 @@ to_tsquery(PG_FUNCTION_ARGS)
str = text2char(in);
PG_FREE_IF_COPY(in, 1);
query = queryin(str, pushval_morph, PG_GETARG_INT32(0),false);
if ( query->size == 0 )
query = queryin(str, pushval_morph, PG_GETARG_INT32(0), false);
if (query->size == 0)
PG_RETURN_POINTER(query);
res = clean_fakeval_v2(GETQUERY(query), &len);
@ -984,8 +985,8 @@ plainto_tsquery(PG_FUNCTION_ARGS)
PG_FREE_IF_COPY(in, 1);
query = queryin(str, pushval_morph, PG_GETARG_INT32(0), true);
if ( query->size == 0 )
if (query->size == 0)
PG_RETURN_POINTER(query);
res = clean_fakeval_v2(GETQUERY(query), &len);
@ -1023,4 +1024,3 @@ plainto_tsquery_current(PG_FUNCTION_ARGS)
Int32GetDatum(get_currcfg()),
PG_GETARG_DATUM(0)));
}

View File

@ -17,7 +17,7 @@ typedef struct ITEM
int4 val;
/* user-friendly value, must correlate with WordEntry */
uint32
istrue:1, /* use for ranking in Cover */
istrue:1, /* use for ranking in Cover */
length:11,
distance:20;
} ITEM;

View File

@ -7,180 +7,201 @@
#include "query.h"
typedef uint64 TPQTGist;
#define SIGLEN (sizeof(TPQTGist)*BITS_PER_BYTE)
#define SIGLEN (sizeof(TPQTGist)*BITS_PER_BYTE)
#define GETENTRY(vec,pos) ((TPQTGist *) DatumGetPointer((vec)->vector[(pos)].key))
PG_FUNCTION_INFO_V1(tsq_mcontains);
Datum tsq_mcontains(PG_FUNCTION_ARGS);
Datum tsq_mcontains(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(tsq_mcontained);
Datum tsq_mcontained(PG_FUNCTION_ARGS);
Datum tsq_mcontained(PG_FUNCTION_ARGS);
static TPQTGist
makesign(QUERYTYPE* a) {
int i;
ITEM *ptr = GETQUERY(a);
makesign(QUERYTYPE * a)
{
int i;
ITEM *ptr = GETQUERY(a);
TPQTGist sign = 0;
for (i = 0; i < a->size; i++) {
if ( ptr->type == VAL )
for (i = 0; i < a->size; i++)
{
if (ptr->type == VAL)
sign |= 1 << (ptr->val % SIGLEN);
ptr++;
}
return sign;
}
Datum
tsq_mcontains(PG_FUNCTION_ARGS) {
tsq_mcontains(PG_FUNCTION_ARGS)
{
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
QUERYTYPE *ex = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
TPQTGist sq, se;
int i,j;
ITEM *iq, *ie;
TPQTGist sq,
se;
int i,
j;
ITEM *iq,
*ie;
if ( query->size < ex->size ) {
if (query->size < ex->size)
{
PG_FREE_IF_COPY(query, 0);
PG_FREE_IF_COPY(ex, 1);
PG_RETURN_BOOL( false );
PG_RETURN_BOOL(false);
}
sq = makesign(query);
se = makesign(ex);
if ( (sq&se)!=se ) {
if ((sq & se) != se)
{
PG_FREE_IF_COPY(query, 0);
PG_FREE_IF_COPY(ex, 1);
PG_RETURN_BOOL( false );
}
PG_RETURN_BOOL(false);
}
ie = GETQUERY(ex);
for(i=0;i<ex->size;i++) {
for (i = 0; i < ex->size; i++)
{
iq = GETQUERY(query);
if ( ie[i].type != VAL )
if (ie[i].type != VAL)
continue;
for(j=0;j<query->size;j++)
if ( iq[j].type == VAL && ie[i].val == iq[j].val ) {
j = query->size+1;
for (j = 0; j < query->size; j++)
if (iq[j].type == VAL && ie[i].val == iq[j].val)
{
j = query->size + 1;
break;
}
if ( j == query->size ) {
if (j == query->size)
{
PG_FREE_IF_COPY(query, 0);
PG_FREE_IF_COPY(ex, 1);
PG_RETURN_BOOL( false );
PG_RETURN_BOOL(false);
}
}
}
PG_FREE_IF_COPY(query, 0);
PG_FREE_IF_COPY(ex, 1);
PG_RETURN_BOOL( true );
PG_RETURN_BOOL(true);
}
Datum
tsq_mcontained(PG_FUNCTION_ARGS) {
tsq_mcontained(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(
DirectFunctionCall2(
tsq_mcontains,
PG_GETARG_DATUM(1),
PG_GETARG_DATUM(0)
)
DirectFunctionCall2(
tsq_mcontains,
PG_GETARG_DATUM(1),
PG_GETARG_DATUM(0)
)
);
}
PG_FUNCTION_INFO_V1(gtsq_in);
Datum gtsq_in(PG_FUNCTION_ARGS);
Datum gtsq_in(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_out);
Datum gtsq_out(PG_FUNCTION_ARGS);
Datum gtsq_out(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_compress);
Datum gtsq_compress(PG_FUNCTION_ARGS);
Datum gtsq_compress(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_decompress);
Datum gtsq_decompress(PG_FUNCTION_ARGS);
Datum gtsq_decompress(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_consistent);
Datum gtsq_consistent(PG_FUNCTION_ARGS);
Datum gtsq_consistent(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_union);
Datum gtsq_union(PG_FUNCTION_ARGS);
Datum gtsq_union(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_same);
Datum gtsq_same(PG_FUNCTION_ARGS);
Datum gtsq_same(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_penalty);
Datum gtsq_penalty(PG_FUNCTION_ARGS);
Datum gtsq_penalty(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(gtsq_picksplit);
Datum gtsq_picksplit(PG_FUNCTION_ARGS);
Datum gtsq_picksplit(PG_FUNCTION_ARGS);
Datum
gtsq_in(PG_FUNCTION_ARGS) {
elog(ERROR, "Not implemented");
PG_RETURN_DATUM(0);
gtsq_in(PG_FUNCTION_ARGS)
{
elog(ERROR, "Not implemented");
PG_RETURN_DATUM(0);
}
Datum
gtsq_out(PG_FUNCTION_ARGS) {
elog(ERROR, "Not implemented");
PG_RETURN_DATUM(0);
gtsq_out(PG_FUNCTION_ARGS)
{
elog(ERROR, "Not implemented");
PG_RETURN_DATUM(0);
}
Datum
gtsq_compress(PG_FUNCTION_ARGS) {
gtsq_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = entry;
if (entry->leafkey) {
TPQTGist *sign = (TPQTGist*)palloc( sizeof(TPQTGist) );
if (entry->leafkey)
{
TPQTGist *sign = (TPQTGist *) palloc(sizeof(TPQTGist));
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
*sign = makesign( (QUERYTYPE*)DatumGetPointer(PG_DETOAST_DATUM(entry->key)) );
*sign = makesign((QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(entry->key)));
gistentryinit(*retval, PointerGetDatum(sign),
entry->rel, entry->page,
entry->offset, sizeof(TPQTGist), FALSE);
entry->rel, entry->page,
entry->offset, sizeof(TPQTGist), FALSE);
}
PG_RETURN_POINTER(retval);
}
Datum
gtsq_decompress(PG_FUNCTION_ARGS) {
gtsq_decompress(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
}
Datum
gtsq_consistent(PG_FUNCTION_ARGS) {
gtsq_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TPQTGist *key = (TPQTGist*) DatumGetPointer(entry->key);
TPQTGist *key = (TPQTGist *) DatumGetPointer(entry->key);
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
TPQTGist sq = makesign(query);
if ( GIST_LEAF(entry) )
PG_RETURN_BOOL( ( (*key) & sq ) == ((strategy==1) ? sq : *key) );
else
PG_RETURN_BOOL( (*key) & sq );
if (GIST_LEAF(entry))
PG_RETURN_BOOL(((*key) & sq) == ((strategy == 1) ? sq : *key));
else
PG_RETURN_BOOL((*key) & sq);
}
Datum
gtsq_union(PG_FUNCTION_ARGS) {
gtsq_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
TPQTGist *sign = (TPQTGist*)palloc( sizeof(TPQTGist) );
int i;
int *size = (int *) PG_GETARG_POINTER(1);
TPQTGist *sign = (TPQTGist *) palloc(sizeof(TPQTGist));
int i;
int *size = (int *) PG_GETARG_POINTER(1);
memset( sign, 0, sizeof(TPQTGist) );
memset(sign, 0, sizeof(TPQTGist));
for (i = 0; i < entryvec->n;i++)
for (i = 0; i < entryvec->n; i++)
*sign |= *GETENTRY(entryvec, i);
*size = sizeof(TPQTGist);
@ -189,35 +210,40 @@ gtsq_union(PG_FUNCTION_ARGS) {
}
Datum
gtsq_same(PG_FUNCTION_ARGS) {
TPQTGist *a = (TPQTGist *) PG_GETARG_POINTER(0);
TPQTGist *b = (TPQTGist *) PG_GETARG_POINTER(1);
gtsq_same(PG_FUNCTION_ARGS)
{
TPQTGist *a = (TPQTGist *) PG_GETARG_POINTER(0);
TPQTGist *b = (TPQTGist *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( *a == *b );
PG_RETURN_POINTER(*a == *b);
}
static int
sizebitvec(TPQTGist sign) {
int size=0,i;
sizebitvec(TPQTGist sign)
{
int size = 0,
i;
for(i=0;i<SIGLEN;i++)
size += 0x01 & (sign>>i);
for (i = 0; i < SIGLEN; i++)
size += 0x01 & (sign >> i);
return size;
}
static int
hemdist(TPQTGist a, TPQTGist b) {
TPQTGist res = a ^ b;
hemdist(TPQTGist a, TPQTGist b)
{
TPQTGist res = a ^ b;
return sizebitvec(res);
}
Datum
gtsq_penalty(PG_FUNCTION_ARGS) {
TPQTGist *origval = (TPQTGist*) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
TPQTGist *newval = (TPQTGist*) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *penalty = (float *) PG_GETARG_POINTER(2);
gtsq_penalty(PG_FUNCTION_ARGS)
{
TPQTGist *origval = (TPQTGist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
TPQTGist *newval = (TPQTGist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *penalty = (float *) PG_GETARG_POINTER(2);
*penalty = hemdist(*origval, *newval);
@ -225,36 +251,45 @@ gtsq_penalty(PG_FUNCTION_ARGS) {
}
typedef struct {
OffsetNumber pos;
int4 cost;
typedef struct
{
OffsetNumber pos;
int4 cost;
} SPLITCOST;
static int
comparecost(const void *a, const void *b) {
if (((SPLITCOST *) a)->cost == ((SPLITCOST *) b)->cost)
return 0;
else
return (((SPLITCOST *) a)->cost > ((SPLITCOST *) b)->cost) ? 1 : -1;
comparecost(const void *a, const void *b)
{
if (((SPLITCOST *) a)->cost == ((SPLITCOST *) b)->cost)
return 0;
else
return (((SPLITCOST *) a)->cost > ((SPLITCOST *) b)->cost) ? 1 : -1;
}
#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
Datum
gtsq_picksplit(PG_FUNCTION_ARGS) {
gtsq_picksplit(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
OffsetNumber maxoff = entryvec->n - 2;
OffsetNumber k,j;
OffsetNumber k,
j;
TPQTGist *datum_l, *datum_r;
int4 size_alpha, size_beta;
int4 size_waste, waste = -1;
int4 nbytes;
OffsetNumber seed_1 = 0, seed_2 = 0;
OffsetNumber *left, *right;
TPQTGist *datum_l,
*datum_r;
int4 size_alpha,
size_beta;
int4 size_waste,
waste = -1;
int4 nbytes;
OffsetNumber seed_1 = 0,
seed_2 = 0;
OffsetNumber *left,
*right;
SPLITCOST *costvector;
SPLITCOST *costvector;
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
left = v->spl_left = (OffsetNumber *) palloc(nbytes);
@ -262,9 +297,11 @@ gtsq_picksplit(PG_FUNCTION_ARGS) {
v->spl_nleft = v->spl_nright = 0;
for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) {
size_waste = hemdist( *GETENTRY(entryvec,j), *GETENTRY(entryvec,k) );
if (size_waste > waste) {
for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
{
size_waste = hemdist(*GETENTRY(entryvec, j), *GETENTRY(entryvec, k));
if (size_waste > waste)
{
waste = size_waste;
seed_1 = k;
seed_2 = j;
@ -272,47 +309,56 @@ gtsq_picksplit(PG_FUNCTION_ARGS) {
}
if (seed_1 == 0 || seed_2 == 0) {
if (seed_1 == 0 || seed_2 == 0)
{
seed_1 = 1;
seed_2 = 2;
}
datum_l = (TPQTGist*)palloc( sizeof(TPQTGist) );
*datum_l=*GETENTRY(entryvec,seed_1);
datum_r = (TPQTGist*)palloc( sizeof(TPQTGist) );
*datum_r=*GETENTRY(entryvec,seed_2);
datum_l = (TPQTGist *) palloc(sizeof(TPQTGist));
*datum_l = *GETENTRY(entryvec, seed_1);
datum_r = (TPQTGist *) palloc(sizeof(TPQTGist));
*datum_r = *GETENTRY(entryvec, seed_2);
maxoff = OffsetNumberNext(maxoff);
costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) {
for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
{
costvector[j - 1].pos = j;
size_alpha = hemdist( *GETENTRY(entryvec,seed_1), *GETENTRY(entryvec,j) );
size_beta = hemdist( *GETENTRY(entryvec,seed_2), *GETENTRY(entryvec,j) );
size_alpha = hemdist(*GETENTRY(entryvec, seed_1), *GETENTRY(entryvec, j));
size_beta = hemdist(*GETENTRY(entryvec, seed_2), *GETENTRY(entryvec, j));
costvector[j - 1].cost = abs(size_alpha - size_beta);
}
qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
for (k = 0; k < maxoff; k++) {
for (k = 0; k < maxoff; k++)
{
j = costvector[k].pos;
if ( j == seed_1 ) {
if (j == seed_1)
{
*left++ = j;
v->spl_nleft++;
continue;
} else if ( j == seed_2 ) {
}
else if (j == seed_2)
{
*right++ = j;
v->spl_nright++;
continue;
}
size_alpha = hemdist( *datum_l, *GETENTRY(entryvec,j) );
size_beta = hemdist( *datum_r, *GETENTRY(entryvec,j) );
size_alpha = hemdist(*datum_l, *GETENTRY(entryvec, j));
size_beta = hemdist(*datum_r, *GETENTRY(entryvec, j));
if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.05)) {
*datum_l |= *GETENTRY(entryvec,j);
if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.05))
{
*datum_l |= *GETENTRY(entryvec, j);
*left++ = j;
v->spl_nleft++;
} else {
*datum_r |= *GETENTRY(entryvec,j);
}
else
{
*datum_r |= *GETENTRY(entryvec, j);
*right++ = j;
v->spl_nright++;
}
@ -324,5 +370,3 @@ gtsq_picksplit(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(v);
}

View File

@ -6,135 +6,167 @@
MemoryContext AggregateContext = NULL;
static int
addone(int * counters, int last, int total) {
addone(int *counters, int last, int total)
{
counters[last]++;
if ( counters[last]>=total ) {
if (last==0)
if (counters[last] >= total)
{
if (last == 0)
return 0;
if ( addone( counters, last-1, total-1 ) == 0 )
if (addone(counters, last - 1, total - 1) == 0)
return 0;
counters[last] = counters[last-1]+1;
counters[last] = counters[last - 1] + 1;
}
return 1;
}
static QTNode *
findeq(QTNode *node, QTNode *ex, MemoryType memtype, QTNode *subs, bool *isfind) {
if ( (node->sign & ex->sign) != ex->sign || node->valnode->type != ex->valnode->type || node->valnode->val != ex->valnode->val )
static QTNode *
findeq(QTNode * node, QTNode * ex, MemoryType memtype, QTNode * subs, bool *isfind)
{
if ((node->sign & ex->sign) != ex->sign || node->valnode->type != ex->valnode->type || node->valnode->val != ex->valnode->val)
return node;
if ( node->flags & QTN_NOCHANGE )
return node;
if (node->flags & QTN_NOCHANGE)
return node;
if ( node->valnode->type==OPR ) {
if ( node->nchild == ex->nchild ) {
if ( QTNEq( node, ex ) ) {
QTNFree( node );
if ( subs ) {
node = QTNCopy( subs, memtype );
if (node->valnode->type == OPR)
{
if (node->nchild == ex->nchild)
{
if (QTNEq(node, ex))
{
QTNFree(node);
if (subs)
{
node = QTNCopy(subs, memtype);
node->flags |= QTN_NOCHANGE;
} else
node = NULL;
}
else
node = NULL;
*isfind = true;
}
} else if ( node->nchild > ex->nchild ) {
int *counters = (int*)palloc( sizeof(int) * node->nchild );
int i;
QTNode *tnode = (QTNode*)MEMALLOC( memtype, sizeof(QTNode) );
}
else if (node->nchild > ex->nchild)
{
int *counters = (int *) palloc(sizeof(int) * node->nchild);
int i;
QTNode *tnode = (QTNode *) MEMALLOC(memtype, sizeof(QTNode));
memset(tnode, 0, sizeof(QTNode));
tnode->child = (QTNode**)MEMALLOC( memtype, sizeof(QTNode*) * ex->nchild );
tnode->child = (QTNode **) MEMALLOC(memtype, sizeof(QTNode *) * ex->nchild);
tnode->nchild = ex->nchild;
tnode->valnode = (ITEM*)MEMALLOC( memtype, sizeof(ITEM) );
tnode->valnode = (ITEM *) MEMALLOC(memtype, sizeof(ITEM));
*(tnode->valnode) = *(ex->valnode);
for(i=0;i<ex->nchild;i++)
counters[i]=i;
for (i = 0; i < ex->nchild; i++)
counters[i] = i;
do {
tnode->sign=0;
for(i=0;i<ex->nchild;i++) {
tnode->child[i] = node->child[ counters[i] ];
do
{
tnode->sign = 0;
for (i = 0; i < ex->nchild; i++)
{
tnode->child[i] = node->child[counters[i]];
tnode->sign |= tnode->child[i]->sign;
}
if ( QTNEq( tnode, ex ) ) {
int j=0;
if (QTNEq(tnode, ex))
{
int j = 0;
MEMFREE( memtype, tnode->valnode );
MEMFREE( memtype, tnode->child );
MEMFREE( memtype, tnode );
if ( subs ) {
tnode = QTNCopy( subs, memtype );
MEMFREE(memtype, tnode->valnode);
MEMFREE(memtype, tnode->child);
MEMFREE(memtype, tnode);
if (subs)
{
tnode = QTNCopy(subs, memtype);
tnode->flags = QTN_NOCHANGE | QTN_NEEDFREE;
} else
}
else
tnode = NULL;
node->child[ counters[0] ] = tnode;
node->child[counters[0]] = tnode;
for(i=1;i<ex->nchild;i++)
node->child[ counters[i] ] = NULL;
for(i=0;i<node->nchild;i++) {
if ( node->child[i] ) {
for (i = 1; i < ex->nchild; i++)
node->child[counters[i]] = NULL;
for (i = 0; i < node->nchild; i++)
{
if (node->child[i])
{
node->child[j] = node->child[i];
j++;
}
}
node->nchild = j;
node->nchild = j;
*isfind = true;
break;
}
} while (addone(counters,ex->nchild-1,node->nchild));
if ( tnode && (tnode->flags & QTN_NOCHANGE) == 0 ) {
MEMFREE( memtype, tnode->valnode );
MEMFREE( memtype, tnode->child );
MEMFREE( memtype, tnode );
} else
QTNSort( node );
pfree( counters );
} while (addone(counters, ex->nchild - 1, node->nchild));
if (tnode && (tnode->flags & QTN_NOCHANGE) == 0)
{
MEMFREE(memtype, tnode->valnode);
MEMFREE(memtype, tnode->child);
MEMFREE(memtype, tnode);
}
else
QTNSort(node);
pfree(counters);
}
} else if ( QTNEq( node, ex ) ) {
QTNFree( node );
if ( subs ) {
node = QTNCopy( subs, memtype );
}
else if (QTNEq(node, ex))
{
QTNFree(node);
if (subs)
{
node = QTNCopy(subs, memtype);
node->flags |= QTN_NOCHANGE;
} else {
}
else
{
node = NULL;
}
*isfind = true;
}
return node;
}
}
static QTNode *
dofindsubquery( QTNode *root, QTNode *ex, MemoryType memtype, QTNode *subs, bool *isfind ) {
root = findeq( root, ex, memtype, subs, isfind );
dofindsubquery(QTNode * root, QTNode * ex, MemoryType memtype, QTNode * subs, bool *isfind)
{
root = findeq(root, ex, memtype, subs, isfind);
if ( root && (root->flags & QTN_NOCHANGE) == 0 && root->valnode->type==OPR) {
int i;
for(i=0;i<root->nchild;i++)
root->child[i] = dofindsubquery( root->child[i], ex, memtype, subs, isfind );
if (root && (root->flags & QTN_NOCHANGE) == 0 && root->valnode->type == OPR)
{
int i;
for (i = 0; i < root->nchild; i++)
root->child[i] = dofindsubquery(root->child[i], ex, memtype, subs, isfind);
}
return root;
}
static QTNode *
dropvoidsubtree( QTNode *root ) {
dropvoidsubtree(QTNode * root)
{
if ( !root )
if (!root)
return NULL;
if ( root->valnode->type==OPR ) {
int i,j=0;
if (root->valnode->type == OPR)
{
int i,
j = 0;
for(i=0;i<root->nchild;i++) {
if ( root->child[i] ) {
for (i = 0; i < root->nchild; i++)
{
if (root->child[i])
{
root->child[j] = root->child[i];
j++;
}
@ -142,88 +174,100 @@ dropvoidsubtree( QTNode *root ) {
root->nchild = j;
if ( root->valnode->val == (int4)'!' && root->nchild==0 ) {
if (root->valnode->val == (int4) '!' && root->nchild == 0)
{
QTNFree(root);
root=NULL;
} else if ( root->nchild==1 ) {
QTNode *nroot = root->child[0];
root = NULL;
}
else if (root->nchild == 1)
{
QTNode *nroot = root->child[0];
pfree(root);
root = nroot;
}
root = nroot;
}
}
return root;
}
static QTNode *
findsubquery( QTNode *root, QTNode *ex, MemoryType memtype, QTNode *subs, bool *isfind ) {
bool DidFind = false;
root = dofindsubquery( root, ex, memtype, subs, &DidFind );
findsubquery(QTNode * root, QTNode * ex, MemoryType memtype, QTNode * subs, bool *isfind)
{
bool DidFind = false;
if ( !subs && DidFind )
root = dropvoidsubtree( root );
root = dofindsubquery(root, ex, memtype, subs, &DidFind);
if ( isfind )
if (!subs && DidFind)
root = dropvoidsubtree(root);
if (isfind)
*isfind = DidFind;
return root;
}
static Oid tsqOid = InvalidOid;
static Oid tsqOid = InvalidOid;
static void
get_tsq_Oid(void)
{
int ret;
bool isnull;
int ret;
bool isnull;
if ((ret = SPI_exec("select oid from pg_type where typname='tsquery'", 1)) < 0)
/* internal error */
elog(ERROR, "SPI_exec to get tsquery oid returns %d", ret);
if ((ret = SPI_exec("select oid from pg_type where typname='tsquery'", 1)) < 0)
/* internal error */
elog(ERROR, "SPI_exec to get tsquery oid returns %d", ret);
if (SPI_processed < 0)
/* internal error */
elog(ERROR, "There is no tsvector type");
tsqOid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
if (tsqOid == InvalidOid)
/* internal error */
elog(ERROR, "tsquery type has InvalidOid");
if (SPI_processed < 0)
/* internal error */
elog(ERROR, "There is no tsvector type");
tsqOid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
if (tsqOid == InvalidOid)
/* internal error */
elog(ERROR, "tsquery type has InvalidOid");
}
PG_FUNCTION_INFO_V1(tsquery_rewrite);
PG_FUNCTION_INFO_V1(rewrite_accum);
Datum rewrite_accum(PG_FUNCTION_ARGS);
Datum rewrite_accum(PG_FUNCTION_ARGS);
Datum
rewrite_accum(PG_FUNCTION_ARGS) {
QUERYTYPE *acc = (QUERYTYPE *) PG_GETARG_POINTER(0);
ArrayType *qa = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
QUERYTYPE *q;
QTNode *qex, *subs = NULL, *acctree;
bool isfind = false;
Datum *elemsp;
int nelemsp;
Datum
rewrite_accum(PG_FUNCTION_ARGS)
{
QUERYTYPE *acc = (QUERYTYPE *) PG_GETARG_POINTER(0);
ArrayType *qa = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
QUERYTYPE *q;
QTNode *qex,
*subs = NULL,
*acctree;
bool isfind = false;
Datum *elemsp;
int nelemsp;
AggregateContext = ((AggState *) fcinfo->context)->aggcontext;
if (acc == NULL || PG_ARGISNULL(0)) {
acc = (QUERYTYPE*)MEMALLOC( AggMemory, sizeof(QUERYTYPE) );
if (acc == NULL || PG_ARGISNULL(0))
{
acc = (QUERYTYPE *) MEMALLOC(AggMemory, sizeof(QUERYTYPE));
acc->len = HDRSIZEQT;
acc->size = 0;
}
if ( qa == NULL || PG_ARGISNULL(1) ) {
PG_FREE_IF_COPY( qa, 1 );
PG_RETURN_POINTER( acc );
if (qa == NULL || PG_ARGISNULL(1))
{
PG_FREE_IF_COPY(qa, 1);
PG_RETURN_POINTER(acc);
}
if ( ARR_NDIM(qa) != 1 )
if (ARR_NDIM(qa) != 1)
elog(ERROR, "array must be one-dimensional, not %d dimension", ARR_NDIM(qa));
if ( ArrayGetNItems( ARR_NDIM(qa), ARR_DIMS(qa)) != 3 )
if (ArrayGetNItems(ARR_NDIM(qa), ARR_DIMS(qa)) != 3)
elog(ERROR, "array should have only three elements");
if (tsqOid == InvalidOid) {
if (tsqOid == InvalidOid)
{
SPI_connect();
get_tsq_Oid();
SPI_finish();
@ -232,108 +276,122 @@ rewrite_accum(PG_FUNCTION_ARGS) {
if (ARR_ELEMTYPE(qa) != tsqOid)
elog(ERROR, "array should contain tsquery type");
deconstruct_array(qa, tsqOid, -1, false, 'i', &elemsp, NULL, &nelemsp);
deconstruct_array(qa, tsqOid, -1, false, 'i', &elemsp, NULL, &nelemsp);
q = (QUERYTYPE*)DatumGetPointer( elemsp[0] );
if ( q->size == 0 ) {
pfree( elemsp );
PG_RETURN_POINTER( acc );
q = (QUERYTYPE *) DatumGetPointer(elemsp[0]);
if (q->size == 0)
{
pfree(elemsp);
PG_RETURN_POINTER(acc);
}
if ( !acc->size ) {
if ( acc->len > HDRSIZEQT ) {
pfree( elemsp );
PG_RETURN_POINTER( acc );
} else
acctree = QT2QTN( GETQUERY(q), GETOPERAND(q) );
} else
acctree = QT2QTN( GETQUERY(acc), GETOPERAND(acc) );
QTNTernary( acctree );
QTNSort( acctree );
q = (QUERYTYPE*)DatumGetPointer( elemsp[1] );
if ( q->size == 0 ) {
pfree( elemsp );
PG_RETURN_POINTER( acc );
if (!acc->size)
{
if (acc->len > HDRSIZEQT)
{
pfree(elemsp);
PG_RETURN_POINTER(acc);
}
else
acctree = QT2QTN(GETQUERY(q), GETOPERAND(q));
}
qex = QT2QTN( GETQUERY(q), GETOPERAND(q) );
QTNTernary( qex );
QTNSort( qex );
q = (QUERYTYPE*)DatumGetPointer( elemsp[2] );
if ( q->size )
subs = QT2QTN( GETQUERY(q), GETOPERAND(q) );
else
acctree = QT2QTN(GETQUERY(acc), GETOPERAND(acc));
acctree = findsubquery( acctree, qex, PlainMemory, subs, &isfind );
QTNTernary(acctree);
QTNSort(acctree);
if ( isfind || !acc->size ) {
q = (QUERYTYPE *) DatumGetPointer(elemsp[1]);
if (q->size == 0)
{
pfree(elemsp);
PG_RETURN_POINTER(acc);
}
qex = QT2QTN(GETQUERY(q), GETOPERAND(q));
QTNTernary(qex);
QTNSort(qex);
q = (QUERYTYPE *) DatumGetPointer(elemsp[2]);
if (q->size)
subs = QT2QTN(GETQUERY(q), GETOPERAND(q));
acctree = findsubquery(acctree, qex, PlainMemory, subs, &isfind);
if (isfind || !acc->size)
{
/* pfree( acc ); do not pfree(p), because nodeAgg.c will */
if ( acctree ) {
QTNBinary( acctree );
acc = QTN2QT( acctree, AggMemory );
} else {
acc = (QUERYTYPE*)MEMALLOC( AggMemory, HDRSIZEQT*2 );
if (acctree)
{
QTNBinary(acctree);
acc = QTN2QT(acctree, AggMemory);
}
else
{
acc = (QUERYTYPE *) MEMALLOC(AggMemory, HDRSIZEQT * 2);
acc->len = HDRSIZEQT * 2;
acc->size = 0;
}
}
pfree( elemsp );
QTNFree( qex );
QTNFree( subs );
QTNFree( acctree );
pfree(elemsp);
QTNFree(qex);
QTNFree(subs);
QTNFree(acctree);
PG_RETURN_POINTER( acc );
PG_RETURN_POINTER(acc);
}
PG_FUNCTION_INFO_V1(rewrite_finish);
Datum rewrite_finish(PG_FUNCTION_ARGS);
Datum rewrite_finish(PG_FUNCTION_ARGS);
Datum
rewrite_finish(PG_FUNCTION_ARGS) {
QUERYTYPE *acc = (QUERYTYPE *) PG_GETARG_POINTER(0);
QUERYTYPE *rewrited;
if (acc == NULL || PG_ARGISNULL(0) || acc->size == 0 ) {
acc = (QUERYTYPE*)palloc(sizeof(QUERYTYPE));
Datum
rewrite_finish(PG_FUNCTION_ARGS)
{
QUERYTYPE *acc = (QUERYTYPE *) PG_GETARG_POINTER(0);
QUERYTYPE *rewrited;
if (acc == NULL || PG_ARGISNULL(0) || acc->size == 0)
{
acc = (QUERYTYPE *) palloc(sizeof(QUERYTYPE));
acc->len = HDRSIZEQT;
acc->size = 0;
}
rewrited = (QUERYTYPE*) palloc( acc->len );
memcpy( rewrited, acc, acc->len );
pfree( acc );
rewrited = (QUERYTYPE *) palloc(acc->len);
memcpy(rewrited, acc, acc->len);
pfree(acc);
PG_RETURN_POINTER(rewrited);
PG_RETURN_POINTER(rewrited);
}
Datum tsquery_rewrite(PG_FUNCTION_ARGS);
Datum tsquery_rewrite(PG_FUNCTION_ARGS);
Datum
tsquery_rewrite(PG_FUNCTION_ARGS) {
tsquery_rewrite(PG_FUNCTION_ARGS)
{
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
text *in = PG_GETARG_TEXT_P(1);
text *in = PG_GETARG_TEXT_P(1);
QUERYTYPE *rewrited = query;
QTNode *tree;
char *buf;
void *plan;
Portal portal;
bool isnull;
int i;
QTNode *tree;
char *buf;
void *plan;
Portal portal;
bool isnull;
int i;
if ( query->size == 0 ) {
if (query->size == 0)
{
PG_FREE_IF_COPY(in, 1);
PG_RETURN_POINTER( rewrited );
PG_RETURN_POINTER(rewrited);
}
tree = QT2QTN( GETQUERY(query), GETOPERAND(query) );
QTNTernary( tree );
QTNSort( tree );
tree = QT2QTN(GETQUERY(query), GETOPERAND(query));
QTNTernary(tree);
QTNSort(tree);
buf = (char*)palloc( VARSIZE(in) );
buf = (char *) palloc(VARSIZE(in));
memcpy(buf, VARDATA(in), VARSIZE(in) - VARHDRSZ);
buf[ VARSIZE(in) - VARHDRSZ ] = '\0';
buf[VARSIZE(in) - VARHDRSZ] = '\0';
SPI_connect();
@ -345,132 +403,147 @@ tsquery_rewrite(PG_FUNCTION_ARGS) {
if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, false)) == NULL)
elog(ERROR, "SPI_cursor_open('%s') returns NULL", buf);
SPI_cursor_fetch(portal, true, 100);
if (SPI_tuptable->tupdesc->natts != 2)
elog(ERROR, "number of fields doesn't equal to 2");
if (SPI_gettypeid(SPI_tuptable->tupdesc, 1) != tsqOid )
if (SPI_gettypeid(SPI_tuptable->tupdesc, 1) != tsqOid)
elog(ERROR, "column #1 isn't of tsquery type");
if (SPI_gettypeid(SPI_tuptable->tupdesc, 2) != tsqOid )
if (SPI_gettypeid(SPI_tuptable->tupdesc, 2) != tsqOid)
elog(ERROR, "column #2 isn't of tsquery type");
while (SPI_processed > 0 && tree ) {
for (i = 0; i < SPI_processed && tree; i++) {
Datum qdata = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull);
Datum sdata;
while (SPI_processed > 0 && tree)
{
for (i = 0; i < SPI_processed && tree; i++)
{
Datum qdata = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull);
Datum sdata;
if ( isnull ) continue;
if (isnull)
continue;
sdata = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 2, &isnull);
if (!isnull) {
QUERYTYPE *qtex = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(qdata));
QUERYTYPE *qtsubs = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(sdata));
QTNode *qex, *qsubs = NULL;
if (!isnull)
{
QUERYTYPE *qtex = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(qdata));
QUERYTYPE *qtsubs = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(sdata));
QTNode *qex,
*qsubs = NULL;
if (qtex->size == 0) {
if ( qtex != (QUERYTYPE *) DatumGetPointer(qdata) )
pfree( qtex );
if ( qtsubs != (QUERYTYPE *) DatumGetPointer(sdata) )
pfree( qtsubs );
if (qtex->size == 0)
{
if (qtex != (QUERYTYPE *) DatumGetPointer(qdata))
pfree(qtex);
if (qtsubs != (QUERYTYPE *) DatumGetPointer(sdata))
pfree(qtsubs);
continue;
}
qex = QT2QTN( GETQUERY(qtex), GETOPERAND(qtex) );
qex = QT2QTN(GETQUERY(qtex), GETOPERAND(qtex));
QTNTernary( qex );
QTNSort( qex );
QTNTernary(qex);
QTNSort(qex);
if ( qtsubs->size )
qsubs = QT2QTN( GETQUERY(qtsubs), GETOPERAND(qtsubs) );
if (qtsubs->size)
qsubs = QT2QTN(GETQUERY(qtsubs), GETOPERAND(qtsubs));
tree = findsubquery( tree, qex, SPIMemory, qsubs, NULL );
QTNFree( qex );
if ( qtex != (QUERYTYPE *) DatumGetPointer(qdata) )
pfree( qtex );
QTNFree( qsubs );
if ( qtsubs != (QUERYTYPE *) DatumGetPointer(sdata) )
pfree( qtsubs );
tree = findsubquery(tree, qex, SPIMemory, qsubs, NULL);
QTNFree(qex);
if (qtex != (QUERYTYPE *) DatumGetPointer(qdata))
pfree(qtex);
QTNFree(qsubs);
if (qtsubs != (QUERYTYPE *) DatumGetPointer(sdata))
pfree(qtsubs);
}
}
SPI_freetuptable(SPI_tuptable);
SPI_cursor_fetch(portal, true, 100);
}
SPI_freetuptable(SPI_tuptable);
SPI_cursor_close(portal);
SPI_freeplan(plan);
SPI_finish();
SPI_finish();
if ( tree ) {
QTNBinary( tree );
rewrited = QTN2QT( tree, PlainMemory );
QTNFree( tree );
if (tree)
{
QTNBinary(tree);
rewrited = QTN2QT(tree, PlainMemory);
QTNFree(tree);
PG_FREE_IF_COPY(query, 0);
} else {
}
else
{
rewrited->len = HDRSIZEQT;
rewrited->size = 0;
}
pfree(buf);
PG_FREE_IF_COPY(in, 1);
PG_RETURN_POINTER( rewrited );
PG_RETURN_POINTER(rewrited);
}
PG_FUNCTION_INFO_V1(tsquery_rewrite_query);
Datum tsquery_rewrite_query(PG_FUNCTION_ARGS);
Datum tsquery_rewrite_query(PG_FUNCTION_ARGS);
Datum
tsquery_rewrite_query(PG_FUNCTION_ARGS) {
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
QUERYTYPE *ex = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
QUERYTYPE *subst = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(2)));
QUERYTYPE *rewrited = query;
QTNode *tree, *qex, *subs = NULL;
tsquery_rewrite_query(PG_FUNCTION_ARGS)
{
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
QUERYTYPE *ex = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
QUERYTYPE *subst = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(2)));
QUERYTYPE *rewrited = query;
QTNode *tree,
*qex,
*subs = NULL;
if ( query->size == 0 || ex->size == 0 ) {
PG_FREE_IF_COPY(ex, 1);
PG_FREE_IF_COPY(subst, 2);
PG_RETURN_POINTER( rewrited );
}
tree = QT2QTN( GETQUERY(query), GETOPERAND(query) );
QTNTernary( tree );
QTNSort( tree );
qex = QT2QTN( GETQUERY(ex), GETOPERAND(ex) );
QTNTernary( qex );
QTNSort( qex );
if ( subst->size )
subs = QT2QTN( GETQUERY(subst), GETOPERAND(subst) );
tree = findsubquery( tree, qex, PlainMemory, subs, NULL );
QTNFree( qex );
QTNFree( subs );
if ( !tree ) {
rewrited->len = HDRSIZEQT;
rewrited->size = 0;
PG_FREE_IF_COPY(ex, 1);
PG_FREE_IF_COPY(subst, 2);
PG_RETURN_POINTER( rewrited );
} else {
QTNBinary( tree );
rewrited = QTN2QT( tree, PlainMemory );
QTNFree( tree );
if (query->size == 0 || ex->size == 0)
{
PG_FREE_IF_COPY(ex, 1);
PG_FREE_IF_COPY(subst, 2);
PG_RETURN_POINTER(rewrited);
}
PG_FREE_IF_COPY(query, 0);
PG_FREE_IF_COPY(ex, 1);
PG_FREE_IF_COPY(subst, 2);
PG_RETURN_POINTER( rewrited );
}
tree = QT2QTN(GETQUERY(query), GETOPERAND(query));
QTNTernary(tree);
QTNSort(tree);
qex = QT2QTN(GETQUERY(ex), GETOPERAND(ex));
QTNTernary(qex);
QTNSort(qex);
if (subst->size)
subs = QT2QTN(GETQUERY(subst), GETOPERAND(subst));
tree = findsubquery(tree, qex, PlainMemory, subs, NULL);
QTNFree(qex);
QTNFree(subs);
if (!tree)
{
rewrited->len = HDRSIZEQT;
rewrited->size = 0;
PG_FREE_IF_COPY(ex, 1);
PG_FREE_IF_COPY(subst, 2);
PG_RETURN_POINTER(rewrited);
}
else
{
QTNBinary(tree);
rewrited = QTN2QT(tree, PlainMemory);
QTNFree(tree);
}
PG_FREE_IF_COPY(query, 0);
PG_FREE_IF_COPY(ex, 1);
PG_FREE_IF_COPY(subst, 2);
PG_RETURN_POINTER(rewrited);
}

View File

@ -4,168 +4,188 @@
#include "query_util.h"
PG_FUNCTION_INFO_V1(tsquery_numnode);
Datum tsquery_numnode(PG_FUNCTION_ARGS);
Datum tsquery_numnode(PG_FUNCTION_ARGS);
Datum
tsquery_numnode(PG_FUNCTION_ARGS) {
tsquery_numnode(PG_FUNCTION_ARGS)
{
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
int nnode = query->size;
PG_FREE_IF_COPY(query,0);
int nnode = query->size;
PG_FREE_IF_COPY(query, 0);
PG_RETURN_INT32(nnode);
}
static QTNode*
join_tsqueries(QUERYTYPE *a, QUERYTYPE *b) {
QTNode *res=(QTNode*)palloc0( sizeof(QTNode) );
static QTNode *
join_tsqueries(QUERYTYPE * a, QUERYTYPE * b)
{
QTNode *res = (QTNode *) palloc0(sizeof(QTNode));
res->flags |= QTN_NEEDFREE;
res->valnode = (ITEM*)palloc0( sizeof(ITEM) );
res->valnode = (ITEM *) palloc0(sizeof(ITEM));
res->valnode->type = OPR;
res->child = (QTNode**)palloc0( sizeof(QTNode*)*2 );
res->child[0] = QT2QTN( GETQUERY(b), GETOPERAND(b) );
res->child[1] = QT2QTN( GETQUERY(a), GETOPERAND(a) );
res->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
res->child[0] = QT2QTN(GETQUERY(b), GETOPERAND(b));
res->child[1] = QT2QTN(GETQUERY(a), GETOPERAND(a));
res->nchild = 2;
return res;
}
PG_FUNCTION_INFO_V1(tsquery_and);
Datum tsquery_and(PG_FUNCTION_ARGS);
Datum tsquery_and(PG_FUNCTION_ARGS);
Datum
tsquery_and(PG_FUNCTION_ARGS) {
tsquery_and(PG_FUNCTION_ARGS)
{
QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
QUERYTYPE *b = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
QTNode *res;
QTNode *res;
QUERYTYPE *query;
if ( a->size == 0 ) {
PG_FREE_IF_COPY(a,1);
if (a->size == 0)
{
PG_FREE_IF_COPY(a, 1);
PG_RETURN_POINTER(b);
} else if ( b->size == 0 ) {
PG_FREE_IF_COPY(b,1);
}
else if (b->size == 0)
{
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POINTER(a);
}
}
res = join_tsqueries(a, b);
res->valnode->val = '&';
query = QTN2QT( res, PlainMemory );
query = QTN2QT(res, PlainMemory);
QTNFree(res);
PG_FREE_IF_COPY(a,0);
PG_FREE_IF_COPY(b,1);
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POINTER(query);
}
PG_FUNCTION_INFO_V1(tsquery_or);
Datum tsquery_or(PG_FUNCTION_ARGS);
Datum tsquery_or(PG_FUNCTION_ARGS);
Datum
tsquery_or(PG_FUNCTION_ARGS) {
tsquery_or(PG_FUNCTION_ARGS)
{
QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
QUERYTYPE *b = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
QTNode *res;
QTNode *res;
QUERYTYPE *query;
if ( a->size == 0 ) {
PG_FREE_IF_COPY(a,1);
if (a->size == 0)
{
PG_FREE_IF_COPY(a, 1);
PG_RETURN_POINTER(b);
} else if ( b->size == 0 ) {
PG_FREE_IF_COPY(b,1);
}
else if (b->size == 0)
{
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POINTER(a);
}
}
res = join_tsqueries(a, b);
res->valnode->val = '|';
query = QTN2QT( res, PlainMemory );
query = QTN2QT(res, PlainMemory);
QTNFree(res);
PG_FREE_IF_COPY(a,0);
PG_FREE_IF_COPY(b,1);
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POINTER(query);
}
PG_FUNCTION_INFO_V1(tsquery_not);
Datum tsquery_not(PG_FUNCTION_ARGS);
Datum tsquery_not(PG_FUNCTION_ARGS);
Datum
tsquery_not(PG_FUNCTION_ARGS) {
tsquery_not(PG_FUNCTION_ARGS)
{
QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
QTNode *res;
QTNode *res;
QUERYTYPE *query;
if ( a->size == 0 )
if (a->size == 0)
PG_RETURN_POINTER(a);
res=(QTNode*)palloc0( sizeof(QTNode) );
res = (QTNode *) palloc0(sizeof(QTNode));
res->flags |= QTN_NEEDFREE;
res->valnode = (ITEM*)palloc0( sizeof(ITEM) );
res->valnode = (ITEM *) palloc0(sizeof(ITEM));
res->valnode->type = OPR;
res->valnode->val = '!';
res->child = (QTNode**)palloc0( sizeof(QTNode*) );
res->child[0] = QT2QTN( GETQUERY(a), GETOPERAND(a) );
res->child = (QTNode **) palloc0(sizeof(QTNode *));
res->child[0] = QT2QTN(GETQUERY(a), GETOPERAND(a));
res->nchild = 1;
query = QTN2QT( res, PlainMemory );
query = QTN2QT(res, PlainMemory);
QTNFree(res);
PG_FREE_IF_COPY(a,0);
PG_FREE_IF_COPY(a, 0);
PG_RETURN_POINTER(query);
}
static int
CompareTSQ( QUERYTYPE *a, QUERYTYPE *b ) {
if ( a->size != b->size ) {
return ( a->size < b->size ) ? -1 : 1;
} else if ( a->len != b->len ) {
return ( a->len < b->len ) ? -1 : 1;
} else {
QTNode *an = QT2QTN( GETQUERY(a), GETOPERAND(a) );
QTNode *bn = QT2QTN( GETQUERY(b), GETOPERAND(b) );
int res = QTNodeCompare(an, bn);
CompareTSQ(QUERYTYPE * a, QUERYTYPE * b)
{
if (a->size != b->size)
{
return (a->size < b->size) ? -1 : 1;
}
else if (a->len != b->len)
{
return (a->len < b->len) ? -1 : 1;
}
else
{
QTNode *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
QTNode *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
int res = QTNodeCompare(an, bn);
QTNFree(an);
QTNFree(bn);
return res;
return res;
}
return 0;
}
PG_FUNCTION_INFO_V1(tsquery_cmp); \
Datum tsquery_cmp(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(tsquery_cmp);
\
Datum tsquery_cmp(PG_FUNCTION_ARGS);
Datum
tsquery_cmp(PG_FUNCTION_ARGS) {
tsquery_cmp(PG_FUNCTION_ARGS)
{
QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
QUERYTYPE *b = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
int res = CompareTSQ(a,b);
int res = CompareTSQ(a, b);
PG_FREE_IF_COPY(a,0);
PG_FREE_IF_COPY(b,1);
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_INT32(res);
}
#define CMPFUNC( NAME, ACTION ) \
#define CMPFUNC( NAME, ACTION ) \
PG_FUNCTION_INFO_V1(NAME); \
Datum NAME(PG_FUNCTION_ARGS); \
\
Datum \
NAME(PG_FUNCTION_ARGS) { \
NAME(PG_FUNCTION_ARGS) { \
QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); \
QUERYTYPE *b = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); \
int res = CompareTSQ(a,b); \
@ -176,12 +196,9 @@ NAME(PG_FUNCTION_ARGS) { \
PG_RETURN_BOOL( ACTION ); \
}
CMPFUNC( tsquery_lt, res <0 );
CMPFUNC( tsquery_le, res<=0 );
CMPFUNC( tsquery_eq, res==0 );
CMPFUNC( tsquery_ge, res>=0 );
CMPFUNC( tsquery_gt, res >0 );
CMPFUNC( tsquery_ne, res!=0 );
CMPFUNC(tsquery_lt, res < 0);
CMPFUNC(tsquery_le, res <= 0);
CMPFUNC(tsquery_eq, res == 0);
CMPFUNC(tsquery_ge, res >= 0);
CMPFUNC(tsquery_gt, res > 0);
CMPFUNC(tsquery_ne, res != 0);

View File

@ -2,153 +2,180 @@
#include "executor/spi.h"
#include "query_util.h"
QTNode*
QT2QTN( ITEM *in, char *operand ) {
QTNode *node = (QTNode*)palloc0( sizeof(QTNode) );
QTNode *
QT2QTN(ITEM * in, char *operand)
{
QTNode *node = (QTNode *) palloc0(sizeof(QTNode));
node->valnode = in;
if (in->type == OPR) {
node->child = (QTNode**)palloc0( sizeof(QTNode*) * 2 );
node->child[0] = QT2QTN( in + 1, operand );
if (in->type == OPR)
{
node->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
node->child[0] = QT2QTN(in + 1, operand);
node->sign = node->child[0]->sign;
if (in->val == (int4) '!')
node->nchild = 1;
else {
else
{
node->nchild = 2;
node->child[1] = QT2QTN( in + in->left, operand );
node->child[1] = QT2QTN(in + in->left, operand);
node->sign |= node->child[1]->sign;
}
} else if ( operand ) {
node->word = operand + in->distance;
node->sign = 1 << ( in->val % 32 );
}
return node;
else if (operand)
{
node->word = operand + in->distance;
node->sign = 1 << (in->val % 32);
}
return node;
}
void
QTNFree( QTNode* in ) {
if ( !in )
void
QTNFree(QTNode * in)
{
if (!in)
return;
if ( in->valnode->type == VAL && in->word && (in->flags & QTN_WORDFREE) !=0 )
pfree( in->word );
if (in->valnode->type == VAL && in->word && (in->flags & QTN_WORDFREE) != 0)
pfree(in->word);
if ( in->child ) {
if ( in->valnode ) {
if ( in->valnode->type == OPR && in->nchild > 0 ) {
int i;
for (i=0;i<in->nchild;i++)
QTNFree( in->child[i] );
if (in->child)
{
if (in->valnode)
{
if (in->valnode->type == OPR && in->nchild > 0)
{
int i;
for (i = 0; i < in->nchild; i++)
QTNFree(in->child[i]);
}
if ( in->flags & QTN_NEEDFREE )
pfree( in->valnode );
if (in->flags & QTN_NEEDFREE)
pfree(in->valnode);
}
pfree( in->child );
pfree(in->child);
}
pfree( in );
pfree(in);
}
int
QTNodeCompare( QTNode *an, QTNode *bn ) {
if ( an->valnode->type != bn->valnode->type )
return ( an->valnode->type > bn->valnode->type ) ? -1 : 1;
else if ( an->valnode->val != bn->valnode->val )
return ( an->valnode->val > bn->valnode->val ) ? -1 : 1;
else if ( an->valnode->type == VAL ) {
if ( an->valnode->length == bn->valnode->length )
return strncmp( an->word, bn->word, an->valnode->length );
else
return ( an->valnode->length > bn->valnode->length ) ? -1 : 1;
} else if ( an->nchild != bn->nchild ) {
return ( an->nchild > bn->nchild ) ? -1 : 1;
} else {
int i,res;
for( i=0; i<an->nchild; i++ )
if ( (res=QTNodeCompare(an->child[i], bn->child[i]))!=0 )
QTNodeCompare(QTNode * an, QTNode * bn)
{
if (an->valnode->type != bn->valnode->type)
return (an->valnode->type > bn->valnode->type) ? -1 : 1;
else if (an->valnode->val != bn->valnode->val)
return (an->valnode->val > bn->valnode->val) ? -1 : 1;
else if (an->valnode->type == VAL)
{
if (an->valnode->length == bn->valnode->length)
return strncmp(an->word, bn->word, an->valnode->length);
else
return (an->valnode->length > bn->valnode->length) ? -1 : 1;
}
else if (an->nchild != bn->nchild)
{
return (an->nchild > bn->nchild) ? -1 : 1;
}
else
{
int i,
res;
for (i = 0; i < an->nchild; i++)
if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0)
return res;
}
}
return 0;
}
static int
cmpQTN( const void *a, const void *b ) {
return QTNodeCompare( *(QTNode**)a, *(QTNode**)b );
cmpQTN(const void *a, const void *b)
{
return QTNodeCompare(*(QTNode **) a, *(QTNode **) b);
}
void
QTNSort( QTNode* in ) {
int i;
if ( in->valnode->type != OPR )
void
QTNSort(QTNode * in)
{
int i;
if (in->valnode->type != OPR)
return;
for (i=0;i<in->nchild;i++)
QTNSort( in->child[i] );
if ( in->nchild > 1 )
qsort((void *) in->child, in->nchild, sizeof(QTNode*), cmpQTN);
for (i = 0; i < in->nchild; i++)
QTNSort(in->child[i]);
if (in->nchild > 1)
qsort((void *) in->child, in->nchild, sizeof(QTNode *), cmpQTN);
}
bool
QTNEq( QTNode* a, QTNode* b ) {
uint32 sign = a->sign & b->sign;
if ( !(sign == a->sign && sign == b->sign) )
bool
QTNEq(QTNode * a, QTNode * b)
{
uint32 sign = a->sign & b->sign;
if (!(sign == a->sign && sign == b->sign))
return 0;
return ( QTNodeCompare(a,b) == 0 ) ? true : false;
return (QTNodeCompare(a, b) == 0) ? true : false;
}
void
QTNTernary( QTNode* in ) {
int i;
void
QTNTernary(QTNode * in)
{
int i;
if ( in->valnode->type != OPR )
if (in->valnode->type != OPR)
return;
for (i=0;i<in->nchild;i++)
QTNTernary( in->child[i] );
for (i = 0; i < in->nchild; i++)
QTNTernary(in->child[i]);
for (i=0;i<in->nchild;i++) {
if ( in->valnode->type == in->child[i]->valnode->type && in->valnode->val == in->child[i]->valnode->val ) {
QTNode* cc = in->child[i];
int oldnchild = in->nchild;
for (i = 0; i < in->nchild; i++)
{
if (in->valnode->type == in->child[i]->valnode->type && in->valnode->val == in->child[i]->valnode->val)
{
QTNode *cc = in->child[i];
int oldnchild = in->nchild;
in->nchild += cc->nchild-1;
in->child = (QTNode**)repalloc( in->child, in->nchild * sizeof(QTNode*) );
if ( i+1 != oldnchild )
memmove( in->child + i + cc->nchild, in->child + i + 1,
(oldnchild-i-1)*sizeof(QTNode*) );
in->nchild += cc->nchild - 1;
in->child = (QTNode **) repalloc(in->child, in->nchild * sizeof(QTNode *));
memcpy( in->child + i, cc->child, cc->nchild * sizeof(QTNode*) );
i += cc->nchild-1;
if (i + 1 != oldnchild)
memmove(in->child + i + cc->nchild, in->child + i + 1,
(oldnchild - i - 1) * sizeof(QTNode *));
memcpy(in->child + i, cc->child, cc->nchild * sizeof(QTNode *));
i += cc->nchild - 1;
pfree(cc);
}
}
}
}
void
QTNBinary( QTNode* in ) {
int i;
void
QTNBinary(QTNode * in)
{
int i;
if ( in->valnode->type != OPR )
if (in->valnode->type != OPR)
return;
for (i=0;i<in->nchild;i++)
QTNBinary( in->child[i] );
for (i = 0; i < in->nchild; i++)
QTNBinary(in->child[i]);
if ( in->nchild <= 2 )
return;
if (in->nchild <= 2)
return;
while( in->nchild > 2 ) {
QTNode *nn = (QTNode*)palloc0( sizeof(QTNode) );
nn->valnode = (ITEM*)palloc0( sizeof(ITEM) );
nn->child = (QTNode**)palloc0( sizeof(QTNode*) * 2 );
while (in->nchild > 2)
{
QTNode *nn = (QTNode *) palloc0(sizeof(QTNode));
nn->valnode = (ITEM *) palloc0(sizeof(ITEM));
nn->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
nn->nchild = 2;
nn->flags = QTN_NEEDFREE;
@ -161,97 +188,114 @@ QTNBinary( QTNode* in ) {
nn->valnode->val = in->valnode->val;
in->child[0] = nn;
in->child[1] = in->child[ in->nchild-1 ];
in->child[1] = in->child[in->nchild - 1];
in->nchild--;
}
}
}
static void
cntsize(QTNode *in, int4 *sumlen, int4 *nnode) {
cntsize(QTNode * in, int4 *sumlen, int4 *nnode)
{
*nnode += 1;
if ( in->valnode->type == OPR ) {
int i;
for (i=0;i<in->nchild;i++)
if (in->valnode->type == OPR)
{
int i;
for (i = 0; i < in->nchild; i++)
cntsize(in->child[i], sumlen, nnode);
} else {
*sumlen += in->valnode->length+1;
}
else
{
*sumlen += in->valnode->length + 1;
}
}
typedef struct {
ITEM *curitem;
char *operand;
char *curoperand;
} QTN2QTState;
typedef struct
{
ITEM *curitem;
char *operand;
char *curoperand;
} QTN2QTState;
static void
fillQT( QTN2QTState *state, QTNode *in ) {
fillQT(QTN2QTState * state, QTNode * in)
{
*(state->curitem) = *(in->valnode);
if ( in->valnode->type == VAL ) {
memcpy( state->curoperand, in->word, in->valnode->length );
if (in->valnode->type == VAL)
{
memcpy(state->curoperand, in->word, in->valnode->length);
state->curitem->distance = state->curoperand - state->operand;
state->curoperand[ in->valnode->length ] = '\0';
state->curoperand += in->valnode->length + 1;
state->curoperand[in->valnode->length] = '\0';
state->curoperand += in->valnode->length + 1;
state->curitem++;
} else {
ITEM *curitem = state->curitem;
Assert( in->nchild<=2 );
state->curitem++;
fillQT( state, in->child[0] );
if ( in->nchild==2 ) {
curitem->left = state->curitem - curitem;
fillQT( state, in->child[1] );
}
}
}
else
{
ITEM *curitem = state->curitem;
QUERYTYPE*
QTN2QT( QTNode* in, MemoryType memtype ) {
QUERYTYPE *out;
int len;
int sumlen=0, nnode=0;
QTN2QTState state;
Assert(in->nchild <= 2);
state->curitem++;
fillQT(state, in->child[0]);
if (in->nchild == 2)
{
curitem->left = state->curitem - curitem;
fillQT(state, in->child[1]);
}
}
}
QUERYTYPE *
QTN2QT(QTNode * in, MemoryType memtype)
{
QUERYTYPE *out;
int len;
int sumlen = 0,
nnode = 0;
QTN2QTState state;
cntsize(in, &sumlen, &nnode);
len = COMPUTESIZE( nnode, sumlen );
len = COMPUTESIZE(nnode, sumlen);
out = (QUERYTYPE*)MEMALLOC(memtype, len);
out->len = len;
out->size = nnode;
out = (QUERYTYPE *) MEMALLOC(memtype, len);
out->len = len;
out->size = nnode;
state.curitem = GETQUERY( out );
state.operand = state.curoperand = GETOPERAND( out );
state.curitem = GETQUERY(out);
state.operand = state.curoperand = GETOPERAND(out);
fillQT( &state, in );
return out;
fillQT(&state, in);
return out;
}
QTNode *
QTNCopy( QTNode* in, MemoryType memtype ) {
QTNode *out = (QTNode*)MEMALLOC( memtype, sizeof(QTNode) );
QTNCopy(QTNode * in, MemoryType memtype)
{
QTNode *out = (QTNode *) MEMALLOC(memtype, sizeof(QTNode));
*out = *in;
out->valnode = (ITEM*)MEMALLOC( memtype, sizeof(ITEM) );
out->valnode = (ITEM *) MEMALLOC(memtype, sizeof(ITEM));
*(out->valnode) = *(in->valnode);
out->flags |= QTN_NEEDFREE;
if ( in->valnode->type == VAL ) {
out->word = MEMALLOC( memtype, in->valnode->length + 1 );
memcpy( out->word, in->word, in->valnode->length );
out->word[ in->valnode->length ] = '\0';
if (in->valnode->type == VAL)
{
out->word = MEMALLOC(memtype, in->valnode->length + 1);
memcpy(out->word, in->word, in->valnode->length);
out->word[in->valnode->length] = '\0';
out->flags |= QTN_WORDFREE;
} else {
int i;
}
else
{
int i;
out->child = (QTNode**)MEMALLOC( memtype, sizeof(QTNode*) * in->nchild );
out->child = (QTNode **) MEMALLOC(memtype, sizeof(QTNode *) * in->nchild);
for(i=0;i<in->nchild;i++)
out->child[i] = QTNCopy( in->child[i], memtype );
}
for (i = 0; i < in->nchild; i++)
out->child[i] = QTNCopy(in->child[i], memtype);
}
return out;
}

View File

@ -6,39 +6,41 @@
#include "query.h"
typedef struct QTNode {
ITEM *valnode;
uint32 flags;
int4 nchild;
char *word;
uint32 sign;
struct QTNode **child;
} QTNode;
typedef struct QTNode
{
ITEM *valnode;
uint32 flags;
int4 nchild;
char *word;
uint32 sign;
struct QTNode **child;
} QTNode;
#define QTN_NEEDFREE 0x01
#define QTN_NOCHANGE 0x02
#define QTN_WORDFREE 0x04
#define QTN_NEEDFREE 0x01
#define QTN_NOCHANGE 0x02
#define QTN_WORDFREE 0x04
typedef enum {
typedef enum
{
PlainMemory,
SPIMemory,
AggMemory
} MemoryType;
} MemoryType;
QTNode* QT2QTN( ITEM *in, char *operand );
QUERYTYPE* QTN2QT( QTNode* in, MemoryType memtype );
void QTNFree( QTNode* in );
void QTNSort( QTNode* in );
void QTNTernary( QTNode* in );
void QTNBinary( QTNode* in );
int QTNodeCompare( QTNode *an, QTNode *bn );
QTNode* QTNCopy( QTNode* in, MemoryType memtype);
bool QTNEq( QTNode* a, QTNode* b );
QTNode *QT2QTN(ITEM * in, char *operand);
QUERYTYPE *QTN2QT(QTNode * in, MemoryType memtype);
void QTNFree(QTNode * in);
void QTNSort(QTNode * in);
void QTNTernary(QTNode * in);
void QTNBinary(QTNode * in);
int QTNodeCompare(QTNode * an, QTNode * bn);
QTNode *QTNCopy(QTNode * in, MemoryType memtype);
bool QTNEq(QTNode * a, QTNode * b);
extern MemoryContext AggregateContext;
extern MemoryContext AggregateContext;
#define MEMALLOC(us, s) ( ((us)==SPIMemory) ? SPI_palloc(s) : ( ( (us)==PlainMemory ) ? palloc(s) : MemoryContextAlloc(AggregateContext, (s)) ) )
#define MEMFREE(us, p) ( ((us)==SPIMemory) ? SPI_pfree(p) : pfree(p) )
#define MEMALLOC(us, s) ( ((us)==SPIMemory) ? SPI_palloc(s) : ( ( (us)==PlainMemory ) ? palloc(s) : MemoryContextAlloc(AggregateContext, (s)) ) )
#define MEMFREE(us, p) ( ((us)==SPIMemory) ? SPI_pfree(p) : pfree(p) )
#endif

View File

@ -266,8 +266,10 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
for (i = 0; i < size; i++)
{
float resj,wjm;
int4 jm;
float resj,
wjm;
int4 jm;
entry = find_wordentry(t, q, item[i]);
if (!entry)
continue;
@ -283,28 +285,29 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
post = POSNULL + 1;
}
resj = 0.0;
wjm = -1.0;
jm = 0;
for (j = 0; j < dimt; j++)
{
resj = resj + wpos(post[j])/((j+1)*(j+1));
if ( wpos(post[j]) > wjm ) {
wjm = wpos(post[j]);
jm = j;
}
}
/*
limit (sum(i/i^2),i->inf) = pi^2/6
resj = sum(wi/i^2),i=1,noccurence,
wi - should be sorted desc,
don't sort for now, just choose maximum weight. This should be corrected
resj = 0.0;
wjm = -1.0;
jm = 0;
for (j = 0; j < dimt; j++)
{
resj = resj + wpos(post[j]) / ((j + 1) * (j + 1));
if (wpos(post[j]) > wjm)
{
wjm = wpos(post[j]);
jm = j;
}
}
/*
limit (sum(i/i^2),i->inf) = pi^2/6
resj = sum(wi/i^2),i=1,noccurence,
wi - should be sorted desc,
don't sort for now, just choose maximum weight. This should be corrected
Oleg Bartunov
*/
res = res + ( wjm + resj - wjm/((jm+1)*(jm+1)))/1.64493406685;
res = res + (wjm + resj - wjm / ((jm + 1) * (jm + 1))) / 1.64493406685;
}
if ( size > 0 )
res = res /size;
if (size > 0)
res = res / size;
pfree(item);
return res;
}
@ -414,7 +417,7 @@ rank_def(PG_FUNCTION_ARGS)
typedef struct
{
ITEM **item;
ITEM **item;
int16 nitem;
bool needfree;
int32 pos;
@ -429,53 +432,59 @@ compareDocR(const void *a, const void *b)
}
static bool
checkcondition_ITEM(void *checkval, ITEM * val) {
return (bool)(val->istrue);
checkcondition_ITEM(void *checkval, ITEM * val)
{
return (bool) (val->istrue);
}
static void
reset_istrue_flag(QUERYTYPE *query) {
ITEM *item = GETQUERY(query);
int i;
reset_istrue_flag(QUERYTYPE * query)
{
ITEM *item = GETQUERY(query);
int i;
/* reset istrue flag */
for(i = 0; i < query->size; i++) {
if ( item->type == VAL )
for (i = 0; i < query->size; i++)
{
if (item->type == VAL)
item->istrue = 0;
item++;
}
}
static bool
Cover(DocRepresentation * doc, int len, QUERYTYPE * query, int *pos, int *p, int *q)
{
DocRepresentation *ptr;
int lastpos = *pos;
int i;
bool found=false;
int i;
bool found = false;
reset_istrue_flag(query);
*p = 0x7fffffff;
*q = 0;
ptr = doc + *pos;
/* find upper bound of cover from current position, move up */
while (ptr - doc < len) {
for(i=0;i<ptr->nitem;i++)
while (ptr - doc < len)
{
for (i = 0; i < ptr->nitem; i++)
ptr->item[i]->istrue = 1;
if ( TS_execute(GETQUERY(query), NULL, false, checkcondition_ITEM) ) {
if (ptr->pos > *q) {
if (TS_execute(GETQUERY(query), NULL, false, checkcondition_ITEM))
{
if (ptr->pos > *q)
{
*q = ptr->pos;
lastpos = ptr - doc;
found = true;
}
}
break;
}
ptr++;
}
if (!found)
if (!found)
return false;
reset_istrue_flag(query);
@ -483,25 +492,31 @@ Cover(DocRepresentation * doc, int len, QUERYTYPE * query, int *pos, int *p, int
ptr = doc + lastpos;
/* find lower bound of cover from founded upper bound, move down */
while (ptr >= doc ) {
for(i=0;i<ptr->nitem;i++)
while (ptr >= doc)
{
for (i = 0; i < ptr->nitem; i++)
ptr->item[i]->istrue = 1;
if ( TS_execute(GETQUERY(query), NULL, true, checkcondition_ITEM) ) {
if (ptr->pos < *p)
if (TS_execute(GETQUERY(query), NULL, true, checkcondition_ITEM))
{
if (ptr->pos < *p)
*p = ptr->pos;
break;
}
ptr--;
}
if ( *p <= *q ) {
/* set position for next try to next lexeme after begining of founded cover */
*pos= (ptr-doc) + 1;
if (*p <= *q)
{
/*
* set position for next try to next lexeme after begining of founded
* cover
*/
*pos = (ptr - doc) + 1;
return true;
}
(*pos)++;
return Cover( doc, len, query, pos, p, q );
return Cover(doc, len, query, pos, p, q);
}
static DocRepresentation *
@ -550,26 +565,32 @@ get_docrep(tsvector * txt, QUERYTYPE * query, int *doclen)
for (j = 0; j < dimt; j++)
{
if ( j == 0 ) {
ITEM *kptr, *iptr = item+i;
int k;
if (j == 0)
{
ITEM *kptr,
*iptr = item + i;
int k;
doc[cur].needfree = false;
doc[cur].nitem = 0;
doc[cur].item = (ITEM**)palloc( sizeof(ITEM*) * query->size );
doc[cur].item = (ITEM **) palloc(sizeof(ITEM *) * query->size);
for(k=0; k < query->size; k++) {
kptr = item+k;
if ( k==i || ( item[k].type == VAL && compareITEM( &kptr, &iptr ) == 0 ) ) {
doc[cur].item[ doc[cur].nitem ] = item+k;
for (k = 0; k < query->size; k++)
{
kptr = item + k;
if (k == i || (item[k].type == VAL && compareITEM(&kptr, &iptr) == 0))
{
doc[cur].item[doc[cur].nitem] = item + k;
doc[cur].nitem++;
kptr->istrue = 1;
}
}
} else {
}
}
else
{
doc[cur].needfree = false;
doc[cur].nitem = doc[cur-1].nitem;
doc[cur].item = doc[cur-1].item;
doc[cur].nitem = doc[cur - 1].nitem;
doc[cur].item = doc[cur - 1].item;
}
doc[cur].pos = WEP_GETPOS(post[j]);
cur++;
@ -604,7 +625,7 @@ rank_cd(PG_FUNCTION_ARGS)
len,
cur,
i,
doclen=0;
doclen = 0;
doc = get_docrep(txt, query, &doclen);
if (!doc)
@ -640,9 +661,9 @@ rank_cd(PG_FUNCTION_ARGS)
elog(ERROR, "unrecognized normalization method: %d", method);
}
for(i=0;i<doclen;i++)
if ( doc[i].needfree )
pfree( doc[i].item );
for (i = 0; i < doclen; i++)
if (doc[i].needfree)
pfree(doc[i].item);
pfree(doc);
PG_FREE_IF_COPY(txt, 1);
PG_FREE_IF_COPY(query, 2);
@ -784,9 +805,9 @@ get_covers(PG_FUNCTION_ARGS)
VARATT_SIZEP(out) = cptr - ((char *) out);
pfree(dw);
for(i=0;i<rlen;i++)
if ( doc[i].needfree )
pfree( doc[i].item );
for (i = 0; i < rlen; i++)
if (doc[i].needfree)
pfree(doc[i].item);
pfree(doc);
PG_FREE_IF_COPY(txt, 0);

View File

@ -23,7 +23,7 @@ struct SN_env
int S_size;
int I_size;
int B_size;
symbol **S;
symbol **S;
int *I;
symbol *B;
};

View File

@ -28,8 +28,8 @@ static symbol s_0_1[5] = {'g', 'e', 'n', 'e', 'r'};
static struct among a_0[2] =
{
/* 0 */ {6, s_0_0, -1, -1, 0},
/* 1 */ {5, s_0_1, -1, -1, 0}
/* 0 */ {6, s_0_0, -1, -1, 0},
/* 1 */ {5, s_0_1, -1, -1, 0}
};
static symbol s_1_0[1] = {'\''};
@ -38,9 +38,9 @@ static symbol s_1_2[2] = {'\'', 's'};
static struct among a_1[3] =
{
/* 0 */ {1, s_1_0, -1, 1, 0},
/* 1 */ {3, s_1_1, 0, 1, 0},
/* 2 */ {2, s_1_2, -1, 1, 0}
/* 0 */ {1, s_1_0, -1, 1, 0},
/* 1 */ {3, s_1_1, 0, 1, 0},
/* 2 */ {2, s_1_2, -1, 1, 0}
};
static symbol s_2_0[3] = {'i', 'e', 'd'};
@ -52,12 +52,12 @@ static symbol s_2_5[2] = {'u', 's'};
static struct among a_2[6] =
{
/* 0 */ {3, s_2_0, -1, 2, 0},
/* 1 */ {1, s_2_1, -1, 3, 0},
/* 2 */ {3, s_2_2, 1, 2, 0},
/* 3 */ {4, s_2_3, 1, 1, 0},
/* 4 */ {2, s_2_4, 1, -1, 0},
/* 5 */ {2, s_2_5, 1, -1, 0}
/* 0 */ {3, s_2_0, -1, 2, 0},
/* 1 */ {1, s_2_1, -1, 3, 0},
/* 2 */ {3, s_2_2, 1, 2, 0},
/* 3 */ {4, s_2_3, 1, 1, 0},
/* 4 */ {2, s_2_4, 1, -1, 0},
/* 5 */ {2, s_2_5, 1, -1, 0}
};
static symbol s_3_1[2] = {'b', 'b'};
@ -75,16 +75,16 @@ static symbol s_3_12[2] = {'i', 'z'};
static struct among a_3[13] =
{
/* 0 */ {0, 0, -1, 3, 0},
/* 1 */ {2, s_3_1, 0, 2, 0},
/* 2 */ {2, s_3_2, 0, 2, 0},
/* 3 */ {2, s_3_3, 0, 2, 0},
/* 4 */ {2, s_3_4, 0, 2, 0},
/* 5 */ {2, s_3_5, 0, 1, 0},
/* 6 */ {2, s_3_6, 0, 2, 0},
/* 7 */ {2, s_3_7, 0, 2, 0},
/* 8 */ {2, s_3_8, 0, 2, 0},
/* 9 */ {2, s_3_9, 0, 2, 0},
/* 0 */ {0, 0, -1, 3, 0},
/* 1 */ {2, s_3_1, 0, 2, 0},
/* 2 */ {2, s_3_2, 0, 2, 0},
/* 3 */ {2, s_3_3, 0, 2, 0},
/* 4 */ {2, s_3_4, 0, 2, 0},
/* 5 */ {2, s_3_5, 0, 1, 0},
/* 6 */ {2, s_3_6, 0, 2, 0},
/* 7 */ {2, s_3_7, 0, 2, 0},
/* 8 */ {2, s_3_8, 0, 2, 0},
/* 9 */ {2, s_3_9, 0, 2, 0},
/* 10 */ {2, s_3_10, 0, 1, 0},
/* 11 */ {2, s_3_11, 0, 2, 0},
/* 12 */ {2, s_3_12, 0, 1, 0}
@ -99,12 +99,12 @@ static symbol s_4_5[5] = {'i', 'n', 'g', 'l', 'y'};
static struct among a_4[6] =
{
/* 0 */ {2, s_4_0, -1, 2, 0},
/* 1 */ {3, s_4_1, 0, 1, 0},
/* 2 */ {3, s_4_2, -1, 2, 0},
/* 3 */ {4, s_4_3, -1, 2, 0},
/* 4 */ {5, s_4_4, 3, 1, 0},
/* 5 */ {5, s_4_5, -1, 2, 0}
/* 0 */ {2, s_4_0, -1, 2, 0},
/* 1 */ {3, s_4_1, 0, 1, 0},
/* 2 */ {3, s_4_2, -1, 2, 0},
/* 3 */ {4, s_4_3, -1, 2, 0},
/* 4 */ {5, s_4_4, 3, 1, 0},
/* 5 */ {5, s_4_5, -1, 2, 0}
};
static symbol s_5_0[4] = {'a', 'n', 'c', 'i'};
@ -134,16 +134,16 @@ static symbol s_5_23[7] = {'o', 'u', 's', 'n', 'e', 's', 's'};
static struct among a_5[24] =
{
/* 0 */ {4, s_5_0, -1, 3, 0},
/* 1 */ {4, s_5_1, -1, 2, 0},
/* 2 */ {3, s_5_2, -1, 13, 0},
/* 3 */ {2, s_5_3, -1, 16, 0},
/* 4 */ {3, s_5_4, 3, 12, 0},
/* 5 */ {4, s_5_5, 4, 4, 0},
/* 6 */ {4, s_5_6, 3, 8, 0},
/* 7 */ {5, s_5_7, 3, 14, 0},
/* 8 */ {6, s_5_8, 3, 15, 0},
/* 9 */ {5, s_5_9, 3, 10, 0},
/* 0 */ {4, s_5_0, -1, 3, 0},
/* 1 */ {4, s_5_1, -1, 2, 0},
/* 2 */ {3, s_5_2, -1, 13, 0},
/* 3 */ {2, s_5_3, -1, 16, 0},
/* 4 */ {3, s_5_4, 3, 12, 0},
/* 5 */ {4, s_5_5, 4, 4, 0},
/* 6 */ {4, s_5_6, 3, 8, 0},
/* 7 */ {5, s_5_7, 3, 14, 0},
/* 8 */ {6, s_5_8, 3, 15, 0},
/* 9 */ {5, s_5_9, 3, 10, 0},
/* 10 */ {5, s_5_10, 3, 5, 0},
/* 11 */ {5, s_5_11, -1, 8, 0},
/* 12 */ {6, s_5_12, -1, 12, 0},
@ -172,15 +172,15 @@ static symbol s_6_8[4] = {'n', 'e', 's', 's'};
static struct among a_6[9] =
{
/* 0 */ {5, s_6_0, -1, 4, 0},
/* 1 */ {5, s_6_1, -1, 6, 0},
/* 2 */ {5, s_6_2, -1, 3, 0},
/* 3 */ {5, s_6_3, -1, 4, 0},
/* 4 */ {4, s_6_4, -1, 4, 0},
/* 5 */ {6, s_6_5, -1, 1, 0},
/* 6 */ {7, s_6_6, 5, 2, 0},
/* 7 */ {3, s_6_7, -1, 5, 0},
/* 8 */ {4, s_6_8, -1, 5, 0}
/* 0 */ {5, s_6_0, -1, 4, 0},
/* 1 */ {5, s_6_1, -1, 6, 0},
/* 2 */ {5, s_6_2, -1, 3, 0},
/* 3 */ {5, s_6_3, -1, 4, 0},
/* 4 */ {4, s_6_4, -1, 4, 0},
/* 5 */ {6, s_6_5, -1, 1, 0},
/* 6 */ {7, s_6_6, 5, 2, 0},
/* 7 */ {3, s_6_7, -1, 5, 0},
/* 8 */ {4, s_6_8, -1, 5, 0}
};
static symbol s_7_0[2] = {'i', 'c'};
@ -204,16 +204,16 @@ static symbol s_7_17[5] = {'e', 'm', 'e', 'n', 't'};
static struct among a_7[18] =
{
/* 0 */ {2, s_7_0, -1, 1, 0},
/* 1 */ {4, s_7_1, -1, 1, 0},
/* 2 */ {4, s_7_2, -1, 1, 0},
/* 3 */ {4, s_7_3, -1, 1, 0},
/* 4 */ {4, s_7_4, -1, 1, 0},
/* 5 */ {3, s_7_5, -1, 1, 0},
/* 6 */ {3, s_7_6, -1, 1, 0},
/* 7 */ {3, s_7_7, -1, 1, 0},
/* 8 */ {3, s_7_8, -1, 1, 0},
/* 9 */ {2, s_7_9, -1, 1, 0},
/* 0 */ {2, s_7_0, -1, 1, 0},
/* 1 */ {4, s_7_1, -1, 1, 0},
/* 2 */ {4, s_7_2, -1, 1, 0},
/* 3 */ {4, s_7_3, -1, 1, 0},
/* 4 */ {4, s_7_4, -1, 1, 0},
/* 5 */ {3, s_7_5, -1, 1, 0},
/* 6 */ {3, s_7_6, -1, 1, 0},
/* 7 */ {3, s_7_7, -1, 1, 0},
/* 8 */ {3, s_7_8, -1, 1, 0},
/* 9 */ {2, s_7_9, -1, 1, 0},
/* 10 */ {3, s_7_10, -1, 1, 0},
/* 11 */ {3, s_7_11, -1, 2, 0},
/* 12 */ {2, s_7_12, -1, 1, 0},
@ -229,8 +229,8 @@ static symbol s_8_1[1] = {'l'};
static struct among a_8[2] =
{
/* 0 */ {1, s_8_0, -1, 1, 0},
/* 1 */ {1, s_8_1, -1, 2, 0}
/* 0 */ {1, s_8_0, -1, 1, 0},
/* 1 */ {1, s_8_1, -1, 2, 0}
};
static symbol s_9_0[7] = {'s', 'u', 'c', 'c', 'e', 'e', 'd'};
@ -244,14 +244,14 @@ static symbol s_9_7[6] = {'o', 'u', 't', 'i', 'n', 'g'};
static struct among a_9[8] =
{
/* 0 */ {7, s_9_0, -1, -1, 0},
/* 1 */ {7, s_9_1, -1, -1, 0},
/* 2 */ {6, s_9_2, -1, -1, 0},
/* 3 */ {7, s_9_3, -1, -1, 0},
/* 4 */ {6, s_9_4, -1, -1, 0},
/* 5 */ {7, s_9_5, -1, -1, 0},
/* 6 */ {7, s_9_6, -1, -1, 0},
/* 7 */ {6, s_9_7, -1, -1, 0}
/* 0 */ {7, s_9_0, -1, -1, 0},
/* 1 */ {7, s_9_1, -1, -1, 0},
/* 2 */ {6, s_9_2, -1, -1, 0},
/* 3 */ {7, s_9_3, -1, -1, 0},
/* 4 */ {6, s_9_4, -1, -1, 0},
/* 5 */ {7, s_9_5, -1, -1, 0},
/* 6 */ {7, s_9_6, -1, -1, 0},
/* 7 */ {6, s_9_7, -1, -1, 0}
};
static symbol s_10_0[5] = {'a', 'n', 'd', 'e', 's'};
@ -275,16 +275,16 @@ static symbol s_10_17[4] = {'u', 'g', 'l', 'y'};
static struct among a_10[18] =
{
/* 0 */ {5, s_10_0, -1, -1, 0},
/* 1 */ {5, s_10_1, -1, -1, 0},
/* 2 */ {4, s_10_2, -1, -1, 0},
/* 3 */ {6, s_10_3, -1, -1, 0},
/* 4 */ {5, s_10_4, -1, 3, 0},
/* 5 */ {5, s_10_5, -1, 9, 0},
/* 6 */ {6, s_10_6, -1, 7, 0},
/* 7 */ {4, s_10_7, -1, -1, 0},
/* 8 */ {4, s_10_8, -1, 6, 0},
/* 9 */ {5, s_10_9, -1, 4, 0},
/* 0 */ {5, s_10_0, -1, -1, 0},
/* 1 */ {5, s_10_1, -1, -1, 0},
/* 2 */ {4, s_10_2, -1, -1, 0},
/* 3 */ {6, s_10_3, -1, -1, 0},
/* 4 */ {5, s_10_4, -1, 3, 0},
/* 5 */ {5, s_10_5, -1, 9, 0},
/* 6 */ {6, s_10_6, -1, 7, 0},
/* 7 */ {4, s_10_7, -1, -1, 0},
/* 8 */ {4, s_10_8, -1, 6, 0},
/* 9 */ {5, s_10_9, -1, 4, 0},
/* 10 */ {4, s_10_10, -1, -1, 0},
/* 11 */ {4, s_10_11, -1, 10, 0},
/* 12 */ {6, s_10_12, -1, 11, 0},
@ -1609,12 +1609,14 @@ lab0:
return 1;
}
extern struct SN_env *english_ISO_8859_1_create_env(void)
extern struct SN_env *
english_ISO_8859_1_create_env(void)
{
return SN_create_env(0, 2, 1);
}
extern void english_ISO_8859_1_close_env(struct SN_env * z)
extern void
english_ISO_8859_1_close_env(struct SN_env * z)
{
SN_close_env(z);
}

View File

@ -6,10 +6,10 @@ extern "C"
{
#endif
extern struct SN_env *english_ISO_8859_1_create_env(void);
extern void english_ISO_8859_1_close_env(struct SN_env * z);
extern struct SN_env *english_ISO_8859_1_create_env(void);
extern void english_ISO_8859_1_close_env(struct SN_env * z);
extern int english_ISO_8859_1_stem(struct SN_env * z);
extern int english_ISO_8859_1_stem(struct SN_env * z);
#ifdef __cplusplus
}

View File

@ -30,15 +30,15 @@ static symbol s_0_8[6] = {0xD9, 0xD7, 0xDB, 0xC9, 0xD3, 0xD8};
static struct among a_0[9] =
{
/* 0 */ {3, s_0_0, -1, 1, 0},
/* 1 */ {4, s_0_1, 0, 2, 0},
/* 2 */ {4, s_0_2, 0, 2, 0},
/* 3 */ {1, s_0_3, -1, 1, 0},
/* 4 */ {2, s_0_4, 3, 2, 0},
/* 5 */ {2, s_0_5, 3, 2, 0},
/* 6 */ {5, s_0_6, -1, 1, 0},
/* 7 */ {6, s_0_7, 6, 2, 0},
/* 8 */ {6, s_0_8, 6, 2, 0}
/* 0 */ {3, s_0_0, -1, 1, 0},
/* 1 */ {4, s_0_1, 0, 2, 0},
/* 2 */ {4, s_0_2, 0, 2, 0},
/* 3 */ {1, s_0_3, -1, 1, 0},
/* 4 */ {2, s_0_4, 3, 2, 0},
/* 5 */ {2, s_0_5, 3, 2, 0},
/* 6 */ {5, s_0_6, -1, 1, 0},
/* 7 */ {6, s_0_7, 6, 2, 0},
/* 8 */ {6, s_0_8, 6, 2, 0}
};
static symbol s_1_0[2] = {0xC0, 0xC0};
@ -70,16 +70,16 @@ static symbol s_1_25[3] = {0xCF, 0xCD, 0xD5};
static struct among a_1[26] =
{
/* 0 */ {2, s_1_0, -1, 1, 0},
/* 1 */ {2, s_1_1, -1, 1, 0},
/* 2 */ {2, s_1_2, -1, 1, 0},
/* 3 */ {2, s_1_3, -1, 1, 0},
/* 4 */ {2, s_1_4, -1, 1, 0},
/* 5 */ {2, s_1_5, -1, 1, 0},
/* 6 */ {2, s_1_6, -1, 1, 0},
/* 7 */ {2, s_1_7, -1, 1, 0},
/* 8 */ {2, s_1_8, -1, 1, 0},
/* 9 */ {2, s_1_9, -1, 1, 0},
/* 0 */ {2, s_1_0, -1, 1, 0},
/* 1 */ {2, s_1_1, -1, 1, 0},
/* 2 */ {2, s_1_2, -1, 1, 0},
/* 3 */ {2, s_1_3, -1, 1, 0},
/* 4 */ {2, s_1_4, -1, 1, 0},
/* 5 */ {2, s_1_5, -1, 1, 0},
/* 6 */ {2, s_1_6, -1, 1, 0},
/* 7 */ {2, s_1_7, -1, 1, 0},
/* 8 */ {2, s_1_8, -1, 1, 0},
/* 9 */ {2, s_1_9, -1, 1, 0},
/* 10 */ {3, s_1_10, -1, 1, 0},
/* 11 */ {3, s_1_11, -1, 1, 0},
/* 12 */ {2, s_1_12, -1, 1, 0},
@ -109,14 +109,14 @@ static symbol s_2_7[3] = {0xD5, 0xC0, 0xDD};
static struct among a_2[8] =
{
/* 0 */ {2, s_2_0, -1, 1, 0},
/* 1 */ {2, s_2_1, -1, 1, 0},
/* 2 */ {2, s_2_2, -1, 1, 0},
/* 3 */ {3, s_2_3, 2, 2, 0},
/* 4 */ {3, s_2_4, 2, 2, 0},
/* 5 */ {1, s_2_5, -1, 1, 0},
/* 6 */ {2, s_2_6, 5, 1, 0},
/* 7 */ {3, s_2_7, 6, 2, 0}
/* 0 */ {2, s_2_0, -1, 1, 0},
/* 1 */ {2, s_2_1, -1, 1, 0},
/* 2 */ {2, s_2_2, -1, 1, 0},
/* 3 */ {3, s_2_3, 2, 2, 0},
/* 4 */ {3, s_2_4, 2, 2, 0},
/* 5 */ {1, s_2_5, -1, 1, 0},
/* 6 */ {2, s_2_6, 5, 1, 0},
/* 7 */ {3, s_2_7, 6, 2, 0}
};
static symbol s_3_0[2] = {0xD3, 0xD1};
@ -124,8 +124,8 @@ static symbol s_3_1[2] = {0xD3, 0xD8};
static struct among a_3[2] =
{
/* 0 */ {2, s_3_0, -1, 1, 0},
/* 1 */ {2, s_3_1, -1, 1, 0}
/* 0 */ {2, s_3_0, -1, 1, 0},
/* 1 */ {2, s_3_1, -1, 1, 0}
};
static symbol s_4_0[1] = {0xC0};
@ -177,16 +177,16 @@ static symbol s_4_45[3] = {0xC5, 0xCE, 0xD9};
static struct among a_4[46] =
{
/* 0 */ {1, s_4_0, -1, 2, 0},
/* 1 */ {2, s_4_1, 0, 2, 0},
/* 2 */ {2, s_4_2, -1, 1, 0},
/* 3 */ {3, s_4_3, 2, 2, 0},
/* 4 */ {3, s_4_4, 2, 2, 0},
/* 5 */ {2, s_4_5, -1, 1, 0},
/* 6 */ {3, s_4_6, 5, 2, 0},
/* 7 */ {3, s_4_7, -1, 1, 0},
/* 8 */ {3, s_4_8, -1, 2, 0},
/* 9 */ {3, s_4_9, -1, 1, 0},
/* 0 */ {1, s_4_0, -1, 2, 0},
/* 1 */ {2, s_4_1, 0, 2, 0},
/* 2 */ {2, s_4_2, -1, 1, 0},
/* 3 */ {3, s_4_3, 2, 2, 0},
/* 4 */ {3, s_4_4, 2, 2, 0},
/* 5 */ {2, s_4_5, -1, 1, 0},
/* 6 */ {3, s_4_6, 5, 2, 0},
/* 7 */ {3, s_4_7, -1, 1, 0},
/* 8 */ {3, s_4_8, -1, 2, 0},
/* 9 */ {3, s_4_9, -1, 1, 0},
/* 10 */ {4, s_4_10, 9, 2, 0},
/* 11 */ {4, s_4_11, 9, 2, 0},
/* 12 */ {2, s_4_12, -1, 1, 0},
@ -264,16 +264,16 @@ static symbol s_5_35[1] = {0xD9};
static struct among a_5[36] =
{
/* 0 */ {1, s_5_0, -1, 1, 0},
/* 1 */ {2, s_5_1, 0, 1, 0},
/* 2 */ {2, s_5_2, 0, 1, 0},
/* 3 */ {1, s_5_3, -1, 1, 0},
/* 4 */ {1, s_5_4, -1, 1, 0},
/* 5 */ {2, s_5_5, 4, 1, 0},
/* 6 */ {2, s_5_6, 4, 1, 0},
/* 7 */ {2, s_5_7, -1, 1, 0},
/* 8 */ {2, s_5_8, -1, 1, 0},
/* 9 */ {3, s_5_9, 8, 1, 0},
/* 0 */ {1, s_5_0, -1, 1, 0},
/* 1 */ {2, s_5_1, 0, 1, 0},
/* 2 */ {2, s_5_2, 0, 1, 0},
/* 3 */ {1, s_5_3, -1, 1, 0},
/* 4 */ {1, s_5_4, -1, 1, 0},
/* 5 */ {2, s_5_5, 4, 1, 0},
/* 6 */ {2, s_5_6, 4, 1, 0},
/* 7 */ {2, s_5_7, -1, 1, 0},
/* 8 */ {2, s_5_8, -1, 1, 0},
/* 9 */ {3, s_5_9, 8, 1, 0},
/* 10 */ {1, s_5_10, -1, 1, 0},
/* 11 */ {2, s_5_11, 10, 1, 0},
/* 12 */ {2, s_5_12, 10, 1, 0},
@ -307,8 +307,8 @@ static symbol s_6_1[4] = {0xCF, 0xD3, 0xD4, 0xD8};
static struct among a_6[2] =
{
/* 0 */ {3, s_6_0, -1, 1, 0},
/* 1 */ {4, s_6_1, -1, 1, 0}
/* 0 */ {3, s_6_0, -1, 1, 0},
/* 1 */ {4, s_6_1, -1, 1, 0}
};
static symbol s_7_0[4] = {0xC5, 0xCA, 0xDB, 0xC5};
@ -318,10 +318,10 @@ static symbol s_7_3[3] = {0xC5, 0xCA, 0xDB};
static struct among a_7[4] =
{
/* 0 */ {4, s_7_0, -1, 1, 0},
/* 1 */ {1, s_7_1, -1, 2, 0},
/* 2 */ {1, s_7_2, -1, 3, 0},
/* 3 */ {3, s_7_3, -1, 1, 0}
/* 0 */ {4, s_7_0, -1, 1, 0},
/* 1 */ {1, s_7_1, -1, 2, 0},
/* 2 */ {1, s_7_2, -1, 3, 0},
/* 3 */ {3, s_7_3, -1, 1, 0}
};
static unsigned char g_v[] = {35, 130, 34, 18};
@ -915,12 +915,14 @@ lab0:
return 1;
}
extern struct SN_env *russian_KOI8_R_create_env(void)
extern struct SN_env *
russian_KOI8_R_create_env(void)
{
return SN_create_env(0, 2, 0);
}
extern void russian_KOI8_R_close_env(struct SN_env * z)
extern void
russian_KOI8_R_close_env(struct SN_env * z)
{
SN_close_env(z);
}

View File

@ -6,10 +6,10 @@ extern "C"
{
#endif
extern struct SN_env *russian_KOI8_R_create_env(void);
extern void russian_KOI8_R_close_env(struct SN_env * z);
extern struct SN_env *russian_KOI8_R_create_env(void);
extern void russian_KOI8_R_close_env(struct SN_env * z);
extern int russian_KOI8_R_stem(struct SN_env * z);
extern int russian_KOI8_R_stem(struct SN_env * z);
#ifdef __cplusplus
}

View File

@ -8,58 +8,64 @@
#if defined(TS_USE_WIDE) && defined(WIN32)
size_t
wchar2char( char *to, const wchar_t *from, size_t len ) {
if (GetDatabaseEncoding() == PG_UTF8) {
int r, nbytes;
wchar2char(char *to, const wchar_t *from, size_t len)
{
if (GetDatabaseEncoding() == PG_UTF8)
{
int r,
nbytes;
if (len==0)
if (len == 0)
return 0;
/* in any case, *to should be allocated with enough space */
nbytes = WideCharToMultiByte(CP_UTF8, 0, from, len, NULL, 0, NULL, NULL);
if ( nbytes==0 )
if (nbytes == 0)
ereport(ERROR,
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
errmsg("UTF-16 to UTF-8 translation failed: %lu",
GetLastError())));
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
errmsg("UTF-16 to UTF-8 translation failed: %lu",
GetLastError())));
r = WideCharToMultiByte(CP_UTF8, 0, from, len, to, nbytes,
NULL, NULL);
NULL, NULL);
if ( r==0 )
if (r == 0)
ereport(ERROR,
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
errmsg("UTF-16 to UTF-8 translation failed: %lu",
GetLastError())));
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
errmsg("UTF-16 to UTF-8 translation failed: %lu",
GetLastError())));
return r;
}
return wcstombs(to, from, len);
}
size_t
char2wchar( wchar_t *to, const char *from, size_t len ) {
if (GetDatabaseEncoding() == PG_UTF8) {
int r;
size_t
char2wchar(wchar_t *to, const char *from, size_t len)
{
if (GetDatabaseEncoding() == PG_UTF8)
{
int r;
if (len==0)
if (len == 0)
return 0;
r = MultiByteToWideChar(CP_UTF8, 0, from, len, to, len);
if (!r) {
if (!r)
{
pg_verifymbstr(from, len, false);
ereport(ERROR,
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
errmsg("invalid multibyte character for locale"),
errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
errmsg("invalid multibyte character for locale"),
errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
}
Assert( r <= len );
Assert(r <= len);
return r;
}
return mbstowcs(to, from, len);
}

View File

@ -22,17 +22,15 @@
#ifdef WIN32
size_t wchar2char( char *to, const wchar_t *from, size_t len );
size_t char2wchar( wchar_t *to, const char *from, size_t len );
#else /* WIN32 */
size_t wchar2char(char *to, const wchar_t *from, size_t len);
size_t char2wchar(wchar_t *to, const char *from, size_t len);
#else /* WIN32 */
/* correct mbstowcs */
#define char2wchar mbstowcs
#define wchar2char wcstombs
#endif /* WIN32 */
#endif /* defined(HAVE_WCSTOMBS) &&
* defined(HAVE_TOWLOWER) */
#endif /* WIN32 */
#endif /* defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER) */
#endif /* __TSLOCALE_H__ */
#endif /* __TSLOCALE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,8 @@
#include <limits.h>
#include "ts_locale.h"
typedef enum {
typedef enum
{
TPS_Base = 0,
TPS_InUWord,
TPS_InLatWord,
@ -78,70 +79,76 @@ typedef enum {
TPS_InHDecimalPart,
TPS_InHVersionPartFirst,
TPS_InHVersionPart,
TPS_Null /* last state (fake value) */
} TParserState;
TPS_Null /* last state (fake value) */
} TParserState;
/* forward declaration */
struct TParser;
typedef int (*TParserCharTest)(struct TParser*); /* any p_is* functions except p_iseq */
typedef void (*TParserSpecial)(struct TParser*); /* special handler for special cases... */
typedef int (*TParserCharTest) (struct TParser *); /* any p_is* functions
* except p_iseq */
typedef void (*TParserSpecial) (struct TParser *); /* special handler for
* special cases... */
typedef struct {
TParserCharTest isclass;
char c;
uint16 flags;
TParserState tostate;
int type;
TParserSpecial special;
} TParserStateActionItem;
typedef struct
{
TParserCharTest isclass;
char c;
uint16 flags;
TParserState tostate;
int type;
TParserSpecial special;
} TParserStateActionItem;
typedef struct {
TParserState state;
TParserStateActionItem *action;
} TParserStateAction;
typedef struct
{
TParserState state;
TParserStateActionItem *action;
} TParserStateAction;
typedef struct TParserPosition {
int posbyte; /* position of parser in bytes */
int poschar; /* osition of parser in characters */
int charlen; /* length of current char */
int lenbytelexeme;
int lencharlexeme;
TParserState state;
struct TParserPosition *prev;
int flags;
TParserStateActionItem *pushedAtAction;
} TParserPosition;
typedef struct TParserPosition
{
int posbyte; /* position of parser in bytes */
int poschar; /* osition of parser in characters */
int charlen; /* length of current char */
int lenbytelexeme;
int lencharlexeme;
TParserState state;
struct TParserPosition *prev;
int flags;
TParserStateActionItem *pushedAtAction;
} TParserPosition;
typedef struct TParser {
typedef struct TParser
{
/* string and position information */
char *str; /* multibyte string */
int lenstr; /* length of mbstring */
wchar_t *wstr; /* wide character string */
int lenwstr; /* length of wsting */
char *str; /* multibyte string */
int lenstr; /* length of mbstring */
wchar_t *wstr; /* wide character string */
int lenwstr; /* length of wsting */
/* State of parse */
int charmaxlen;
int charmaxlen;
bool usewide;
TParserPosition *state;
TParserPosition *state;
bool ignore;
bool wanthost;
/* silly char */
char c;
char c;
/* out */
char *lexeme;
int lenbytelexeme;
int lencharlexeme;
int type;
} TParser;
char *lexeme;
int lenbytelexeme;
int lencharlexeme;
int type;
} TParser;
TParser* TParserInit( char *, int );
bool TParserGet( TParser* );
void TParserClose( TParser* );
TParser *TParserInit(char *, int);
bool TParserGet(TParser *);
void TParserClose(TParser *);
#endif

View File

@ -39,7 +39,7 @@ Datum prsd_start(PG_FUNCTION_ARGS);
Datum
prsd_start(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(TParserInit( (char *) PG_GETARG_POINTER(0), PG_GETARG_INT32(1)));
PG_RETURN_POINTER(TParserInit((char *) PG_GETARG_POINTER(0), PG_GETARG_INT32(1)));
}
PG_FUNCTION_INFO_V1(prsd_getlexeme);
@ -47,14 +47,14 @@ Datum prsd_getlexeme(PG_FUNCTION_ARGS);
Datum
prsd_getlexeme(PG_FUNCTION_ARGS)
{
TParser *p=(TParser*)PG_GETARG_POINTER(0);
TParser *p = (TParser *) PG_GETARG_POINTER(0);
char **t = (char **) PG_GETARG_POINTER(1);
int *tlen = (int *) PG_GETARG_POINTER(2);
if ( !TParserGet(p) )
if (!TParserGet(p))
PG_RETURN_INT32(0);
*t = p->lexeme;
*t = p->lexeme;
*tlen = p->lenbytelexeme;
PG_RETURN_INT32(p->type);
@ -65,8 +65,9 @@ Datum prsd_end(PG_FUNCTION_ARGS);
Datum
prsd_end(PG_FUNCTION_ARGS)
{
TParser *p=(TParser*)PG_GETARG_POINTER(0);
TParserClose(p);
TParser *p = (TParser *) PG_GETARG_POINTER(0);
TParserClose(p);
PG_RETURN_VOID();
}