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:
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -23,7 +23,7 @@ struct SN_env
|
||||
int S_size;
|
||||
int I_size;
|
||||
int B_size;
|
||||
symbol **S;
|
||||
symbol **S;
|
||||
int *I;
|
||||
symbol *B;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user