1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-20 00:42:27 +03:00

pgindent run.

This commit is contained in:
Bruce Momjian 2003-08-04 00:43:34 +00:00
parent 63354a0228
commit 089003fb46
554 changed files with 24888 additions and 21245 deletions

View File

@ -23,4 +23,3 @@ typedef struct rix
extern GIST_SPLITVEC *btree_picksplit(bytea *entryvec, GIST_SPLITVEC *v,
BINARY_UNION bu, CMPFUNC cmp);

View File

@ -131,7 +131,8 @@ cube_out(NDBOX * cube)
* Get the number of digits to display.
*/
ndig = DBL_DIG + extra_float_digits;
if (ndig < 1) ndig = 1;
if (ndig < 1)
ndig = 1;
/*
* while printing the first (LL) corner, check if it is equal to the
@ -1192,7 +1193,8 @@ cube_enlarge(NDBOX * a, double *r, int4 n)
j,
k;
if (n > CUBE_MAX_DIM) n = CUBE_MAX_DIM;
if (n > CUBE_MAX_DIM)
n = CUBE_MAX_DIM;
if (*r > 0 && n > 0)
dim = n;
if (a->dim > dim)
@ -1235,6 +1237,7 @@ cube_f8(double *x1)
{
NDBOX *result;
int size;
size = offsetof(NDBOX, x[0]) + sizeof(double) * 2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
@ -1251,6 +1254,7 @@ cube_f8_f8(double *x1, double *x2)
{
NDBOX *result;
int size;
size = offsetof(NDBOX, x[0]) + sizeof(double) * 2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
@ -1269,12 +1273,14 @@ cube_c_f8(NDBOX *c, double *x1)
NDBOX *result;
int size;
int i;
size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) *2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
result->size = size;
result->dim = c->dim + 1;
for (i = 0; i < c->dim; i++) {
for (i = 0; i < c->dim; i++)
{
result->x[i] = c->x[i];
result->x[result->dim + i] = c->x[c->dim + i];
}
@ -1290,12 +1296,14 @@ cube_c_f8_f8(NDBOX *c, double *x1, double *x2)
NDBOX *result;
int size;
int i;
size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) *2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
result->size = size;
result->dim = c->dim + 1;
for (i = 0; i < c->dim; i++) {
for (i = 0; i < c->dim; i++)
{
result->x[i] = c->x[i];
result->x[result->dim + i] = c->x[c->dim + i];
}

View File

@ -446,14 +446,12 @@ do_inserts(PGconn *conn, char *table, dbhead * dbh)
j = 0; /* counter for fields in the output */
for (h = 0; h < dbh->db_nfields; h++)
{
if (!strlen(fields[h].db_name)) /* When the new fieldname is empty, the field is skipped */
{
if (!strlen(fields[h].db_name)) /* When the new fieldname
* is empty, the field is
* skipped */
continue;
}
else
{
j++;
}
if (j > 1) /* not for the first field! */
strcat(query, "\t"); /* COPY statement field

View File

@ -429,9 +429,7 @@ dblink_fetch(PG_FUNCTION_ARGS)
if (!res ||
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
{
DBLINK_RES_ERROR("sql error");
}
else if (PQresultStatus(res) == PGRES_COMMAND_OK)
{
/* cursor does not exist - closed already or bad name */
@ -591,8 +589,8 @@ dblink_record(PG_FUNCTION_ARGS)
TEXTOID, -1, 0, false);
/*
* and save a copy of the command status string to return
* as our result tuple
* and save a copy of the command status string to return as
* our result tuple
*/
sql_cmd_status = PQcmdStatus(res);
funcctx->max_calls = 1;
@ -741,8 +739,8 @@ dblink_exec(PG_FUNCTION_ARGS)
TEXTOID, -1, 0, false);
/*
* and save a copy of the command status string to return as
* our result tuple
* and save a copy of the command status string to return as our
* result tuple
*/
sql_cmd_status = GET_TEXT(PQcmdStatus(res));
}
@ -802,6 +800,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s\" does not exist",
GET_STR(PG_GETARG_TEXT_P(0)))));
/*
* need a tuple descriptor representing one INT and one TEXT
* column

View File

@ -1,6 +1,6 @@
/****************************************************************************
* pending.c
* $Id: pending.c,v 1.12 2003/07/24 17:52:20 tgl Exp $
* $Id: pending.c,v 1.13 2003/08/04 00:43:10 momjian Exp $
*
* This file contains a trigger for Postgresql-7.x to record changes to tables
* to a pending table for mirroring.
@ -81,6 +81,7 @@ recordchange(PG_FUNCTION_ARGS)
char op = 0;
char *schemaname;
char *fullyqualtblname;
if (fcinfo->context != NULL)
{
@ -166,7 +167,7 @@ storePending(char *cpTableName, HeapTuple tBeforeTuple,
int iResult = 0;
HeapTuple tCurTuple;
//Points the current tuple(before or after)
/* Points the current tuple(before or after) */
Datum saPlanData[4];
Oid taPlanArgTypes[3] = {NAMEOID, CHAROID, INT4OID};
void *vpPlan;

View File

@ -68,7 +68,8 @@ geo_distance(Point *pt1, Point *pt2)
sino = sqrt(sin(fabs(lat1 - lat2) / 2.) * sin(fabs(lat1 - lat2) / 2.) +
cos(lat1) * cos(lat2) * sin(longdiff / 2.) * sin(longdiff / 2.));
if (sino > 1.) sino = 1.;
if (sino > 1.)
sino = 1.;
*resultp = 2. * EARTH_RADIUS * asin(sino);
return resultp;

View File

@ -3,7 +3,7 @@
*
* Copyright 2002 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/contrib/findoidjoins/Attic/findoidjoins.c,v 1.20 2003/05/14 03:25:56 tgl Exp $
* $Header: /cvsroot/pgsql/contrib/findoidjoins/Attic/findoidjoins.c,v 1.21 2003/08/04 00:43:10 momjian Exp $
*/
#include "postgres_fe.h"
@ -24,7 +24,8 @@ main(int argc, char **argv)
char *fk_attname;
char *pk_relname;
char *pk_nspname;
int fk, pk; /* loop counters */
int fk,
pk; /* loop counters */
if (argc != 2)
{
@ -95,8 +96,8 @@ main(int argc, char **argv)
fkrel_res = res;
/*
* For each column and each relation-having-OIDs, look to see if
* the column contains any values matching entries in the relation.
* For each column and each relation-having-OIDs, look to see if the
* column contains any values matching entries in the relation.
*/
for (fk = 0; fk < PQntuples(fkrel_res); fk++)

View File

@ -132,9 +132,9 @@ ShrinkPGArray(PGARRAY * p)
/* use current transaction context */
pnew = palloc(cb);
/*
* Fix up the fields in the new structure, so Postgres
* understands
* Fix up the fields in the new structure, so Postgres understands
*/
memcpy(pnew, p, cb);
pnew->a.size = cb;

View File

@ -173,5 +173,3 @@ int compDESC(const void *a, const void *b);
if (ARRNELEMS(a) > 1) \
qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4), \
(direction) ? compASC : compDESC )

View File

@ -743,4 +743,3 @@ querytree(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(res);
}

View File

@ -85,12 +85,15 @@ g_int_consistent(PG_FUNCTION_ARGS)
}
Datum
g_int_union(PG_FUNCTION_ARGS) {
g_int_union(PG_FUNCTION_ARGS)
{
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
int *size = (int *) PG_GETARG_POINTER(1);
int4 i,len = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
int4 i,
len = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
ArrayType *res;
int totlen=0,*ptr;
int totlen = 0,
*ptr;
for (i = 0; i < len; i++)
totlen += ARRNELEMS(GETENTRY(entryvec, i));
@ -98,7 +101,8 @@ g_int_union(PG_FUNCTION_ARGS) {
res = new_intArrayType(totlen);
ptr = ARRPTR(res);
for (i = 0; i < len; i++) {
for (i = 0; i < len; i++)
{
memcpy(ptr, ARRPTR(GETENTRY(entryvec, i)), ARRNELEMS(GETENTRY(entryvec, i)) * sizeof(int4));
ptr += ARRNELEMS(GETENTRY(entryvec, i));
}
@ -239,7 +243,8 @@ g_int_decompress(PG_FUNCTION_ARGS)
** The GiST Penalty method for _intments
*/
Datum
g_int_penalty(PG_FUNCTION_ARGS) {
g_int_penalty(PG_FUNCTION_ARGS)
{
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
float *result = (float *) PG_GETARG_POINTER(2);
@ -311,7 +316,8 @@ comparecost(const void *a, const void *b)
** We use Guttman's poly time split algorithm
*/
Datum
g_int_picksplit(PG_FUNCTION_ARGS) {
g_int_picksplit(PG_FUNCTION_ARGS)
{
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
OffsetNumber i,
@ -501,4 +507,3 @@ g_int_picksplit(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(v);
}

View File

@ -367,4 +367,3 @@ compDESC(const void *a, const void *b)
return 0;
return (*(int4 *) a < *(int4 *) b) ? 1 : -1;
}

View File

@ -144,8 +144,10 @@ _lt_q_regex(PG_FUNCTION_ARGS)
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("array must be one-dimensional")));
while (num > 0) {
if ( array_iterator(_tree, ltq_regex, (void*)query, NULL) ) {
while (num > 0)
{
if (array_iterator(_tree, ltq_regex, (void *) query, NULL))
{
res = true;
break;
}

View File

@ -123,10 +123,15 @@ printFieldNot(FieldNot *fn ) {
}
*/
static struct {
static struct
{
bool muse;
uint32 high_pos;
} SomeStack = {false,0,};
} SomeStack =
{
false, 0,
};
static bool
checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_numlevel, FieldNot * ptr)
@ -140,7 +145,8 @@ checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_
lquery_level *prevq = NULL;
ltree_level *prevt = NULL;
if ( SomeStack.muse ) {
if (SomeStack.muse)
{
high_pos = SomeStack.high_pos;
qlen--;
prevq = curq;
@ -200,8 +206,10 @@ checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_
curt = LEVEL_NEXT(curt);
tlen--;
cur_tpos++;
if ( isok && prevq && prevq->numvar==0 && tlen>0 && cur_tpos <= high_pos ) {
if (isok && prevq && prevq->numvar == 0 && tlen > 0 && cur_tpos <= high_pos)
{
FieldNot tmpptr;
if (ptr)
memcpy(&tmpptr, ptr, sizeof(FieldNot));
SomeStack.high_pos = high_pos - cur_tpos;
@ -321,9 +329,11 @@ lt_q_regex(PG_FUNCTION_ARGS)
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("array must be one-dimensional")));
while (num > 0) {
while (num > 0)
{
if (DatumGetBool(DirectFunctionCall2(ltq_regex,
PointerGetDatum(tree), PointerGetDatum(query)))) {
PointerGetDatum(tree), PointerGetDatum(query))))
{
res = true;
break;
@ -345,5 +355,3 @@ lt_q_rregex(PG_FUNCTION_ARGS)
PG_GETARG_DATUM(0)
));
}

View File

@ -332,36 +332,45 @@ ltree_index(PG_FUNCTION_ARGS)
ltree *a = PG_GETARG_LTREE(0);
ltree *b = PG_GETARG_LTREE(1);
int start = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
int i,j;
ltree_level *startptr, *aptr, *bptr;
int i,
j;
ltree_level *startptr,
*aptr,
*bptr;
bool found = false;
if ( start < 0 ) {
if (start < 0)
{
if (-start >= a->numlevel)
start = 0;
else
start = (int) (a->numlevel) + start;
}
if ( a->numlevel - start < b->numlevel || a->numlevel==0 || b->numlevel==0 ) {
if (a->numlevel - start < b->numlevel || a->numlevel == 0 || b->numlevel == 0)
{
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_INT32(-1);
}
startptr = LTREE_FIRST(a);
for(i=0; i<=a->numlevel-b->numlevel; i++) {
if ( i>=start ) {
for (i = 0; i <= a->numlevel - b->numlevel; i++)
{
if (i >= start)
{
aptr = startptr;
bptr = LTREE_FIRST(b);
for(j=0;j<b->numlevel;j++) {
for (j = 0; j < b->numlevel; j++)
{
if (!(aptr->len == bptr->len && strncmp(aptr->name, bptr->name, aptr->len) == 0))
break;
aptr = LEVEL_NEXT(aptr);
bptr = LEVEL_NEXT(bptr);
}
if ( j==b->numlevel ) {
if (j == b->numlevel)
{
found = true;
break;
}
@ -524,8 +533,10 @@ ltree2text(PG_FUNCTION_ARGS)
out = (text *) palloc(in->len + VARHDRSZ);
ptr = VARDATA(out);
curlevel = LTREE_FIRST(in);
for (i = 0; i < in->numlevel; i++) {
if (i != 0) {
for (i = 0; i < in->numlevel; i++)
{
if (i != 0)
{
*ptr = '.';
ptr++;
}
@ -539,7 +550,3 @@ ltree2text(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(out);
}

View File

@ -15,16 +15,19 @@ log_entry (const char *logentry)
{
time_t curtime;
struct tm *loctime;
curtime = time(NULL);
loctime = localtime(&curtime);
strftime (timebuffer, TIMEBUFF, "%Y-%m-%d %r", loctime); /* cbb - %F is not always available */
strftime(timebuffer, TIMEBUFF, "%Y-%m-%d %r", loctime); /* cbb - %F is not
* always available */
fprintf(LOGOUTPUT, "[%s] %s\n", timebuffer, logentry);
}
/* Function used to detatch the pg_autovacuum daemon from the tty and go into the background *
* This code is mostly ripped directly from pm_dameonize in postmaster.c *
* with unneeded code removed. */
void daemonize ()
void
daemonize()
{
pid_t pid;
@ -60,7 +63,8 @@ init_table_info (PGresult * res, int row, db_info *dbi)
{
tbl_info *new_tbl = (tbl_info *) malloc(sizeof(tbl_info));
if (!new_tbl) {
if (!new_tbl)
{
log_entry("init_table_info: Cannot get memory");
fflush(LOGOUTPUT);
return NULL;
@ -73,7 +77,8 @@ init_table_info (PGresult * res, int row, db_info *dbi)
new_tbl->schema_name = (char *)
malloc(strlen(PQgetvalue(res, row, PQfnumber(res, "schemaname"))) + 1);
if (!new_tbl->schema_name) {
if (!new_tbl->schema_name)
{
log_entry("init_table_info: malloc failed on new_tbl->schema_name");
fflush(LOGOUTPUT);
return NULL;
@ -84,7 +89,8 @@ init_table_info (PGresult * res, int row, db_info *dbi)
new_tbl->table_name = (char *)
malloc(strlen(PQgetvalue(res, row, PQfnumber(res, "relname"))) +
strlen(new_tbl->schema_name) + 2);
if (!new_tbl->table_name) {
if (!new_tbl->table_name)
{
log_entry("init_table_info: malloc failed on new_tbl->table_name");
fflush(LOGOUTPUT);
return NULL;
@ -112,9 +118,8 @@ init_table_info (PGresult * res, int row, db_info *dbi)
new_tbl->vacuum_threshold =
args->vacuum_base_threshold + args->vacuum_scaling_factor * new_tbl->reltuples;
if (args->debug >= 2) {
if (args->debug >= 2)
print_table_info(new_tbl);
}
return new_tbl;
}
@ -128,20 +133,26 @@ update_table_thresholds (db_info * dbi, tbl_info * tbl,int vacuum_type)
int disconnect = 0;
char query[128];
if (NULL == dbi->conn) {
if (NULL == dbi->conn)
{
dbi->conn = db_connect(dbi);
disconnect = 1;
}
if (NULL != dbi->conn) {
if (NULL != dbi->conn)
{
snprintf(query, sizeof(query), PAGES_QUERY, tbl->relfilenode);
res = send_query(query, dbi);
if (NULL != res) {
if (NULL != res)
{
tbl->reltuples =
atoi(PQgetvalue(res, 0, PQfnumber(res, "reltuples")));
tbl->relpages = atoi(PQgetvalue(res, 0, PQfnumber(res, "relpages")));
/* update vacuum thresholds only of we just did a vacuum analyze */
/*
* update vacuum thresholds only of we just did a vacuum
* analyze
*/
if (VACUUM_ANALYZE == vacuum_type)
{
tbl->vacuum_threshold =
@ -156,8 +167,11 @@ update_table_thresholds (db_info * dbi, tbl_info * tbl,int vacuum_type)
PQclear(res);
/* If the stats collector is reporting fewer updates then we have on record
then the stats were probably reset, so we need to reset also */
/*
* If the stats collector is reporting fewer updates then we
* have on record then the stats were probably reset, so we
* need to reset also
*/
if ((tbl->curr_analyze_count < tbl->CountAtLastAnalyze) ||
(tbl->curr_vacuum_count < tbl->CountAtLastVacuum))
{
@ -177,46 +191,62 @@ update_table_list (db_info * dbi)
PGresult *res = NULL;
tbl_info *tbl = NULL;
Dlelem *tbl_elem = DLGetHead(dbi->table_list);
int i = 0, t = 0, found_match = 0;
int i = 0,
t = 0,
found_match = 0;
if (NULL == dbi->conn) {
if (NULL == dbi->conn)
{
dbi->conn = db_connect(dbi);
disconnect = 1;
}
if (NULL != dbi->conn) {
/* Get a result set that has all the information
we will need to both remove tables from the list
that no longer exist and add tables to the list
that are new */
if (NULL != dbi->conn)
{
/*
* Get a result set that has all the information we will need to
* both remove tables from the list that no longer exist and add
* tables to the list that are new
*/
res = send_query(query_table_stats(dbi), dbi);
t = PQntuples(res);
/* First: use the tbl_list as the outer loop and
the result set as the inner loop, this will
determine what tables should be removed */
while (NULL != tbl_elem) {
/*
* First: use the tbl_list as the outer loop and the result set as
* the inner loop, this will determine what tables should be
* removed
*/
while (NULL != tbl_elem)
{
tbl = ((tbl_info *) DLE_VAL(tbl_elem));
found_match = 0;
for (i = 0; i < t; i++) { /* loop through result set looking for a match */
if (tbl->relfilenode == atoi (PQgetvalue (res, i, PQfnumber (res, "relfilenode")))) {
for (i = 0; i < t; i++)
{ /* loop through result set looking for a
* match */
if (tbl->relfilenode == atoi(PQgetvalue(res, i, PQfnumber(res, "relfilenode"))))
{
found_match = 1;
break;
}
}
if (0 == found_match) { /* then we didn't find this tbl_elem in the result set */
if (0 == found_match)
{ /* then we didn't find this tbl_elem in
* the result set */
Dlelem *elem_to_remove = tbl_elem;
tbl_elem = DLGetSucc(tbl_elem);
remove_table_from_list(elem_to_remove);
}
else
tbl_elem = DLGetSucc(tbl_elem);
} /* Done removing dropped tables from the table_list */
} /* Done removing dropped tables from the
* table_list */
/* Then loop use result set as outer loop and
tbl_list as the inner loop to determine
what tables are new */
/*
* Then loop use result set as outer loop and tbl_list as the
* inner loop to determine what tables are new
*/
for (i = 0; i < t; i++)
{
tbl_elem = DLGetHead(dbi->table_list);
@ -231,7 +261,8 @@ update_table_list (db_info * dbi)
}
tbl_elem = DLGetSucc(tbl_elem);
}
if (0 == found_match) /*then we didn't find this result now in the tbl_list */
if (0 == found_match) /* then we didn't find this result
* now in the tbl_list */
{
DLAddTail(dbi->table_list, DLNewElem(init_table_info(res, i, dbi)));
if (args->debug >= 1)
@ -245,9 +276,8 @@ update_table_list (db_info * dbi)
fflush(LOGOUTPUT);
PQclear(res);
res = NULL;
if (args->debug >= 3) {
if (args->debug >= 3)
print_table_list(dbi->table_list);
}
if (disconnect)
db_disconnect(dbi);
}
@ -259,22 +289,26 @@ remove_table_from_list (Dlelem * tbl_to_remove)
{
tbl_info *tbl = ((tbl_info *) DLE_VAL(tbl_to_remove));
if (args->debug >= 1) {
if (args->debug >= 1)
{
sprintf(logbuffer, "Removing table: %s from list.", tbl->table_name);
log_entry(logbuffer);
fflush(LOGOUTPUT);
}
DLRemove(tbl_to_remove);
if (tbl->schema_name) {
if (tbl->schema_name)
{
free(tbl->schema_name);
tbl->schema_name = NULL;
}
if (tbl->table_name) {
if (tbl->table_name)
{
free(tbl->table_name);
tbl->table_name = NULL;
}
if (tbl) {
if (tbl)
{
free(tbl);
tbl = NULL;
}
@ -287,7 +321,9 @@ free_tbl_list (Dllist * tbl_list)
{
Dlelem *tbl_elem = DLGetHead(tbl_list);
Dlelem *tbl_elem_to_remove = NULL;
while (NULL != tbl_elem) {
while (NULL != tbl_elem)
{
tbl_elem_to_remove = tbl_elem;
tbl_elem = DLGetSucc(tbl_elem);
remove_table_from_list(tbl_elem_to_remove);
@ -299,7 +335,9 @@ void
print_table_list(Dllist *table_list)
{
Dlelem *table_elem = DLGetHead(table_list);
while (NULL != table_elem) {
while (NULL != table_elem)
{
print_table_info(((tbl_info *) DLE_VAL(table_elem)));
table_elem = DLGetSucc(table_elem);
}
@ -339,27 +377,31 @@ init_db_list ()
PGresult *res = NULL;
DLAddHead(db_list, DLNewElem(init_dbinfo((char *) "template1", 0, 0)));
if (NULL == DLGetHead (db_list)) { /* Make sure init_dbinfo was successful */
if (NULL == DLGetHead(db_list))
{ /* Make sure init_dbinfo was successful */
log_entry("init_db_list(): Error creating db_list for db: template1.");
fflush(LOGOUTPUT);
return NULL;
}
/* We do this just so we can set the proper oid for the template1 database */
/*
* We do this just so we can set the proper oid for the template1
* database
*/
dbs = ((db_info *) DLE_VAL(DLGetHead(db_list)));
dbs->conn = db_connect(dbs);
if (NULL != dbs->conn) {
if (NULL != dbs->conn)
{
res = send_query(FROZENOID_QUERY, dbs);
dbs->oid = atoi(PQgetvalue(res, 0, PQfnumber(res, "oid")));
dbs->age = atoi(PQgetvalue(res, 0, PQfnumber(res, "age")));
if (res)
PQclear(res);
if (args->debug >= 2) {
if (args->debug >= 2)
print_db_list(db_list, 0);
}
}
return db_list;
}
@ -369,17 +411,20 @@ db_info *
init_dbinfo(char *dbname, int oid, int age)
{
db_info *newdbinfo = (db_info *) malloc(sizeof(db_info));
newdbinfo->analyze_threshold = args->vacuum_base_threshold;
newdbinfo->vacuum_threshold = args->analyze_base_threshold;
newdbinfo->dbname = (char *) malloc(strlen(dbname) + 1);
strcpy(newdbinfo->dbname, dbname);
newdbinfo->username = NULL;
if (NULL != args->user) {
if (NULL != args->user)
{
newdbinfo->username = (char *) malloc(strlen(args->user) + 1);
strcpy(newdbinfo->username, args->user);
}
newdbinfo->password = NULL;
if (NULL != args->password) {
if (NULL != args->password)
{
newdbinfo->password = (char *) malloc(strlen(args->password) + 1);
strcpy(newdbinfo->password, args->password);
}
@ -388,9 +433,8 @@ init_dbinfo (char *dbname, int oid, int age)
newdbinfo->table_list = DLNewList();
newdbinfo->conn = NULL;
if (args->debug >= 2) {
if (args->debug >= 2)
print_table_list(newdbinfo->table_list);
}
return newdbinfo;
}
@ -404,53 +448,74 @@ update_db_list (Dllist * db_list)
Dlelem *db_elem = DLGetHead(db_list);
db_info *dbi = NULL;
db_info *dbi_template1 = DLE_VAL(db_elem);
int i = 0, t = 0, found_match = 0;
int i = 0,
t = 0,
found_match = 0;
if (args->debug >= 2) {
if (args->debug >= 2)
{
log_entry("updating the database list");
fflush(LOGOUTPUT);
}
if (NULL == dbi_template1->conn) {
if (NULL == dbi_template1->conn)
{
dbi_template1->conn = db_connect(dbi_template1);
disconnect = 1;
}
if (NULL != dbi_template1->conn) {
/* Get a result set that has all the information
we will need to both remove databasews from the list
that no longer exist and add databases to the list
that are new */
if (NULL != dbi_template1->conn)
{
/*
* Get a result set that has all the information we will need to
* both remove databasews from the list that no longer exist and
* add databases to the list that are new
*/
res = send_query(FROZENOID_QUERY2, dbi_template1);
t = PQntuples(res);
/* First: use the db_list as the outer loop and
the result set as the inner loop, this will
determine what databases should be removed */
while (NULL != db_elem) {
/*
* First: use the db_list as the outer loop and the result set as
* the inner loop, this will determine what databases should be
* removed
*/
while (NULL != db_elem)
{
dbi = ((db_info *) DLE_VAL(db_elem));
found_match = 0;
for (i = 0; i < t; i++) { /* loop through result set looking for a match */
if (dbi->oid == atoi (PQgetvalue (res, i, PQfnumber (res, "oid")))) {
for (i = 0; i < t; i++)
{ /* loop through result set looking for a
* match */
if (dbi->oid == atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))))
{
found_match = 1;
/* update the dbi->age so that we ensure xid_wraparound won't happen */
/*
* update the dbi->age so that we ensure
* xid_wraparound won't happen
*/
dbi->age = atoi(PQgetvalue(res, i, PQfnumber(res, "age")));
break;
}
}
if (0 == found_match) { /*then we didn't find this db_elem in the result set */
if (0 == found_match)
{ /* then we didn't find this db_elem in the
* result set */
Dlelem *elem_to_remove = db_elem;
db_elem = DLGetSucc(db_elem);
remove_db_from_list(elem_to_remove);
}
else
db_elem = DLGetSucc(db_elem);
} /* Done removing dropped databases from the table_list */
} /* Done removing dropped databases from
* the table_list */
/* Then loop use result set as outer loop and
db_list as the inner loop to determine
what databases are new */
/*
* Then loop use result set as outer loop and db_list as the inner
* loop to determine what databases are new
*/
for (i = 0; i < t; i++)
{
db_elem = DLGetHead(db_list);
@ -465,7 +530,8 @@ update_db_list (Dllist * db_list)
}
db_elem = DLGetSucc(db_elem);
}
if (0 == found_match) /*then we didn't find this result now in the tbl_list */
if (0 == found_match) /* then we didn't find this result
* now in the tbl_list */
{
DLAddTail(db_list, DLNewElem(init_dbinfo
(PQgetvalue(res, i, PQfnumber(res, "datname")),
@ -481,9 +547,8 @@ update_db_list (Dllist * db_list)
fflush(LOGOUTPUT);
PQclear(res);
res = NULL;
if (args->debug >= 3) {
if (args->debug >= 3)
print_db_list(db_list, 0);
}
if (disconnect)
db_disconnect(dbi_template1);
}
@ -506,11 +571,16 @@ return 1 if the database needed a database wide vacuum
int
xid_wraparound_check(db_info * dbi)
{
/* FIXME: should probably do something better here so that we don't vacuum all the
databases on the server at the same time. We have 500million xacts to work with so
we should be able to spread the load of full database vacuums a bit */
if (1500000000 < dbi->age) {
/*
* FIXME: should probably do something better here so that we don't
* vacuum all the databases on the server at the same time. We have
* 500million xacts to work with so we should be able to spread the
* load of full database vacuums a bit
*/
if (1500000000 < dbi->age)
{
PGresult *res = NULL;
res = send_query("vacuum", dbi);
/* FIXME: Perhaps should add a check for PQ_COMMAND_OK */
PQclear(res);
@ -525,7 +595,8 @@ remove_db_from_list (Dlelem * db_to_remove)
{
db_info *dbi = ((db_info *) DLE_VAL(db_to_remove));
if (args->debug >= 1) {
if (args->debug >= 1)
{
sprintf(logbuffer, "Removing db: %s from list.", dbi->dbname);
log_entry(logbuffer);
fflush(LOGOUTPUT);
@ -533,23 +604,28 @@ remove_db_from_list (Dlelem * db_to_remove)
DLRemove(db_to_remove);
if (dbi->conn)
db_disconnect(dbi);
if (dbi->dbname) {
if (dbi->dbname)
{
free(dbi->dbname);
dbi->dbname = NULL;
}
if (dbi->username) {
if (dbi->username)
{
free(dbi->username);
dbi->username = NULL;
}
if (dbi->password) {
if (dbi->password)
{
free(dbi->password);
dbi->password = NULL;
}
if (dbi->table_list) {
if (dbi->table_list)
{
free_tbl_list(dbi->table_list);
dbi->table_list = NULL;
}
if (dbi) {
if (dbi)
{
free(dbi);
dbi = NULL;
}
@ -563,7 +639,9 @@ free_db_list (Dllist * db_list)
{
Dlelem *db_elem = DLGetHead(db_list);
Dlelem *db_elem_to_remove = NULL;
while (NULL != db_elem) {
while (NULL != db_elem)
{
db_elem_to_remove = db_elem;
db_elem = DLGetSucc(db_elem);
remove_db_from_list(db_elem_to_remove);
@ -576,7 +654,9 @@ void
print_db_list(Dllist *db_list, int print_table_lists)
{
Dlelem *db_elem = DLGetHead(db_list);
while (NULL != db_elem) {
while (NULL != db_elem)
{
print_db_info(((db_info *) DLE_VAL(db_elem)), print_table_lists);
db_elem = DLGetSucc(db_elem);
}
@ -609,7 +689,9 @@ print_db_info (db_info * dbi, int print_tbl_list)
char *
query_table_stats(db_info * dbi)
{
if (!strcmp (dbi->dbname, "template1")) /* Use template1 to monitor the system tables */
if (!strcmp(dbi->dbname, "template1")) /* Use template1 to
* monitor the system
* tables */
return (char *) TABLE_STATS_ALL;
else
return (char *) TABLE_STATS_USER;
@ -623,7 +705,8 @@ db_connect (db_info * dbi)
PQsetdbLogin(args->host, args->port, NULL, NULL, dbi->dbname,
dbi->username, dbi->password);
if (CONNECTION_OK != PQstatus (db_conn)) {
if (CONNECTION_OK != PQstatus(db_conn))
{
sprintf(logbuffer, "Failed connection to database %s with error: %s.",
dbi->dbname, PQerrorMessage(db_conn));
log_entry(logbuffer);
@ -637,7 +720,8 @@ db_connect (db_info * dbi)
void
db_disconnect(db_info * dbi)
{
if (NULL != dbi->conn) {
if (NULL != dbi->conn)
{
PQfinish(dbi->conn);
dbi->conn = NULL;
}
@ -648,6 +732,7 @@ check_stats_enabled (db_info * dbi)
{
PGresult *res = NULL;
int ret = 0;
res = send_query("show stats_row_level", dbi);
ret =
strcmp("on", PQgetvalue(res, 0, PQfnumber(res, "stats_row_level")));
@ -665,7 +750,8 @@ send_query (const char *query, db_info * dbi)
res = PQexec(dbi->conn, query);
if (!res) {
if (!res)
{
sprintf(logbuffer,
"Fatal error occured while sending query (%s) to database %s",
query, dbi->dbname);
@ -676,7 +762,8 @@ send_query (const char *query, db_info * dbi)
return NULL;
}
if (PQresultStatus(res) != PGRES_TUPLES_OK
&& PQresultStatus (res) != PGRES_COMMAND_OK) {
&& PQresultStatus(res) != PGRES_COMMAND_OK)
{
sprintf(logbuffer,
"Can not refresh statistics information from the database %s.",
dbi->dbname);
@ -694,7 +781,8 @@ send_query (const char *query, db_info * dbi)
void
free_cmd_args()
{
if (NULL != args) {
if (NULL != args)
{
if (NULL != args->user)
free(args->user);
if (NULL != args->user)
@ -707,6 +795,7 @@ cmd_args *
get_cmd_args(int argc, char *argv[])
{
int c;
args = (cmd_args *) malloc(sizeof(cmd_args));
args->sleep_base_value = SLEEPBASEVALUE;
args->sleep_scaling_factor = SLEEPSCALINGFACTOR;
@ -717,9 +806,14 @@ get_cmd_args (int argc, char *argv[])
args->debug = AUTOVACUUM_DEBUG;
args->daemonize = 0;
/* Fixme: Should add some sanity checking such as positive integer values etc */
while (-1 != (c = getopt (argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hD"))) {
switch (c) {
/*
* Fixme: Should add some sanity checking such as positive integer
* values etc
*/
while (-1 != (c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hD")))
{
switch (c)
{
case 's':
args->sleep_base_value = atoi(optarg);
break;
@ -763,15 +857,21 @@ get_cmd_args (int argc, char *argv[])
usage();
exit(0);
default:
/* It's here that we know that things are invalid...
It is not forcibly an error to call usage */
/*
* It's here that we know that things are invalid... It is
* not forcibly an error to call usage
*/
fprintf(stderr, "Error: Invalid Command Line Options.\n");
usage();
exit(1);
break;
}
/* if values for insert thresholds are not specified,
then they default to 1/2 of the delete values */
/*
* if values for insert thresholds are not specified, then they
* default to 1/2 of the delete values
*/
if (-1 == args->analyze_base_threshold)
args->analyze_base_threshold = args->vacuum_base_threshold / 2;
if (-1 == args->analyze_scaling_factor)
@ -780,10 +880,12 @@ get_cmd_args (int argc, char *argv[])
return args;
}
void usage()
void
usage()
{
int i = 0;
float f = 0;
fprintf(stderr, "usage: pg_autovacuum \n");
fprintf(stderr, " [-D] Daemonize (Detach from tty and run in the background)\n");
i = AUTOVACUUM_DEBUG;
@ -854,42 +956,49 @@ int
main(int argc, char *argv[])
{
char buf[256];
int j = 0, loops = 0;
int j = 0,
loops = 0;
/* int numInserts, numDeletes, */
int sleep_secs;
Dllist *db_list;
Dlelem *db_elem, *tbl_elem;
Dlelem *db_elem,
*tbl_elem;
db_info *dbs;
tbl_info *tbl;
PGresult *res = NULL;
long long diff = 0;
struct timeval now, then;
struct timeval now,
then;
args = get_cmd_args (argc, argv); /* Get Command Line Args and put them in the args struct */
args = get_cmd_args(argc, argv); /* Get Command Line Args and put
* them in the args struct */
/* Dameonize if requested */
if (1 == args->daemonize){ daemonize(); }
if (1 == args->daemonize)
daemonize();
if (args->logfile) {
if (args->logfile)
{
LOGOUTPUT = fopen(args->logfile, "a");
if (!LOGOUTPUT) {
if (!LOGOUTPUT)
{
fprintf(stderr, "Could not open log file - [%s]\n", args->logfile);
exit(-1);
}
}
else {
else
LOGOUTPUT = stderr;
}
if (args->debug >= 2) {
if (args->debug >= 2)
print_cmd_args();
}
/* Init the db list with template1 */
db_list = init_db_list();
if (NULL == db_list)
return 1;
if (0 != check_stats_enabled (((db_info *) DLE_VAL (DLGetHead (db_list))))) {
if (0 != check_stats_enabled(((db_info *) DLE_VAL(DLGetHead(db_list)))))
{
log_entry("Error: GUC variable stats_row_level must be enabled.");
log_entry(" Please fix the problems and try again.");
fflush(LOGOUTPUT);
@ -899,13 +1008,19 @@ main (int argc, char *argv[])
gettimeofday(&then, 0); /* for use later to caluculate sleep time */
while (1) { /* Main Loop */
db_elem = DLGetHead (db_list); /* Reset cur_db_node to the beginning of the db_list */
while (1)
{ /* Main Loop */
db_elem = DLGetHead(db_list); /* Reset cur_db_node to the
* beginning of the db_list */
dbs = ((db_info *) DLE_VAL (db_elem)); /* get pointer to cur_db's db_info struct */
if (NULL == dbs->conn) {
dbs = ((db_info *) DLE_VAL(db_elem)); /* get pointer to cur_db's
* db_info struct */
if (NULL == dbs->conn)
{
dbs->conn = db_connect(dbs);
if (NULL == dbs->conn) { /* Serious problem: We can't connect to template1 */
if (NULL == dbs->conn)
{ /* Serious problem: We can't connect to
* template1 */
log_entry("Error: Cannot connect to template1, exiting.");
fflush(LOGOUTPUT);
fclose(LOGOUTPUT);
@ -913,26 +1028,41 @@ main (int argc, char *argv[])
}
}
if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if it's time */
update_db_list (db_list); /* Add and remove databases from the list */
if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if it's
* time */
update_db_list(db_list); /* Add and remove databases from
* the list */
while (NULL != db_elem) { /* Loop through databases in list */
dbs = ((db_info *) DLE_VAL (db_elem)); /* get pointer to cur_db's db_info struct */
while (NULL != db_elem)
{ /* Loop through databases in list */
dbs = ((db_info *) DLE_VAL(db_elem)); /* get pointer to
* cur_db's db_info
* struct */
if (NULL == dbs->conn)
dbs->conn = db_connect(dbs);
if (NULL != dbs->conn) {
if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if it's time */
update_table_list (dbs); /* Add and remove tables from the list */
if (NULL != dbs->conn)
{
if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if
* it's time */
update_table_list(dbs); /* Add and remove tables
* from the list */
if (0 == xid_wraparound_check(dbs));
{
res = send_query (query_table_stats (dbs), dbs); /* Get an updated snapshot of this dbs table stats */
for (j = 0; j < PQntuples (res); j++) { /* loop through result set */
tbl_elem = DLGetHead (dbs->table_list); /* Reset tbl_elem to top of dbs->table_list */
while (NULL != tbl_elem) { /* Loop through tables in list */
tbl = ((tbl_info *) DLE_VAL (tbl_elem)); /* set tbl_info = current_table */
if (tbl->relfilenode == atoi (PQgetvalue(res, j, PQfnumber (res, "relfilenode")))) {
res = send_query(query_table_stats(dbs), dbs); /* Get an updated
* snapshot of this dbs
* table stats */
for (j = 0; j < PQntuples(res); j++)
{ /* loop through result set */
tbl_elem = DLGetHead(dbs->table_list); /* Reset tbl_elem to top
* of dbs->table_list */
while (NULL != tbl_elem)
{ /* Loop through tables in list */
tbl = ((tbl_info *) DLE_VAL(tbl_elem)); /* set tbl_info =
* current_table */
if (tbl->relfilenode == atoi(PQgetvalue(res, j, PQfnumber(res, "relfilenode"))))
{
tbl->curr_analyze_count =
(atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_ins"))) +
atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_upd"))) +
@ -941,38 +1071,52 @@ main (int argc, char *argv[])
(atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_del"))) +
atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_upd"))));
/* Check numDeletes to see if we need to vacuum, if so:
Run vacuum analyze (adding analyze is small so we might as well)
Update table thresholds and related information
if numDeletes is not big enough for vacuum then check numInserts for analyze */
/*
* Check numDeletes to see if we need to
* vacuum, if so: Run vacuum analyze
* (adding analyze is small so we might as
* well) Update table thresholds and
* related information if numDeletes is
* not big enough for vacuum then check
* numInserts for analyze
*/
if ((tbl->curr_vacuum_count - tbl->CountAtLastVacuum) >= tbl->vacuum_threshold)
{
snprintf(buf, sizeof(buf), "vacuum analyze %s", tbl->table_name);
if (args->debug >= 1) {
if (args->debug >= 1)
{
sprintf(logbuffer, "Performing: %s", buf);
log_entry(logbuffer);
fflush(LOGOUTPUT);
}
send_query(buf, dbs);
update_table_thresholds(dbs, tbl, VACUUM_ANALYZE);
if (args->debug >= 2) {print_table_info (tbl);}
if (args->debug >= 2)
print_table_info(tbl);
}
else if ((tbl->curr_analyze_count - tbl->CountAtLastAnalyze) >= tbl->analyze_threshold)
{
snprintf(buf, sizeof(buf), "analyze %s", tbl->table_name);
if (args->debug >= 1) {
if (args->debug >= 1)
{
sprintf(logbuffer, "Performing: %s", buf);
log_entry(logbuffer);
fflush(LOGOUTPUT);
}
send_query(buf, dbs);
update_table_thresholds(dbs, tbl, ANALYZE_ONLY);
if (args->debug >= 2) { print_table_info (tbl); }
if (args->debug >= 2)
print_table_info(tbl);
}
break; /* once we have found a match, no need to keep checking. */
break; /* once we have found a match, no
* need to keep checking. */
}
/* Advance the table pointers for the next loop */
/*
* Advance the table pointers for the next
* loop
*/
tbl_elem = DLGetSucc(tbl_elem);
} /* end for table while loop */
@ -983,7 +1127,8 @@ main (int argc, char *argv[])
res = NULL;
db_disconnect(dbs);
}
db_elem = DLGetSucc (db_elem); /* move on to next DB regardless */
db_elem = DLGetSucc(db_elem); /* move on to next DB
* regardless */
} /* end of db_list while loop */
/* Figure out how long to sleep etc ... */
@ -992,7 +1137,8 @@ main (int argc, char *argv[])
sleep_secs = args->sleep_base_value + args->sleep_scaling_factor * diff / 1000000;
loops++;
if (args->debug >= 2) {
if (args->debug >= 2)
{
sprintf(logbuffer,
"%i All DBs checked in: %lld usec, will sleep for %i secs.",
loops, diff, sleep_secs);
@ -1005,7 +1151,10 @@ main (int argc, char *argv[])
} /* end of while loop */
/* program is exiting, this should never run, but is here to make compiler / valgrind happy */
/*
* program is exiting, this should never run, but is here to make
* compiler / valgrind happy
*/
free_db_list(db_list);
free_cmd_args();
return EXIT_SUCCESS;

View File

@ -44,9 +44,19 @@
/* define cmd_args stucture */
struct cmdargs
{
int vacuum_base_threshold, analyze_base_threshold, sleep_base_value, debug, daemonize;
float vacuum_scaling_factor, analyze_scaling_factor, sleep_scaling_factor;
char *user, *password, *host, *logfile, *port;
int vacuum_base_threshold,
analyze_base_threshold,
sleep_base_value,
debug,
daemonize;
float vacuum_scaling_factor,
analyze_scaling_factor,
sleep_scaling_factor;
char *user,
*password,
*host,
*logfile,
*port;
};
typedef struct cmdargs cmd_args;
@ -57,23 +67,38 @@ cmd_args *args;
I think we need to guarantee this happens approx every 1Million TX's */
struct dbinfo
{
int oid, age;
int analyze_threshold, vacuum_threshold; /* Use these as defaults for table thresholds */
int oid,
age;
int analyze_threshold,
vacuum_threshold; /* Use these as defaults for table
* thresholds */
PGconn *conn;
char *dbname, *username, *password;
char *dbname,
*username,
*password;
Dllist *table_list;
};
typedef struct dbinfo db_info;
struct tableinfo
{
char *schema_name, *table_name;
int relfilenode, reltuples, relpages;
long analyze_threshold, vacuum_threshold;
long CountAtLastAnalyze; /* equal to: inserts + updates as of the last analyze or initial values at startup */
long CountAtLastVacuum; /* equal to: deletes + updates as of the last vacuum or initial values at startup */
long curr_analyze_count, curr_vacuum_count; /* Latest values from stats system */
db_info *dbi; /* pointer to the database that this table belongs to */
char *schema_name,
*table_name;
int relfilenode,
reltuples,
relpages;
long analyze_threshold,
vacuum_threshold;
long CountAtLastAnalyze; /* equal to: inserts + updates as
* of the last analyze or initial
* values at startup */
long CountAtLastVacuum; /* equal to: deletes + updates as
* of the last vacuum or initial
* values at startup */
long curr_analyze_count,
curr_vacuum_count; /* Latest values from stats system */
db_info *dbi; /* pointer to the database that this table
* belongs to */
};
typedef struct tableinfo tbl_info;

View File

@ -1,7 +1,7 @@
/* -------------------------------------------------------------------------
* pg_dumplo
*
* $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.16 2003/05/14 03:25:56 tgl Exp $
* $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.17 2003/08/04 00:43:11 momjian Exp $
*
* Karel Zak 1999-2000
* -------------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
/*
* $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.25 2003/08/01 02:21:17 tgl Exp $
* $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.26 2003/08/04 00:43:11 momjian Exp $
*
* pgbench: a simple TPC-B like benchmark program for PostgreSQL
* written by Tatsuo Ishii

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: openssl.c,v 1.11 2002/11/15 02:54:44 momjian Exp $
* $Id: openssl.c,v 1.12 2003/08/04 00:43:11 momjian Exp $
*/
#include <postgres.h>
@ -134,7 +134,8 @@ px_find_digest(const char *name, PX_MD ** res)
* So need to manage ciphers ourselves.
*/
struct ossl_cipher {
struct ossl_cipher
{
int (*init) (PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv);
int (*encrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res);
int (*decrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res);
@ -510,8 +511,10 @@ px_find_cipher(const char *name, PX_Cipher ** res)
const struct ossl_cipher *ossl_ciph = NULL;
name = px_resolve_alias(ossl_aliases, name);
for (i = 0; ossl_cipher_types[i].name; i++) {
if (!strcmp(ossl_cipher_types[i].name, name)) {
for (i = 0; ossl_cipher_types[i].name; i++)
{
if (!strcmp(ossl_cipher_types[i].name, name))
{
ossl_ciph = ossl_cipher_types[i].ciph;
break;
}

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: pgcrypto.c,v 1.13 2003/07/24 17:52:33 tgl Exp $
* $Id: pgcrypto.c,v 1.14 2003/08/04 00:43:11 momjian Exp $
*/
#include <postgres.h>

View File

@ -1,5 +1,5 @@
/*
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.11 2003/08/01 02:21:17 tgl Exp $
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.12 2003/08/04 00:43:11 momjian Exp $
*
* Copyright (c) 2001,2002 Tatsuo Ishii
*

View File

@ -261,7 +261,8 @@ timetravel(PG_FUNCTION_ARGS)
relname, args[a_time_on], args[a_time_off]);
}
if (oldtimeoff != NOEND_ABSTIME)
{ /* current record is a deleted/updated record */
{ /* current record is a deleted/updated
* record */
pfree(relname);
return PointerGetDatum(NULL);
}
@ -282,7 +283,8 @@ timetravel(PG_FUNCTION_ARGS)
}
/* change date column(s) */
cvals[attnum[a_time_off] - 1] = newtimeoff; /* stop_date eq current date */
cvals[attnum[a_time_off] - 1] = newtimeoff; /* stop_date eq current
* date */
cnulls[attnum[a_time_off] - 1] = ' ';
if (!newtuple)
@ -399,7 +401,8 @@ timetravel(PG_FUNCTION_ARGS)
*/
/* SPI_pfree(tmptuple); */
}
else /* DELETE case */
else
/* DELETE case */
rettuple = trigtuple;
SPI_finish(); /* don't forget say Bye to SPI mgr */
@ -423,7 +426,8 @@ set_timetravel(PG_FUNCTION_ARGS)
char *d;
char *s;
int32 ret;
TTOffList *p,*pp;
TTOffList *p,
*pp;
for (pp = (p = &TTOff)->next; pp; pp = (p = pp)->next)
{
@ -492,6 +496,7 @@ static int
findTTStatus(char *name)
{
TTOffList *pp;
for (pp = TTOff.next; pp; pp = pp->next)
if (strcasecmp(name, pp->name) == 0)
return 0;

View File

@ -729,9 +729,9 @@ crosstab_hash(PG_FUNCTION_ARGS)
/*
* Check to make sure we have a reasonable tuple descriptor
*
* Note we will attempt to coerce the values into whatever
* the return attribute type is and depend on the "in"
* function to complain if needed.
* Note we will attempt to coerce the values into whatever the return
* attribute type is and depend on the "in" function to complain if
* needed.
*/
if (tupdesc->natts < 2)
ereport(ERROR,
@ -781,8 +781,8 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
ctl.entrysize = sizeof(crosstab_HashEnt);
/*
* use INIT_CATS, defined above as a guess of how
* many hash table entries to create, initially
* use INIT_CATS, defined above as a guess of how many hash table
* entries to create, initially
*/
crosstab_HashTable = hash_create("crosstab hash", INIT_CATS, &ctl, HASH_ELEM);
@ -803,8 +803,8 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
int i;
/*
* The provided categories SQL query must always return one column:
* category - the label or identifier for each column
* The provided categories SQL query must always return one
* column: category - the label or identifier for each column
*/
if (spi_tupdesc->natts != 1)
ereport(ERROR,
@ -890,21 +890,24 @@ get_crosstab_tuplestore(char *sql,
int ncols = spi_tupdesc->natts;
char *rowid;
char *lastrowid = NULL;
int i, j;
int i,
j;
int result_ncols;
/*
* The provided SQL query must always return at least three columns:
* 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. value the values used to populate the value-columns
* 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
* "category" and "values". The first column is taken as "rowname".
* Additional columns (2 thru N-2) are assumed the same for the same
* "rowname", and are copied into the result tuple from the first
* time we encounter a particular rowname.
* "category" and "values". The first column is taken as
* "rowname". Additional columns (2 thru N-2) are assumed the same
* for the same "rowname", and are copied into the result tuple
* from the first time we encounter a particular rowname.
*/
if (ncols < 3)
ereport(ERROR,
@ -958,7 +961,10 @@ get_crosstab_tuplestore(char *sql,
*/
if (lastrowid != NULL)
{
/* switch to appropriate context while storing the tuple */
/*
* switch to appropriate context while storing the
* tuple
*/
SPIcontext = MemoryContextSwitchTo(per_query_ctx);
/* rowid changed, flush the previous output row */

View File

@ -51,7 +51,8 @@ DICT dicts[] = {
#undef DICT_TABLE
/* array for storing dictionary's objects (if needed) */
void *dictobjs[lengthof(dicts)];
void *dictobjs[
lengthof(dicts)];
#define STOPLEXEM -2
#define BYLOCALE -1

View File

@ -5,43 +5,59 @@
#include "dict.h"
text *
char2text(char* in) {
char2text(char *in)
{
return charl2text(in, strlen(in));
}
text* charl2text(char* in, int len) {
text *
charl2text(char *in, int len)
{
text *out = (text *) palloc(len + VARHDRSZ);
memcpy(VARDATA(out), in, len);
VARATT_SIZEP(out) = len + VARHDRSZ;
return out;
}
char
*text2char(text* in) {
*
text2char(text *in)
{
char *out = palloc(VARSIZE(in));
memcpy(out, VARDATA(in), VARSIZE(in) - VARHDRSZ);
out[VARSIZE(in) - VARHDRSZ] = '\0';
return out;
}
char
*pnstrdup(char* in, int len) {
*
pnstrdup(char *in, int len)
{
char *out = palloc(len + 1);
memcpy(out, in, len);
out[len] = '\0';
return out;
}
text
*ptextdup(text* in) {
*
ptextdup(text *in)
{
text *out = (text *) palloc(VARSIZE(in));
memcpy(out, in, VARSIZE(in));
return out;
}
text
*mtextdup(text* in) {
*
mtextdup(text *in)
{
text *out = (text *) malloc(VARSIZE(in));
if (!out)
ts_error(ERROR, "No memory");
memcpy(out, in, VARSIZE(in));
@ -49,9 +65,11 @@ text
}
void
ts_error(int state, const char *format, ...) {
ts_error(int state, const char *format,...)
{
va_list args;
int tlen = 128, len=0;
int tlen = 128,
len = 0;
char *buf;
reset_cfg();
@ -61,7 +79,8 @@ ts_error(int state, const char *format, ...) {
va_start(args, format);
buf = palloc(tlen);
len = vsnprintf(buf, tlen - 1, format, args);
if ( len >= tlen ) {
if (len >= tlen)
{
tlen = len + 1;
buf = repalloc(buf, tlen);
vsnprintf(buf, tlen - 1, format, args);
@ -74,10 +93,10 @@ ts_error(int state, const char *format, ...) {
}
int
text_cmp(text *a, text *b) {
text_cmp(text *a, text *b)
{
if (VARSIZE(a) == VARSIZE(b))
return strncmp(VARDATA(a), VARDATA(b), VARSIZE(a) - VARHDRSZ);
return (int) VARSIZE(a) - (int) VARSIZE(b);
}

View File

@ -22,7 +22,8 @@
static void *plan_getdict = NULL;
void
init_dict(Oid id, DictInfo *dict) {
init_dict(Oid id, DictInfo * dict)
{
Oid arg[1] = {OIDOID};
bool isnull;
Datum pars[1] = {ObjectIdGetDatum(id)};
@ -30,7 +31,8 @@ init_dict(Oid id, DictInfo *dict) {
memset(dict, 0, sizeof(DictInfo));
SPI_connect();
if ( !plan_getdict ) {
if (!plan_getdict)
{
plan_getdict = SPI_saveplan(SPI_prepare("select dict_init, dict_initoption, dict_lexize from pg_ts_dict where oid = $1", 1, arg));
if (!plan_getdict)
ts_error(ERROR, "SPI_prepare() failed");
@ -39,11 +41,14 @@ init_dict(Oid id, DictInfo *dict) {
stat = SPI_execp(plan_getdict, pars, " ", 1);
if (stat < 0)
ts_error(ERROR, "SPI_execp return %d", stat);
if ( SPI_processed > 0 ) {
if (SPI_processed > 0)
{
Datum opt;
Oid oid = InvalidOid;
oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
if ( !(isnull || oid==InvalidOid) ) {
if (!(isnull || oid == InvalidOid))
{
opt = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull);
dict->dictionary = (void *) DatumGetPointer(OidFunctionCall1(oid, opt));
}
@ -52,12 +57,14 @@ init_dict(Oid id, DictInfo *dict) {
ts_error(ERROR, "Null dict_lexize for dictonary %d", id);
fmgr_info_cxt(oid, &(dict->lexize_info), TopMemoryContext);
dict->dict_id = id;
} else
}
else
ts_error(ERROR, "No dictionary with id %d", id);
SPI_finish();
}
typedef struct {
typedef struct
{
DictInfo *last_dict;
int len;
int reallen;
@ -68,7 +75,8 @@ typedef struct {
static DictList DList = {NULL, 0, 0, NULL, {0, 0, NULL}};
void
reset_dict(void) {
reset_dict(void)
{
freeSNMap(&(DList.name2id_map));
/* XXX need to free DList.list[*].dictionary */
if (DList.list)
@ -78,20 +86,24 @@ reset_dict(void) {
static int
comparedict(const void *a, const void *b) {
comparedict(const void *a, const void *b)
{
return ((DictInfo *) a)->dict_id - ((DictInfo *) b)->dict_id;
}
DictInfo *
finddict(Oid id) {
finddict(Oid id)
{
/* last used dict */
if (DList.last_dict && DList.last_dict->dict_id == id)
return DList.last_dict;
/* already used dict */
if ( DList.len != 0 ) {
if (DList.len != 0)
{
DictInfo key;
key.dict_id = id;
DList.last_dict = bsearch(&key, DList.list, DList.len, sizeof(DictInfo), comparedict);
if (DList.last_dict != NULL)
@ -99,9 +111,11 @@ finddict(Oid id) {
}
/* last chance */
if ( DList.len==DList.reallen ) {
if (DList.len == DList.reallen)
{
DictInfo *tmp;
int reallen = (DList.reallen) ? 2 * DList.reallen : 16;
tmp = (DictInfo *) realloc(DList.list, sizeof(DictInfo) * reallen);
if (!tmp)
ts_error(ERROR, "No memory");
@ -119,7 +133,8 @@ finddict(Oid id) {
static void *plan_name2id = NULL;
Oid
name2id_dict(text *name) {
name2id_dict(text *name)
{
Oid arg[1] = {TEXTOID};
bool isnull;
Datum pars[1] = {PointerGetDatum(name)};
@ -130,7 +145,8 @@ name2id_dict(text *name) {
return id;
SPI_connect();
if ( !plan_name2id ) {
if (!plan_name2id)
{
plan_name2id = SPI_saveplan(SPI_prepare("select oid from pg_ts_dict where dict_name = $1", 1, arg));
if (!plan_name2id)
ts_error(ERROR, "SPI_prepare() failed");
@ -154,10 +170,12 @@ PG_FUNCTION_INFO_V1(lexize);
Datum lexize(PG_FUNCTION_ARGS);
Datum
lexize(PG_FUNCTION_ARGS) {
lexize(PG_FUNCTION_ARGS)
{
text *in = PG_GETARG_TEXT_P(1);
DictInfo *dict = finddict(PG_GETARG_OID(0));
char **res, **ptr;
char **res,
**ptr;
Datum *da;
ArrayType *a;
@ -170,17 +188,20 @@ lexize(PG_FUNCTION_ARGS) {
)
);
PG_FREE_IF_COPY(in, 1);
if ( !res ) {
if (!res)
{
if (PG_NARGS() > 2)
PG_RETURN_POINTER(NULL);
else
PG_RETURN_NULL();
}
while(*ptr) ptr++;
while (*ptr)
ptr++;
da = (Datum *) palloc(sizeof(Datum) * (ptr - res + 1));
ptr = res;
while(*ptr) {
while (*ptr)
{
da[ptr - res] = PointerGetDatum(char2text(*ptr));
ptr++;
}
@ -195,7 +216,8 @@ lexize(PG_FUNCTION_ARGS) {
);
ptr = res;
while(*ptr) {
while (*ptr)
{
pfree(DatumGetPointer(da[ptr - res]));
pfree(*ptr);
ptr++;
@ -209,7 +231,8 @@ lexize(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(lexize_byname);
Datum lexize_byname(PG_FUNCTION_ARGS);
Datum
lexize_byname(PG_FUNCTION_ARGS) {
lexize_byname(PG_FUNCTION_ARGS)
{
text *dictname = PG_GETARG_TEXT_P(0);
Datum res;
@ -232,7 +255,8 @@ static Oid currect_dictionary_id=0;
PG_FUNCTION_INFO_V1(set_curdict);
Datum set_curdict(PG_FUNCTION_ARGS);
Datum
set_curdict(PG_FUNCTION_ARGS) {
set_curdict(PG_FUNCTION_ARGS)
{
finddict(PG_GETARG_OID(0));
currect_dictionary_id = PG_GETARG_OID(0);
PG_RETURN_VOID();
@ -241,7 +265,8 @@ set_curdict(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(set_curdict_byname);
Datum set_curdict_byname(PG_FUNCTION_ARGS);
Datum
set_curdict_byname(PG_FUNCTION_ARGS) {
set_curdict_byname(PG_FUNCTION_ARGS)
{
text *dictname = PG_GETARG_TEXT_P(0);
DirectFunctionCall1(
@ -255,8 +280,10 @@ set_curdict_byname(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(lexize_bycurrent);
Datum lexize_bycurrent(PG_FUNCTION_ARGS);
Datum
lexize_bycurrent(PG_FUNCTION_ARGS) {
lexize_bycurrent(PG_FUNCTION_ARGS)
{
Datum res;
if (currect_dictionary_id == 0)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
@ -274,5 +301,3 @@ lexize_bycurrent(PG_FUNCTION_ARGS) {
else
PG_RETURN_NULL();
}

View File

@ -3,7 +3,8 @@
#include "postgres.h"
#include "fmgr.h"
typedef struct {
typedef struct
{
int len;
char **stop;
char *(*wordop) (char *);
@ -15,7 +16,8 @@ void readstoplist(text *in, StopList *s);
bool searchstoplist(StopList * s, char *key);
char *lowerstr(char *str);
typedef struct {
typedef struct
{
Oid dict_id;
FmgrInfo lexize_info;
void *dictionary;
@ -28,7 +30,8 @@ void reset_dict(void);
/* simple parser of cfg string */
typedef struct {
typedef struct
{
char *key;
char *value;
} Map;

View File

@ -11,18 +11,21 @@
#include "dict.h"
#include "common.h"
typedef struct {
typedef struct
{
StopList stoplist;
} DictExample;
PG_FUNCTION_INFO_V1(dex_init);
Datum dex_init(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(dex_lexize);
Datum dex_lexize(PG_FUNCTION_ARGS);
Datum
dex_init(PG_FUNCTION_ARGS) {
dex_init(PG_FUNCTION_ARGS)
{
DictExample *d = (DictExample *) malloc(sizeof(DictExample));
if (!d)
@ -33,8 +36,10 @@ dex_init(PG_FUNCTION_ARGS) {
d->stoplist.wordop = lowerstr;
if ( !PG_ARGISNULL(0) && PG_GETARG_POINTER(0)!=NULL ) {
if (!PG_ARGISNULL(0) && PG_GETARG_POINTER(0) != NULL)
{
text *in = PG_GETARG_TEXT_P(0);
readstoplist(in, &(d->stoplist));
sortstoplist(&(d->stoplist));
PG_FREE_IF_COPY(in, 0);
@ -44,16 +49,19 @@ dex_init(PG_FUNCTION_ARGS) {
}
Datum
dex_lexize(PG_FUNCTION_ARGS) {
dex_lexize(PG_FUNCTION_ARGS)
{
DictExample *d = (DictExample *) PG_GETARG_POINTER(0);
char *in = (char *) PG_GETARG_POINTER(1);
char *txt = pnstrdup(in, PG_GETARG_INT32(2));
char **res = palloc(sizeof(char *) * 2);
if ( *txt=='\0' || searchstoplist(&(d->stoplist),txt) ) {
if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
{
pfree(txt);
res[0] = NULL;
} else
}
else
res[0] = txt;
res[1] = NULL;

View File

@ -12,29 +12,36 @@
#include "common.h"
#include "ispell/spell.h"
typedef struct {
typedef struct
{
StopList stoplist;
IspellDict obj;
} DictISpell;
PG_FUNCTION_INFO_V1(spell_init);
Datum spell_init(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(spell_lexize);
Datum spell_lexize(PG_FUNCTION_ARGS);
static void
freeDictISpell(DictISpell *d) {
freeDictISpell(DictISpell * d)
{
FreeIspell(&(d->obj));
freestoplist(&(d->stoplist));
free(d);
}
Datum
spell_init(PG_FUNCTION_ARGS) {
spell_init(PG_FUNCTION_ARGS)
{
DictISpell *d;
Map *cfg, *pcfg;
Map *cfg,
*pcfg;
text *in;
bool affloaded=false, dictloaded=false, stoploaded=false;
bool affloaded = false,
dictloaded = false,
stoploaded = false;
if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
ereport(ERROR,
@ -53,15 +60,19 @@ spell_init(PG_FUNCTION_ARGS) {
parse_cfgdict(in, &cfg);
PG_FREE_IF_COPY(in, 0);
pcfg = cfg;
while(pcfg->key) {
if ( strcasecmp("DictFile", pcfg->key) == 0 ) {
if ( dictloaded ) {
while (pcfg->key)
{
if (strcasecmp("DictFile", pcfg->key) == 0)
{
if (dictloaded)
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("dictionary already loaded")));
}
if ( ImportDictionary(&(d->obj), pcfg->value) ) {
if (ImportDictionary(&(d->obj), pcfg->value))
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
@ -69,14 +80,18 @@ spell_init(PG_FUNCTION_ARGS) {
pcfg->value)));
}
dictloaded = true;
} else if ( strcasecmp("AffFile", pcfg->key) == 0 ) {
if ( affloaded ) {
}
else if (strcasecmp("AffFile", pcfg->key) == 0)
{
if (affloaded)
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("affixes already loaded")));
}
if ( ImportAffixes(&(d->obj), pcfg->value) ) {
if (ImportAffixes(&(d->obj), pcfg->value))
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
@ -84,9 +99,13 @@ spell_init(PG_FUNCTION_ARGS) {
pcfg->value)));
}
affloaded = true;
} else if ( strcasecmp("StopFile", pcfg->key) == 0 ) {
}
else if (strcasecmp("StopFile", pcfg->key) == 0)
{
text *tmp = char2text(pcfg->value);
if ( stoploaded ) {
if (stoploaded)
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
@ -96,7 +115,9 @@ spell_init(PG_FUNCTION_ARGS) {
sortstoplist(&(d->stoplist));
pfree(tmp);
stoploaded = true;
} else {
}
else
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
@ -109,15 +130,20 @@ spell_init(PG_FUNCTION_ARGS) {
}
pfree(cfg);
if ( affloaded && dictloaded ) {
if (affloaded && dictloaded)
{
SortDictionary(&(d->obj));
SortAffixes(&(d->obj));
} else if ( !affloaded ) {
}
else if (!affloaded)
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("no affixes")));
} else {
}
else
{
freeDictISpell(d);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
@ -128,12 +154,14 @@ spell_init(PG_FUNCTION_ARGS) {
}
Datum
spell_lexize(PG_FUNCTION_ARGS) {
spell_lexize(PG_FUNCTION_ARGS)
{
DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
char *in = (char *) PG_GETARG_POINTER(1);
char *txt;
char **res;
char **ptr, **cptr;
char **ptr,
**cptr;
if (!PG_GETARG_INT32(2))
PG_RETURN_POINTER(NULL);
@ -147,18 +175,22 @@ spell_lexize(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(NULL);
ptr = cptr = res;
while(*ptr) {
if ( searchstoplist(&(d->stoplist),*ptr) ) {
while (*ptr)
{
if (searchstoplist(&(d->stoplist), *ptr))
{
pfree(*ptr);
*ptr = NULL;
ptr++;
} else {
}
else
{
*cptr = *ptr;
cptr++; ptr++;
cptr++;
ptr++;
}
}
*cptr = NULL;
PG_RETURN_POINTER(res);
}

View File

@ -14,7 +14,8 @@
#include "snowball/english_stem.h"
#include "snowball/russian_stem.h"
typedef struct {
typedef struct
{
struct SN_env *z;
StopList stoplist;
int (*stem) (struct SN_env * z);
@ -23,13 +24,16 @@ typedef struct {
PG_FUNCTION_INFO_V1(snb_en_init);
Datum snb_en_init(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(snb_ru_init);
Datum snb_ru_init(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(snb_lexize);
Datum snb_lexize(PG_FUNCTION_ARGS);
Datum
snb_en_init(PG_FUNCTION_ARGS) {
snb_en_init(PG_FUNCTION_ARGS)
{
DictSnowball *d = (DictSnowball *) malloc(sizeof(DictSnowball));
if (!d)
@ -39,15 +43,18 @@ snb_en_init(PG_FUNCTION_ARGS) {
memset(d, 0, sizeof(DictSnowball));
d->stoplist.wordop = lowerstr;
if ( !PG_ARGISNULL(0) && PG_GETARG_POINTER(0)!=NULL ) {
if (!PG_ARGISNULL(0) && PG_GETARG_POINTER(0) != NULL)
{
text *in = PG_GETARG_TEXT_P(0);
readstoplist(in, &(d->stoplist));
sortstoplist(&(d->stoplist));
PG_FREE_IF_COPY(in, 0);
}
d->z = english_create_env();
if (!d->z) {
if (!d->z)
{
freestoplist(&(d->stoplist));
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
@ -59,7 +66,8 @@ snb_en_init(PG_FUNCTION_ARGS) {
}
Datum
snb_ru_init(PG_FUNCTION_ARGS) {
snb_ru_init(PG_FUNCTION_ARGS)
{
DictSnowball *d = (DictSnowball *) malloc(sizeof(DictSnowball));
if (!d)
@ -69,15 +77,18 @@ snb_ru_init(PG_FUNCTION_ARGS) {
memset(d, 0, sizeof(DictSnowball));
d->stoplist.wordop = lowerstr;
if ( !PG_ARGISNULL(0) && PG_GETARG_POINTER(0)!=NULL ) {
if (!PG_ARGISNULL(0) && PG_GETARG_POINTER(0) != NULL)
{
text *in = PG_GETARG_TEXT_P(0);
readstoplist(in, &(d->stoplist));
sortstoplist(&(d->stoplist));
PG_FREE_IF_COPY(in, 0);
}
d->z = russian_create_env();
if (!d->z) {
if (!d->z)
{
freestoplist(&(d->stoplist));
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
@ -89,19 +100,24 @@ snb_ru_init(PG_FUNCTION_ARGS) {
}
Datum
snb_lexize(PG_FUNCTION_ARGS) {
snb_lexize(PG_FUNCTION_ARGS)
{
DictSnowball *d = (DictSnowball *) PG_GETARG_POINTER(0);
char *in = (char *) PG_GETARG_POINTER(1);
char *txt = pnstrdup(in, PG_GETARG_INT32(2));
char **res = palloc(sizeof(char *) * 2);
if ( *txt=='\0' || searchstoplist(&(d->stoplist),txt) ) {
if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
{
pfree(txt);
res[0] = NULL;
} else {
}
else
{
SN_set_current(d->z, strlen(txt), txt);
(d->stem) (d->z);
if ( d->z->p && d->z->l ) {
if (d->z->p && d->z->l)
{
txt = repalloc(txt, d->z->l + 1);
memcpy(txt, d->z->p, d->z->l);
txt[d->z->l] = '\0';
@ -113,4 +129,3 @@ snb_lexize(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(res);
}

View File

@ -13,23 +13,27 @@
#include "common.h"
#define SYNBUFLEN 4096
typedef struct {
typedef struct
{
char *in;
char *out;
} Syn;
typedef struct {
typedef struct
{
int len;
Syn *syn;
} DictSyn;
PG_FUNCTION_INFO_V1(syn_init);
Datum syn_init(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(syn_lexize);
Datum syn_lexize(PG_FUNCTION_ARGS);
static char *
findwrd(char *in, char **end) {
findwrd(char *in, char **end)
{
char *start;
*end = NULL;
@ -48,20 +52,24 @@ findwrd(char *in, char **end) {
}
static int
compareSyn(const void *a, const void *b) {
compareSyn(const void *a, const void *b)
{
return strcmp(((Syn *) a)->in, ((Syn *) b)->in);
}
Datum
syn_init(PG_FUNCTION_ARGS) {
syn_init(PG_FUNCTION_ARGS)
{
text *in;
DictSyn *d;
int cur = 0;
FILE *fin;
char *filename;
char buf[SYNBUFLEN];
char *starti,*starto,*end=NULL;
char *starti,
*starto,
*end = NULL;
int slen;
if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
@ -84,7 +92,8 @@ syn_init(PG_FUNCTION_ARGS) {
filename)));
d = (DictSyn *) malloc(sizeof(DictSyn));
if ( !d ) {
if (!d)
{
fclose(fin);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
@ -92,14 +101,18 @@ syn_init(PG_FUNCTION_ARGS) {
}
memset(d, 0, sizeof(DictSyn));
while( fgets(buf,SYNBUFLEN,fin) ) {
while (fgets(buf, SYNBUFLEN, fin))
{
slen = strlen(buf) - 1;
buf[slen] = '\0';
if ( *buf=='\0' ) continue;
if (cur==d->len) {
if (*buf == '\0')
continue;
if (cur == d->len)
{
d->len = (d->len) ? 2 * d->len : 16;
d->syn = (Syn *) realloc(d->syn, sizeof(Syn) * d->len);
if ( !d->syn ) {
if (!d->syn)
{
fclose(fin);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
@ -121,7 +134,8 @@ syn_init(PG_FUNCTION_ARGS) {
d->syn[cur].in = strdup(lowerstr(starti));
d->syn[cur].out = strdup(lowerstr(starto));
if ( !(d->syn[cur].in && d->syn[cur].out) ) {
if (!(d->syn[cur].in && d->syn[cur].out))
{
fclose(fin);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
@ -142,10 +156,12 @@ syn_init(PG_FUNCTION_ARGS) {
}
Datum
syn_lexize(PG_FUNCTION_ARGS) {
syn_lexize(PG_FUNCTION_ARGS)
{
DictSyn *d = (DictSyn *) PG_GETARG_POINTER(0);
char *in = (char *) PG_GETARG_POINTER(1);
Syn key,*found;
Syn key,
*found;
char **res = NULL;
if (!PG_GETARG_INT32(2))
@ -167,4 +183,3 @@ syn_lexize(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(res);
}

View File

@ -11,14 +11,19 @@
#define STRNCASECMP(x,y) (strncasecmp(x,y,strlen(y)))
static int cmpspell(const void *s1,const void *s2){
static int
cmpspell(const void *s1, const void *s2)
{
return (strcmp(((const SPELL *) s1)->word, ((const SPELL *) s2)->word));
}
static void
strlower( char * str ) {
strlower(char *str)
{
unsigned char *ptr = (unsigned char *) str;
while ( *ptr ) {
while (*ptr)
{
*ptr = tolower(*ptr);
ptr++;
}
@ -26,38 +31,60 @@ strlower( char * str ) {
/* backward string compaire for suffix tree operations */
static int
strbcmp(const char *s1, const char *s2) {
int l1 = strlen(s1)-1, l2 = strlen(s2)-1;
while (l1 >= 0 && l2 >= 0) {
if (s1[l1] < s2[l2]) return -1;
if (s1[l1] > s2[l2]) return 1;
l1--; l2--;
strbcmp(const char *s1, const char *s2)
{
int l1 = strlen(s1) - 1,
l2 = strlen(s2) - 1;
while (l1 >= 0 && l2 >= 0)
{
if (s1[l1] < s2[l2])
return -1;
if (s1[l1] > s2[l2])
return 1;
l1--;
l2--;
}
if (l1 < l2) return -1;
if (l1 > l2) return 1;
if (l1 < l2)
return -1;
if (l1 > l2)
return 1;
return 0;
}
static int
strbncmp(const char *s1, const char *s2, size_t count) {
int l1 = strlen(s1) - 1, l2 = strlen(s2) - 1, l = count;
while (l1 >= 0 && l2 >= 0 && l > 0) {
if (s1[l1] < s2[l2]) return -1;
if (s1[l1] > s2[l2]) return 1;
strbncmp(const char *s1, const char *s2, size_t count)
{
int l1 = strlen(s1) - 1,
l2 = strlen(s2) - 1,
l = count;
while (l1 >= 0 && l2 >= 0 && l > 0)
{
if (s1[l1] < s2[l2])
return -1;
if (s1[l1] > s2[l2])
return 1;
l1--;
l2--;
l--;
}
if (l == 0) return 0;
if (l1 < l2) return -1;
if (l1 > l2) return 1;
if (l == 0)
return 0;
if (l1 < l2)
return -1;
if (l1 > l2)
return 1;
return 0;
}
static int
cmpaffix(const void *s1,const void *s2){
if (((const AFFIX*)s1)->type < ((const AFFIX*)s2)->type) return -1;
if (((const AFFIX*)s1)->type > ((const AFFIX*)s2)->type) return 1;
cmpaffix(const void *s1, const void *s2)
{
if (((const AFFIX *) s1)->type < ((const AFFIX *) s2)->type)
return -1;
if (((const AFFIX *) s1)->type > ((const AFFIX *) s2)->type)
return 1;
if (((const AFFIX *) s1)->type == 'p')
return (strcmp(((const AFFIX *) s1)->repl, ((const AFFIX *) s2)->repl));
else
@ -65,12 +92,17 @@ cmpaffix(const void *s1,const void *s2){
}
int
AddSpell(IspellDict * Conf,const char * word,const char *flag){
if(Conf->nspell>=Conf->mspell){
if(Conf->mspell){
AddSpell(IspellDict * Conf, const char *word, const char *flag)
{
if (Conf->nspell >= Conf->mspell)
{
if (Conf->mspell)
{
Conf->mspell += 1024 * 20;
Conf->Spell = (SPELL *) realloc(Conf->Spell, Conf->mspell * sizeof(SPELL));
}else{
}
else
{
Conf->mspell = 1024 * 20;
Conf->Spell = (SPELL *) malloc(Conf->mspell * sizeof(SPELL));
}
@ -91,37 +123,47 @@ AddSpell(IspellDict * Conf,const char * word,const char *flag){
int
ImportDictionary(IspellDict * Conf,const char *filename){
ImportDictionary(IspellDict * Conf, const char *filename)
{
unsigned char str[BUFSIZ];
FILE *dict;
if(!(dict=fopen(filename,"r")))return(1);
while(fgets(str,sizeof(str),dict)){
if (!(dict = fopen(filename, "r")))
return (1);
while (fgets(str, sizeof(str), dict))
{
unsigned char *s;
const unsigned char *flag;
flag = NULL;
if((s=strchr(str,'/'))){
if ((s = strchr(str, '/')))
{
*s = 0;
s++;flag=s;
while(*s){
s++;
flag = s;
while (*s)
{
if (((*s >= 'A') && (*s <= 'Z')) || ((*s >= 'a') && (*s <= 'z')))
s++;
else {
else
{
*s = 0;
break;
}
}
}else{
flag="";
}
else
flag = "";
strlower(str);
/* Dont load words if first letter is not required */
/* It allows to optimize loading at search time */
s = str;
while(*s){
if(*s=='\r')*s=0;
if(*s=='\n')*s=0;
while (*s)
{
if (*s == '\r')
*s = 0;
if (*s == '\n')
*s = 0;
s++;
}
AddSpell(Conf, str, flag);
@ -132,37 +174,48 @@ ImportDictionary(IspellDict * Conf,const char *filename){
static SPELL *
FindWord(IspellDict * Conf, const char *word, int affixflag) {
int l,c,r,resc,resl,resr, i;
FindWord(IspellDict * Conf, const char *word, int affixflag)
{
int l,
c,
r,
resc,
resl,
resr,
i;
i = (int) (*word) & 255;
l = Conf->SpellTree.Left[i];
r = Conf->SpellTree.Right[i];
if (l == -1) return (NULL);
while(l<=r){
if (l == -1)
return (NULL);
while (l <= r)
{
c = (l + r) >> 1;
resc = strcmp(Conf->Spell[c].word, word);
if ((resc == 0) &&
((affixflag == 0) || (strchr(Conf->Spell[c].flag, affixflag) != NULL)) ) {
((affixflag == 0) || (strchr(Conf->Spell[c].flag, affixflag) != NULL)))
return (&Conf->Spell[c]);
}
resl = strcmp(Conf->Spell[l].word, word);
if ((resl == 0) &&
((affixflag == 0) || (strchr(Conf->Spell[l].flag, affixflag) != NULL)) ) {
((affixflag == 0) || (strchr(Conf->Spell[l].flag, affixflag) != NULL)))
return (&Conf->Spell[l]);
}
resr = strcmp(Conf->Spell[r].word, word);
if ((resr == 0) &&
((affixflag == 0) || (strchr(Conf->Spell[r].flag, affixflag) != NULL)) ) {
((affixflag == 0) || (strchr(Conf->Spell[r].flag, affixflag) != NULL)))
return (&Conf->Spell[r]);
}
if(resc < 0){
if (resc < 0)
{
l = c + 1;
r--;
} else if(resc > 0){
}
else if (resc > 0)
{
r = c - 1;
l++;
} else {
}
else
{
l++;
r--;
}
@ -171,12 +224,17 @@ FindWord(IspellDict * Conf, const char *word, int affixflag) {
}
int
AddAffix(IspellDict * Conf,int flag,const char *mask,const char *find,const char *repl,int type) {
if(Conf->naffixes>=Conf->maffixes){
if(Conf->maffixes){
AddAffix(IspellDict * Conf, int flag, const char *mask, const char *find, const char *repl, int type)
{
if (Conf->naffixes >= Conf->maffixes)
{
if (Conf->maffixes)
{
Conf->maffixes += 16;
Conf->Affix = (AFFIX *) realloc((void *) Conf->Affix, Conf->maffixes * sizeof(AFFIX));
}else{
}
else
{
Conf->maffixes = 16;
Conf->Affix = (AFFIX *) malloc(Conf->maffixes * sizeof(AFFIX));
}
@ -185,11 +243,10 @@ AddAffix(IspellDict * Conf,int flag,const char *mask,const char *find,const char
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
}
if (type=='s') {
if (type == 's')
sprintf(Conf->Affix[Conf->naffixes].mask, "%s$", mask);
} else {
else
sprintf(Conf->Affix[Conf->naffixes].mask, "^%s", mask);
}
Conf->Affix[Conf->naffixes].compile = 1;
Conf->Affix[Conf->naffixes].flag = flag;
Conf->Affix[Conf->naffixes].type = type;
@ -202,12 +259,17 @@ AddAffix(IspellDict * Conf,int flag,const char *mask,const char *find,const char
}
static char *
remove_spaces(char *dist,char *src){
char *d,*s;
remove_spaces(char *dist, char *src)
{
char *d,
*s;
d = dist;
s = src;
while(*s){
if(*s!=' '&&*s!='-'&&*s!='\t'){
while (*s)
{
if (*s != ' ' && *s != '-' && *s != '\t')
{
*d = *s;
d++;
}
@ -219,7 +281,8 @@ char *d,*s;
int
ImportAffixes(IspellDict * Conf,const char *filename){
ImportAffixes(IspellDict * Conf, const char *filename)
{
unsigned char str[BUFSIZ];
unsigned char flag = 0;
unsigned char mask[BUFSIZ] = "";
@ -234,40 +297,52 @@ ImportAffixes(IspellDict * Conf,const char *filename){
if (!(affix = fopen(filename, "r")))
return (1);
while(fgets(str,sizeof(str),affix)){
if(!STRNCASECMP(str,"suffixes")){
while (fgets(str, sizeof(str), affix))
{
if (!STRNCASECMP(str, "suffixes"))
{
suffixes = 1;
prefixes = 0;
continue;
}
if(!STRNCASECMP(str,"prefixes")){
if (!STRNCASECMP(str, "prefixes"))
{
suffixes = 0;
prefixes = 1;
continue;
}
if(!STRNCASECMP(str,"flag ")){
if (!STRNCASECMP(str, "flag "))
{
s = str + 5;
while (strchr("* ", *s))
s++;
flag = *s;
continue;
}
if((!suffixes)&&(!prefixes))continue;
if((s=strchr(str,'#')))*s=0;
if(!*str)continue;
if ((!suffixes) && (!prefixes))
continue;
if ((s = strchr(str, '#')))
*s = 0;
if (!*str)
continue;
strlower(str);
strcpy(mask, "");
strcpy(find, "");
strcpy(repl, "");
i = sscanf(str, "%[^>\n]>%[^,\n],%[^\n]", mask, find, repl);
remove_spaces(str,repl);strcpy(repl,str);
remove_spaces(str,find);strcpy(find,str);
remove_spaces(str,mask);strcpy(mask,str);
switch(i){
remove_spaces(str, repl);
strcpy(repl, str);
remove_spaces(str, find);
strcpy(find, str);
remove_spaces(str, mask);
strcpy(mask, str);
switch (i)
{
case 3:
break;
case 2:
if(*find != '\0'){
if (*find != '\0')
{
strcpy(repl, find);
strcpy(find, "");
}
@ -285,17 +360,22 @@ ImportAffixes(IspellDict * Conf,const char *filename){
}
void
SortDictionary(IspellDict * Conf){
int CurLet = -1, Let;size_t i;
SortDictionary(IspellDict * Conf)
{
int CurLet = -1,
Let;
size_t i;
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL), cmpspell);
for (i = 0; i < 256; i++)
Conf->SpellTree.Left[i] = -1;
for(i = 0; i < Conf->nspell; i++) {
for (i = 0; i < Conf->nspell; i++)
{
Let = (int) (*(Conf->Spell[i].word)) & 255;
if (CurLet != Let) {
if (CurLet != Let)
{
Conf->SpellTree.Left[Let] = i;
CurLet = Let;
}
@ -304,29 +384,40 @@ SortDictionary(IspellDict * Conf){
}
void
SortAffixes(IspellDict * Conf) {
int CurLetP = -1, CurLetS = -1, Let;
AFFIX *Affix; size_t i;
SortAffixes(IspellDict * Conf)
{
int CurLetP = -1,
CurLetS = -1,
Let;
AFFIX *Affix;
size_t i;
if (Conf->naffixes > 1)
qsort((void *) Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
for(i = 0; i < 256; i++) {
for (i = 0; i < 256; i++)
{
Conf->PrefixTree.Left[i] = Conf->PrefixTree.Right[i] = -1;
Conf->SuffixTree.Left[i] = Conf->SuffixTree.Right[i] = -1;
}
for(i = 0; i < Conf->naffixes; i++) {
for (i = 0; i < Conf->naffixes; i++)
{
Affix = &(((AFFIX *) Conf->Affix)[i]);
if(Affix->type == 'p') {
if (Affix->type == 'p')
{
Let = (int) (*(Affix->repl)) & 255;
if (CurLetP != Let) {
if (CurLetP != Let)
{
Conf->PrefixTree.Left[Let] = i;
CurLetP = Let;
}
Conf->PrefixTree.Right[Let] = i;
} else {
}
else
{
Let = (Affix->replen) ? (int) (Affix->repl[Affix->replen - 1]) & 255 : 0;
if (CurLetS != Let) {
if (CurLetS != Let)
{
Conf->SuffixTree.Left[Let] = i;
CurLetS = Let;
}
@ -336,31 +427,33 @@ SortAffixes(IspellDict * Conf) {
}
static char *
CheckSuffix(const char *word, size_t len, AFFIX *Affix, int *res, IspellDict *Conf) {
CheckSuffix(const char *word, size_t len, AFFIX * Affix, int *res, IspellDict * Conf)
{
regmatch_t subs[2]; /* workaround for apache&linux */
char newword[2 * MAXNORMLEN] = "";
int err;
*res = strbncmp(word, Affix->repl, Affix->replen);
if (*res < 0) {
if (*res < 0)
return NULL;
}
if (*res > 0) {
if (*res > 0)
return NULL;
}
strcpy(newword, word);
strcpy(newword + len - Affix->replen, Affix->find);
if (Affix->compile) {
if (Affix->compile)
{
err = regcomp(&(Affix->reg), Affix->mask, REG_EXTENDED | REG_ICASE | REG_NOSUB);
if(err){
if (err)
{
/* regerror(err, &(Affix->reg), regerrstr, ERRSTRSIZE); */
regfree(&(Affix->reg));
return (NULL);
}
Affix->compile = 0;
}
if(!(err=regexec(&(Affix->reg),newword,1,subs,0))){
if (!(err = regexec(&(Affix->reg), newword, 1, subs, 0)))
{
if (FindWord(Conf, newword, Affix->flag))
return pstrdup(newword);
}
@ -371,44 +464,56 @@ CheckSuffix(const char *word, size_t len, AFFIX *Affix, int *res, IspellDict *Co
#define MAX_NORM 512
static int
CheckPrefix(const char *word, size_t len, AFFIX * Affix, IspellDict * Conf, int pi,
char **forms, char ***cur ) {
char **forms, char ***cur)
{
regmatch_t subs[NS * 2];
char newword[2 * MAXNORMLEN] = "";
int err, ls, res, lres;
int err,
ls,
res,
lres;
size_t newlen;
AFFIX *CAffix = Conf->Affix;
res = strncmp(word, Affix->repl, Affix->replen);
if (res != 0) {
if (res != 0)
return res;
}
strcpy(newword, Affix->find);
strcat(newword, word + Affix->replen);
if (Affix->compile) {
if (Affix->compile)
{
err = regcomp(&(Affix->reg), Affix->mask, REG_EXTENDED | REG_ICASE | REG_NOSUB);
if(err){
if (err)
{
/* regerror(err, &(Affix->reg), regerrstr, ERRSTRSIZE); */
regfree(&(Affix->reg));
return (0);
}
Affix->compile = 0;
}
if(!(err=regexec(&(Affix->reg),newword,1,subs,0))){
if (!(err = regexec(&(Affix->reg), newword, 1, subs, 0)))
{
SPELL *curspell;
if((curspell=FindWord(Conf, newword, Affix->flag))){
if ((*cur - forms) < (MAX_NORM-1)) {
if ((curspell = FindWord(Conf, newword, Affix->flag)))
{
if ((*cur - forms) < (MAX_NORM - 1))
{
**cur = pstrdup(newword);
(*cur)++; **cur = NULL;
(*cur)++;
**cur = NULL;
}
}
newlen = strlen(newword);
ls = Conf->SuffixTree.Left[pi];
if ( ls>=0 && ((*cur - forms) < (MAX_NORM-1)) ) {
if (ls >= 0 && ((*cur - forms) < (MAX_NORM - 1)))
{
**cur = CheckSuffix(newword, newlen, &CAffix[ls], &lres, Conf);
if (**cur) {
(*cur)++; **cur = NULL;
if (**cur)
{
(*cur)++;
**cur = NULL;
}
}
}
@ -417,14 +522,24 @@ CheckPrefix(const char *word, size_t len, AFFIX *Affix, IspellDict *Conf, int pi
char **
NormalizeWord(IspellDict * Conf,char *word){
NormalizeWord(IspellDict * Conf, char *word)
{
/*regmatch_t subs[NS];*/
size_t len;
char **forms;
char **cur;
AFFIX *Affix;
int ri, pi, ipi, lp, rp, cp, ls, rs;
int lres, rres, cres = 0;
int ri,
pi,
ipi,
lp,
rp,
cp,
ls,
rs;
int lres,
rres,
cres = 0;
SPELL *spell;
len = strlen(word);
@ -434,44 +549,51 @@ int lres, rres, cres = 0;
strlower(word);
forms = (char **) palloc(MAX_NORM * sizeof(char **));
cur=forms;*cur=NULL;
cur = forms;
*cur = NULL;
ri = (int) (*word) & 255;
pi = (int) (word[strlen(word) - 1]) & 255;
Affix = (AFFIX *) Conf->Affix;
/* Check that the word itself is normal form */
if((spell = FindWord(Conf, word, 0))){
if ((spell = FindWord(Conf, word, 0)))
{
*cur = pstrdup(word);
cur++;*cur=NULL;
cur++;
*cur = NULL;
}
/* Find all other NORMAL forms of the 'word' */
for (ipi = 0; ipi <= pi; ipi += pi) {
for (ipi = 0; ipi <= pi; ipi += pi)
{
/* check prefix */
lp = Conf->PrefixTree.Left[ri];
rp = Conf->PrefixTree.Right[ri];
while (lp >= 0 && lp <= rp) {
while (lp >= 0 && lp <= rp)
{
cp = (lp + rp) >> 1;
cres = 0;
if ((cur - forms) < (MAX_NORM-1)) {
if ((cur - forms) < (MAX_NORM - 1))
cres = CheckPrefix(word, len, &Affix[cp], Conf, ipi, forms, &cur);
}
if ((lp < cp) && ((cur - forms) < (MAX_NORM-1)) ) {
if ((lp < cp) && ((cur - forms) < (MAX_NORM - 1)))
lres = CheckPrefix(word, len, &Affix[lp], Conf, ipi, forms, &cur);
}
if ( (rp > cp) && ((cur - forms) < (MAX_NORM-1)) ) {
if ((rp > cp) && ((cur - forms) < (MAX_NORM - 1)))
rres = CheckPrefix(word, len, &Affix[rp], Conf, ipi, forms, &cur);
}
if (cres < 0) {
if (cres < 0)
{
rp = cp - 1;
lp++;
} else if (cres > 0) {
}
else if (cres > 0)
{
lp = cp + 1;
rp--;
} else {
}
else
{
lp++;
rp--;
}
@ -480,17 +602,24 @@ int lres, rres, cres = 0;
/* check suffix */
ls = Conf->SuffixTree.Left[ipi];
rs = Conf->SuffixTree.Right[ipi];
while (ls >= 0 && ls <= rs) {
if ( ((cur - forms) < (MAX_NORM-1)) ) {
while (ls >= 0 && ls <= rs)
{
if (((cur - forms) < (MAX_NORM - 1)))
{
*cur = CheckSuffix(word, len, &Affix[ls], &lres, Conf);
if (*cur) {
cur++; *cur = NULL;
if (*cur)
{
cur++;
*cur = NULL;
}
}
if ( (rs > ls) && ((cur - forms) < (MAX_NORM-1)) ) {
if ((rs > ls) && ((cur - forms) < (MAX_NORM - 1)))
{
*cur = CheckSuffix(word, len, &Affix[rs], &rres, Conf);
if (*cur) {
cur++; *cur = NULL;
if (*cur)
{
cur++;
*cur = NULL;
}
}
ls++;
@ -499,7 +628,8 @@ int lres, rres, cres = 0;
} /* for ipi */
if(cur==forms){
if (cur == forms)
{
pfree(forms);
return (NULL);
}
@ -507,18 +637,18 @@ int lres, rres, cres = 0;
}
void
FreeIspell (IspellDict *Conf) {
FreeIspell(IspellDict * Conf)
{
int i;
AFFIX *Affix = (AFFIX *) Conf->Affix;
for (i = 0; i < Conf->naffixes; i++) {
if (Affix[i].compile == 0) {
for (i = 0; i < Conf->naffixes; i++)
{
if (Affix[i].compile == 0)
regfree(&(Affix[i].reg));
}
}
for (i = 0; i < Conf->naffixes; i++) {
for (i = 0; i < Conf->naffixes; i++)
free(Conf->Spell[i].word);
}
free(Conf->Affix);
free(Conf->Spell);
memset((void *) Conf, 0, sizeof(IspellDict));

View File

@ -4,12 +4,14 @@
#include <sys/types.h>
#include <regex.h>
typedef struct spell_struct {
typedef struct spell_struct
{
char *word;
char flag[10];
} SPELL;
typedef struct aff_struct {
typedef struct aff_struct
{
char flag;
char type;
char mask[33];
@ -20,11 +22,14 @@ typedef struct aff_struct {
char compile;
} AFFIX;
typedef struct Tree_struct {
int Left[256], Right[256];
typedef struct Tree_struct
{
int Left[256],
Right[256];
} Tree_struct;
typedef struct {
typedef struct
{
int maffixes;
int naffixes;
AFFIX *Affix;

View File

@ -22,15 +22,21 @@
#define CS_IN2ESC 8
static char *
nstrdup(char *ptr, int len) {
char *res=palloc(len+1), *cptr;
nstrdup(char *ptr, int len)
{
char *res = palloc(len + 1),
*cptr;
memcpy(res, ptr, len);
res[len] = '\0';
cptr = ptr = res;
while(*ptr) {
while (*ptr)
{
if (*ptr == '\\')
ptr++;
*cptr=*ptr; ptr++; cptr++;
*cptr = *ptr;
ptr++;
cptr++;
}
*cptr = '\0';
@ -38,45 +44,61 @@ nstrdup(char *ptr, int len) {
}
void
parse_cfgdict(text *in, Map **m) {
parse_cfgdict(text *in, Map ** m)
{
Map *mptr;
char *ptr=VARDATA(in), *begin=NULL;
char *ptr = VARDATA(in),
*begin = NULL;
char num = 0;
int state = CS_WAITKEY;
while( ptr-VARDATA(in) < VARSIZE(in) - VARHDRSZ ) {
if ( *ptr==',' ) num++;
while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
{
if (*ptr == ',')
num++;
ptr++;
}
*m = mptr = (Map *) palloc(sizeof(Map) * (num + 2));
memset(mptr, 0, sizeof(Map) * (num + 2));
ptr = VARDATA(in);
while( ptr-VARDATA(in) < VARSIZE(in) - VARHDRSZ ) {
if (state==CS_WAITKEY) {
if (isalpha(*ptr)) {
while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
{
if (state == CS_WAITKEY)
{
if (isalpha(*ptr))
{
begin = ptr;
state = CS_INKEY;
} else if ( !isspace(*ptr) )
}
else if (!isspace(*ptr))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Syntax error in position %d near \"%c\"",
(int) (ptr - VARDATA(in)), *ptr)));
} else if (state==CS_INKEY) {
if ( isspace(*ptr) ) {
}
else if (state == CS_INKEY)
{
if (isspace(*ptr))
{
mptr->key = nstrdup(begin, ptr - begin);
state = CS_WAITEQ;
} else if ( *ptr=='=' ) {
}
else if (*ptr == '=')
{
mptr->key = nstrdup(begin, ptr - begin);
state = CS_WAITVALUE;
} else if ( !isalpha(*ptr) )
}
else if (!isalpha(*ptr))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Syntax error in position %d near \"%c\"",
(int) (ptr - VARDATA(in)), *ptr)));
} else if ( state==CS_WAITEQ ) {
}
else if (state == CS_WAITEQ)
{
if (*ptr == '=')
state = CS_WAITVALUE;
else if (!isspace(*ptr))
@ -85,29 +107,44 @@ parse_cfgdict(text *in, Map **m) {
errmsg("syntax error"),
errdetail("Syntax error in position %d near \"%c\"",
(int) (ptr - VARDATA(in)), *ptr)));
} else if ( state==CS_WAITVALUE ) {
if ( *ptr=='"' ) {
}
else if (state == CS_WAITVALUE)
{
if (*ptr == '"')
{
begin = ptr + 1;
state = CS_INVALUE;
} else if ( !isspace(*ptr) ) {
}
else if (!isspace(*ptr))
{
begin = ptr;
state = CS_IN2VALUE;
}
} else if ( state==CS_INVALUE ) {
if ( *ptr=='"' ) {
}
else if (state == CS_INVALUE)
{
if (*ptr == '"')
{
mptr->value = nstrdup(begin, ptr - begin);
mptr++;
state = CS_WAITDELIM;
} else if ( *ptr=='\\' )
}
else if (*ptr == '\\')
state = CS_INESC;
} else if ( state==CS_IN2VALUE ) {
if ( isspace(*ptr) || *ptr==',' ) {
}
else if (state == CS_IN2VALUE)
{
if (isspace(*ptr) || *ptr == ',')
{
mptr->value = nstrdup(begin, ptr - begin);
mptr++;
state = (*ptr == ',') ? CS_WAITKEY : CS_WAITDELIM;
} else if ( *ptr=='\\' )
}
else if (*ptr == '\\')
state = CS_INESC;
} else if ( state==CS_WAITDELIM ) {
}
else if (state == CS_WAITDELIM)
{
if (*ptr == ',')
state = CS_WAITKEY;
else if (!isspace(*ptr))
@ -116,11 +153,12 @@ parse_cfgdict(text *in, Map **m) {
errmsg("syntax error"),
errdetail("Syntax error in position %d near \"%c\"",
(int) (ptr - VARDATA(in)), *ptr)));
} else if ( state == CS_INESC ) {
}
else if (state == CS_INESC)
state = CS_INVALUE;
} else if ( state == CS_IN2ESC ) {
else if (state == CS_IN2ESC)
state = CS_IN2VALUE;
} else
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad parser state"),
@ -129,13 +167,13 @@ parse_cfgdict(text *in, Map **m) {
ptr++;
}
if (state==CS_IN2VALUE) {
if (state == CS_IN2VALUE)
{
mptr->value = nstrdup(begin, ptr - begin);
mptr++;
} else if ( !(state==CS_WAITDELIM || state==CS_WAITKEY) )
}
else if (!(state == CS_WAITDELIM || state == CS_WAITKEY))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unexpected end of line")));
}

View File

@ -103,20 +103,32 @@ typedef struct
} QPRS_STATE;
static char *
get_weight(char *buf, int2 *weight) {
get_weight(char *buf, int2 *weight)
{
*weight = 0;
if (*buf != ':')
return buf;
buf++;
while( *buf ) {
switch(tolower(*buf)) {
case 'a': *weight |= 1<<3; break;
case 'b': *weight |= 1<<2; break;
case 'c': *weight |= 1<<1; break;
case 'd': *weight |= 1; break;
default: return buf;
while (*buf)
{
switch (tolower(*buf))
{
case 'a':
*weight |= 1 << 3;
break;
case 'b':
*weight |= 1 << 2;
break;
case 'c':
*weight |= 1 << 1;
break;
case 'd':
*weight |= 1;
break;
default:
return buf;
}
buf++;
}
@ -146,11 +158,15 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, int2
state->count++;
(state->buf)++;
return OPEN;
} else if ( *(state->buf) == ':' ) {
}
else if (*(state->buf) == ':')
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("error at start of operand")));
} else if (*(state->buf) != ' ') {
}
else if (*(state->buf) != ' ')
{
state->valstate.prsbuf = state->buf;
state->state = WAITOPERATOR;
if (gettoken_tsvector(&(state->valstate)))
@ -266,7 +282,8 @@ pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval, int2 we
parsetext_v2(findcfg(state->cfg_id), &prs, strval, lenval);
for(count=0;count<prs.curwords;count++) {
for (count = 0; count < prs.curwords; count++)
{
pushval_asis(state, VAL, prs.words[count].word, prs.words[count].len, weight);
pfree(prs.words[count].word);
if (count)
@ -381,10 +398,13 @@ ValCompare(CHKVAL * chkval, WordEntry * ptr, ITEM * item)
* check weight info
*/
static bool
checkclass_str(CHKVAL * chkval, WordEntry * val, ITEM * item) {
checkclass_str(CHKVAL * chkval, WordEntry * val, ITEM * item)
{
WordEntryPos *ptr = (WordEntryPos *) (chkval->values + val->pos + SHORTALIGN(val->len) + sizeof(uint16));
uint16 len = *((uint16 *) (chkval->values + val->pos + SHORTALIGN(val->len)));
while (len--) {
while (len--)
{
if (item->weight & (1 << ptr->weight))
return true;
ptr++;
@ -678,12 +698,30 @@ infix(INFIX * in, bool first)
}
*(in->cur) = '\'';
in->cur++;
if ( in->curpol->weight ) {
*(in->cur) = ':'; in->cur++;
if ( in->curpol->weight & (1<<3) ) { *(in->cur) = 'A'; in->cur++; }
if ( in->curpol->weight & (1<<2) ) { *(in->cur) = 'B'; in->cur++; }
if ( in->curpol->weight & (1<<1) ) { *(in->cur) = 'C'; in->cur++; }
if ( in->curpol->weight & 1 ) { *(in->cur) = 'D'; in->cur++; }
if (in->curpol->weight)
{
*(in->cur) = ':';
in->cur++;
if (in->curpol->weight & (1 << 3))
{
*(in->cur) = 'A';
in->cur++;
}
if (in->curpol->weight & (1 << 2))
{
*(in->cur) = 'B';
in->cur++;
}
if (in->curpol->weight & (1 << 1))
{
*(in->cur) = 'C';
in->cur++;
}
if (in->curpol->weight & 1)
{
*(in->cur) = 'D';
in->cur++;
}
}
*(in->cur) = '\0';
in->curpol++;
@ -827,7 +865,8 @@ tsquerytree(PG_FUNCTION_ARGS)
}
Datum
to_tsquery(PG_FUNCTION_ARGS) {
to_tsquery(PG_FUNCTION_ARGS)
{
text *in = PG_GETARG_TEXT_P(1);
char *str;
QUERYTYPE *query;
@ -851,7 +890,8 @@ to_tsquery(PG_FUNCTION_ARGS) {
}
Datum
to_tsquery_name(PG_FUNCTION_ARGS) {
to_tsquery_name(PG_FUNCTION_ARGS)
{
text *name = PG_GETARG_TEXT_P(0);
Datum res = DirectFunctionCall2(
to_tsquery,
@ -864,12 +904,11 @@ to_tsquery_name(PG_FUNCTION_ARGS) {
}
Datum
to_tsquery_current(PG_FUNCTION_ARGS) {
to_tsquery_current(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall2(
to_tsquery,
Int32GetDatum(get_currcfg()),
PG_GETARG_DATUM(0)
));
}

View File

@ -46,7 +46,9 @@ static float weights[]={0.1, 0.2, 0.4, 1.0};
/*
* Returns a weight of a word collocation
*/
static float4 word_distance ( int4 w ) {
static float4
word_distance(int4 w)
{
if (w > 100)
return 1e-30;
@ -54,11 +56,15 @@ static float4 word_distance ( int4 w ) {
}
static int
cnt_length( tsvector *t ) {
WordEntry *ptr=ARRPTR(t), *end=(WordEntry*)STRPTR(t);
int len = 0, clen;
cnt_length(tsvector * t)
{
WordEntry *ptr = ARRPTR(t),
*end = (WordEntry *) STRPTR(t);
int len = 0,
clen;
while(ptr < end) {
while (ptr < end)
{
if ((clen = POSDATALEN(t, ptr)) == 0)
len += 1;
else
@ -70,7 +76,8 @@ cnt_length( tsvector *t ) {
}
static int4
WordECompareITEM(char *eval, char *qval, WordEntry * ptr, ITEM * item) {
WordECompareITEM(char *eval, char *qval, WordEntry * ptr, ITEM * item)
{
if (ptr->len == item->length)
return strncmp(
eval + ptr->pos,
@ -81,7 +88,8 @@ WordECompareITEM(char *eval, char *qval, WordEntry * ptr, ITEM * item) {
}
static WordEntry *
find_wordentry(tsvector *t, QUERYTYPE *q, ITEM *item) {
find_wordentry(tsvector * t, QUERYTYPE * q, ITEM * item)
{
WordEntry *StopLow = ARRPTR(t);
WordEntry *StopHigh = (WordEntry *) STRPTR(t);
WordEntry *StopMiddle;
@ -110,19 +118,27 @@ static WordEntryPos POSNULL[]={
};
static float
calc_rank_and(float *w, tsvector *t, QUERYTYPE *q) {
calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
{
uint16 **pos = (uint16 **) palloc(sizeof(uint16 *) * q->size);
int i,k,l,p;
int i,
k,
l,
p;
WordEntry *entry;
WordEntryPos *post,*ct;
int4 dimt,lenct,dist;
WordEntryPos *post,
*ct;
int4 dimt,
lenct,
dist;
float res = -1.0;
ITEM *item = GETQUERY(q);
memset(pos, 0, sizeof(uint16 **) * q->size);
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
for(i=0; i<q->size; i++) {
for (i = 0; i < q->size; i++)
{
if (item[i].type != VAL)
continue;
@ -139,16 +155,23 @@ calc_rank_and(float *w, tsvector *t, QUERYTYPE *q) {
dimt = *(uint16 *) (pos[i]);
post = (WordEntryPos *) (pos[i] + 1);
for( k=0; k<i; k++ ) {
if ( !pos[k] ) continue;
for (k = 0; k < i; k++)
{
if (!pos[k])
continue;
lenct = *(uint16 *) (pos[k]);
ct = (WordEntryPos *) (pos[k] + 1);
for(l=0; l<dimt; l++) {
for(p=0; p<lenct; p++) {
for (l = 0; l < dimt; l++)
{
for (p = 0; p < lenct; p++)
{
dist = abs(post[l].pos - ct[p].pos);
if ( dist || (dist==0 && (pos[i]==(uint16*)POSNULL || pos[k]==(uint16*)POSNULL) ) ) {
if (dist || (dist == 0 && (pos[i] == (uint16 *) POSNULL || pos[k] == (uint16 *) POSNULL)))
{
float curw;
if ( !dist ) dist=MAXENTRYPOS;
if (!dist)
dist = MAXENTRYPOS;
curw = sqrt(wpos(&(post[l])) * wpos(&(ct[p])) * word_distance(dist));
res = (res < 0) ? curw : 1.0 - (1.0 - res) * (1.0 - curw);
}
@ -161,16 +184,20 @@ calc_rank_and(float *w, tsvector *t, QUERYTYPE *q) {
}
static float
calc_rank_or(float *w, tsvector *t, QUERYTYPE *q) {
calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
{
WordEntry *entry;
WordEntryPos *post;
int4 dimt,j,i;
int4 dimt,
j,
i;
float res = -1.0;
ITEM *item = GETQUERY(q);
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
for(i=0; i<q->size; i++) {
for (i = 0; i < q->size; i++)
{
if (item[i].type != VAL)
continue;
@ -178,15 +205,19 @@ calc_rank_or(float *w, tsvector *t, QUERYTYPE *q) {
if (!entry)
continue;
if ( entry->haspos ) {
if (entry->haspos)
{
dimt = POSDATALEN(t, entry);
post = POSDATAPTR(t, entry);
} else {
}
else
{
dimt = *(uint16 *) POSNULL;
post = POSNULL + 1;
}
for(j=0;j<dimt;j++) {
for (j = 0; j < dimt; j++)
{
if (res < 0)
res = wpos(&(post[j]));
else
@ -197,7 +228,8 @@ calc_rank_or(float *w, tsvector *t, QUERYTYPE *q) {
}
static float
calc_rank(float *w, tsvector *t, QUERYTYPE *q, int4 method) {
calc_rank(float *w, tsvector * t, QUERYTYPE * q, int4 method)
{
ITEM *item = GETQUERY(q);
float res = 0.0;
@ -210,10 +242,16 @@ calc_rank(float *w, tsvector *t, QUERYTYPE *q, int4 method) {
if (res < 0)
res = 1e-20;
switch(method) {
case 0: break;
case 1: res /= log((float)cnt_length(t)); break;
case 2: res /= (float)cnt_length(t); break;
switch (method)
{
case 0:
break;
case 1:
res /= log((float) cnt_length(t));
break;
case 2:
res /= (float) cnt_length(t);
break;
default:
/* internal error */
elog(ERROR, "unrecognized normalization method: %d", method);
@ -223,7 +261,8 @@ calc_rank(float *w, tsvector *t, QUERYTYPE *q, int4 method) {
}
Datum
rank(PG_FUNCTION_ARGS) {
rank(PG_FUNCTION_ARGS)
{
ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(2));
@ -242,7 +281,8 @@ rank(PG_FUNCTION_ARGS) {
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("array of weight is too short")));
for(i=0;i<lengthof(weights);i++) {
for (i = 0; i < lengthof(weights); i++)
{
ws[i] = (((float4 *) ARR_DATA_PTR(win))[i] >= 0) ? ((float4 *) ARR_DATA_PTR(win))[i] : weights[i];
if (ws[i] > 1.0)
ereport(ERROR,
@ -262,7 +302,8 @@ rank(PG_FUNCTION_ARGS) {
}
Datum
rank_def(PG_FUNCTION_ARGS) {
rank_def(PG_FUNCTION_ARGS)
{
tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
float res = 0.0;
@ -279,29 +320,34 @@ rank_def(PG_FUNCTION_ARGS) {
}
typedef struct {
typedef struct
{
ITEM *item;
int32 pos;
} DocRepresentation;
static int
compareDocR(const void *a, const void *b) {
compareDocR(const void *a, const void *b)
{
if (((DocRepresentation *) a)->pos == ((DocRepresentation *) b)->pos)
return 1;
return (((DocRepresentation *) a)->pos > ((DocRepresentation *) b)->pos) ? 1 : -1;
}
typedef struct {
typedef struct
{
DocRepresentation *doc;
int len;
} ChkDocR;
static bool
checkcondition_DR(void *checkval, ITEM *val) {
checkcondition_DR(void *checkval, ITEM * val)
{
DocRepresentation *ptr = ((ChkDocR *) checkval)->doc;
while( ptr - ((ChkDocR*)checkval)->doc < ((ChkDocR*)checkval)->len ) {
while (ptr - ((ChkDocR *) checkval)->doc < ((ChkDocR *) checkval)->len)
{
if (val == ptr->item)
return true;
ptr++;
@ -312,9 +358,11 @@ checkcondition_DR(void *checkval, ITEM *val) {
static bool
Cover(DocRepresentation *doc, int len, QUERYTYPE *query, int *pos, int *p, int *q) {
Cover(DocRepresentation * doc, int len, QUERYTYPE * query, int *pos, int *p, int *q)
{
int i;
DocRepresentation *ptr,*f=(DocRepresentation*)0xffffffff;
DocRepresentation *ptr,
*f = (DocRepresentation *) 0xffffffff;
ITEM *item = GETQUERY(query);
int lastpos = *pos;
int oldq = *q;
@ -322,16 +370,21 @@ Cover(DocRepresentation *doc, int len, QUERYTYPE *query, int *pos, int *p, int *
*p = 0x7fffffff;
*q = 0;
for(i=0; i<query->size; i++) {
if ( item->type != VAL ) {
for (i = 0; i < query->size; i++)
{
if (item->type != VAL)
{
item++;
continue;
}
ptr = doc + *pos;
while(ptr-doc<len) {
if ( ptr->item == item ) {
if ( ptr->pos > *q ) {
while (ptr - doc < len)
{
if (ptr->item == item)
{
if (ptr->pos > *q)
{
*q = ptr->pos;
lastpos = ptr - doc;
}
@ -346,22 +399,28 @@ Cover(DocRepresentation *doc, int len, QUERYTYPE *query, int *pos, int *p, int *
if (*q == 0)
return false;
if (*q==oldq) { /* already check this pos */
if (*q == oldq)
{ /* already check this pos */
(*pos)++;
return Cover(doc, len, query, pos, p, q);
}
item = GETQUERY(query);
for(i=0; i<query->size; i++) {
if ( item->type != VAL ) {
for (i = 0; i < query->size; i++)
{
if (item->type != VAL)
{
item++;
continue;
}
ptr = doc + lastpos;
while(ptr>=doc+*pos) {
if ( ptr->item == item ) {
if ( ptr->pos < *p ) {
while (ptr >= doc + *pos)
{
if (ptr->item == item)
{
if (ptr->pos < *p)
{
*p = ptr->pos;
f = ptr;
}
@ -372,13 +431,20 @@ Cover(DocRepresentation *doc, int len, QUERYTYPE *query, int *pos, int *p, int *
item++;
}
if ( *p<=*q ) {
if (*p <= *q)
{
ChkDocR ch = {f, (doc + lastpos) - f + 1};
*pos = f - doc + 1;
if ( TS_execute(GETQUERY(query), &ch, false, checkcondition_DR) ) {
/*elog(NOTICE,"OP:%d NP:%d P:%d Q:%d", *pos, lastpos, *p, *q);*/
if (TS_execute(GETQUERY(query), &ch, false, checkcondition_DR))
{
/*
* elog(NOTICE,"OP:%d NP:%d P:%d Q:%d", *pos, lastpos, *p,
* *q);
*/
return true;
} else
}
else
return Cover(doc, len, query, pos, p, q);
}
@ -386,17 +452,22 @@ Cover(DocRepresentation *doc, int len, QUERYTYPE *query, int *pos, int *p, int *
}
static DocRepresentation *
get_docrep(tsvector *txt, QUERYTYPE *query, int *doclen) {
get_docrep(tsvector * txt, QUERYTYPE * query, int *doclen)
{
ITEM *item = GETQUERY(query);
WordEntry *entry;
WordEntryPos *post;
int4 dimt,j,i;
int len=query->size*4,cur=0;
int4 dimt,
j,
i;
int len = query->size * 4,
cur = 0;
DocRepresentation *doc;
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
doc = (DocRepresentation *) palloc(sizeof(DocRepresentation) * len);
for(i=0; i<query->size; i++) {
for (i = 0; i < query->size; i++)
{
if (item[i].type != VAL)
continue;
@ -404,20 +475,25 @@ get_docrep(tsvector *txt, QUERYTYPE *query, int *doclen) {
if (!entry)
continue;
if ( entry->haspos ) {
if (entry->haspos)
{
dimt = POSDATALEN(txt, entry);
post = POSDATAPTR(txt, entry);
} else {
}
else
{
dimt = *(uint16 *) POSNULL;
post = POSNULL + 1;
}
while( cur+dimt >= len ) {
while (cur + dimt >= len)
{
len *= 2;
doc = (DocRepresentation *) repalloc(doc, sizeof(DocRepresentation) * len);
}
for(j=0;j<dimt;j++) {
for (j = 0; j < dimt; j++)
{
doc[cur].item = &(item[i]);
doc[cur].pos = post[j].pos;
cur++;
@ -426,7 +502,8 @@ get_docrep(tsvector *txt, QUERYTYPE *query, int *doclen) {
*doclen = cur;
if ( cur>0 ) {
if (cur > 0)
{
if (cur > 1)
qsort((void *) doc, cur, sizeof(DocRepresentation), compareDocR);
return doc;
@ -438,17 +515,22 @@ get_docrep(tsvector *txt, QUERYTYPE *query, int *doclen) {
Datum
rank_cd(PG_FUNCTION_ARGS) {
rank_cd(PG_FUNCTION_ARGS)
{
int K = PG_GETARG_INT32(0);
tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(2));
int method = DEF_NORM_METHOD;
DocRepresentation *doc;
float res = 0.0;
int p=0,q=0,len,cur;
int p = 0,
q = 0,
len,
cur;
doc = get_docrep(txt, query, &len);
if ( !doc ) {
if (!doc)
{
PG_FREE_IF_COPY(txt, 1);
PG_FREE_IF_COPY(query, 2);
PG_RETURN_FLOAT4(0.0);
@ -463,10 +545,16 @@ rank_cd(PG_FUNCTION_ARGS) {
if (PG_NARGS() == 4)
method = PG_GETARG_INT32(3);
switch(method) {
case 0: break;
case 1: res /= log((float)cnt_length(txt)); break;
case 2: res /= (float)cnt_length(txt); break;
switch (method)
{
case 0:
break;
case 1:
res /= log((float) cnt_length(txt));
break;
case 2:
res /= (float) cnt_length(txt);
break;
default:
/* internal error */
elog(ERROR, "unrecognized normalization method: %d", method);
@ -481,7 +569,8 @@ rank_cd(PG_FUNCTION_ARGS) {
Datum
rank_cd_def(PG_FUNCTION_ARGS) {
rank_cd_def(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall4(
rank_cd,
Int32GetDatum(-1),
@ -493,7 +582,8 @@ rank_cd_def(PG_FUNCTION_ARGS) {
/**************debug*************/
typedef struct {
typedef struct
{
char *w;
int2 len;
int2 pos;
@ -502,7 +592,8 @@ typedef struct {
} DocWord;
static int
compareDocWord(const void *a, const void *b) {
compareDocWord(const void *a, const void *b)
{
if (((DocWord *) a)->pos == ((DocWord *) b)->pos)
return 1;
return (((DocWord *) a)->pos > ((DocWord *) b)->pos) ? 1 : -1;
@ -510,21 +601,32 @@ compareDocWord(const void *a, const void *b) {
Datum
get_covers(PG_FUNCTION_ARGS) {
get_covers(PG_FUNCTION_ARGS)
{
tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
WordEntry *pptr = ARRPTR(txt);
int i,dlen=0,j,cur=0,len=0,rlen;
DocWord *dw,*dwptr;
int i,
dlen = 0,
j,
cur = 0,
len = 0,
rlen;
DocWord *dw,
*dwptr;
text *out;
char *cptr;
DocRepresentation *doc;
int pos=0,p,q,olddwpos=0;
int pos = 0,
p,
q,
olddwpos = 0;
int ncover = 1;
doc = get_docrep(txt, query, &rlen);
if ( !doc ) {
if (!doc)
{
out = palloc(VARHDRSZ);
VARATT_SIZEP(out) = VARHDRSZ;
PG_FREE_IF_COPY(txt, 0);
@ -532,7 +634,8 @@ get_covers(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(out);
}
for(i=0;i<txt->size;i++) {
for (i = 0; i < txt->size; i++)
{
if (!pptr[i].haspos)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
@ -543,9 +646,12 @@ get_covers(PG_FUNCTION_ARGS) {
dwptr = dw = palloc(sizeof(DocWord) * dlen);
memset(dw, 0, sizeof(DocWord) * dlen);
for(i=0;i<txt->size;i++) {
for (i = 0; i < txt->size; i++)
{
WordEntryPos *posdata = POSDATAPTR(txt, &(pptr[i]));
for(j=0;j<POSDATALEN(txt,&(pptr[i]));j++) {
for (j = 0; j < POSDATALEN(txt, &(pptr[i])); j++)
{
dw[cur].w = STRPTR(txt) + pptr[i].pos;
dw[cur].len = pptr[i].len;
dw[cur].pos = posdata[j].pos;
@ -555,7 +661,8 @@ get_covers(PG_FUNCTION_ARGS) {
}
qsort((void *) dw, dlen, sizeof(DocWord), compareDocWord);
while( Cover(doc, rlen, query, &pos, &p, &q) ) {
while (Cover(doc, rlen, query, &pos, &p, &q))
{
dwptr = dw + olddwpos;
while (dwptr->pos < p && dwptr - dw < dlen)
dwptr++;
@ -572,8 +679,10 @@ get_covers(PG_FUNCTION_ARGS) {
cptr = ((char *) out) + VARHDRSZ;
dwptr = dw;
while( dwptr-dw < dlen) {
if ( dwptr->start ) {
while (dwptr - dw < dlen)
{
if (dwptr->start)
{
sprintf(cptr, "{%d ", dwptr->start);
cptr = strchr(cptr, '\0');
}
@ -581,7 +690,8 @@ get_covers(PG_FUNCTION_ARGS) {
cptr += dwptr->len;
*cptr = ' ';
cptr++;
if ( dwptr->finish ) {
if (dwptr->finish)
{
sprintf(cptr, "}%d ", dwptr->finish);
cptr = strchr(cptr, '\0');
}
@ -597,4 +707,3 @@ get_covers(PG_FUNCTION_ARGS) {
PG_FREE_IF_COPY(query, 1);
PG_RETURN_POINTER(out);
}

View File

@ -11,15 +11,19 @@
#include "common.h"
static int
compareSNMapEntry(const void *a, const void *b) {
compareSNMapEntry(const void *a, const void *b)
{
return strcmp(((SNMapEntry *) a)->key, ((SNMapEntry *) b)->key);
}
void
addSNMap( SNMap *map, char *key, Oid value ) {
if (map->len>=map->reallen) {
addSNMap(SNMap * map, char *key, Oid value)
{
if (map->len >= map->reallen)
{
SNMapEntry *tmp;
int len = (map->reallen) ? 2 * map->reallen : 16;
tmp = (SNMapEntry *) realloc(map->list, sizeof(SNMapEntry) * len);
if (!tmp)
ereport(ERROR,
@ -35,20 +39,25 @@ addSNMap( SNMap *map, char *key, Oid value ) {
errmsg("out of memory")));
map->list[map->len].value = value;
map->len++;
if ( map->len>1 ) qsort(map->list, map->len, sizeof(SNMapEntry), compareSNMapEntry);
if (map->len > 1)
qsort(map->list, map->len, sizeof(SNMapEntry), compareSNMapEntry);
}
void
addSNMap_t( SNMap *map, text *key, Oid value ) {
addSNMap_t(SNMap * map, text *key, Oid value)
{
char *k = text2char(key);
addSNMap(map, k, value);
pfree(k);
}
Oid
findSNMap( SNMap *map, char *key ) {
findSNMap(SNMap * map, char *key)
{
SNMapEntry *ptr;
SNMapEntry ks = {key, 0};
if (map->len == 0 || !map->list)
return 0;
ptr = (SNMapEntry *) bsearch(&ks, map->list, map->len, sizeof(SNMapEntry), compareSNMapEntry);
@ -56,24 +65,31 @@ findSNMap( SNMap *map, char *key ) {
}
Oid
findSNMap_t( SNMap *map, text *key ) {
findSNMap_t(SNMap * map, text *key)
{
char *k = text2char(key);
int res;
res = findSNMap(map, k);
pfree(k);
return res;
}
void freeSNMap( SNMap *map ) {
void
freeSNMap(SNMap * map)
{
SNMapEntry *entry = map->list;
if ( map->list ) {
while( map->len ) {
if ( entry->key ) free(entry->key);
entry++; map->len--;
if (map->list)
{
while (map->len)
{
if (entry->key)
free(entry->key);
entry++;
map->len--;
}
free(map->list);
}
memset(map, 0, sizeof(SNMap));
}

View File

@ -3,12 +3,14 @@
#include "postgres.h"
typedef struct {
typedef struct
{
char *key;
Oid value;
} SNMapEntry;
typedef struct {
typedef struct
{
int len;
int reallen;
SNMapEntry *list;

View File

@ -2,48 +2,64 @@
#include "header.h"
extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size)
{ struct SN_env * z = (struct SN_env *) calloc(1, sizeof(struct SN_env));
extern struct SN_env *
SN_create_env(int S_size, int I_size, int B_size)
{
struct SN_env *z = (struct SN_env *) calloc(1, sizeof(struct SN_env));
z->p = create_s();
if (S_size)
{ z->S = (symbol * *) calloc(S_size, sizeof(symbol *));
{ int i;
for (i = 0; i < S_size; i++) z->S[i] = create_s();
{
z->S = (symbol * *) calloc(S_size, sizeof(symbol *));
{
int i;
for (i = 0; i < S_size; i++)
z->S[i] = create_s();
}
z->S_size = S_size;
}
if (I_size)
{ z->I = (int *) calloc(I_size, sizeof(int));
{
z->I = (int *) calloc(I_size, sizeof(int));
z->I_size = I_size;
}
if (B_size)
{ z->B = (symbol *) calloc(B_size, sizeof(symbol));
{
z->B = (symbol *) calloc(B_size, sizeof(symbol));
z->B_size = B_size;
}
return z;
}
extern void SN_close_env(struct SN_env * z)
extern void
SN_close_env(struct SN_env * z)
{
if (z->S_size)
{
{ int i;
for (i = 0; i < z->S_size; i++) lose_s(z->S[i]);
{
int i;
for (i = 0; i < z->S_size; i++)
lose_s(z->S[i]);
}
free(z->S);
}
if (z->I_size) free(z->I);
if (z->B_size) free(z->B);
if (z->p) lose_s(z->p);
if (z->I_size)
free(z->I);
if (z->B_size)
free(z->B);
if (z->p)
lose_s(z->p);
free(z);
}
extern void SN_set_current(struct SN_env * z, int size, const symbol * s)
extern void
SN_set_current(struct SN_env * z, int size, const symbol * s)
{
replace_s(z, 0, z->l, size, s);
z->c = 0;
}

View File

@ -11,10 +11,18 @@ typedef unsigned char symbol;
*/
struct SN_env {
struct SN_env
{
symbol *p;
int c; int a; int l; int lb; int bra; int ket;
int S_size; int I_size; int B_size;
int c;
int a;
int l;
int lb;
int bra;
int ket;
int S_size;
int I_size;
int B_size;
symbol **S;
int *I;
symbol *B;
@ -24,4 +32,3 @@ extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size);
extern void SN_close_env(struct SN_env * z);
extern void SN_set_current(struct SN_env * z, int size, const symbol * s);

View File

@ -338,32 +338,47 @@ static symbol s_46[] = { 's', 'i', 'n', 'g', 'l' };
static symbol s_47[] = {'Y'};
static symbol s_48[] = {'y'};
static int r_prelude(struct SN_env * z) {
static int
r_prelude(struct SN_env * z)
{
z->B[0] = 0; /* unset Y_found, line 24 */
{ int c = z->c; /* do, line 25 */
{
int c = z->c; /* do, line 25 */
z->bra = z->c; /* [, line 25 */
if (!(eq_s(z, 1, s_0))) goto lab0;
if (!(eq_s(z, 1, s_0)))
goto lab0;
z->ket = z->c; /* ], line 25 */
if (!(in_grouping(z, g_v, 97, 121))) goto lab0;
if (!(in_grouping(z, g_v, 97, 121)))
goto lab0;
slice_from_s(z, 1, s_1); /* <-, line 25 */
z->B[0] = 1; /* set Y_found, line 25 */
lab0:
z->c = c;
}
{ int c = z->c; /* do, line 26 */
while(1) { /* repeat, line 26 */
{
int c = z->c; /* do, line 26 */
while (1)
{ /* repeat, line 26 */
int c = z->c;
while(1) { /* goto, line 26 */
while (1)
{ /* goto, line 26 */
int c = z->c;
if (!(in_grouping(z, g_v, 97, 121))) goto lab3;
if (!(in_grouping(z, g_v, 97, 121)))
goto lab3;
z->bra = z->c; /* [, line 26 */
if (!(eq_s(z, 1, s_2))) goto lab3;
if (!(eq_s(z, 1, s_2)))
goto lab3;
z->ket = z->c; /* ], line 26 */
z->c = c;
break;
lab3:
z->c = c;
if (z->c >= z->l) goto lab2;
if (z->c >= z->l)
goto lab2;
z->c++;
}
slice_from_s(z, 1, s_3); /* <-, line 26 */
@ -378,44 +393,63 @@ static int r_prelude(struct SN_env * z) {
return 1;
}
static int r_mark_regions(struct SN_env * z) {
static int
r_mark_regions(struct SN_env * z)
{
z->I[0] = z->l;
z->I[1] = z->l;
{ int c = z->c; /* do, line 32 */
{ int c = z->c; /* or, line 36 */
if (!(find_among(z, a_0, 1))) goto lab2; /* among, line 33 */
{
int c = z->c; /* do, line 32 */
{
int c = z->c; /* or, line 36 */
if (!(find_among(z, a_0, 1)))
goto lab2; /* among, line 33 */
goto lab1;
lab2:
z->c = c;
while(1) { /* gopast, line 36 */
if (!(in_grouping(z, g_v, 97, 121))) goto lab3;
while (1)
{ /* gopast, line 36 */
if (!(in_grouping(z, g_v, 97, 121)))
goto lab3;
break;
lab3:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
while(1) { /* gopast, line 36 */
if (!(out_grouping(z, g_v, 97, 121))) goto lab4;
while (1)
{ /* gopast, line 36 */
if (!(out_grouping(z, g_v, 97, 121)))
goto lab4;
break;
lab4:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
}
lab1:
z->I[0] = z->c; /* setmark p1, line 37 */
while(1) { /* gopast, line 38 */
if (!(in_grouping(z, g_v, 97, 121))) goto lab5;
while (1)
{ /* gopast, line 38 */
if (!(in_grouping(z, g_v, 97, 121)))
goto lab5;
break;
lab5:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
while(1) { /* gopast, line 38 */
if (!(out_grouping(z, g_v, 97, 121))) goto lab6;
while (1)
{ /* gopast, line 38 */
if (!(out_grouping(z, g_v, 97, 121)))
goto lab6;
break;
lab6:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
z->I[1] = z->c; /* setmark p2, line 38 */
@ -425,48 +459,74 @@ static int r_mark_regions(struct SN_env * z) {
return 1;
}
static int r_shortv(struct SN_env * z) {
{ int m = z->l - z->c; /* or, line 46 */
if (!(out_grouping_b(z, g_v_WXY, 89, 121))) goto lab1;
if (!(in_grouping_b(z, g_v, 97, 121))) goto lab1;
if (!(out_grouping_b(z, g_v, 97, 121))) goto lab1;
static int
r_shortv(struct SN_env * z)
{
{
int m = z->l - z->c; /* or, line 46 */
if (!(out_grouping_b(z, g_v_WXY, 89, 121)))
goto lab1;
if (!(in_grouping_b(z, g_v, 97, 121)))
goto lab1;
if (!(out_grouping_b(z, g_v, 97, 121)))
goto lab1;
goto lab0;
lab1:
z->c = z->l - m;
if (!(out_grouping_b(z, g_v, 97, 121))) return 0;
if (!(in_grouping_b(z, g_v, 97, 121))) return 0;
if (z->c > z->lb) return 0; /* atlimit, line 47 */
if (!(out_grouping_b(z, g_v, 97, 121)))
return 0;
if (!(in_grouping_b(z, g_v, 97, 121)))
return 0;
if (z->c > z->lb)
return 0; /* atlimit, line 47 */
}
lab0:
return 1;
}
static int r_R1(struct SN_env * z) {
if (!(z->I[0] <= z->c)) return 0;
static int
r_R1(struct SN_env * z)
{
if (!(z->I[0] <= z->c))
return 0;
return 1;
}
static int r_R2(struct SN_env * z) {
if (!(z->I[1] <= z->c)) return 0;
static int
r_R2(struct SN_env * z)
{
if (!(z->I[1] <= z->c))
return 0;
return 1;
}
static int r_Step_1a(struct SN_env * z) {
static int
r_Step_1a(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 54 */
among_var = find_among_b(z, a_1, 6); /* substring, line 54 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 54 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
slice_from_s(z, 2, s_4); /* <-, line 55 */
break;
case 2:
{ int m = z->l - z->c; /* or, line 57 */
if (z->c <= z->lb) goto lab1;
{
int m = z->l - z->c; /* or, line 57 */
if (z->c <= z->lb)
goto lab1;
z->c--; /* next, line 57 */
if (z->c > z->lb) goto lab1; /* atlimit, line 57 */
if (z->c > z->lb)
goto lab1; /* atlimit, line 57 */
slice_from_s(z, 2, s_5); /* <-, line 57 */
goto lab0;
lab1:
@ -476,13 +536,17 @@ static int r_Step_1a(struct SN_env * z) {
lab0:
break;
case 3:
if (z->c <= z->lb) return 0;
if (z->c <= z->lb)
return 0;
z->c--; /* next, line 58 */
while(1) { /* gopast, line 58 */
if (!(in_grouping_b(z, g_v, 97, 121))) goto lab2;
while (1)
{ /* gopast, line 58 */
if (!(in_grouping_b(z, g_v, 97, 121)))
goto lab2;
break;
lab2:
if (z->c <= z->lb) return 0;
if (z->c <= z->lb)
return 0;
z->c--;
}
slice_del(z); /* delete, line 58 */
@ -491,57 +555,83 @@ static int r_Step_1a(struct SN_env * z) {
return 1;
}
static int r_Step_1b(struct SN_env * z) {
static int
r_Step_1b(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 64 */
among_var = find_among_b(z, a_3, 6); /* substring, line 64 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 64 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
if (!r_R1(z)) return 0; /* call R1, line 66 */
if (!r_R1(z))
return 0; /* call R1, line 66 */
slice_from_s(z, 2, s_7); /* <-, line 66 */
break;
case 2:
{ int m_test = z->l - z->c; /* test, line 69 */
while(1) { /* gopast, line 69 */
if (!(in_grouping_b(z, g_v, 97, 121))) goto lab0;
{
int m_test = z->l - z->c; /* test, line 69 */
while (1)
{ /* gopast, line 69 */
if (!(in_grouping_b(z, g_v, 97, 121)))
goto lab0;
break;
lab0:
if (z->c <= z->lb) return 0;
if (z->c <= z->lb)
return 0;
z->c--;
}
z->c = z->l - m_test;
}
slice_del(z); /* delete, line 69 */
{ int m_test = z->l - z->c; /* test, line 70 */
{
int m_test = z->l - z->c; /* test, line 70 */
among_var = find_among_b(z, a_2, 13); /* substring, line 70 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->c = z->l - m_test;
}
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
{ int c = z->c;
{
int c = z->c;
insert_s(z, z->c, z->c, 1, s_8); /* <+, line 72 */
z->c = c;
}
break;
case 2:
z->ket = z->c; /* [, line 75 */
if (z->c <= z->lb) return 0;
if (z->c <= z->lb)
return 0;
z->c--; /* next, line 75 */
z->bra = z->c; /* ], line 75 */
slice_del(z); /* delete, line 75 */
break;
case 3:
if (z->c != z->I[0]) return 0; /* atmark, line 76 */
{ int m_test = z->l - z->c; /* test, line 76 */
if (!r_shortv(z)) return 0; /* call shortv, line 76 */
if (z->c != z->I[0])
return 0; /* atmark, line 76 */
{
int m_test = z->l - z->c; /* test, line 76 */
if (!r_shortv(z))
return 0; /* call shortv, line 76 */
z->c = z->l - m_test;
}
{ int c = z->c;
{
int c = z->c;
insert_s(z, z->c, z->c, 1, s_9); /* <+, line 76 */
z->c = c;
}
@ -552,20 +642,30 @@ static int r_Step_1b(struct SN_env * z) {
return 1;
}
static int r_Step_1c(struct SN_env * z) {
static int
r_Step_1c(struct SN_env * z)
{
z->ket = z->c; /* [, line 83 */
{ int m = z->l - z->c; /* or, line 83 */
if (!(eq_s_b(z, 1, s_10))) goto lab1;
{
int m = z->l - z->c; /* or, line 83 */
if (!(eq_s_b(z, 1, s_10)))
goto lab1;
goto lab0;
lab1:
z->c = z->l - m;
if (!(eq_s_b(z, 1, s_11))) return 0;
if (!(eq_s_b(z, 1, s_11)))
return 0;
}
lab0:
z->bra = z->c; /* ], line 83 */
if (!(out_grouping_b(z, g_v, 97, 121))) return 0;
{ int m = z->l - z->c; /* not, line 84 */
if (z->c > z->lb) goto lab2; /* atlimit, line 84 */
if (!(out_grouping_b(z, g_v, 97, 121)))
return 0;
{
int m = z->l - z->c; /* not, line 84 */
if (z->c > z->lb)
goto lab2; /* atlimit, line 84 */
return 0;
lab2:
z->c = z->l - m;
@ -574,15 +674,22 @@ lab0:
return 1;
}
static int r_Step_2(struct SN_env * z) {
static int
r_Step_2(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 89 */
among_var = find_among_b(z, a_4, 24); /* substring, line 89 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 89 */
if (!r_R1(z)) return 0; /* call R1, line 89 */
switch(among_var) {
case 0: return 0;
if (!r_R1(z))
return 0; /* call R1, line 89 */
switch (among_var)
{
case 0:
return 0;
case 1:
slice_from_s(z, 4, s_13); /* <-, line 90 */
break;
@ -620,7 +727,8 @@ static int r_Step_2(struct SN_env * z) {
slice_from_s(z, 3, s_24); /* <-, line 107 */
break;
case 13:
if (!(eq_s_b(z, 1, s_25))) return 0;
if (!(eq_s_b(z, 1, s_25)))
return 0;
slice_from_s(z, 2, s_26); /* <-, line 108 */
break;
case 14:
@ -630,22 +738,30 @@ static int r_Step_2(struct SN_env * z) {
slice_from_s(z, 4, s_28); /* <-, line 110 */
break;
case 16:
if (!(in_grouping_b(z, g_valid_LI, 99, 116))) return 0;
if (!(in_grouping_b(z, g_valid_LI, 99, 116)))
return 0;
slice_del(z); /* delete, line 111 */
break;
}
return 1;
}
static int r_Step_3(struct SN_env * z) {
static int
r_Step_3(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 116 */
among_var = find_among_b(z, a_5, 9); /* substring, line 116 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 116 */
if (!r_R1(z)) return 0; /* call R1, line 116 */
switch(among_var) {
case 0: return 0;
if (!r_R1(z))
return 0; /* call R1, line 116 */
switch (among_var)
{
case 0:
return 0;
case 1:
slice_from_s(z, 4, s_29); /* <-, line 117 */
break;
@ -662,32 +778,44 @@ static int r_Step_3(struct SN_env * z) {
slice_del(z); /* delete, line 123 */
break;
case 6:
if (!r_R2(z)) return 0; /* call R2, line 125 */
if (!r_R2(z))
return 0; /* call R2, line 125 */
slice_del(z); /* delete, line 125 */
break;
}
return 1;
}
static int r_Step_4(struct SN_env * z) {
static int
r_Step_4(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 130 */
among_var = find_among_b(z, a_6, 18); /* substring, line 130 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 130 */
if (!r_R2(z)) return 0; /* call R2, line 130 */
switch(among_var) {
case 0: return 0;
if (!r_R2(z))
return 0; /* call R2, line 130 */
switch (among_var)
{
case 0:
return 0;
case 1:
slice_del(z); /* delete, line 133 */
break;
case 2:
{ int m = z->l - z->c; /* or, line 134 */
if (!(eq_s_b(z, 1, s_33))) goto lab1;
{
int m = z->l - z->c; /* or, line 134 */
if (!(eq_s_b(z, 1, s_33)))
goto lab1;
goto lab0;
lab1:
z->c = z->l - m;
if (!(eq_s_b(z, 1, s_34))) return 0;
if (!(eq_s_b(z, 1, s_34)))
return 0;
}
lab0:
slice_del(z); /* delete, line 134 */
@ -696,23 +824,36 @@ static int r_Step_4(struct SN_env * z) {
return 1;
}
static int r_Step_5(struct SN_env * z) {
static int
r_Step_5(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 139 */
among_var = find_among_b(z, a_7, 2); /* substring, line 139 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 139 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
{ int m = z->l - z->c; /* or, line 140 */
if (!r_R2(z)) goto lab1; /* call R2, line 140 */
{
int m = z->l - z->c; /* or, line 140 */
if (!r_R2(z))
goto lab1; /* call R2, line 140 */
goto lab0;
lab1:
z->c = z->l - m;
if (!r_R1(z)) return 0; /* call R1, line 140 */
{ int m = z->l - z->c; /* not, line 140 */
if (!r_shortv(z)) goto lab2; /* call shortv, line 140 */
if (!r_R1(z))
return 0; /* call R1, line 140 */
{
int m = z->l - z->c; /* not, line 140 */
if (!r_shortv(z))
goto lab2; /* call shortv, line 140 */
return 0;
lab2:
z->c = z->l - m;
@ -722,31 +863,44 @@ static int r_Step_5(struct SN_env * z) {
slice_del(z); /* delete, line 140 */
break;
case 2:
if (!r_R2(z)) return 0; /* call R2, line 141 */
if (!(eq_s_b(z, 1, s_35))) return 0;
if (!r_R2(z))
return 0; /* call R2, line 141 */
if (!(eq_s_b(z, 1, s_35)))
return 0;
slice_del(z); /* delete, line 141 */
break;
}
return 1;
}
static int r_exception2(struct SN_env * z) {
static int
r_exception2(struct SN_env * z)
{
z->ket = z->c; /* [, line 147 */
if (!(find_among_b(z, a_8, 8))) return 0; /* substring, line 147 */
if (!(find_among_b(z, a_8, 8)))
return 0; /* substring, line 147 */
z->bra = z->c; /* ], line 147 */
if (z->c > z->lb) return 0; /* atlimit, line 147 */
if (z->c > z->lb)
return 0; /* atlimit, line 147 */
return 1;
}
static int r_exception1(struct SN_env * z) {
static int
r_exception1(struct SN_env * z)
{
int among_var;
z->bra = z->c; /* [, line 159 */
among_var = find_among(z, a_9, 18); /* substring, line 159 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->ket = z->c; /* ], line 159 */
if (z->c < z->l) return 0; /* atlimit, line 159 */
switch(among_var) {
case 0: return 0;
if (z->c < z->l)
return 0; /* atlimit, line 159 */
switch (among_var)
{
case 0:
return 0;
case 1:
slice_from_s(z, 3, s_36); /* <-, line 163 */
break;
@ -784,20 +938,29 @@ static int r_exception1(struct SN_env * z) {
return 1;
}
static int r_postlude(struct SN_env * z) {
if (!(z->B[0])) return 0; /* Boolean test Y_found, line 192 */
while(1) { /* repeat, line 192 */
static int
r_postlude(struct SN_env * z)
{
if (!(z->B[0]))
return 0; /* Boolean test Y_found, line 192 */
while (1)
{ /* repeat, line 192 */
int c = z->c;
while(1) { /* goto, line 192 */
while (1)
{ /* goto, line 192 */
int c = z->c;
z->bra = z->c; /* [, line 192 */
if (!(eq_s(z, 1, s_47))) goto lab1;
if (!(eq_s(z, 1, s_47)))
goto lab1;
z->ket = z->c; /* ], line 192 */
z->c = c;
break;
lab1:
z->c = c;
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
slice_from_s(z, 1, s_48); /* <-, line 192 */
@ -809,76 +972,120 @@ static int r_postlude(struct SN_env * z) {
return 1;
}
extern int english_stem(struct SN_env * z) {
{ int c = z->c; /* or, line 196 */
if (!r_exception1(z)) goto lab1; /* call exception1, line 196 */
extern int
english_stem(struct SN_env * z)
{
{
int c = z->c; /* or, line 196 */
if (!r_exception1(z))
goto lab1; /* call exception1, line 196 */
goto lab0;
lab1:
z->c = c;
{ int c_test = z->c; /* test, line 198 */
{ int c = z->c + 3;
if (0 > c || c > z->l) return 0;
{
int c_test = z->c; /* test, line 198 */
{
int c = z->c + 3;
if (0 > c || c > z->l)
return 0;
z->c = c; /* hop, line 198 */
}
z->c = c_test;
}
{ int c = z->c; /* do, line 199 */
if (!r_prelude(z)) goto lab2; /* call prelude, line 199 */
{
int c = z->c; /* do, line 199 */
if (!r_prelude(z))
goto lab2; /* call prelude, line 199 */
lab2:
z->c = c;
}
{ int c = z->c; /* do, line 200 */
if (!r_mark_regions(z)) goto lab3; /* call mark_regions, line 200 */
{
int c = z->c; /* do, line 200 */
if (!r_mark_regions(z))
goto lab3; /* call mark_regions, line 200 */
lab3:
z->c = c;
}
z->lb = z->c; z->c = z->l; /* backwards, line 201 */
z->lb = z->c;
z->c = z->l; /* backwards, line 201 */
{ int m = z->l - z->c; /* do, line 203 */
if (!r_Step_1a(z)) goto lab4; /* call Step_1a, line 203 */
{
int m = z->l - z->c; /* do, line 203 */
if (!r_Step_1a(z))
goto lab4; /* call Step_1a, line 203 */
lab4:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* or, line 205 */
if (!r_exception2(z)) goto lab6; /* call exception2, line 205 */
{
int m = z->l - z->c; /* or, line 205 */
if (!r_exception2(z))
goto lab6; /* call exception2, line 205 */
goto lab5;
lab6:
z->c = z->l - m;
{ int m = z->l - z->c; /* do, line 207 */
if (!r_Step_1b(z)) goto lab7; /* call Step_1b, line 207 */
{
int m = z->l - z->c; /* do, line 207 */
if (!r_Step_1b(z))
goto lab7; /* call Step_1b, line 207 */
lab7:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* do, line 208 */
if (!r_Step_1c(z)) goto lab8; /* call Step_1c, line 208 */
{
int m = z->l - z->c; /* do, line 208 */
if (!r_Step_1c(z))
goto lab8; /* call Step_1c, line 208 */
lab8:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* do, line 210 */
if (!r_Step_2(z)) goto lab9; /* call Step_2, line 210 */
{
int m = z->l - z->c; /* do, line 210 */
if (!r_Step_2(z))
goto lab9; /* call Step_2, line 210 */
lab9:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* do, line 211 */
if (!r_Step_3(z)) goto lab10; /* call Step_3, line 211 */
{
int m = z->l - z->c; /* do, line 211 */
if (!r_Step_3(z))
goto lab10; /* call Step_3, line 211 */
lab10:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* do, line 212 */
if (!r_Step_4(z)) goto lab11; /* call Step_4, line 212 */
{
int m = z->l - z->c; /* do, line 212 */
if (!r_Step_4(z))
goto lab11; /* call Step_4, line 212 */
lab11:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* do, line 214 */
if (!r_Step_5(z)) goto lab12; /* call Step_5, line 214 */
{
int m = z->l - z->c; /* do, line 214 */
if (!r_Step_5(z))
goto lab12; /* call Step_5, line 214 */
lab12:
z->c = z->l - m;
}
}
lab5:
z->c = z->lb;
{ int c = z->c; /* do, line 217 */
if (!r_postlude(z)) goto lab13; /* call postlude, line 217 */
{
int c = z->c; /* do, line 217 */
if (!r_postlude(z))
goto lab13; /* call postlude, line 217 */
lab13:
z->c = c;
}
@ -887,7 +1094,12 @@ lab0:
return 1;
}
extern struct SN_env * english_create_env(void) { return SN_create_env(0, 2, 1); }
extern void english_close_env(struct SN_env * z) { SN_close_env(z); }
extern struct SN_env *english_create_env(void)
{
return SN_create_env(0, 2, 1);
}
extern void english_close_env(struct SN_env * z)
{
SN_close_env(z);
}

View File

@ -5,4 +5,3 @@ extern struct SN_env * english_create_env(void);
extern void english_close_env(struct SN_env * z);
extern int english_stem(struct SN_env * z);

View File

@ -7,7 +7,8 @@
#define CAPACITY(p) ((int *)(p))[-2]
struct among
{ int s_size; /* number of chars in string */
{
int s_size; /* number of chars in string */
symbol *s; /* search string */
int substring_i; /* index to longest matching substring */
int result; /* result of the lookup */
@ -48,4 +49,3 @@ extern symbol * slice_to(struct SN_env * z, symbol * p);
extern symbol *assign_to(struct SN_env * z, symbol * p);
extern void debug(struct SN_env * z, int number, int line_count);

View File

@ -337,37 +337,53 @@ static symbol s_7[] = { 206 };
static symbol s_8[] = {206};
static symbol s_9[] = {201};
static int r_mark_regions(struct SN_env * z) {
static int
r_mark_regions(struct SN_env * z)
{
z->I[0] = z->l;
z->I[1] = z->l;
{ int c = z->c; /* do, line 100 */
while(1) { /* gopast, line 101 */
if (!(in_grouping(z, g_v, 192, 220))) goto lab1;
{
int c = z->c; /* do, line 100 */
while (1)
{ /* gopast, line 101 */
if (!(in_grouping(z, g_v, 192, 220)))
goto lab1;
break;
lab1:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
z->I[0] = z->c; /* setmark pV, line 101 */
while(1) { /* gopast, line 101 */
if (!(out_grouping(z, g_v, 192, 220))) goto lab2;
while (1)
{ /* gopast, line 101 */
if (!(out_grouping(z, g_v, 192, 220)))
goto lab2;
break;
lab2:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
while(1) { /* gopast, line 102 */
if (!(in_grouping(z, g_v, 192, 220))) goto lab3;
while (1)
{ /* gopast, line 102 */
if (!(in_grouping(z, g_v, 192, 220)))
goto lab3;
break;
lab3:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
while(1) { /* gopast, line 102 */
if (!(out_grouping(z, g_v, 192, 220))) goto lab4;
while (1)
{ /* gopast, line 102 */
if (!(out_grouping(z, g_v, 192, 220)))
goto lab4;
break;
lab4:
if (z->c >= z->l) goto lab0;
if (z->c >= z->l)
goto lab0;
z->c++;
}
z->I[1] = z->c; /* setmark p2, line 102 */
@ -377,26 +393,39 @@ static int r_mark_regions(struct SN_env * z) {
return 1;
}
static int r_R2(struct SN_env * z) {
if (!(z->I[1] <= z->c)) return 0;
static int
r_R2(struct SN_env * z)
{
if (!(z->I[1] <= z->c))
return 0;
return 1;
}
static int r_perfective_gerund(struct SN_env * z) {
static int
r_perfective_gerund(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 111 */
among_var = find_among_b(z, a_0, 9); /* substring, line 111 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 111 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
{ int m = z->l - z->c; /* or, line 115 */
if (!(eq_s_b(z, 1, s_0))) goto lab1;
{
int m = z->l - z->c; /* or, line 115 */
if (!(eq_s_b(z, 1, s_0)))
goto lab1;
goto lab0;
lab1:
z->c = z->l - m;
if (!(eq_s_b(z, 1, s_1))) return 0;
if (!(eq_s_b(z, 1, s_1)))
return 0;
}
lab0:
slice_del(z); /* delete, line 115 */
@ -408,14 +437,20 @@ static int r_perfective_gerund(struct SN_env * z) {
return 1;
}
static int r_adjective(struct SN_env * z) {
static int
r_adjective(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 127 */
among_var = find_among_b(z, a_1, 26); /* substring, line 127 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 127 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
slice_del(z); /* delete, line 136 */
break;
@ -423,23 +458,45 @@ static int r_adjective(struct SN_env * z) {
return 1;
}
static int r_adjectival(struct SN_env * z) {
static int
r_adjectival(struct SN_env * z)
{
int among_var;
if (!r_adjective(z)) return 0; /* call adjective, line 141 */
{ int m = z->l - z->c; /* try, line 148 */
if (!r_adjective(z))
return 0; /* call adjective, line 141 */
{
int m = z->l - z->c; /* try, line 148 */
z->ket = z->c; /* [, line 149 */
among_var = find_among_b(z, a_2, 8); /* substring, line 149 */
if (!(among_var)) { z->c = z->l - m; goto lab0; }
if (!(among_var))
{
z->c = z->l - m;
goto lab0;
}
z->bra = z->c; /* ], line 149 */
switch(among_var) {
case 0: { z->c = z->l - m; goto lab0; }
switch (among_var)
{
case 0:
{
z->c = z->l - m;
goto lab0;
}
case 1:
{ int m = z->l - z->c; /* or, line 154 */
if (!(eq_s_b(z, 1, s_2))) goto lab2;
{
int m = z->l - z->c; /* or, line 154 */
if (!(eq_s_b(z, 1, s_2)))
goto lab2;
goto lab1;
lab2:
z->c = z->l - m;
if (!(eq_s_b(z, 1, s_3))) { z->c = z->l - m; goto lab0; }
if (!(eq_s_b(z, 1, s_3)))
{
z->c = z->l - m;
goto lab0;
}
}
lab1:
slice_del(z); /* delete, line 154 */
@ -454,14 +511,20 @@ static int r_adjectival(struct SN_env * z) {
return 1;
}
static int r_reflexive(struct SN_env * z) {
static int
r_reflexive(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 168 */
among_var = find_among_b(z, a_3, 2); /* substring, line 168 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 168 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
slice_del(z); /* delete, line 171 */
break;
@ -469,21 +532,31 @@ static int r_reflexive(struct SN_env * z) {
return 1;
}
static int r_verb(struct SN_env * z) {
static int
r_verb(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 176 */
among_var = find_among_b(z, a_4, 46); /* substring, line 176 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 176 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
{ int m = z->l - z->c; /* or, line 182 */
if (!(eq_s_b(z, 1, s_4))) goto lab1;
{
int m = z->l - z->c; /* or, line 182 */
if (!(eq_s_b(z, 1, s_4)))
goto lab1;
goto lab0;
lab1:
z->c = z->l - m;
if (!(eq_s_b(z, 1, s_5))) return 0;
if (!(eq_s_b(z, 1, s_5)))
return 0;
}
lab0:
slice_del(z); /* delete, line 182 */
@ -495,14 +568,20 @@ static int r_verb(struct SN_env * z) {
return 1;
}
static int r_noun(struct SN_env * z) {
static int
r_noun(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 199 */
among_var = find_among_b(z, a_5, 36); /* substring, line 199 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 199 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
slice_del(z); /* delete, line 206 */
break;
@ -510,15 +589,22 @@ static int r_noun(struct SN_env * z) {
return 1;
}
static int r_derivational(struct SN_env * z) {
static int
r_derivational(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 215 */
among_var = find_among_b(z, a_6, 2); /* substring, line 215 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 215 */
if (!r_R2(z)) return 0; /* call R2, line 215 */
switch(among_var) {
case 0: return 0;
if (!r_R2(z))
return 0; /* call R2, line 215 */
switch (among_var)
{
case 0:
return 0;
case 1:
slice_del(z); /* delete, line 218 */
break;
@ -526,24 +612,33 @@ static int r_derivational(struct SN_env * z) {
return 1;
}
static int r_tidy_up(struct SN_env * z) {
static int
r_tidy_up(struct SN_env * z)
{
int among_var;
z->ket = z->c; /* [, line 223 */
among_var = find_among_b(z, a_7, 4); /* substring, line 223 */
if (!(among_var)) return 0;
if (!(among_var))
return 0;
z->bra = z->c; /* ], line 223 */
switch(among_var) {
case 0: return 0;
switch (among_var)
{
case 0:
return 0;
case 1:
slice_del(z); /* delete, line 227 */
z->ket = z->c; /* [, line 228 */
if (!(eq_s_b(z, 1, s_6))) return 0;
if (!(eq_s_b(z, 1, s_6)))
return 0;
z->bra = z->c; /* ], line 228 */
if (!(eq_s_b(z, 1, s_7))) return 0;
if (!(eq_s_b(z, 1, s_7)))
return 0;
slice_del(z); /* delete, line 228 */
break;
case 2:
if (!(eq_s_b(z, 1, s_8))) return 0;
if (!(eq_s_b(z, 1, s_8)))
return 0;
slice_del(z); /* delete, line 231 */
break;
case 3:
@ -553,41 +648,67 @@ static int r_tidy_up(struct SN_env * z) {
return 1;
}
extern int russian_stem(struct SN_env * z) {
{ int c = z->c; /* do, line 240 */
if (!r_mark_regions(z)) goto lab0; /* call mark_regions, line 240 */
extern int
russian_stem(struct SN_env * z)
{
{
int c = z->c; /* do, line 240 */
if (!r_mark_regions(z))
goto lab0; /* call mark_regions, line 240 */
lab0:
z->c = c;
}
z->lb = z->c; z->c = z->l; /* backwards, line 241 */
z->lb = z->c;
z->c = z->l; /* backwards, line 241 */
{ int m = z->l - z->c; /* setlimit, line 241 */
{
int m = z->l - z->c; /* setlimit, line 241 */
int m3;
if (z->c < z->I[0]) return 0;
if (z->c < z->I[0])
return 0;
z->c = z->I[0]; /* tomark, line 241 */
m3 = z->lb; z->lb = z->c;
m3 = z->lb;
z->lb = z->c;
z->c = z->l - m;
{ int m = z->l - z->c; /* do, line 242 */
{ int m = z->l - z->c; /* or, line 243 */
if (!r_perfective_gerund(z)) goto lab3; /* call perfective_gerund, line 243 */
{
int m = z->l - z->c; /* do, line 242 */
{
int m = z->l - z->c; /* or, line 243 */
if (!r_perfective_gerund(z))
goto lab3; /* call perfective_gerund, line 243 */
goto lab2;
lab3:
z->c = z->l - m;
{ int m = z->l - z->c; /* try, line 244 */
if (!r_reflexive(z)) { z->c = z->l - m; goto lab4; } /* call reflexive, line 244 */
{
int m = z->l - z->c; /* try, line 244 */
if (!r_reflexive(z))
{
z->c = z->l - m;
goto lab4;
} /* call reflexive, line 244 */
lab4:
;
}
{ int m = z->l - z->c; /* or, line 245 */
if (!r_adjectival(z)) goto lab6; /* call adjectival, line 245 */
{
int m = z->l - z->c; /* or, line 245 */
if (!r_adjectival(z))
goto lab6; /* call adjectival, line 245 */
goto lab5;
lab6:
z->c = z->l - m;
if (!r_verb(z)) goto lab7; /* call verb, line 245 */
if (!r_verb(z))
goto lab7; /* call verb, line 245 */
goto lab5;
lab7:
z->c = z->l - m;
if (!r_noun(z)) goto lab1; /* call noun, line 245 */
if (!r_noun(z))
goto lab1; /* call noun, line 245 */
}
lab5:
;
@ -596,21 +717,33 @@ extern int russian_stem(struct SN_env * z) {
lab1:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* try, line 248 */
{
int m = z->l - z->c; /* try, line 248 */
z->ket = z->c; /* [, line 248 */
if (!(eq_s_b(z, 1, s_9))) { z->c = z->l - m; goto lab8; }
if (!(eq_s_b(z, 1, s_9)))
{
z->c = z->l - m;
goto lab8;
}
z->bra = z->c; /* ], line 248 */
slice_del(z); /* delete, line 248 */
lab8:
;
}
{ int m = z->l - z->c; /* do, line 251 */
if (!r_derivational(z)) goto lab9; /* call derivational, line 251 */
{
int m = z->l - z->c; /* do, line 251 */
if (!r_derivational(z))
goto lab9; /* call derivational, line 251 */
lab9:
z->c = z->l - m;
}
{ int m = z->l - z->c; /* do, line 252 */
if (!r_tidy_up(z)) goto lab10; /* call tidy_up, line 252 */
{
int m = z->l - z->c; /* do, line 252 */
if (!r_tidy_up(z))
goto lab10; /* call tidy_up, line 252 */
lab10:
z->c = z->l - m;
}
@ -620,7 +753,12 @@ extern int russian_stem(struct SN_env * z) {
return 1;
}
extern struct SN_env * russian_create_env(void) { return SN_create_env(0, 2, 0); }
extern void russian_close_env(struct SN_env * z) { SN_close_env(z); }
extern struct SN_env *russian_create_env(void)
{
return SN_create_env(0, 2, 0);
}
extern void russian_close_env(struct SN_env * z)
{
SN_close_env(z);
}

View File

@ -5,4 +5,3 @@ extern struct SN_env * russian_create_env(void);
extern void russian_close_env(struct SN_env * z);
extern int russian_stem(struct SN_env * z);

View File

@ -9,118 +9,190 @@
#define CREATE_SIZE 1
extern symbol * create_s(void)
{ symbol * p = (symbol *) (HEAD + (char *) malloc(HEAD + (CREATE_SIZE + 1) * sizeof(symbol)));
extern symbol *
create_s(void)
{
symbol *p = (symbol *) (HEAD + (char *) malloc(HEAD + (CREATE_SIZE + 1) * sizeof(symbol)));
CAPACITY(p) = CREATE_SIZE;
SET_SIZE(p, CREATE_SIZE);
return p;
}
extern void lose_s(symbol * p) { free((char *) p - HEAD); }
extern void lose_s(symbol * p)
{
free((char *) p - HEAD);
}
extern int
in_grouping(struct SN_env * z, unsigned char *s, int min, int max)
{
if (z->c >= z->l)
return 0;
{
int ch = z->p[z->c];
extern int in_grouping(struct SN_env * z, unsigned char * s, int min, int max)
{ if (z->c >= z->l) return 0;
{ int ch = z->p[z->c];
if
(ch > max || (ch -= min) < 0 ||
(s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
(s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
return 0;
}
z->c++; return 1;
z->c++;
return 1;
}
extern int in_grouping_b(struct SN_env * z, unsigned char * s, int min, int max)
{ if (z->c <= z->lb) return 0;
{ int ch = z->p[z->c - 1];
extern int
in_grouping_b(struct SN_env * z, unsigned char *s, int min, int max)
{
if (z->c <= z->lb)
return 0;
{
int ch = z->p[z->c - 1];
if
(ch > max || (ch -= min) < 0 ||
(s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
(s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
return 0;
}
z->c--; return 1;
z->c--;
return 1;
}
extern int out_grouping(struct SN_env * z, unsigned char * s, int min, int max)
{ if (z->c >= z->l) return 0;
{ int ch = z->p[z->c];
extern int
out_grouping(struct SN_env * z, unsigned char *s, int min, int max)
{
if (z->c >= z->l)
return 0;
{
int ch = z->p[z->c];
unless
(ch > max || (ch -= min) < 0 ||
(s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
}
z->c++; return 1;
z->c++;
return 1;
}
extern int out_grouping_b(struct SN_env * z, unsigned char * s, int min, int max)
{ if (z->c <= z->lb) return 0;
{ int ch = z->p[z->c - 1];
extern int
out_grouping_b(struct SN_env * z, unsigned char *s, int min, int max)
{
if (z->c <= z->lb)
return 0;
{
int ch = z->p[z->c - 1];
unless
(ch > max || (ch -= min) < 0 ||
(s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
}
z->c--; return 1;
z->c--;
return 1;
}
extern int in_range(struct SN_env * z, int min, int max)
{ if (z->c >= z->l) return 0;
{ int ch = z->p[z->c];
extern int
in_range(struct SN_env * z, int min, int max)
{
if (z->c >= z->l)
return 0;
{
int ch = z->p[z->c];
if
(ch > max || ch < min) return 0;
(ch > max || ch < min)
return 0;
}
z->c++; return 1;
z->c++;
return 1;
}
extern int in_range_b(struct SN_env * z, int min, int max)
{ if (z->c <= z->lb) return 0;
{ int ch = z->p[z->c - 1];
extern int
in_range_b(struct SN_env * z, int min, int max)
{
if (z->c <= z->lb)
return 0;
{
int ch = z->p[z->c - 1];
if
(ch > max || ch < min) return 0;
(ch > max || ch < min)
return 0;
}
z->c--; return 1;
z->c--;
return 1;
}
extern int out_range(struct SN_env * z, int min, int max)
{ if (z->c >= z->l) return 0;
{ int ch = z->p[z->c];
extern int
out_range(struct SN_env * z, int min, int max)
{
if (z->c >= z->l)
return 0;
{
int ch = z->p[z->c];
unless
(ch > max || ch < min) return 0;
}
z->c++; return 1;
z->c++;
return 1;
}
extern int out_range_b(struct SN_env * z, int min, int max)
{ if (z->c <= z->lb) return 0;
{ int ch = z->p[z->c - 1];
extern int
out_range_b(struct SN_env * z, int min, int max)
{
if (z->c <= z->lb)
return 0;
{
int ch = z->p[z->c - 1];
unless
(ch > max || ch < min) return 0;
}
z->c--; return 1;
z->c--;
return 1;
}
extern int eq_s(struct SN_env * z, int s_size, symbol * s)
{ if (z->l - z->c < s_size ||
memcmp(z->p + z->c, s, s_size * sizeof(symbol)) != 0) return 0;
z->c += s_size; return 1;
extern int
eq_s(struct SN_env * z, int s_size, symbol * s)
{
if (z->l - z->c < s_size ||
memcmp(z->p + z->c, s, s_size * sizeof(symbol)) != 0)
return 0;
z->c += s_size;
return 1;
}
extern int eq_s_b(struct SN_env * z, int s_size, symbol * s)
{ if (z->c - z->lb < s_size ||
memcmp(z->p + z->c - s_size, s, s_size * sizeof(symbol)) != 0) return 0;
z->c -= s_size; return 1;
extern int
eq_s_b(struct SN_env * z, int s_size, symbol * s)
{
if (z->c - z->lb < s_size ||
memcmp(z->p + z->c - s_size, s, s_size * sizeof(symbol)) != 0)
return 0;
z->c -= s_size;
return 1;
}
extern int eq_v(struct SN_env * z, symbol * p)
{ return eq_s(z, SIZE(p), p);
extern int
eq_v(struct SN_env * z, symbol * p)
{
return eq_s(z, SIZE(p), p);
}
extern int eq_v_b(struct SN_env * z, symbol * p)
{ return eq_s_b(z, SIZE(p), p);
extern int
eq_v_b(struct SN_env * z, symbol * p)
{
return eq_s_b(z, SIZE(p), p);
}
extern int find_among(struct SN_env * z, struct among * v, int v_size)
extern int
find_among(struct SN_env * z, struct among * v, int v_size)
{
int i = 0;
int j = v_size;
int c = z->c; int l = z->l;
int c = z->c;
int l = z->l;
symbol *q = z->p + c;
struct among *w;
@ -131,54 +203,88 @@ extern int find_among(struct SN_env * z, struct among * v, int v_size)
int first_key_inspected = 0;
while (1)
{ int k = i + ((j - i) >> 1);
{
int k = i + ((j - i) >> 1);
int diff = 0;
int common = common_i < common_j ? common_i : common_j; /* smaller */
w = v + k;
{ int i; for (i = common; i < w->s_size; i++)
{ if (c + common == l) { diff = -1; break; }
{
int i;
for (i = common; i < w->s_size; i++)
{
if (c + common == l)
{
diff = -1;
break;
}
diff = q[common] - w->s[i];
if (diff != 0) break;
if (diff != 0)
break;
common++;
}
}
if (diff < 0) { j = k; common_j = common; }
else { i = k; common_i = common; }
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{ if (i > 0) break; /* v->s has been inspected */
if (j == i) break; /* only one item in v */
{
if (i > 0)
break; /* v->s has been inspected */
if (j == i)
break; /* only one item in v */
/* - but now we need to go round once more to get
v->s inspected. This looks messy, but is actually
the optimal approach. */
/*
* - but now we need to go round once more to get v->s
* inspected. This looks messy, but is actually the optimal
* approach.
*/
if (first_key_inspected) break;
if (first_key_inspected)
break;
first_key_inspected = 1;
}
}
while (1)
{ w = v + i;
{
w = v + i;
if (common_i >= w->s_size)
{ z->c = c + w->s_size;
if (w->function == 0) return w->result;
{ int res = w->function(z);
{
z->c = c + w->s_size;
if (res) return w->result;
if (w->function == 0)
return w->result;
{
int res = w->function(z);
z->c = c + w->s_size;
if (res)
return w->result;
}
}
i = w->substring_i;
if (i < 0) return 0;
if (i < 0)
return 0;
}
}
/* find_among_b is for backwards processing. Same comments apply */
extern int find_among_b(struct SN_env * z, struct among * v, int v_size)
extern int
find_among_b(struct SN_env * z, struct among * v, int v_size)
{
int i = 0;
int j = v_size;
int c = z->c; int lb = z->lb;
int c = z->c;
int lb = z->lb;
symbol *q = z->p + c - 1;
struct among *w;
@ -189,69 +295,112 @@ extern int find_among_b(struct SN_env * z, struct among * v, int v_size)
int first_key_inspected = 0;
while (1)
{ int k = i + ((j - i) >> 1);
{
int k = i + ((j - i) >> 1);
int diff = 0;
int common = common_i < common_j ? common_i : common_j;
w = v + k;
{ int i; for (i = w->s_size - 1 - common; i >= 0; i--)
{ if (c - common == lb) { diff = -1; break; }
{
int i;
for (i = w->s_size - 1 - common; i >= 0; i--)
{
if (c - common == lb)
{
diff = -1;
break;
}
diff = q[-common] - w->s[i];
if (diff != 0) break;
if (diff != 0)
break;
common++;
}
}
if (diff < 0) { j = k; common_j = common; }
else { i = k; common_i = common; }
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{ if (i > 0) break;
if (j == i) break;
if (first_key_inspected) break;
{
if (i > 0)
break;
if (j == i)
break;
if (first_key_inspected)
break;
first_key_inspected = 1;
}
}
while (1)
{ w = v + i;
{
w = v + i;
if (common_i >= w->s_size)
{ z->c = c - w->s_size;
if (w->function == 0) return w->result;
{ int res = w->function(z);
{
z->c = c - w->s_size;
if (res) return w->result;
if (w->function == 0)
return w->result;
{
int res = w->function(z);
z->c = c - w->s_size;
if (res)
return w->result;
}
}
i = w->substring_i;
if (i < 0) return 0;
if (i < 0)
return 0;
}
}
extern symbol * increase_size(symbol * p, int n)
{ int new_size = n + 20;
extern symbol *
increase_size(symbol * p, int n)
{
int new_size = n + 20;
symbol *q = (symbol *) (HEAD + (char *) malloc(HEAD + (new_size + 1) * sizeof(symbol)));
CAPACITY(q) = new_size;
memmove(q, p, CAPACITY(p) * sizeof(symbol)); lose_s(p); return q;
memmove(q, p, CAPACITY(p) * sizeof(symbol));
lose_s(p);
return q;
}
/* to replace symbols between c_bra and c_ket in z->p by the
s_size symbols at s
*/
extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s)
{ int adjustment = s_size - (c_ket - c_bra);
extern int
replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s)
{
int adjustment = s_size - (c_ket - c_bra);
int len = SIZE(z->p);
if (adjustment != 0)
{ if (adjustment + len > CAPACITY(z->p)) z->p = increase_size(z->p, adjustment + len);
{
if (adjustment + len > CAPACITY(z->p))
z->p = increase_size(z->p, adjustment + len);
memmove(z->p + c_ket + adjustment, z->p + c_ket, (len - c_ket) * sizeof(symbol));
SET_SIZE(z->p, adjustment + len);
z->l += adjustment;
if (z->c >= c_ket) z->c += adjustment; else
if (z->c > c_bra) z->c = c_bra;
if (z->c >= c_ket)
z->c += adjustment;
else if (z->c > c_bra)
z->c = c_bra;
}
unless(s_size == 0) memmove(z->p + c_bra, s, s_size * sizeof(symbol));
return adjustment;
}
static void slice_check(struct SN_env * z)
static void
slice_check(struct SN_env * z)
{
if (!(0 <= z->bra &&
z->bra <= z->ket &&
@ -264,63 +413,101 @@ static void slice_check(struct SN_env * z)
}
}
extern void slice_from_s(struct SN_env * z, int s_size, symbol * s)
{ slice_check(z);
extern void
slice_from_s(struct SN_env * z, int s_size, symbol * s)
{
slice_check(z);
replace_s(z, z->bra, z->ket, s_size, s);
}
extern void slice_from_v(struct SN_env * z, symbol * p)
{ slice_from_s(z, SIZE(p), p);
extern void
slice_from_v(struct SN_env * z, symbol * p)
{
slice_from_s(z, SIZE(p), p);
}
extern void slice_del(struct SN_env * z)
{ slice_from_s(z, 0, 0);
extern void
slice_del(struct SN_env * z)
{
slice_from_s(z, 0, 0);
}
extern void insert_s(struct SN_env * z, int bra, int ket, int s_size, symbol * s)
{ int adjustment = replace_s(z, bra, ket, s_size, s);
if (bra <= z->bra) z->bra += adjustment;
if (bra <= z->ket) z->ket += adjustment;
extern void
insert_s(struct SN_env * z, int bra, int ket, int s_size, symbol * s)
{
int adjustment = replace_s(z, bra, ket, s_size, s);
if (bra <= z->bra)
z->bra += adjustment;
if (bra <= z->ket)
z->ket += adjustment;
}
extern void insert_v(struct SN_env * z, int bra, int ket, symbol * p)
{ int adjustment = replace_s(z, bra, ket, SIZE(p), p);
if (bra <= z->bra) z->bra += adjustment;
if (bra <= z->ket) z->ket += adjustment;
extern void
insert_v(struct SN_env * z, int bra, int ket, symbol * p)
{
int adjustment = replace_s(z, bra, ket, SIZE(p), p);
if (bra <= z->bra)
z->bra += adjustment;
if (bra <= z->ket)
z->ket += adjustment;
}
extern symbol * slice_to(struct SN_env * z, symbol * p)
{ slice_check(z);
{ int len = z->ket - z->bra;
if (CAPACITY(p) < len) p = increase_size(p, len);
extern symbol *
slice_to(struct SN_env * z, symbol * p)
{
slice_check(z);
{
int len = z->ket - z->bra;
if (CAPACITY(p) < len)
p = increase_size(p, len);
memmove(p, z->p + z->bra, len * sizeof(symbol));
SET_SIZE(p, len);
}
return p;
}
extern symbol * assign_to(struct SN_env * z, symbol * p)
{ int len = z->l;
if (CAPACITY(p) < len) p = increase_size(p, len);
extern symbol *
assign_to(struct SN_env * z, symbol * p)
{
int len = z->l;
if (CAPACITY(p) < len)
p = increase_size(p, len);
memmove(p, z->p, len * sizeof(symbol));
SET_SIZE(p, len);
return p;
}
extern void debug(struct SN_env * z, int number, int line_count)
{ int i;
extern void
debug(struct SN_env * z, int number, int line_count)
{
int i;
int limit = SIZE(z->p);
/* if (number >= 0) printf("%3d (line %4d): '", number, line_count); */
if (number >= 0) printf("%3d (line %4d): [%d]'", number, line_count,limit);
if (number >= 0)
printf("%3d (line %4d): [%d]'", number, line_count, limit);
for (i = 0; i <= limit; i++)
{ if (z->lb == i) printf("{");
if (z->bra == i) printf("[");
if (z->c == i) printf("|");
if (z->ket == i) printf("]");
if (z->l == i) printf("}");
{
if (z->lb == i)
printf("{");
if (z->bra == i)
printf("[");
if (z->c == i)
printf("|");
if (z->ket == i)
printf("]");
if (z->l == i)
printf("}");
if (i < limit)
{ int ch = z->p[i];
if (ch == 0) ch = '#';
{
int ch = z->p[i];
if (ch == 0)
ch = '#';
printf("%c", ch);
}
}

View File

@ -14,9 +14,12 @@
#define STOPBUFLEN 4096
char *
lowerstr(char *str) {
lowerstr(char *str)
{
char *ptr = str;
while(*ptr) {
while (*ptr)
{
*ptr = tolower(*(unsigned char *) ptr);
ptr++;
}
@ -24,22 +27,29 @@ lowerstr(char *str) {
}
void
freestoplist(StopList *s) {
freestoplist(StopList * s)
{
char **ptr = s->stop;
if (ptr)
while( *ptr && s->len >0 ) {
while (*ptr && s->len > 0)
{
free(*ptr);
ptr++; s->len--;
ptr++;
s->len--;
free(s->stop);
}
memset(s, 0, sizeof(StopList));
}
void
readstoplist(text *in, StopList *s) {
readstoplist(text *in, StopList * s)
{
char **stop = NULL;
s->len = 0;
if ( in && VARSIZE(in) - VARHDRSZ > 0 ) {
if (in && VARSIZE(in) - VARHDRSZ > 0)
{
char *filename = text2char(in);
FILE *hin = NULL;
char buf[STOPBUFLEN];
@ -51,15 +61,20 @@ readstoplist(text *in, StopList *s) {
errmsg("could not open file \"%s\": %m",
filename)));
while( fgets(buf,STOPBUFLEN,hin) ) {
while (fgets(buf, STOPBUFLEN, hin))
{
buf[strlen(buf) - 1] = '\0';
if ( *buf=='\0' ) continue;
if (*buf == '\0')
continue;
if ( s->len>= reallen ) {
if (s->len >= reallen)
{
char **tmp;
reallen = (reallen) ? reallen * 2 : 16;
tmp = (char **) realloc((void *) stop, sizeof(char *) * reallen);
if (!tmp) {
if (!tmp)
{
freestoplist(s);
fclose(hin);
ereport(ERROR,
@ -70,7 +85,8 @@ readstoplist(text *in, StopList *s) {
}
stop[s->len] = strdup(buf);
if ( !stop[s->len] ) {
if (!stop[s->len])
{
freestoplist(s);
fclose(hin);
ereport(ERROR,
@ -89,21 +105,22 @@ readstoplist(text *in, StopList *s) {
}
static int
comparestr(const void *a, const void *b) {
comparestr(const void *a, const void *b)
{
return strcmp(*(char **) a, *(char **) b);
}
void
sortstoplist(StopList *s) {
sortstoplist(StopList * s)
{
if (s->stop && s->len > 0)
qsort(s->stop, s->len, sizeof(char *), comparestr);
}
bool
searchstoplist(StopList *s, char *key) {
searchstoplist(StopList * s, char *key)
{
if (s->wordop)
key = (*(s->wordop)) (key);
return (s->stop && s->len > 0 && bsearch(&key, s->stop, s->len, sizeof(char *), comparestr)) ? true : false;
}

View File

@ -30,18 +30,22 @@ static void *plan_name2id=NULL;
static Oid current_cfg_id = 0;
void
init_cfg(Oid id, TSCfgInfo *cfg) {
init_cfg(Oid id, TSCfgInfo * cfg)
{
Oid arg[2] = {OIDOID, OIDOID};
bool isnull;
Datum pars[2] = {ObjectIdGetDatum(id), ObjectIdGetDatum(id)};
int stat,i,j;
int stat,
i,
j;
text *ptr;
text *prsname = NULL;
MemoryContext oldcontext;
memset(cfg, 0, sizeof(TSCfgInfo));
SPI_connect();
if ( !plan_getcfg ) {
if (!plan_getcfg)
{
plan_getcfg = SPI_saveplan(SPI_prepare("select prs_name from pg_ts_cfg where oid = $1", 1, arg));
if (!plan_getcfg)
ts_error(ERROR, "SPI_prepare() failed");
@ -50,7 +54,8 @@ init_cfg(Oid id, TSCfgInfo *cfg) {
stat = SPI_execp(plan_getcfg, pars, " ", 1);
if (stat < 0)
ts_error(ERROR, "SPI_execp return %d", stat);
if ( SPI_processed > 0 ) {
if (SPI_processed > 0)
{
prsname = (text *) DatumGetPointer(
SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull)
);
@ -59,11 +64,13 @@ init_cfg(Oid id, TSCfgInfo *cfg) {
MemoryContextSwitchTo(oldcontext);
cfg->id = id;
} else
}
else
ts_error(ERROR, "No tsearch cfg with id %d", id);
arg[0] = TEXTOID;
if ( !plan_getmap ) {
if (!plan_getmap)
{
plan_getmap = SPI_saveplan(SPI_prepare("select lt.tokid, pg_ts_cfgmap.dict_name from pg_ts_cfgmap, pg_ts_cfg, token_type( $1 ) as lt where lt.alias = pg_ts_cfgmap.tok_alias and pg_ts_cfgmap.ts_name = pg_ts_cfg.ts_name and pg_ts_cfg.oid= $2 order by lt.tokid desc;", 2, arg));
if (!plan_getmap)
ts_error(ERROR, "SPI_prepare() failed");
@ -76,12 +83,14 @@ init_cfg(Oid id, TSCfgInfo *cfg) {
if (SPI_processed <= 0)
ts_error(ERROR, "No parser with id %d", id);
for(i=0;i<SPI_processed;i++) {
for (i = 0; i < SPI_processed; i++)
{
int lexid = DatumGetInt32(SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull));
ArrayType *toasted_a = (ArrayType *) PointerGetDatum(SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 2, &isnull));
ArrayType *a;
if ( !cfg->map ) {
if (!cfg->map)
{
cfg->len = lexid + 1;
cfg->map = (ListDictionary *) malloc(sizeof(ListDictionary) * cfg->len);
if (!cfg->map)
@ -106,7 +115,8 @@ init_cfg(Oid id, TSCfgInfo *cfg) {
memset(cfg->map[lexid].dict_id, 0, sizeof(Datum) * cfg->map[lexid].len);
ptr = (text *) ARR_DATA_PTR(a);
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
for(j=0;j<cfg->map[lexid].len;j++) {
for (j = 0; j < cfg->map[lexid].len; j++)
{
cfg->map[lexid].dict_id[j] = PointerGetDatum(ptextdup(ptr));
ptr = NEXTVAL(ptr);
}
@ -119,8 +129,10 @@ init_cfg(Oid id, TSCfgInfo *cfg) {
SPI_finish();
cfg->prs_id = name2id_prs(prsname);
pfree(prsname);
for(i=0;i<cfg->len;i++) {
for(j=0;j<cfg->map[i].len;j++) {
for (i = 0; i < cfg->len; i++)
{
for (j = 0; j < cfg->map[i].len; j++)
{
ptr = (text *) DatumGetPointer(cfg->map[i].dict_id[j]);
cfg->map[i].dict_id[j] = ObjectIdGetDatum(name2id_dict(ptr));
pfree(ptr);
@ -128,7 +140,8 @@ init_cfg(Oid id, TSCfgInfo *cfg) {
}
}
typedef struct {
typedef struct
{
TSCfgInfo *last_cfg;
int len;
int reallen;
@ -139,12 +152,17 @@ typedef struct {
static CFGList CList = {NULL, 0, 0, NULL, {0, 0, NULL}};
void
reset_cfg(void) {
reset_cfg(void)
{
freeSNMap(&(CList.name2id_map));
if ( CList.list ) {
int i,j;
if (CList.list)
{
int i,
j;
for (i = 0; i < CList.len; i++)
if ( CList.list[i].map ) {
if (CList.list[i].map)
{
for (j = 0; j < CList.list[i].len; j++)
if (CList.list[i].map[j].dict_id)
free(CList.list[i].map[j].dict_id);
@ -156,19 +174,23 @@ reset_cfg(void) {
}
static int
comparecfg(const void *a, const void *b) {
comparecfg(const void *a, const void *b)
{
return ((TSCfgInfo *) a)->id - ((TSCfgInfo *) b)->id;
}
TSCfgInfo *
findcfg(Oid id) {
findcfg(Oid id)
{
/* last used cfg */
if (CList.last_cfg && CList.last_cfg->id == id)
return CList.last_cfg;
/* already used cfg */
if ( CList.len != 0 ) {
if (CList.len != 0)
{
TSCfgInfo key;
key.id = id;
CList.last_cfg = bsearch(&key, CList.list, CList.len, sizeof(TSCfgInfo), comparecfg);
if (CList.last_cfg != NULL)
@ -176,9 +198,11 @@ findcfg(Oid id) {
}
/* last chance */
if ( CList.len==CList.reallen ) {
if (CList.len == CList.reallen)
{
TSCfgInfo *tmp;
int reallen = (CList.reallen) ? 2 * CList.reallen : 16;
tmp = (TSCfgInfo *) realloc(CList.list, sizeof(TSCfgInfo) * reallen);
if (!tmp)
ts_error(ERROR, "No memory");
@ -194,7 +218,8 @@ findcfg(Oid id) {
Oid
name2id_cfg(text *name) {
name2id_cfg(text *name)
{
Oid arg[1] = {TEXTOID};
bool isnull;
Datum pars[1] = {PointerGetDatum(name)};
@ -205,7 +230,8 @@ name2id_cfg(text *name) {
return id;
SPI_connect();
if ( !plan_name2id ) {
if (!plan_name2id)
{
plan_name2id = SPI_saveplan(SPI_prepare("select oid from pg_ts_cfg where ts_name = $1", 1, arg));
if (!plan_name2id)
/* internal error */
@ -216,13 +242,15 @@ name2id_cfg(text *name) {
if (stat < 0)
/* internal error */
elog(ERROR, "SPI_execp return %d", stat);
if ( SPI_processed > 0 ) {
if (SPI_processed > 0)
{
id = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("null id for tsearch config")));
} else
}
else
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("no tsearch config")));
@ -234,8 +262,11 @@ name2id_cfg(text *name) {
void
parsetext_v2(TSCfgInfo *cfg, PRSTEXT * prs, char *buf, int4 buflen) {
int type, lenlemm, i;
parsetext_v2(TSCfgInfo * cfg, PRSTEXT * prs, char *buf, int4 buflen)
{
int type,
lenlemm,
i;
char *lemm = NULL;
WParserInfo *prsobj = findprs(cfg->prs_id);
@ -251,7 +282,8 @@ parsetext_v2(TSCfgInfo *cfg, PRSTEXT * prs, char *buf, int4 buflen) {
&(prsobj->getlexeme_info),
PointerGetDatum(prsobj->prs),
PointerGetDatum(&lemm),
PointerGetDatum(&lenlemm))) ) != 0 ) {
PointerGetDatum(&lenlemm)))) != 0)
{
if (lenlemm >= MAXSTRLEN)
ereport(ERROR,
@ -261,9 +293,11 @@ parsetext_v2(TSCfgInfo *cfg, PRSTEXT * prs, char *buf, int4 buflen) {
if (type >= cfg->len) /* skip this type of lexem */
continue;
for(i=0;i<cfg->map[type].len;i++) {
for (i = 0; i < cfg->map[type].len; i++)
{
DictInfo *dict = finddict(DatumGetObjectId(cfg->map[type].dict_id[i]));
char **norms, **ptr;
char **norms,
**ptr;
norms = ptr = (char **) DatumGetPointer(
FunctionCall3(
@ -278,8 +312,10 @@ parsetext_v2(TSCfgInfo *cfg, PRSTEXT * prs, char *buf, int4 buflen) {
prs->pos++; /* set pos */
while( *ptr ) {
if (prs->curwords == prs->lenwords) {
while (*ptr)
{
if (prs->curwords == prs->lenwords)
{
prs->lenwords *= 2;
prs->words = (WORD *) repalloc((void *) prs->words, prs->lenwords * sizeof(WORD));
}
@ -292,7 +328,8 @@ parsetext_v2(TSCfgInfo *cfg, PRSTEXT * prs, char *buf, int4 buflen) {
prs->curwords++;
}
pfree(norms);
break; /* lexem already normalized or is stop word*/
break; /* lexem already normalized or is stop
* word */
}
}
@ -303,8 +340,10 @@ parsetext_v2(TSCfgInfo *cfg, PRSTEXT * prs, char *buf, int4 buflen) {
}
static void
hladdword(HLPRSTEXT * prs, char *buf, int4 buflen, int type) {
while (prs->curwords >= prs->lenwords) {
hladdword(HLPRSTEXT * prs, char *buf, int4 buflen, int type)
{
while (prs->curwords >= prs->lenwords)
{
prs->lenwords *= 2;
prs->words = (HLWORD *) repalloc((void *) prs->words, prs->lenwords * sizeof(HLWORD));
}
@ -317,24 +356,30 @@ hladdword(HLPRSTEXT * prs, char *buf, int4 buflen, int type) {
}
static void
hlfinditem(HLPRSTEXT * prs, QUERYTYPE *query, char *buf, int buflen ) {
hlfinditem(HLPRSTEXT * prs, QUERYTYPE * query, char *buf, int buflen)
{
int i;
ITEM *item = GETQUERY(query);
HLWORD *word = &(prs->words[prs->curwords - 1]);
while (prs->curwords + query->size >= prs->lenwords) {
while (prs->curwords + query->size >= prs->lenwords)
{
prs->lenwords *= 2;
prs->words = (HLWORD *) repalloc((void *) prs->words, prs->lenwords * sizeof(HLWORD));
}
for(i=0; i<query->size; i++) {
if ( item->type == VAL && item->length == buflen && strncmp( GETOPERAND(query) + item->distance, buf, buflen )==0 ) {
if ( word->item ) {
for (i = 0; i < query->size; i++)
{
if (item->type == VAL && item->length == buflen && strncmp(GETOPERAND(query) + item->distance, buf, buflen) == 0)
{
if (word->item)
{
memcpy(&(prs->words[prs->curwords]), word, sizeof(HLWORD));
prs->words[prs->curwords].item = item;
prs->words[prs->curwords].repeated = 1;
prs->curwords++;
} else
}
else
word->item = item;
}
item++;
@ -342,8 +387,11 @@ hlfinditem(HLPRSTEXT * prs, QUERYTYPE *query, char *buf, int buflen ) {
}
void
hlparsetext(TSCfgInfo *cfg, HLPRSTEXT * prs, QUERYTYPE *query, char *buf, int4 buflen) {
int type, lenlemm, i;
hlparsetext(TSCfgInfo * cfg, HLPRSTEXT * prs, QUERYTYPE * query, char *buf, int4 buflen)
{
int type,
lenlemm,
i;
char *lemm = NULL;
WParserInfo *prsobj = findprs(cfg->prs_id);
@ -359,7 +407,8 @@ hlparsetext(TSCfgInfo *cfg, HLPRSTEXT * prs, QUERYTYPE *query, char *buf, int4 b
&(prsobj->getlexeme_info),
PointerGetDatum(prsobj->prs),
PointerGetDatum(&lemm),
PointerGetDatum(&lenlemm))) ) != 0 ) {
PointerGetDatum(&lenlemm)))) != 0)
{
if (lenlemm >= MAXSTRLEN)
ereport(ERROR,
@ -371,9 +420,11 @@ hlparsetext(TSCfgInfo *cfg, HLPRSTEXT * prs, QUERYTYPE *query, char *buf, int4 b
if (type >= cfg->len)
continue;
for(i=0;i<cfg->map[type].len;i++) {
for (i = 0; i < cfg->map[type].len; i++)
{
DictInfo *dict = finddict(DatumGetObjectId(cfg->map[type].dict_id[i]));
char **norms, **ptr;
char **norms,
**ptr;
norms = ptr = (char **) DatumGetPointer(
FunctionCall3(
@ -386,13 +437,15 @@ hlparsetext(TSCfgInfo *cfg, HLPRSTEXT * prs, QUERYTYPE *query, char *buf, int4 b
if (!norms) /* dictionary doesn't know this lexem */
continue;
while( *ptr ) {
while (*ptr)
{
hlfinditem(prs, query, *ptr, strlen(*ptr));
pfree(*ptr);
ptr++;
}
pfree(norms);
break; /* lexem already normalized or is stop word*/
break; /* lexem already normalized or is stop
* word */
}
}
@ -403,7 +456,8 @@ hlparsetext(TSCfgInfo *cfg, HLPRSTEXT * prs, QUERYTYPE *query, char *buf, int4 b
}
text *
genhl(HLPRSTEXT * prs) {
genhl(HLPRSTEXT * prs)
{
text *out;
int len = 128;
char *ptr;
@ -412,26 +466,35 @@ genhl(HLPRSTEXT * prs) {
out = (text *) palloc(len);
ptr = ((char *) out) + VARHDRSZ;
while( wrd - prs->words < prs->curwords ) {
while ( wrd->len + prs->stopsellen + prs->startsellen + (ptr - ((char*)out)) >= len ) {
while (wrd - prs->words < prs->curwords)
{
while (wrd->len + prs->stopsellen + prs->startsellen + (ptr - ((char *) out)) >= len)
{
int dist = ptr - ((char *) out);
len *= 2;
out = (text *) repalloc(out, len);
ptr = ((char *) out) + dist;
}
if ( wrd->in && !wrd->skip && !wrd->repeated ) {
if ( wrd->replace ) {
if (wrd->in && !wrd->skip && !wrd->repeated)
{
if (wrd->replace)
{
*ptr = ' ';
ptr++;
} else {
if (wrd->selected) {
}
else
{
if (wrd->selected)
{
memcpy(ptr, prs->startsel, prs->startsellen);
ptr += prs->startsellen;
}
memcpy(ptr, wrd->word, wrd->len);
ptr += wrd->len;
if (wrd->selected) {
if (wrd->selected)
{
memcpy(ptr, prs->stopsel, prs->stopsellen);
ptr += prs->stopsellen;
}
@ -449,7 +512,8 @@ genhl(HLPRSTEXT * prs) {
}
int
get_currcfg(void) {
get_currcfg(void)
{
Oid arg[1] = {TEXTOID};
const char *curlocale;
Datum pars[1];
@ -460,7 +524,8 @@ get_currcfg(void) {
return current_cfg_id;
SPI_connect();
if ( !plan_getcfg_bylocale ) {
if (!plan_getcfg_bylocale)
{
plan_getcfg_bylocale = SPI_saveplan(SPI_prepare("select oid from pg_ts_cfg where locale = $1 ", 1, arg));
if (!plan_getcfg_bylocale)
/* internal error */
@ -489,7 +554,8 @@ get_currcfg(void) {
PG_FUNCTION_INFO_V1(set_curcfg);
Datum set_curcfg(PG_FUNCTION_ARGS);
Datum
set_curcfg(PG_FUNCTION_ARGS) {
set_curcfg(PG_FUNCTION_ARGS)
{
findcfg(PG_GETARG_OID(0));
current_cfg_id = PG_GETARG_OID(0);
PG_RETURN_VOID();
@ -498,7 +564,8 @@ set_curcfg(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(set_curcfg_byname);
Datum set_curcfg_byname(PG_FUNCTION_ARGS);
Datum
set_curcfg_byname(PG_FUNCTION_ARGS) {
set_curcfg_byname(PG_FUNCTION_ARGS)
{
text *name = PG_GETARG_TEXT_P(0);
DirectFunctionCall1(
@ -512,14 +579,16 @@ set_curcfg_byname(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(show_curcfg);
Datum show_curcfg(PG_FUNCTION_ARGS);
Datum
show_curcfg(PG_FUNCTION_ARGS) {
show_curcfg(PG_FUNCTION_ARGS)
{
PG_RETURN_OID(get_currcfg());
}
PG_FUNCTION_INFO_V1(reset_tsearch);
Datum reset_tsearch(PG_FUNCTION_ARGS);
Datum
reset_tsearch(PG_FUNCTION_ARGS) {
reset_tsearch(PG_FUNCTION_ARGS)
{
ts_error(NOTICE, "TSearch cache cleaned");
PG_RETURN_VOID();
}

View File

@ -3,12 +3,14 @@
#include "postgres.h"
#include "query.h"
typedef struct {
typedef struct
{
int len;
Datum *dict_id;
} ListDictionary;
typedef struct {
typedef struct
{
Oid id;
Oid prs_id;
int len;
@ -20,9 +22,11 @@ TSCfgInfo * findcfg(Oid id);
void init_cfg(Oid id, TSCfgInfo * cfg);
void reset_cfg(void);
typedef struct {
typedef struct
{
uint16 len;
union {
union
{
uint16 pos;
uint16 *apos;
} pos;
@ -30,14 +34,16 @@ typedef struct {
uint32 alen;
} WORD;
typedef struct {
typedef struct
{
WORD *words;
int4 lenwords;
int4 curwords;
int4 pos;
} PRSTEXT;
typedef struct {
typedef struct
{
uint16 len;
uint8 selected:1,
in:1,
@ -49,7 +55,8 @@ typedef struct {
ITEM *item;
} HLWORD;
typedef struct {
typedef struct
{
HLWORD *words;
int4 lenwords;
int4 curwords;

View File

@ -12,8 +12,10 @@
PG_FUNCTION_INFO_V1(tsstat_in);
Datum tsstat_in(PG_FUNCTION_ARGS);
Datum
tsstat_in(PG_FUNCTION_ARGS) {
tsstat_in(PG_FUNCTION_ARGS)
{
tsstat *stat = palloc(STATHDRSIZE);
stat->len = STATHDRSIZE;
stat->size = 0;
PG_RETURN_POINTER(stat);
@ -22,7 +24,8 @@ tsstat_in(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(tsstat_out);
Datum tsstat_out(PG_FUNCTION_ARGS);
Datum
tsstat_out(PG_FUNCTION_ARGS) {
tsstat_out(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("tsstat_out not implemented")));
@ -30,11 +33,15 @@ tsstat_out(PG_FUNCTION_ARGS) {
}
static WordEntry **
SEI_realloc( WordEntry** in, uint32 *len ) {
if ( *len==0 || in==NULL ) {
SEI_realloc(WordEntry ** in, uint32 *len)
{
if (*len == 0 || in == NULL)
{
*len = 8;
in = palloc(sizeof(WordEntry *) * (*len));
} else {
}
else
{
*len *= 2;
in = repalloc(in, sizeof(WordEntry *) * (*len));
}
@ -42,7 +49,8 @@ SEI_realloc( WordEntry** in, uint32 *len ) {
}
static int
compareStatWord(StatEntry *a, WordEntry *b, tsstat *stat, tsvector *txt) {
compareStatWord(StatEntry * a, WordEntry * b, tsstat * stat, tsvector * txt)
{
if (a->len == b->len)
return strncmp(
STATSTRPTR(stat) + a->pos,
@ -53,15 +61,19 @@ compareStatWord(StatEntry *a, WordEntry *b, tsstat *stat, tsvector *txt) {
}
static tsstat *
formstat(tsstat *stat, tsvector *txt, WordEntry** entry, uint32 len) {
formstat(tsstat * stat, tsvector * txt, WordEntry ** entry, uint32 len)
{
tsstat *newstat;
uint32 totallen, nentry;
uint32 totallen,
nentry;
uint32 slen = 0;
WordEntry **ptr = entry;
char *curptr;
StatEntry *sptr,*nptr;
StatEntry *sptr,
*nptr;
while(ptr-entry<len) {
while (ptr - entry < len)
{
slen += (*ptr)->len;
ptr++;
}
@ -80,11 +92,13 @@ formstat(tsstat *stat, tsvector *txt, WordEntry** entry, uint32 len) {
sptr = STATPTR(stat);
nptr = STATPTR(newstat);
if ( len == 1 ) {
if (len == 1)
{
StatEntry *StopLow = STATPTR(stat);
StatEntry *StopHigh = (StatEntry *) STATSTRPTR(stat);
while (StopLow < StopHigh) {
while (StopLow < StopHigh)
{
sptr = StopLow + (StopHigh - StopLow) / 2;
if (compareStatWord(sptr, *ptr, stat, txt) < 0)
StopLow = sptr + 1;
@ -101,12 +115,18 @@ formstat(tsstat *stat, tsvector *txt, WordEntry** entry, uint32 len) {
memcpy(curptr, STRPTR(txt) + (*ptr)->pos, nptr->len);
nptr->pos = curptr - STATSTRPTR(newstat);
memcpy(nptr + 1, StopLow, sizeof(StatEntry) * (((StatEntry *) STATSTRPTR(stat)) - StopLow));
} else {
while( sptr-STATPTR(stat) < stat->size && ptr-entry<len) {
if ( compareStatWord(sptr,*ptr,stat,txt) < 0 ) {
}
else
{
while (sptr - STATPTR(stat) < stat->size && ptr - entry < len)
{
if (compareStatWord(sptr, *ptr, stat, txt) < 0)
{
memcpy(nptr, sptr, sizeof(StatEntry));
sptr++;
} else {
}
else
{
nptr->nentry = POSDATALEN(txt, *ptr);
if (nptr->nentry == 0)
nptr->nentry = 1;
@ -122,7 +142,8 @@ formstat(tsstat *stat, tsvector *txt, WordEntry** entry, uint32 len) {
memcpy(nptr, sptr, sizeof(StatEntry) * (stat->size - (sptr - STATPTR(stat))));
while(ptr-entry<len) {
while (ptr - entry < len)
{
nptr->nentry = POSDATALEN(txt, *ptr);
if (nptr->nentry == 0)
nptr->nentry = 1;
@ -131,7 +152,8 @@ formstat(tsstat *stat, tsvector *txt, WordEntry** entry, uint32 len) {
memcpy(curptr, STRPTR(txt) + (*ptr)->pos, nptr->len);
nptr->pos = curptr - STATSTRPTR(newstat);
curptr += nptr->len;
ptr++; nptr++;
ptr++;
nptr++;
}
}
@ -141,22 +163,27 @@ formstat(tsstat *stat, tsvector *txt, WordEntry** entry, uint32 len) {
PG_FUNCTION_INFO_V1(ts_accum);
Datum ts_accum(PG_FUNCTION_ARGS);
Datum
ts_accum(PG_FUNCTION_ARGS) {
tsstat *newstat,*stat= (tsstat*)PG_GETARG_POINTER(0);
ts_accum(PG_FUNCTION_ARGS)
{
tsstat *newstat,
*stat = (tsstat *) PG_GETARG_POINTER(0);
tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
WordEntry **newentry = NULL;
uint32 len=0, cur=0;
uint32 len = 0,
cur = 0;
StatEntry *sptr;
WordEntry *wptr;
if ( stat==NULL || PG_ARGISNULL(0) ) { /* Init in first */
if (stat == NULL || PG_ARGISNULL(0))
{ /* Init in first */
stat = palloc(STATHDRSIZE);
stat->len = STATHDRSIZE;
stat->size = 0;
}
/* simple check of correctness */
if ( txt==NULL || PG_ARGISNULL(1) || txt->size==0 ) {
if (txt == NULL || PG_ARGISNULL(1) || txt->size == 0)
{
PG_FREE_IF_COPY(txt, 1);
PG_RETURN_POINTER(stat);
}
@ -164,54 +191,74 @@ ts_accum(PG_FUNCTION_ARGS) {
sptr = STATPTR(stat);
wptr = ARRPTR(txt);
if ( stat->size < 100*txt->size ) { /* merge */
while( sptr-STATPTR(stat) < stat->size && wptr-ARRPTR(txt) < txt->size ) {
if (stat->size < 100 * txt->size)
{ /* merge */
while (sptr - STATPTR(stat) < stat->size && wptr - ARRPTR(txt) < txt->size)
{
int cmp = compareStatWord(sptr, wptr, stat, txt);
if ( cmp<0 ) {
if (cmp < 0)
sptr++;
} else if ( cmp==0 ) {
else if (cmp == 0)
{
int n = POSDATALEN(txt, wptr);
if (n==0) n=1;
if (n == 0)
n = 1;
sptr->ndoc++;
sptr->nentry += n;
sptr++; wptr++;
} else {
sptr++;
wptr++;
}
else
{
if (cur == len)
newentry = SEI_realloc(newentry, &len);
newentry[cur] = wptr;
wptr++; cur++;
wptr++;
cur++;
}
}
while( wptr-ARRPTR(txt) < txt->size ) {
while (wptr - ARRPTR(txt) < txt->size)
{
if (cur == len)
newentry = SEI_realloc(newentry, &len);
newentry[cur] = wptr;
wptr++; cur++;
wptr++;
cur++;
}
} else { /* search */
while( wptr-ARRPTR(txt) < txt->size ) {
}
else
{ /* search */
while (wptr - ARRPTR(txt) < txt->size)
{
StatEntry *StopLow = STATPTR(stat);
StatEntry *StopHigh = (StatEntry *) STATSTRPTR(stat);
int cmp;
while (StopLow < StopHigh) {
while (StopLow < StopHigh)
{
sptr = StopLow + (StopHigh - StopLow) / 2;
cmp = compareStatWord(sptr, wptr, stat, txt);
if (cmp==0) {
if (cmp == 0)
{
int n = POSDATALEN(txt, wptr);
if (n==0) n=1;
if (n == 0)
n = 1;
sptr->ndoc++;
sptr->nentry += n;
break;
} else if ( cmp < 0 )
}
else if (cmp < 0)
StopLow = sptr + 1;
else
StopHigh = sptr;
}
if ( StopLow >= StopHigh ) { /* not found */
if (StopLow >= StopHigh)
{ /* not found */
if (cur == len)
newentry = SEI_realloc(newentry, &len);
newentry[cur] = wptr;
@ -222,7 +269,8 @@ ts_accum(PG_FUNCTION_ARGS) {
}
if ( cur==0 ) { /* no new words */
if (cur == 0)
{ /* no new words */
PG_FREE_IF_COPY(txt, 1);
PG_RETURN_POINTER(stat);
}
@ -235,13 +283,15 @@ ts_accum(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(newstat);
}
typedef struct {
typedef struct
{
uint32 cur;
tsvector *stat;
} StatStorage;
static void
ts_setup_firstcall(FuncCallContext *funcctx, tsstat *stat) {
ts_setup_firstcall(FuncCallContext *funcctx, tsstat * stat)
{
TupleDesc tupdesc;
MemoryContext oldcontext;
StatStorage *st;
@ -260,11 +310,14 @@ ts_setup_firstcall(FuncCallContext *funcctx, tsstat *stat) {
static Datum
ts_process_call(FuncCallContext *funcctx) {
ts_process_call(FuncCallContext *funcctx)
{
StatStorage *st;
st = (StatStorage *) funcctx->user_fctx;
if ( st->cur < st->stat->size ) {
if (st->cur < st->stat->size)
{
Datum result;
char *values[3];
char ndoc[16];
@ -286,7 +339,9 @@ ts_process_call(FuncCallContext *funcctx) {
pfree(values[0]);
st->cur++;
return result;
} else {
}
else
{
pfree(st->stat);
pfree(st);
}
@ -297,11 +352,13 @@ ts_process_call(FuncCallContext *funcctx) {
PG_FUNCTION_INFO_V1(ts_accum_finish);
Datum ts_accum_finish(PG_FUNCTION_ARGS);
Datum
ts_accum_finish(PG_FUNCTION_ARGS) {
ts_accum_finish(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
ts_setup_firstcall(funcctx, (tsstat *) PG_GETARG_POINTER(0));
}
@ -314,7 +371,8 @@ ts_accum_finish(PG_FUNCTION_ARGS) {
static Oid tiOid = InvalidOid;
static void
get_ti_Oid(void) {
get_ti_Oid(void)
{
int ret;
bool isnull;
@ -332,10 +390,12 @@ get_ti_Oid(void) {
}
static tsstat *
ts_stat_sql(text *txt) {
ts_stat_sql(text *txt)
{
char *query = text2char(txt);
int i;
tsstat *newstat,*stat;
tsstat *newstat,
*stat;
bool isnull;
Portal portal;
void *plan;
@ -365,11 +425,14 @@ ts_stat_sql(text *txt) {
stat->len = STATHDRSIZE;
stat->size = 0;
while(SPI_processed>0) {
for(i=0;i<SPI_processed;i++) {
while (SPI_processed > 0)
{
for (i = 0; i < SPI_processed; i++)
{
Datum data = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull);
if ( !isnull ) {
if (!isnull)
{
newstat = (tsstat *) DatumGetPointer(DirectFunctionCall2(
ts_accum,
PointerGetDatum(stat),
@ -396,11 +459,13 @@ ts_stat_sql(text *txt) {
PG_FUNCTION_INFO_V1(ts_stat);
Datum ts_stat(PG_FUNCTION_ARGS);
Datum
ts_stat(PG_FUNCTION_ARGS) {
ts_stat(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
tsstat *stat;
text *txt = PG_GETARG_TEXT_P(0);
@ -417,5 +482,3 @@ ts_stat(PG_FUNCTION_ARGS) {
SRF_RETURN_NEXT(funcctx, result);
SRF_RETURN_DONE(funcctx);
}

View File

@ -8,14 +8,16 @@
#include "utils/builtins.h"
#include "storage/bufpage.h"
typedef struct {
typedef struct
{
uint32 len;
uint32 pos;
uint32 ndoc;
uint32 nentry;
} StatEntry;
typedef struct {
typedef struct
{
int4 len;
int4 size;
char data[1];

View File

@ -31,8 +31,10 @@ Datum tsvector_out(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(to_tsvector);
Datum to_tsvector(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(to_tsvector_current);
Datum to_tsvector_current(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(to_tsvector_name);
Datum to_tsvector_name(PG_FUNCTION_ARGS);
@ -46,15 +48,18 @@ Datum tsvector_length(PG_FUNCTION_ARGS);
* in/out text index type
*/
static int
comparePos(const void *a, const void *b) {
comparePos(const void *a, const void *b)
{
if (((WordEntryPos *) a)->pos == ((WordEntryPos *) b)->pos)
return 1;
return (((WordEntryPos *) a)->pos > ((WordEntryPos *) b)->pos) ? 1 : -1;
}
static int
uniquePos(WordEntryPos *a, int4 l) {
WordEntryPos *ptr, *res;
uniquePos(WordEntryPos * a, int4 l)
{
WordEntryPos *ptr,
*res;
res = a;
if (l == 1)
@ -63,14 +68,17 @@ uniquePos(WordEntryPos *a, int4 l) {
qsort((void *) a, l, sizeof(WordEntryPos), comparePos);
ptr = a + 1;
while (ptr - a < l) {
if ( ptr->pos != res->pos ) {
while (ptr - a < l)
{
if (ptr->pos != res->pos)
{
res++;
res->pos = ptr->pos;
res->weight = ptr->weight;
if (res - a >= MAXNUMPOS - 1 || res->pos == MAXENTRYPOS - 1)
break;
} else if ( ptr->weight > res->weight )
}
else if (ptr->weight > res->weight)
res->weight = ptr->weight;
ptr++;
}
@ -98,8 +106,10 @@ uniqueentry(WordEntryIN * a, int4 l, char *buf, int4 *outbuflen)
*res;
res = a;
if (l == 1) {
if ( a->entry.haspos ) {
if (l == 1)
{
if (a->entry.haspos)
{
*(uint16 *) (a->pos) = uniquePos(&(a->pos[1]), *(uint16 *) (a->pos));
*outbuflen = SHORTALIGN(res->entry.len) + (*(uint16 *) (a->pos) + 1) * sizeof(WordEntryPos);
}
@ -115,29 +125,37 @@ uniqueentry(WordEntryIN * a, int4 l, char *buf, int4 *outbuflen)
if (!(ptr->entry.len == res->entry.len &&
strncmp(&buf[ptr->entry.pos], &buf[res->entry.pos], res->entry.len) == 0))
{
if ( res->entry.haspos ) {
if (res->entry.haspos)
{
*(uint16 *) (res->pos) = uniquePos(&(res->pos[1]), *(uint16 *) (res->pos));
*outbuflen += *(uint16 *) (res->pos) * sizeof(WordEntryPos);
}
*outbuflen += SHORTALIGN(res->entry.len);
res++;
memcpy(res, ptr, sizeof(WordEntryIN));
} else if ( ptr->entry.haspos ){
if ( res->entry.haspos ) {
}
else if (ptr->entry.haspos)
{
if (res->entry.haspos)
{
int4 len = *(uint16 *) (ptr->pos) + 1 + *(uint16 *) (res->pos);
res->pos = (WordEntryPos *) repalloc(res->pos, len * sizeof(WordEntryPos));
memcpy(&(res->pos[*(uint16 *) (res->pos) + 1]),
&(ptr->pos[1]), *(uint16 *) (ptr->pos) * sizeof(WordEntryPos));
*(uint16 *) (res->pos) += *(uint16 *) (ptr->pos);
pfree(ptr->pos);
} else {
}
else
{
res->entry.haspos = 1;
res->pos = ptr->pos;
}
}
ptr++;
}
if ( res->entry.haspos ) {
if (res->entry.haspos)
{
*(uint16 *) (res->pos) = uniquePos(&(res->pos[1]), *(uint16 *) (res->pos));
*outbuflen += *(uint16 *) (res->pos) * sizeof(WordEntryPos);
}
@ -229,7 +247,9 @@ gettoken_tsvector(TI_IN_STATE * state)
errmsg("syntax error")));
*(state->curpos) = '\0';
return 1;
} else if ( *(state->prsbuf) == ':' ) {
}
else if (*(state->prsbuf) == ':')
{
if (state->curpos == state->word)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
@ -257,10 +277,12 @@ gettoken_tsvector(TI_IN_STATE * state)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
if ( state->oprisdelim ) {
if (state->oprisdelim)
{
state->prsbuf++;
return 1;
} else
}
else
state->state = WAITPOSINFO;
}
else if (*(state->prsbuf) == '\\')
@ -278,18 +300,26 @@ gettoken_tsvector(TI_IN_STATE * state)
*(state->curpos) = *(state->prsbuf);
state->curpos++;
}
} else if (state->state == WAITPOSINFO) {
}
else if (state->state == WAITPOSINFO)
{
if (*(state->prsbuf) == ':')
state->state = INPOSINFO;
else
return 1;
} else if (state->state == INPOSINFO) {
if ( isdigit(*(state->prsbuf)) ) {
if ( state->alen==0 ) {
}
else if (state->state == INPOSINFO)
{
if (isdigit(*(state->prsbuf)))
{
if (state->alen == 0)
{
state->alen = 4;
state->pos = (WordEntryPos *) palloc(sizeof(WordEntryPos) * state->alen);
*(uint16 *) (state->pos) = 0;
} else if ( *(uint16*)(state->pos) +1 >= state->alen ) {
}
else if (*(uint16 *) (state->pos) + 1 >= state->alen)
{
state->alen *= 2;
state->pos = (WordEntryPos *) repalloc(state->pos, sizeof(WordEntryPos) * state->alen);
}
@ -301,44 +331,56 @@ gettoken_tsvector(TI_IN_STATE * state)
errmsg("wrong position info")));
state->pos[*(uint16 *) (state->pos)].weight = 0;
state->state = WAITPOSDELIM;
} else
}
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
} else if (state->state == WAITPOSDELIM) {
if ( *(state->prsbuf) == ',' ) {
}
else if (state->state == WAITPOSDELIM)
{
if (*(state->prsbuf) == ',')
state->state = INPOSINFO;
} else if ( tolower(*(state->prsbuf)) == 'a' || *(state->prsbuf)=='*' ) {
else if (tolower(*(state->prsbuf)) == 'a' || *(state->prsbuf) == '*')
{
if (state->pos[*(uint16 *) (state->pos)].weight)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
state->pos[*(uint16 *) (state->pos)].weight = 3;
} else if ( tolower(*(state->prsbuf)) == 'b' ) {
}
else if (tolower(*(state->prsbuf)) == 'b')
{
if (state->pos[*(uint16 *) (state->pos)].weight)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
state->pos[*(uint16 *) (state->pos)].weight = 2;
} else if ( tolower(*(state->prsbuf)) == 'c' ) {
}
else if (tolower(*(state->prsbuf)) == 'c')
{
if (state->pos[*(uint16 *) (state->pos)].weight)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
state->pos[*(uint16 *) (state->pos)].weight = 1;
} else if ( tolower(*(state->prsbuf)) == 'd' ) {
}
else if (tolower(*(state->prsbuf)) == 'd')
{
if (state->pos[*(uint16 *) (state->pos)].weight)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
state->pos[*(uint16 *) (state->pos)].weight = 0;
} else if ( isspace(*(state->prsbuf)) || *(state->prsbuf) == '\0' ) {
}
else if (isspace(*(state->prsbuf)) || *(state->prsbuf) == '\0')
return 1;
} else if ( !isdigit(*(state->prsbuf)) )
else if (!isdigit(*(state->prsbuf)))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
} else
}
else
/* internal error */
elog(ERROR, "internal error");
state->prsbuf++;
@ -396,10 +438,12 @@ tsvector_in(PG_FUNCTION_ARGS)
arr[len].entry.pos = cur - tmpbuf;
memcpy((void *) cur, (void *) state.word, arr[len].entry.len);
cur += arr[len].entry.len;
if ( state.alen ) {
if (state.alen)
{
arr[len].entry.haspos = 1;
arr[len].pos = state.pos;
} else
}
else
arr[len].entry.haspos = 0;
len++;
}
@ -419,7 +463,8 @@ tsvector_in(PG_FUNCTION_ARGS)
memcpy((void *) cur, (void *) &tmpbuf[arr[i].entry.pos], arr[i].entry.len);
arr[i].entry.pos = cur - STRPTR(in);
cur += SHORTALIGN(arr[i].entry.len);
if ( arr[i].entry.haspos ) {
if (arr[i].entry.haspos)
{
memcpy(cur, arr[i].pos, (*(uint16 *) arr[i].pos + 1) * sizeof(WordEntryPos));
cur += (*(uint16 *) arr[i].pos + 1) * sizeof(WordEntryPos);
pfree(arr[i].pos);
@ -448,13 +493,15 @@ tsvector_out(PG_FUNCTION_ARGS)
char *outbuf;
int4 i,
j,
lenbuf = 0, pp;
lenbuf = 0,
pp;
WordEntry *ptr = ARRPTR(out);
char *curin,
*curout;
lenbuf = out->size * 2 /* '' */ + out->size - 1 /* space */ + 2 /* \0 */ ;
for (i = 0; i < out->size; i++) {
for (i = 0; i < out->size; i++)
{
lenbuf += ptr[i].len * 2 /* for escape */ ;
if (ptr[i].haspos)
lenbuf += 7 * POSDATALEN(out, &(ptr[i]));
@ -481,22 +528,35 @@ tsvector_out(PG_FUNCTION_ARGS)
*curout++ = *curin++;
}
*curout++ = '\'';
if ( (pp=POSDATALEN(out,ptr)) != 0 ) {
if ((pp = POSDATALEN(out, ptr)) != 0)
{
WordEntryPos *wptr;
*curout++ = ':';
wptr = POSDATAPTR(out, ptr);
while(pp) {
while (pp)
{
sprintf(curout, "%d", wptr->pos);
curout = strchr(curout, '\0');
switch( wptr->weight ) {
case 3: *curout++ = 'A'; break;
case 2: *curout++ = 'B'; break;
case 1: *curout++ = 'C'; break;
switch (wptr->weight)
{
case 3:
*curout++ = 'A';
break;
case 2:
*curout++ = 'B';
break;
case 1:
*curout++ = 'C';
break;
case 0:
default: break;
default:
break;
}
if ( pp>1 ) *curout++ = ',';
pp--; wptr++;
if (pp > 1)
*curout++ = ',';
pp--;
wptr++;
}
}
ptr++;
@ -510,11 +570,13 @@ tsvector_out(PG_FUNCTION_ARGS)
static int
compareWORD(const void *a, const void *b)
{
if (((WORD *) a)->len == ((WORD *) b)->len) {
if (((WORD *) a)->len == ((WORD *) b)->len)
{
int res = strncmp(
((WORD *) a)->word,
((WORD *) b)->word,
((WORD *) b)->len);
if (res == 0)
return (((WORD *) a)->pos.pos > ((WORD *) b)->pos.pos) ? 1 : -1;
return res;
@ -529,7 +591,8 @@ uniqueWORD(WORD * a, int4 l)
*res;
int tmppos;
if (l == 1) {
if (l == 1)
{
tmppos = LIMITPOS(a->pos.pos);
a->alen = 2;
a->pos.apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
@ -561,10 +624,14 @@ uniqueWORD(WORD * a, int4 l)
res->pos.apos = (uint16 *) palloc(sizeof(uint16) * res->alen);
res->pos.apos[0] = 1;
res->pos.apos[1] = tmppos;
} else {
}
else
{
pfree(ptr->word);
if ( res->pos.apos[0] < MAXNUMPOS-1 && res->pos.apos[ res->pos.apos[0] ] != MAXENTRYPOS-1 ) {
if ( res->pos.apos[0]+1 >= res->alen ) {
if (res->pos.apos[0] < MAXNUMPOS - 1 && res->pos.apos[res->pos.apos[0]] != MAXENTRYPOS - 1)
{
if (res->pos.apos[0] + 1 >= res->alen)
{
res->alen *= 2;
res->pos.apos = (uint16 *) repalloc(res->pos.apos, sizeof(uint16) * res->alen);
}
@ -584,7 +651,8 @@ uniqueWORD(WORD * a, int4 l)
static tsvector *
makevalue(PRSTEXT * prs)
{
int4 i,j,
int4 i,
j,
lenstr = 0,
totallen;
tsvector *in;
@ -593,7 +661,8 @@ makevalue(PRSTEXT * prs)
*cur;
prs->curwords = uniqueWORD(prs->words, prs->curwords);
for (i = 0; i < prs->curwords; i++) {
for (i = 0; i < prs->curwords; i++)
{
lenstr += SHORTALIGN(prs->words[i].len);
if (prs->words[i].alen)
@ -619,19 +688,22 @@ makevalue(PRSTEXT * prs)
memcpy((void *) cur, (void *) prs->words[i].word, prs->words[i].len);
pfree(prs->words[i].word);
cur += SHORTALIGN(prs->words[i].len);
if ( prs->words[i].alen ) {
if (prs->words[i].alen)
{
WordEntryPos *wptr;
ptr->haspos = 1;
*(uint16 *) cur = prs->words[i].pos.apos[0];
wptr = POSDATAPTR(in, ptr);
for(j=0;j<*(uint16*)cur;j++) {
for (j = 0; j < *(uint16 *) cur; j++)
{
wptr[j].weight = 0;
wptr[j].pos = prs->words[i].pos.apos[j + 1];
}
cur += sizeof(uint16) + prs->words[i].pos.apos[0] * sizeof(WordEntryPos);
pfree(prs->words[i].pos.apos);
} else
}
else
ptr->haspos = 0;
ptr++;
}
@ -658,7 +730,8 @@ to_tsvector(PG_FUNCTION_ARGS)
if (prs.curwords)
out = makevalue(&prs);
else {
else
{
pfree(prs.words);
out = palloc(CALCDATASIZE(0, 0));
out->len = CALCDATASIZE(0, 0);
@ -668,7 +741,8 @@ to_tsvector(PG_FUNCTION_ARGS)
}
Datum
to_tsvector_name(PG_FUNCTION_ARGS) {
to_tsvector_name(PG_FUNCTION_ARGS)
{
text *cfg = PG_GETARG_TEXT_P(0);
Datum res = DirectFunctionCall3(
to_tsvector,
@ -676,24 +750,29 @@ to_tsvector_name(PG_FUNCTION_ARGS) {
PG_GETARG_DATUM(1),
(Datum) 0
);
PG_FREE_IF_COPY(cfg, 0);
PG_RETURN_DATUM(res);
}
Datum
to_tsvector_current(PG_FUNCTION_ARGS) {
to_tsvector_current(PG_FUNCTION_ARGS)
{
Datum res = DirectFunctionCall3(
to_tsvector,
Int32GetDatum(get_currcfg()),
PG_GETARG_DATUM(0),
(Datum) 0
);
PG_RETURN_DATUM(res);
}
static Oid
findFunc(char *fname) {
FuncCandidateList clist,ptr;
findFunc(char *fname)
{
FuncCandidateList clist,
ptr;
Oid funcid = InvalidOid;
List *names = makeList1(makeString(fname));
@ -703,7 +782,8 @@ findFunc(char *fname) {
if (!ptr)
return funcid;
while(ptr) {
while (ptr)
{
if (ptr->args[0] == TEXTOID && funcid == InvalidOid)
funcid = ptr->oid;
clist = ptr->next;
@ -805,15 +885,18 @@ tsearch2(PG_FUNCTION_ARGS)
if (isnull)
continue;
if ( funcoid!=InvalidOid ) {
if (funcoid != InvalidOid)
{
text *txttmp = (text *) DatumGetPointer(OidFunctionCall1(
funcoid,
PointerGetDatum(txt_toasted)
));
txt = (text *) DatumGetPointer(PG_DETOAST_DATUM(PointerGetDatum(txttmp)));
if (txt == txttmp)
txt_toasted = PointerGetDatum(txt);
} else
}
else
txt = (text *) DatumGetPointer(PG_DETOAST_DATUM(PointerGetDatum(txt_toasted)));
parsetext_v2(cfg, &prs, VARDATA(txt), VARSIZE(txt) - VARHDRSZ);
@ -832,6 +915,7 @@ tsearch2(PG_FUNCTION_ARGS)
else
{
tsvector *out = palloc(CALCDATASIZE(0, 0));
out->len = CALCDATASIZE(0, 0);
out->size = 0;
datum = PointerGetDatum(out);

View File

@ -12,20 +12,24 @@
#include "utils/builtins.h"
#include "storage/bufpage.h"
typedef struct {
typedef struct
{
uint32
haspos:1,
len:11, /* MAX 2Kb */
pos:20; /* MAX 1Mb */
} WordEntry;
#define MAXSTRLEN ( 1<<11 )
#define MAXSTRPOS ( 1<<20 )
typedef struct {
typedef struct
{
uint16
weight:2,
pos:14;
} WordEntryPos;
#define MAXENTRYPOS (1<<14)
#define MAXNUMPOS 256
#define LIMITPOS(x) ( ( (x) >= MAXENTRYPOS ) ? (MAXENTRYPOS-1) : (x) )
@ -47,7 +51,8 @@ typedef struct
#define POSDATAPTR(x,e) ( (WordEntryPos*)( _POSDATAPTR(x,e)+sizeof(uint16) ) )
typedef struct {
typedef struct
{
WordEntry entry;
WordEntryPos *pos;
} WordEntryIN;

View File

@ -35,8 +35,10 @@ strip(PG_FUNCTION_ARGS)
{
tsvector *in = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
tsvector *out;
int i,len=0;
WordEntry *arrin=ARRPTR(in), *arrout;
int i,
len = 0;
WordEntry *arrin = ARRPTR(in),
*arrout;
char *cur;
for (i = 0; i < in->size; i++)
@ -49,7 +51,8 @@ strip(PG_FUNCTION_ARGS)
out->size = in->size;
arrout = ARRPTR(out);
cur = STRPTR(out);
for(i=0;i<in->size;i++) {
for (i = 0; i < in->size; i++)
{
memcpy(cur, STRPTR(in) + arrin[i].pos, arrin[i].len);
arrout[i].haspos = 0;
arrout[i].len = arrin[i].len;
@ -67,28 +70,42 @@ setweight(PG_FUNCTION_ARGS)
tsvector *in = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
char cw = PG_GETARG_CHAR(1);
tsvector *out;
int i,j;
int i,
j;
WordEntry *entry;
WordEntryPos *p;
int w = 0;
switch(tolower(cw)) {
case 'a': w=3; break;
case 'b': w=2; break;
case 'c': w=1; break;
case 'd': w=0; break;
switch (tolower(cw))
{
case 'a':
w = 3;
break;
case 'b':
w = 2;
break;
case 'c':
w = 1;
break;
case 'd':
w = 0;
break;
/* internal error */
default: elog(ERROR,"unrecognized weight");
default:
elog(ERROR, "unrecognized weight");
}
out = (tsvector *) palloc(in->len);
memcpy(out, in, in->len);
entry = ARRPTR(out);
i = out->size;
while(i--) {
if ( (j=POSDATALEN(out,entry)) != 0 ) {
while (i--)
{
if ((j = POSDATALEN(out, entry)) != 0)
{
p = POSDATAPTR(out, entry);
while(j--) {
while (j--)
{
p->weight = w;
p++;
}
@ -114,17 +131,21 @@ compareEntry(char *ptra, WordEntry* a, char *ptrb, WordEntry* b)
}
static int4
add_pos(tsvector *src, WordEntry *srcptr, tsvector *dest, WordEntry *destptr, int4 maxpos ) {
add_pos(tsvector * src, WordEntry * srcptr, tsvector * dest, WordEntry * destptr, int4 maxpos)
{
uint16 *clen = (uint16 *) _POSDATAPTR(dest, destptr);
int i;
uint16 slen = POSDATALEN(src, srcptr), startlen;
WordEntryPos *spos=POSDATAPTR(src, srcptr), *dpos=POSDATAPTR(dest,destptr);
uint16 slen = POSDATALEN(src, srcptr),
startlen;
WordEntryPos *spos = POSDATAPTR(src, srcptr),
*dpos = POSDATAPTR(dest, destptr);
if (!destptr->haspos)
*clen = 0;
startlen = *clen;
for(i=0; i<slen && *clen<MAXNUMPOS && ( *clen==0 || dpos[ *clen-1 ].pos != MAXENTRYPOS-1 ) ;i++) {
for (i = 0; i < slen && *clen < MAXNUMPOS && (*clen == 0 || dpos[*clen - 1].pos != MAXENTRYPOS - 1); i++)
{
dpos[*clen].weight = spos[i].weight;
dpos[*clen].pos = LIMITPOS(spos[i].pos + maxpos);
(*clen)++;
@ -137,23 +158,34 @@ add_pos(tsvector *src, WordEntry *srcptr, tsvector *dest, WordEntry *destptr, in
Datum
concat(PG_FUNCTION_ARGS) {
concat(PG_FUNCTION_ARGS)
{
tsvector *in1 = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
tsvector *in2 = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
tsvector *out;
WordEntry *ptr;
WordEntry *ptr1,*ptr2;
WordEntry *ptr1,
*ptr2;
WordEntryPos *p;
int maxpos=0,i,j,i1,i2;
int maxpos = 0,
i,
j,
i1,
i2;
char *cur;
char *data,*data1,*data2;
char *data,
*data1,
*data2;
ptr = ARRPTR(in1);
i = in1->size;
while(i--) {
if ( (j=POSDATALEN(in1,ptr)) != 0 ) {
while (i--)
{
if ((j = POSDATALEN(in1, ptr)) != 0)
{
p = POSDATAPTR(in1, ptr);
while(j--) {
while (j--)
{
if (p->pos > maxpos)
maxpos = p->pos;
p++;
@ -162,93 +194,128 @@ concat(PG_FUNCTION_ARGS) {
ptr++;
}
ptr1=ARRPTR(in1); ptr2=ARRPTR(in2);
data1=STRPTR(in1); data2=STRPTR(in2);
i1=in1->size; i2=in2->size;
ptr1 = ARRPTR(in1);
ptr2 = ARRPTR(in2);
data1 = STRPTR(in1);
data2 = STRPTR(in2);
i1 = in1->size;
i2 = in2->size;
out = (tsvector *) palloc(in1->len + in2->len);
memset(out, 0, in1->len + in2->len);
out->len = in1->len + in2->len;
out->size = in1->size + in2->size;
data = cur = STRPTR(out);
ptr = ARRPTR(out);
while( i1 && i2 ) {
while (i1 && i2)
{
int cmp = compareEntry(data1, ptr1, data2, ptr2);
if ( cmp < 0 ) { /* in1 first */
if (cmp < 0)
{ /* in1 first */
ptr->haspos = ptr1->haspos;
ptr->len = ptr1->len;
memcpy(cur, data1 + ptr1->pos, ptr1->len);
ptr->pos = cur - data;
cur += SHORTALIGN(ptr1->len);
if ( ptr->haspos ) {
if (ptr->haspos)
{
memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
}
ptr++; ptr1++; i1--;
} else if ( cmp>0 ) { /* in2 first */
ptr++;
ptr1++;
i1--;
}
else if (cmp > 0)
{ /* in2 first */
ptr->haspos = ptr2->haspos;
ptr->len = ptr2->len;
memcpy(cur, data2 + ptr2->pos, ptr2->len);
ptr->pos = cur - data;
cur += SHORTALIGN(ptr2->len);
if ( ptr->haspos ) {
if (ptr->haspos)
{
int addlen = add_pos(in2, ptr2, out, ptr, maxpos);
if (addlen == 0)
ptr->haspos = 0;
else
cur += addlen * sizeof(WordEntryPos) + sizeof(uint16);
}
ptr++; ptr2++; i2--;
} else {
ptr++;
ptr2++;
i2--;
}
else
{
ptr->haspos = ptr1->haspos | ptr2->haspos;
ptr->len = ptr1->len;
memcpy(cur, data1 + ptr1->pos, ptr1->len);
ptr->pos = cur - data;
cur += SHORTALIGN(ptr1->len);
if ( ptr->haspos ) {
if ( ptr1->haspos ) {
if (ptr->haspos)
{
if (ptr1->haspos)
{
memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
if (ptr2->haspos)
cur += add_pos(in2, ptr2, out, ptr, maxpos) * sizeof(WordEntryPos);
} else if ( ptr2->haspos ) {
}
else if (ptr2->haspos)
{
int addlen = add_pos(in2, ptr2, out, ptr, maxpos);
if (addlen == 0)
ptr->haspos = 0;
else
cur += addlen * sizeof(WordEntryPos) + sizeof(uint16);
}
}
ptr++; ptr1++; ptr2++; i1--; i2--;
ptr++;
ptr1++;
ptr2++;
i1--;
i2--;
}
}
while(i1) {
while (i1)
{
ptr->haspos = ptr1->haspos;
ptr->len = ptr1->len;
memcpy(cur, data1 + ptr1->pos, ptr1->len);
ptr->pos = cur - data;
cur += SHORTALIGN(ptr1->len);
if ( ptr->haspos ) {
if (ptr->haspos)
{
memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
}
ptr++; ptr1++; i1--;
ptr++;
ptr1++;
i1--;
}
while(i2) {
while (i2)
{
ptr->haspos = ptr2->haspos;
ptr->len = ptr2->len;
memcpy(cur, data2 + ptr2->pos, ptr2->len);
ptr->pos = cur - data;
cur += SHORTALIGN(ptr2->len);
if ( ptr->haspos ) {
if (ptr->haspos)
{
int addlen = add_pos(in2, ptr2, out, ptr, maxpos);
if (addlen == 0)
ptr->haspos = 0;
else
cur += addlen * sizeof(WordEntryPos) + sizeof(uint16);
}
ptr++; ptr2++; i2--;
ptr++;
ptr2++;
i2--;
}
out->size = ptr - ARRPTR(out);
@ -260,4 +327,3 @@ concat(PG_FUNCTION_ARGS) {
PG_FREE_IF_COPY(in2, 1);
PG_RETURN_POINTER(out);
}

View File

@ -53,4 +53,3 @@ const char *tok_alias[]={
"uint",
"entity"
};

View File

@ -25,7 +25,8 @@ static void *plan_getparser=NULL;
static Oid current_parser_id = InvalidOid;
void
init_prs(Oid id, WParserInfo *prs) {
init_prs(Oid id, WParserInfo * prs)
{
Oid arg[1] = {OIDOID};
bool isnull;
Datum pars[1] = {ObjectIdGetDatum(id)};
@ -33,7 +34,8 @@ init_prs(Oid id, WParserInfo *prs) {
memset(prs, 0, sizeof(WParserInfo));
SPI_connect();
if ( !plan_getparser ) {
if (!plan_getparser)
{
plan_getparser = SPI_saveplan(SPI_prepare("select prs_start, prs_nexttoken, prs_end, prs_lextype, prs_headline from pg_ts_parser where oid = $1", 1, arg));
if (!plan_getparser)
ts_error(ERROR, "SPI_prepare() failed");
@ -42,8 +44,10 @@ init_prs(Oid id, WParserInfo *prs) {
stat = SPI_execp(plan_getparser, pars, " ", 1);
if (stat < 0)
ts_error(ERROR, "SPI_execp return %d", stat);
if ( SPI_processed > 0 ) {
if (SPI_processed > 0)
{
Oid oid = InvalidOid;
oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
fmgr_info_cxt(oid, &(prs->start_info), TopMemoryContext);
oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull));
@ -54,12 +58,14 @@ init_prs(Oid id, WParserInfo *prs) {
oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 5, &isnull));
fmgr_info_cxt(oid, &(prs->headline_info), TopMemoryContext);
prs->prs_id = id;
} else
}
else
ts_error(ERROR, "No parser with id %d", id);
SPI_finish();
}
typedef struct {
typedef struct
{
WParserInfo *last_prs;
int len;
int reallen;
@ -70,7 +76,8 @@ typedef struct {
static PrsList PList = {NULL, 0, 0, NULL, {0, 0, NULL}};
void
reset_prs(void) {
reset_prs(void)
{
freeSNMap(&(PList.name2id_map));
if (PList.list)
free(PList.list);
@ -78,19 +85,23 @@ reset_prs(void) {
}
static int
compareprs(const void *a, const void *b) {
compareprs(const void *a, const void *b)
{
return ((WParserInfo *) a)->prs_id - ((WParserInfo *) b)->prs_id;
}
WParserInfo *
findprs(Oid id) {
findprs(Oid id)
{
/* last used prs */
if (PList.last_prs && PList.last_prs->prs_id == id)
return PList.last_prs;
/* already used prs */
if ( PList.len != 0 ) {
if (PList.len != 0)
{
WParserInfo key;
key.prs_id = id;
PList.last_prs = bsearch(&key, PList.list, PList.len, sizeof(WParserInfo), compareprs);
if (PList.last_prs != NULL)
@ -98,9 +109,11 @@ findprs(Oid id) {
}
/* last chance */
if ( PList.len==PList.reallen ) {
if (PList.len == PList.reallen)
{
WParserInfo *tmp;
int reallen = (PList.reallen) ? 2 * PList.reallen : 16;
tmp = (WParserInfo *) realloc(PList.list, sizeof(WParserInfo) * reallen);
if (!tmp)
ts_error(ERROR, "No memory");
@ -117,7 +130,8 @@ findprs(Oid id) {
static void *plan_name2id = NULL;
Oid
name2id_prs(text *name) {
name2id_prs(text *name)
{
Oid arg[1] = {TEXTOID};
bool isnull;
Datum pars[1] = {PointerGetDatum(name)};
@ -129,7 +143,8 @@ name2id_prs(text *name) {
SPI_connect();
if ( !plan_name2id ) {
if (!plan_name2id)
{
plan_name2id = SPI_saveplan(SPI_prepare("select oid from pg_ts_parser where prs_name = $1", 1, arg));
if (!plan_name2id)
ts_error(ERROR, "SPI_prepare() failed");
@ -149,13 +164,15 @@ name2id_prs(text *name) {
/******sql-level interface******/
typedef struct {
typedef struct
{
int cur;
LexDescr *list;
} TypeStorage;
static void
setup_firstcall(FuncCallContext *funcctx, Oid prsid) {
setup_firstcall(FuncCallContext *funcctx, Oid prsid)
{
TupleDesc tupdesc;
MemoryContext oldcontext;
TypeStorage *st;
@ -176,11 +193,13 @@ setup_firstcall(FuncCallContext *funcctx, Oid prsid) {
}
static Datum
process_call(FuncCallContext *funcctx) {
process_call(FuncCallContext *funcctx)
{
TypeStorage *st;
st = (TypeStorage *) funcctx->user_fctx;
if ( st->list && st->list[st->cur].lexid ) {
if (st->list && st->list[st->cur].lexid)
{
Datum result;
char *values[3];
char txtid[16];
@ -198,8 +217,11 @@ process_call(FuncCallContext *funcctx) {
pfree(values[2]);
st->cur++;
return result;
} else {
if ( st->list ) pfree(st->list);
}
else
{
if (st->list)
pfree(st->list);
pfree(st);
}
return (Datum) 0;
@ -209,11 +231,13 @@ PG_FUNCTION_INFO_V1(token_type);
Datum token_type(PG_FUNCTION_ARGS);
Datum
token_type(PG_FUNCTION_ARGS) {
token_type(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
setup_firstcall(funcctx, PG_GETARG_OID(0));
}
@ -228,12 +252,15 @@ token_type(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(token_type_byname);
Datum token_type_byname(PG_FUNCTION_ARGS);
Datum
token_type_byname(PG_FUNCTION_ARGS) {
token_type_byname(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
text *name = PG_GETARG_TEXT_P(0);
funcctx = SRF_FIRSTCALL_INIT();
setup_firstcall(funcctx, name2id_prs(name));
PG_FREE_IF_COPY(name, 0);
@ -249,11 +276,13 @@ token_type_byname(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(token_type_current);
Datum token_type_current(PG_FUNCTION_ARGS);
Datum
token_type_current(PG_FUNCTION_ARGS) {
token_type_current(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
if (current_parser_id == InvalidOid)
current_parser_id = name2id_prs(char2text("default"));
@ -271,7 +300,8 @@ token_type_current(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(set_curprs);
Datum set_curprs(PG_FUNCTION_ARGS);
Datum
set_curprs(PG_FUNCTION_ARGS) {
set_curprs(PG_FUNCTION_ARGS)
{
findprs(PG_GETARG_OID(0));
current_parser_id = PG_GETARG_OID(0);
PG_RETURN_VOID();
@ -280,7 +310,8 @@ set_curprs(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(set_curprs_byname);
Datum set_curprs_byname(PG_FUNCTION_ARGS);
Datum
set_curprs_byname(PG_FUNCTION_ARGS) {
set_curprs_byname(PG_FUNCTION_ARGS)
{
text *name = PG_GETARG_TEXT_P(0);
DirectFunctionCall1(
@ -291,12 +322,14 @@ set_curprs_byname(PG_FUNCTION_ARGS) {
PG_RETURN_VOID();
}
typedef struct {
typedef struct
{
int type;
char *lexem;
} LexemEntry;
typedef struct {
typedef struct
{
int cur;
int len;
LexemEntry *list;
@ -304,13 +337,15 @@ typedef struct {
static void
prs_setup_firstcall(FuncCallContext *funcctx, int prsid, text *txt) {
prs_setup_firstcall(FuncCallContext *funcctx, int prsid, text *txt)
{
TupleDesc tupdesc;
MemoryContext oldcontext;
PrsStorage *st;
WParserInfo *prs = findprs(prsid);
char *lex = NULL;
int llen=0, type=0;
int llen = 0,
type = 0;
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
@ -331,9 +366,11 @@ prs_setup_firstcall(FuncCallContext *funcctx, int prsid, text *txt) {
&(prs->getlexeme_info),
PointerGetDatum(prs->prs),
PointerGetDatum(&lex),
PointerGetDatum(&llen))) ) != 0 ) {
PointerGetDatum(&llen)))) != 0)
{
if ( st->cur>=st->len ) {
if (st->cur >= st->len)
{
st->len = 2 * st->len;
st->list = (LexemEntry *) repalloc(st->list, sizeof(LexemEntry) * st->len);
}
@ -360,11 +397,13 @@ prs_setup_firstcall(FuncCallContext *funcctx, int prsid, text *txt) {
}
static Datum
prs_process_call(FuncCallContext *funcctx) {
prs_process_call(FuncCallContext *funcctx)
{
PrsStorage *st;
st = (PrsStorage *) funcctx->user_fctx;
if ( st->cur < st->len ) {
if (st->cur < st->len)
{
Datum result;
char *values[2];
char tid[16];
@ -379,8 +418,11 @@ prs_process_call(FuncCallContext *funcctx) {
pfree(values[1]);
st->cur++;
return result;
} else {
if ( st->list ) pfree(st->list);
}
else
{
if (st->list)
pfree(st->list);
pfree(st);
}
return (Datum) 0;
@ -391,12 +433,15 @@ prs_process_call(FuncCallContext *funcctx) {
PG_FUNCTION_INFO_V1(parse);
Datum parse(PG_FUNCTION_ARGS);
Datum
parse(PG_FUNCTION_ARGS) {
parse(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
text *txt = PG_GETARG_TEXT_P(1);
funcctx = SRF_FIRSTCALL_INIT();
prs_setup_firstcall(funcctx, PG_GETARG_OID(0), txt);
PG_FREE_IF_COPY(txt, 1);
@ -412,13 +457,16 @@ parse(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(parse_byname);
Datum parse_byname(PG_FUNCTION_ARGS);
Datum
parse_byname(PG_FUNCTION_ARGS) {
parse_byname(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
text *name = PG_GETARG_TEXT_P(0);
text *txt = PG_GETARG_TEXT_P(1);
funcctx = SRF_FIRSTCALL_INIT();
prs_setup_firstcall(funcctx, name2id_prs(name), txt);
PG_FREE_IF_COPY(name, 0);
@ -436,12 +484,15 @@ parse_byname(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(parse_current);
Datum parse_current(PG_FUNCTION_ARGS);
Datum
parse_current(PG_FUNCTION_ARGS) {
parse_current(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL()) {
if (SRF_IS_FIRSTCALL())
{
text *txt = PG_GETARG_TEXT_P(0);
funcctx = SRF_FIRSTCALL_INIT();
if (current_parser_id == InvalidOid)
current_parser_id = name2id_prs(char2text("default"));
@ -459,7 +510,8 @@ parse_current(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(headline);
Datum headline(PG_FUNCTION_ARGS);
Datum
headline(PG_FUNCTION_ARGS) {
headline(PG_FUNCTION_ARGS)
{
TSCfgInfo *cfg = findcfg(PG_GETARG_OID(0));
text *in = PG_GETARG_TEXT_P(1);
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(2)));
@ -485,7 +537,8 @@ headline(PG_FUNCTION_ARGS) {
PG_FREE_IF_COPY(in, 1);
PG_FREE_IF_COPY(query, 2);
if ( opt ) PG_FREE_IF_COPY(opt,3);
if (opt)
PG_FREE_IF_COPY(opt, 3);
pfree(prs.words);
pfree(prs.startsel);
pfree(prs.stopsel);
@ -497,7 +550,8 @@ headline(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(headline_byname);
Datum headline_byname(PG_FUNCTION_ARGS);
Datum
headline_byname(PG_FUNCTION_ARGS) {
headline_byname(PG_FUNCTION_ARGS)
{
text *cfg = PG_GETARG_TEXT_P(0);
Datum out = DirectFunctionCall4(
@ -515,7 +569,8 @@ headline_byname(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(headline_current);
Datum headline_current(PG_FUNCTION_ARGS);
Datum
headline_current(PG_FUNCTION_ARGS) {
headline_current(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall4(
headline,
ObjectIdGetDatum(get_currcfg()),
@ -524,6 +579,3 @@ headline_current(PG_FUNCTION_ARGS) {
(PG_NARGS() > 2) ? PG_GETARG_DATUM(2) : PointerGetDatum(NULL)
));
}

View File

@ -3,7 +3,8 @@
#include "postgres.h"
#include "fmgr.h"
typedef struct {
typedef struct
{
Oid prs_id;
FmgrInfo start_info;
FmgrInfo getlexeme_info;
@ -19,7 +20,8 @@ Oid name2id_prs(text *name);
void reset_prs(void);
typedef struct {
typedef struct
{
int lexid;
char *alias;
char *descr;

View File

@ -20,11 +20,13 @@ PG_FUNCTION_INFO_V1(prsd_lextype);
Datum prsd_lextype(PG_FUNCTION_ARGS);
Datum
prsd_lextype(PG_FUNCTION_ARGS) {
prsd_lextype(PG_FUNCTION_ARGS)
{
LexDescr *descr = (LexDescr *) palloc(sizeof(LexDescr) * (LASTNUM + 1));
int i;
for(i=1;i<=LASTNUM;i++) {
for (i = 1; i <= LASTNUM; i++)
{
descr[i - 1].lexid = i;
descr[i - 1].alias = pstrdup(tok_alias[i]);
descr[i - 1].descr = pstrdup(lex_descr[i]);
@ -38,7 +40,8 @@ prsd_lextype(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(prsd_start);
Datum prsd_start(PG_FUNCTION_ARGS);
Datum
prsd_start(PG_FUNCTION_ARGS) {
prsd_start(PG_FUNCTION_ARGS)
{
start_parse_str((char *) PG_GETARG_POINTER(0), PG_GETARG_INT32(1));
PG_RETURN_POINTER(NULL);
}
@ -46,7 +49,8 @@ prsd_start(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(prsd_getlexeme);
Datum prsd_getlexeme(PG_FUNCTION_ARGS);
Datum
prsd_getlexeme(PG_FUNCTION_ARGS) {
prsd_getlexeme(PG_FUNCTION_ARGS)
{
/* ParserState *p=(ParserState*)PG_GETARG_POINTER(0); */
char **t = (char **) PG_GETARG_POINTER(1);
int *tlen = (int *) PG_GETARG_POINTER(2);
@ -60,7 +64,8 @@ prsd_getlexeme(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(prsd_end);
Datum prsd_end(PG_FUNCTION_ARGS);
Datum
prsd_end(PG_FUNCTION_ARGS) {
prsd_end(PG_FUNCTION_ARGS)
{
/* ParserState *p=(ParserState*)PG_GETARG_POINTER(0); */
end_parse();
PG_RETURN_VOID();
@ -76,15 +81,19 @@ prsd_end(PG_FUNCTION_ARGS) {
#define NONWORDTOKEN(x) ( (x)==12 || HLIDIGNORE(x) )
#define NOENDTOKEN(x) ( NONWORDTOKEN(x) || (x)==7 || (x)==8 || (x)==20 || (x)==21 || (x)==22 || IDIGNORE(x) )
typedef struct {
typedef struct
{
HLWORD *words;
int len;
} hlCheck;
static bool
checkcondition_HL(void *checkval, ITEM *val) {
checkcondition_HL(void *checkval, ITEM * val)
{
int i;
for(i=0;i<((hlCheck*)checkval)->len;i++) {
for (i = 0; i < ((hlCheck *) checkval)->len; i++)
{
if (((hlCheck *) checkval)->words[i].item == val)
return true;
}
@ -93,20 +102,27 @@ checkcondition_HL(void *checkval, ITEM *val) {
static bool
hlCover(HLPRSTEXT *prs, QUERYTYPE *query, int *p, int *q) {
int i,j;
hlCover(HLPRSTEXT * prs, QUERYTYPE * query, int *p, int *q)
{
int i,
j;
ITEM *item = GETQUERY(query);
int pos = *p;
*q = 0;
*p = 0x7fffffff;
for(j=0;j<query->size;j++) {
if ( item->type != VAL ) {
for (j = 0; j < query->size; j++)
{
if (item->type != VAL)
{
item++;
continue;
}
for(i=pos;i<prs->curwords;i++) {
if ( prs->words[i].item == item ) {
for (i = pos; i < prs->curwords; i++)
{
if (prs->words[i].item == item)
{
if (i > *q)
*q = i;
break;
@ -119,13 +135,17 @@ hlCover(HLPRSTEXT *prs, QUERYTYPE *query, int *p, int *q) {
return false;
item = GETQUERY(query);
for(j=0;j<query->size;j++) {
if ( item->type != VAL ) {
for (j = 0; j < query->size; j++)
{
if (item->type != VAL)
{
item++;
continue;
}
for(i=*q;i>=pos;i--) {
if ( prs->words[i].item == item ) {
for (i = *q; i >= pos; i--)
{
if (prs->words[i].item == item)
{
if (i < *p)
*p = i;
break;
@ -134,11 +154,14 @@ hlCover(HLPRSTEXT *prs, QUERYTYPE *query, int *p, int *q) {
item++;
}
if ( *p<=*q ) {
if (*p <= *q)
{
hlCheck ch = {&(prs->words[*p]), *q - *p + 1};
if ( TS_execute(GETQUERY(query), &ch, false, checkcondition_HL) ) {
if (TS_execute(GETQUERY(query), &ch, false, checkcondition_HL))
return true;
} else {
else
{
(*p)++;
return hlCover(prs, query, p, q);
}
@ -150,32 +173,41 @@ hlCover(HLPRSTEXT *prs, QUERYTYPE *query, int *p, int *q) {
PG_FUNCTION_INFO_V1(prsd_headline);
Datum prsd_headline(PG_FUNCTION_ARGS);
Datum
prsd_headline(PG_FUNCTION_ARGS) {
prsd_headline(PG_FUNCTION_ARGS)
{
HLPRSTEXT *prs = (HLPRSTEXT *) PG_GETARG_POINTER(0);
text *opt = (text *) PG_GETARG_POINTER(1); /* can't be toasted */
QUERYTYPE *query = (QUERYTYPE *) PG_GETARG_POINTER(2); /* can't be toasted */
/* from opt + start and and tag */
int min_words = 15;
int max_words = 35;
int shortword = 3;
int p=0,q=0;
int bestb=-1,beste=-1;
int p = 0,
q = 0;
int bestb = -1,
beste = -1;
int bestlen = -1;
int pose=0, poslen, curlen;
int pose = 0,
poslen,
curlen;
int i;
/* config */
prs->startsel = NULL;
prs->stopsel = NULL;
if ( opt ) {
Map *map,*mptr;
if (opt)
{
Map *map,
*mptr;
parse_cfgdict(opt, &map);
mptr = map;
while(mptr && mptr->key) {
while (mptr && mptr->key)
{
if (strcasecmp(mptr->key, "MaxWords") == 0)
max_words = pg_atoi(mptr->value, 4, 1);
else if (strcasecmp(mptr->key, "MinWords") == 0)
@ -208,11 +240,13 @@ prsd_headline(PG_FUNCTION_ARGS) {
errmsg("must be ShortWord >= 0")));
}
while( hlCover(prs,query,&p,&q) ) {
while (hlCover(prs, query, &p, &q))
{
/* find cover len in words */
curlen = 0;
poslen = 0;
for(i=p;i<=q && curlen < max_words ; i++) {
for (i = p; i <= q && curlen < max_words; i++)
{
if (!NONWORDTOKEN(prs->words[i].type))
curlen++;
if (prs->words[i].item && !prs->words[i].repeated)
@ -220,15 +254,19 @@ prsd_headline(PG_FUNCTION_ARGS) {
pose = i;
}
if ( poslen<bestlen && !(NOENDTOKEN(prs->words[beste].type) || prs->words[beste].len <= shortword) ) {
if (poslen < bestlen && !(NOENDTOKEN(prs->words[beste].type) || prs->words[beste].len <= shortword))
{
/* best already finded, so try one more cover */
p++;
continue;
}
if ( curlen < max_words ) { /* find good end */
for(i=i-1 ;i<prs->curwords && curlen<max_words; i++) {
if ( i!=q ) {
if (curlen < max_words)
{ /* find good end */
for (i = i - 1; i < prs->curwords && curlen < max_words; i++)
{
if (i != q)
{
if (!NONWORDTOKEN(prs->words[i].type))
curlen++;
if (prs->words[i].item && !prs->words[i].repeated)
@ -240,8 +278,11 @@ prsd_headline(PG_FUNCTION_ARGS) {
if (curlen >= min_words)
break;
}
} else { /* shorter cover :((( */
for(;curlen>min_words;i--) {
}
else
{ /* shorter cover :((( */
for (; curlen > min_words; i--)
{
if (!NONWORDTOKEN(prs->words[i].type))
curlen--;
if (prs->words[i].item && !prs->words[i].repeated)
@ -255,26 +296,32 @@ prsd_headline(PG_FUNCTION_ARGS) {
if (bestlen < 0 || (poslen > bestlen && !(NOENDTOKEN(prs->words[pose].type) || prs->words[pose].len <= shortword)) ||
(bestlen >= 0 && !(NOENDTOKEN(prs->words[pose].type) || prs->words[pose].len <= shortword) &&
(NOENDTOKEN(prs->words[beste].type) || prs->words[beste].len <= shortword) ) ) {
bestb=p; beste=pose;
(NOENDTOKEN(prs->words[beste].type) || prs->words[beste].len <= shortword)))
{
bestb = p;
beste = pose;
bestlen = poslen;
}
p++;
}
if ( bestlen<0 ) {
if (bestlen < 0)
{
curlen = 0;
poslen = 0;
for(i=0;i<prs->curwords && curlen<min_words ; i++) {
for (i = 0; i < prs->curwords && curlen < min_words; i++)
{
if (!NONWORDTOKEN(prs->words[i].type))
curlen++;
pose = i;
}
bestb=0; beste=pose;
bestb = 0;
beste = pose;
}
for(i=bestb;i<=beste;i++) {
for (i = bestb; i <= beste; i++)
{
if (prs->words[i].item)
prs->words[i].selected = 1;
if (prs->words[i].repeated)
@ -294,4 +341,3 @@ prsd_headline(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(prs);
}

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.84 2003/07/21 20:29:37 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.85 2003/08/04 00:43:11 momjian Exp $
*
* NOTES
* The old interface functions have been converted to macros

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.65 2003/07/21 20:29:37 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.66 2003/08/04 00:43:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.75 2003/07/21 20:29:38 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.76 2003/08/04 00:43:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -81,8 +81,8 @@ printtup_create_DR(CommandDest dest, Portal portal)
else
{
/*
* In protocol 2.0 the Bind message does not exist, so there is
* no way for the columns to have different print formats; it's
* In protocol 2.0 the Bind message does not exist, so there is no
* way for the columns to have different print formats; it's
* sufficient to look at the first one.
*/
if (portal->formats && portal->formats[0] != 0)
@ -116,7 +116,8 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
{
/*
* Send portal name to frontend (obsolete cruft, gone in proto 3.0)
* Send portal name to frontend (obsolete cruft, gone in proto
* 3.0)
*
* If portal name not specified, use "blank" portal.
*/
@ -129,8 +130,8 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
}
/*
* If this is a retrieve, and we are supposed to emit row descriptions,
* then we send back the tuple descriptor of the tuples.
* If this is a retrieve, and we are supposed to emit row
* descriptions, then we send back the tuple descriptor of the tuples.
*/
if (operation == CMD_SELECT && myState->sendDescrip)
{
@ -320,8 +321,8 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
}
/*
* If we have a toasted datum, forcibly detoast it here to
* avoid memory leakage inside the type's output routine.
* If we have a toasted datum, forcibly detoast it here to avoid
* memory leakage inside the type's output routine.
*/
if (thisState->typisvarlena)
attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
@ -424,8 +425,8 @@ printtup_20(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
Assert(thisState->format == 0);
/*
* If we have a toasted datum, forcibly detoast it here to
* avoid memory leakage inside the type's output routine.
* If we have a toasted datum, forcibly detoast it here to avoid
* memory leakage inside the type's output routine.
*/
if (thisState->typisvarlena)
attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
@ -536,9 +537,10 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
continue;
getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
&typoutput, &typelem, &typisvarlena);
/*
* If we have a toasted datum, forcibly detoast it here to
* avoid memory leakage inside the type's output routine.
* If we have a toasted datum, forcibly detoast it here to avoid
* memory leakage inside the type's output routine.
*/
if (typisvarlena)
attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
@ -627,8 +629,8 @@ printtup_internal_20(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
Assert(thisState->format == 1);
/*
* If we have a toasted datum, forcibly detoast it here to
* avoid memory leakage inside the type's output routine.
* If we have a toasted datum, forcibly detoast it here to avoid
* memory leakage inside the type's output routine.
*/
if (thisState->typisvarlena)
attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.45 2003/07/28 00:09:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.46 2003/08/04 00:43:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -104,11 +104,12 @@ gistrescan(PG_FUNCTION_ARGS)
memmove(s->keyData,
key,
s->numberOfKeys * sizeof(ScanKeyData));
/*
* Play games here with the scan key to use the Consistent
* function for all comparisons: 1) the sk_procedure field
* will now be used to hold the strategy number 2) the
* sk_func field will point to the Consistent function
* function for all comparisons: 1) the sk_procedure field will
* now be used to hold the strategy number 2) the sk_func field
* will point to the Consistent function
*/
for (i = 0; i < s->numberOfKeys; i++)
{

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.36 2003/06/22 22:04:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.37 2003/08/04 00:43:12 momjian Exp $
*
* NOTES
* These functions are stored in pg_amproc. For each operator class
@ -60,9 +60,9 @@ hashfloat4(PG_FUNCTION_ARGS)
float4 key = PG_GETARG_FLOAT4(0);
/*
* On IEEE-float machines, minus zero and zero have different bit patterns
* but should compare as equal. We must ensure that they have the same
* hash value, which is most easily done this way:
* On IEEE-float machines, minus zero and zero have different bit
* patterns but should compare as equal. We must ensure that they
* have the same hash value, which is most easily done this way:
*/
if (key == (float4) 0)
PG_RETURN_UINT32(0);
@ -76,9 +76,9 @@ hashfloat8(PG_FUNCTION_ARGS)
float8 key = PG_GETARG_FLOAT8(0);
/*
* On IEEE-float machines, minus zero and zero have different bit patterns
* but should compare as equal. We must ensure that they have the same
* hash value, which is most easily done this way:
* On IEEE-float machines, minus zero and zero have different bit
* patterns but should compare as equal. We must ensure that they
* have the same hash value, which is most easily done this way:
*/
if (key == (float8) 0)
PG_RETURN_UINT32(0);
@ -121,9 +121,9 @@ hashtext(PG_FUNCTION_ARGS)
Datum result;
/*
* Note: this is currently identical in behavior to hashvarlena,
* but it seems likely that we may need to do something different
* in non-C locales. (See also hashbpchar, if so.)
* Note: this is currently identical in behavior to hashvarlena, but
* it seems likely that we may need to do something different in non-C
* locales. (See also hashbpchar, if so.)
*/
result = hash_any((unsigned char *) VARDATA(key),
VARSIZE(key) - VARHDRSZ);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.35 2003/07/21 20:29:38 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.36 2003/08/04 00:43:12 momjian Exp $
*
* NOTES
* Overflow pages look like ordinary relation pages.

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.152 2003/07/21 20:29:38 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.153 2003/08/04 00:43:14 momjian Exp $
*
*
* INTERFACE ROUTINES
@ -1132,6 +1132,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
xlhdr.t_natts = tup->t_data->t_natts;
xlhdr.t_infomask = tup->t_data->t_infomask;
xlhdr.t_hoff = tup->t_data->t_hoff;
/*
* note we mark rdata[1] as belonging to buffer; if XLogInsert
* decides to write the whole page to the xlog, we don't need to
@ -1149,9 +1150,9 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
rdata[2].next = NULL;
/*
* If this is the single and first tuple on page, we can reinit the
* page instead of restoring the whole thing. Set flag, and hide
* buffer references from XLogInsert.
* If this is the single and first tuple on page, we can reinit
* the page instead of restoring the whole thing. Set flag, and
* hide buffer references from XLogInsert.
*/
if (ItemPointerGetOffsetNumber(&(tup->t_self)) == FirstOffsetNumber &&
PageGetMaxOffsetNumber(page) == FirstOffsetNumber)
@ -1991,9 +1992,10 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
2 * sizeof(TransactionId));
hsize += 2 * sizeof(TransactionId);
}
/*
* As with insert records, we need not store the rdata[2] segment
* if we decide to store the whole buffer instead.
* As with insert records, we need not store the rdata[2] segment if
* we decide to store the whole buffer instead.
*/
rdata[2].buffer = newbuf;
rdata[2].data = (char *) &xlhdr;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.67 2003/07/21 20:29:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.68 2003/08/04 00:43:15 momjian Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
@ -394,8 +394,8 @@ index_restrpos(IndexScanDesc scan)
/*
* We do not reset got_tuple; so if the scan is actually being
* short-circuited by index_getnext, the effective position restoration
* is done by restoring unique_tuple_pos.
* short-circuited by index_getnext, the effective position
* restoration is done by restoring unique_tuple_pos.
*/
scan->unique_tuple_pos = scan->unique_tuple_mark;
@ -427,20 +427,20 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
}
/*
* If we already got a tuple and it must be unique, there's no need
* to make the index AM look through any additional tuples. (This can
* If we already got a tuple and it must be unique, there's no need to
* make the index AM look through any additional tuples. (This can
* save a useful amount of work in scenarios where there are many dead
* tuples due to heavy update activity.)
*
* To do this we must keep track of the logical scan position
* (before/on/after tuple). Also, we have to be sure to release scan
* resources before returning NULL; if we fail to do so then a multi-index
* scan can easily run the system out of free buffers. We can release
* index-level resources fairly cheaply by calling index_rescan. This
* means there are two persistent states as far as the index AM is
* concerned: on-tuple and rescanned. If we are actually asked to
* re-fetch the single tuple, we have to go through a fresh indexscan
* startup, which penalizes that (infrequent) case.
* resources before returning NULL; if we fail to do so then a
* multi-index scan can easily run the system out of free buffers. We
* can release index-level resources fairly cheaply by calling
* index_rescan. This means there are two persistent states as far as
* the index AM is concerned: on-tuple and rescanned. If we are
* actually asked to re-fetch the single tuple, we have to go through
* a fresh indexscan startup, which penalizes that (infrequent) case.
*/
if (scan->keys_are_unique && scan->got_tuple)
{
@ -459,18 +459,19 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
if (new_tuple_pos == 0)
{
/*
* We are moving onto the unique tuple from having been off it.
* We just fall through and let the index AM do the work. Note
* we should get the right answer regardless of scan direction.
* We are moving onto the unique tuple from having been off
* it. We just fall through and let the index AM do the work.
* Note we should get the right answer regardless of scan
* direction.
*/
scan->unique_tuple_pos = 0; /* need to update position */
}
else
{
/*
* Moving off the tuple; must do amrescan to release index-level
* pins before we return NULL. Since index_rescan will reset
* my state, must save and restore...
* Moving off the tuple; must do amrescan to release
* index-level pins before we return NULL. Since index_rescan
* will reset my state, must save and restore...
*/
int unique_tuple_mark = scan->unique_tuple_mark;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.102 2003/07/28 00:09:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.103 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -432,9 +432,9 @@ _bt_insertonpg(Relation rel,
*
* must write-lock that page before releasing write lock on
* current page; else someone else's _bt_check_unique scan
* could fail to see our insertion. write locks on intermediate
* dead pages won't do because we don't know when they will get
* de-linked from the tree.
* could fail to see our insertion. write locks on
* intermediate dead pages won't do because we don't know when
* they will get de-linked from the tree.
*/
Buffer rbuf = InvalidBuffer;
@ -523,9 +523,10 @@ _bt_insertonpg(Relation rel,
/*
* If we are doing this insert because we split a page that was
* the only one on its tree level, but was not the root, it may
* have been the "fast root". We need to ensure that the fast root
* link points at or above the current page. We can safely acquire
* a lock on the metapage here --- see comments for _bt_newroot().
* have been the "fast root". We need to ensure that the fast
* root link points at or above the current page. We can safely
* acquire a lock on the metapage here --- see comments for
* _bt_newroot().
*/
if (split_only_page)
{
@ -1155,19 +1156,19 @@ _bt_insert_parent(Relation rel,
bool is_only)
{
/*
* Here we have to do something Lehman and Yao don't talk about:
* deal with a root split and construction of a new root. If our
* stack is empty then we have just split a node on what had been
* the root level when we descended the tree. If it was still the
* root then we perform a new-root construction. If it *wasn't*
* the root anymore, search to find the next higher level that
* someone constructed meanwhile, and find the right place to insert
* as for the normal case.
* Here we have to do something Lehman and Yao don't talk about: deal
* with a root split and construction of a new root. If our stack is
* empty then we have just split a node on what had been the root
* level when we descended the tree. If it was still the root then we
* perform a new-root construction. If it *wasn't* the root anymore,
* search to find the next higher level that someone constructed
* meanwhile, and find the right place to insert as for the normal
* case.
*
* If we have to search for the parent level, we do so by
* re-descending from the root. This is not super-efficient,
* but it's rare enough not to matter. (This path is also taken
* when called from WAL recovery --- we have no stack in that case.)
* If we have to search for the parent level, we do so by re-descending
* from the root. This is not super-efficient, but it's rare enough
* not to matter. (This path is also taken when called from WAL
* recovery --- we have no stack in that case.)
*/
if (is_root)
{
@ -1222,9 +1223,9 @@ _bt_insert_parent(Relation rel,
/*
* Find the parent buffer and get the parent page.
*
* Oops - if we were moved right then we need to change stack
* item! We want to find parent pointing to where we are,
* right ? - vadim 05/27/97
* Oops - if we were moved right then we need to change stack item!
* We want to find parent pointing to where we are, right ? -
* vadim 05/27/97
*/
ItemPointerSet(&(stack->bts_btitem.bti_itup.t_tid),
bknum, P_HIKEY);
@ -1296,16 +1297,16 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
/*
* start = InvalidOffsetNumber means "search the whole page".
* We need this test anyway due to possibility that
* page has a high key now when it didn't before.
* We need this test anyway due to possibility that page has a
* high key now when it didn't before.
*/
if (start < minoff)
start = minoff;
/*
* These loops will check every item on the page --- but in an
* order that's attuned to the probability of where it actually
* is. Scan to the right first, then to the left.
* order that's attuned to the probability of where it
* actually is. Scan to the right first, then to the left.
*/
for (offnum = start;
offnum <= maxoff;

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.66 2003/07/21 20:29:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.67 2003/08/04 00:43:15 momjian Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
@ -181,8 +181,8 @@ _bt_getroot(Relation rel, int access)
/*
* Metadata initialized by someone else. In order to
* guarantee no deadlocks, we have to release the metadata
* page and start all over again. (Is that really true?
* But it's hardly worth trying to optimize this case.)
* page and start all over again. (Is that really true? But
* it's hardly worth trying to optimize this case.)
*/
_bt_relbuf(rel, metabuf);
return _bt_getroot(rel, access);
@ -190,8 +190,8 @@ _bt_getroot(Relation rel, int access)
/*
* Get, initialize, write, and leave a lock of the appropriate
* type on the new root page. Since this is the first page in
* the tree, it's a leaf as well as the root.
* type on the new root page. Since this is the first page in the
* tree, it's a leaf as well as the root.
*/
rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
rootblkno = BufferGetBlockNumber(rootbuf);
@ -284,8 +284,8 @@ _bt_getroot(Relation rel, int access)
}
/*
* By here, we have a pin and read lock on the root page, and no
* lock set on the metadata page. Return the root page's buffer.
* By here, we have a pin and read lock on the root page, and no lock
* set on the metadata page. Return the root page's buffer.
*/
return rootbuf;
}
@ -406,9 +406,9 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
* First see if the FSM knows of any free pages.
*
* We can't trust the FSM's report unreservedly; we have to check
* that the page is still free. (For example, an already-free page
* could have been re-used between the time the last VACUUM scanned
* it and the time the VACUUM made its FSM updates.)
* that the page is still free. (For example, an already-free
* page could have been re-used between the time the last VACUUM
* scanned it and the time the VACUUM made its FSM updates.)
*/
for (;;)
{
@ -431,10 +431,10 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
/*
* Extend the relation by one page.
*
* We have to use a lock to ensure no one else is extending the rel at
* the same time, else we will both try to initialize the same new
* page. We can skip locking for new or temp relations, however,
* since no one else could be accessing them.
* We have to use a lock to ensure no one else is extending the rel
* at the same time, else we will both try to initialize the same
* new page. We can skip locking for new or temp relations,
* however, since no one else could be accessing them.
*/
needLock = !(rel->rd_isnew || rel->rd_istemp);
@ -444,8 +444,8 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
buf = ReadBuffer(rel, P_NEW);
/*
* Release the file-extension lock; it's now OK for someone else to
* extend the relation some more.
* Release the file-extension lock; it's now OK for someone else
* to extend the relation some more.
*/
if (needLock)
UnlockPage(rel, 0, ExclusiveLock);
@ -534,13 +534,14 @@ _bt_page_recyclable(Page page)
BTPageOpaque opaque;
/*
* It's possible to find an all-zeroes page in an index --- for example,
* a backend might successfully extend the relation one page and then
* crash before it is able to make a WAL entry for adding the page.
* If we find a zeroed page then reclaim it.
* It's possible to find an all-zeroes page in an index --- for
* example, a backend might successfully extend the relation one page
* and then crash before it is able to make a WAL entry for adding the
* page. If we find a zeroed page then reclaim it.
*/
if (PageIsNew(page))
return true;
/*
* Otherwise, recycle if deleted and too old to have any processes
* interested in it.
@ -646,9 +647,7 @@ _bt_delitems(Relation rel, Buffer buf,
* adjusting item numbers for previous deletions.
*/
for (i = nitems - 1; i >= 0; i--)
{
PageIndexTupleDelete(page, itemnos[i]);
}
/* XLOG stuff */
if (!rel->rd_istemp)
@ -666,8 +665,8 @@ _bt_delitems(Relation rel, Buffer buf,
rdata[0].next = &(rdata[1]);
/*
* The target-offsets array is not in the buffer, but pretend
* that it is. When XLogInsert stores the whole buffer, the offsets
* The target-offsets array is not in the buffer, but pretend that
* it is. When XLogInsert stores the whole buffer, the offsets
* array need not be stored too.
*/
rdata[1].buffer = buf;
@ -751,6 +750,7 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
_bt_relbuf(rel, buf);
return 0;
}
/*
* Save info about page, including a copy of its high key (it must
* have one, being non-rightmost).
@ -760,12 +760,13 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
leftsib = opaque->btpo_prev;
itemid = PageGetItemId(page, P_HIKEY);
targetkey = CopyBTItem((BTItem) PageGetItem(page, itemid));
/*
* We need to get an approximate pointer to the page's parent page.
* Use the standard search mechanism to search for the page's high key;
* this will give us a link to either the current parent or someplace
* to its left (if there are multiple equal high keys). To avoid
* deadlocks, we'd better drop the target page lock first.
* Use the standard search mechanism to search for the page's high
* key; this will give us a link to either the current parent or
* someplace to its left (if there are multiple equal high keys). To
* avoid deadlocks, we'd better drop the target page lock first.
*/
_bt_relbuf(rel, buf);
/* we need a scan key to do our search, so build one */
@ -775,9 +776,11 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
&lbuf, BT_READ);
/* don't need a pin on that either */
_bt_relbuf(rel, lbuf);
/*
* If we are trying to delete an interior page, _bt_search did more
* than we needed. Locate the stack item pointing to our parent level.
* than we needed. Locate the stack item pointing to our parent
* level.
*/
ilevel = 0;
for (;;)
@ -789,9 +792,11 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
stack = stack->bts_parent;
ilevel++;
}
/*
* We have to lock the pages we need to modify in the standard order:
* moving right, then up. Else we will deadlock against other writers.
* moving right, then up. Else we will deadlock against other
* writers.
*
* So, we need to find and write-lock the current left sibling of the
* target page. The sibling that was current a moment ago could have
@ -823,18 +828,21 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
}
else
lbuf = InvalidBuffer;
/*
* Next write-lock the target page itself. It should be okay to take just
* a write lock not a superexclusive lock, since no scans would stop on an
* empty page.
* Next write-lock the target page itself. It should be okay to take
* just a write lock not a superexclusive lock, since no scans would
* stop on an empty page.
*/
buf = _bt_getbuf(rel, target, BT_WRITE);
page = BufferGetPage(buf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
/*
* Check page is still empty etc, else abandon deletion. The empty check
* is necessary since someone else might have inserted into it while
* we didn't have it locked; the others are just for paranoia's sake.
* Check page is still empty etc, else abandon deletion. The empty
* check is necessary since someone else might have inserted into it
* while we didn't have it locked; the others are just for paranoia's
* sake.
*/
if (P_RIGHTMOST(opaque) || P_ISROOT(opaque) || P_ISDELETED(opaque) ||
P_FIRSTDATAKEY(opaque) <= PageGetMaxOffsetNumber(page))
@ -846,14 +854,17 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
}
if (opaque->btpo_prev != leftsib)
elog(ERROR, "left link changed unexpectedly");
/*
* And next write-lock the (current) right sibling.
*/
rightsib = opaque->btpo_next;
rbuf = _bt_getbuf(rel, rightsib, BT_WRITE);
/*
* Next find and write-lock the current parent of the target page.
* This is essentially the same as the corresponding step of splitting.
* This is essentially the same as the corresponding step of
* splitting.
*/
ItemPointerSet(&(stack->bts_btitem.bti_itup.t_tid),
target, P_HIKEY);
@ -863,10 +874,11 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
RelationGetRelationName(rel));
parent = stack->bts_blkno;
poffset = stack->bts_offset;
/*
* If the target is the rightmost child of its parent, then we can't
* delete, unless it's also the only child --- in which case the parent
* changes to half-dead status.
* delete, unless it's also the only child --- in which case the
* parent changes to half-dead status.
*/
page = BufferGetPage(pbuf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
@ -893,12 +905,13 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
if (OffsetNumberNext(P_FIRSTDATAKEY(opaque)) == maxoff)
parent_one_child = true;
}
/*
* If we are deleting the next-to-last page on the target's level,
* then the rightsib is a candidate to become the new fast root.
* (In theory, it might be possible to push the fast root even further
* down, but the odds of doing so are slim, and the locking considerations
* daunting.)
* then the rightsib is a candidate to become the new fast root. (In
* theory, it might be possible to push the fast root even further
* down, but the odds of doing so are slim, and the locking
* considerations daunting.)
*
* We can safely acquire a lock on the metapage here --- see comments for
* _bt_newroot().
@ -914,10 +927,11 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
metapg = BufferGetPage(metabuf);
metad = BTPageGetMeta(metapg);
/*
* The expected case here is btm_fastlevel == targetlevel+1;
* if the fastlevel is <= targetlevel, something is wrong, and we
* choose to overwrite it to fix it.
* if the fastlevel is <= targetlevel, something is wrong, and
* we choose to overwrite it to fix it.
*/
if (metad->btm_fastlevel > targetlevel + 1)
{
@ -937,9 +951,9 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
/*
* Update parent. The normal case is a tad tricky because we want to
* delete the target's downlink and the *following* key. Easiest way is
* to copy the right sibling's downlink over the target downlink, and then
* delete the following item.
* delete the target's downlink and the *following* key. Easiest way
* is to copy the right sibling's downlink over the target downlink,
* and then delete the following item.
*/
page = BufferGetPage(pbuf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
@ -968,8 +982,8 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
}
/*
* Update siblings' side-links. Note the target page's side-links will
* continue to point to the siblings.
* Update siblings' side-links. Note the target page's side-links
* will continue to point to the siblings.
*/
if (BufferIsValid(lbuf))
{
@ -1096,10 +1110,11 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
_bt_wrtbuf(rel, lbuf);
/*
* If parent became half dead, recurse to try to delete it. Otherwise,
* if right sibling is empty and is now the last child of the parent,
* recurse to try to delete it. (These cases cannot apply at the same
* time, though the second case might itself recurse to the first.)
* If parent became half dead, recurse to try to delete it.
* Otherwise, if right sibling is empty and is now the last child of
* the parent, recurse to try to delete it. (These cases cannot apply
* at the same time, though the second case might itself recurse to
* the first.)
*/
if (parent_half_dead)
{

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.103 2003/07/21 20:29:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.104 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -580,19 +580,20 @@ btbulkdelete(PG_FUNCTION_ARGS)
/*
* The outer loop iterates over index leaf pages, the inner over items
* on a leaf page. We issue just one _bt_delitems() call per page,
* so as to minimize WAL traffic.
* on a leaf page. We issue just one _bt_delitems() call per page, so
* as to minimize WAL traffic.
*
* Note that we exclusive-lock every leaf page containing data items,
* in sequence left to right. It sounds attractive to only exclusive-lock
* those containing items we need to delete, but unfortunately that
* is not safe: we could then pass a stopped indexscan, which could
* in rare cases lead to deleting the item it needs to find when it
* resumes. (See _bt_restscan --- this could only happen if an indexscan
* stops on a deletable item and then a page split moves that item
* into a page further to its right, which the indexscan will have no
* pin on.) We can skip obtaining exclusive lock on empty pages
* though, since no indexscan could be stopped on those.
* Note that we exclusive-lock every leaf page containing data items, in
* sequence left to right. It sounds attractive to only
* exclusive-lock those containing items we need to delete, but
* unfortunately that is not safe: we could then pass a stopped
* indexscan, which could in rare cases lead to deleting the item it
* needs to find when it resumes. (See _bt_restscan --- this could
* only happen if an indexscan stops on a deletable item and then a
* page split moves that item into a page further to its right, which
* the indexscan will have no pin on.) We can skip obtaining
* exclusive lock on empty pages though, since no indexscan could be
* stopped on those.
*/
buf = _bt_get_endpoint(rel, 0, false);
if (BufferIsValid(buf)) /* check for empty index */
@ -622,12 +623,14 @@ btbulkdelete(PG_FUNCTION_ARGS)
*/
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
LockBufferForCleanup(buf);
/*
* Recompute minoff/maxoff, both of which could have changed
* while we weren't holding the lock.
* Recompute minoff/maxoff, both of which could have
* changed while we weren't holding the lock.
*/
minoff = P_FIRSTDATAKEY(opaque);
maxoff = PageGetMaxOffsetNumber(page);
/*
* Scan over all items to see which ones need deleted
* according to the callback function.
@ -651,6 +654,7 @@ btbulkdelete(PG_FUNCTION_ARGS)
num_index_tuples += 1;
}
}
/*
* If we need to delete anything, do it and write the buffer;
* else just release the buffer.
@ -662,9 +666,7 @@ btbulkdelete(PG_FUNCTION_ARGS)
_bt_wrtbuf(rel, buf);
}
else
{
_bt_relbuf(rel, buf);
}
/* And advance to next page, if any */
if (nextpage == P_NONE)
break;
@ -787,10 +789,10 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
}
/*
* During VACUUM FULL, we truncate off any recyclable pages at the
* end of the index. In a normal vacuum it'd be unsafe to do this
* except by acquiring exclusive lock on the index and then rechecking
* all the pages; doesn't seem worth it.
* During VACUUM FULL, we truncate off any recyclable pages at the end
* of the index. In a normal vacuum it'd be unsafe to do this except
* by acquiring exclusive lock on the index and then rechecking all
* the pages; doesn't seem worth it.
*/
if (info->vacuum_full && nFreePages > 0)
{
@ -810,9 +812,10 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
* Okay to truncate.
*
* First, flush any shared buffers for the blocks we intend to
* delete. FlushRelationBuffers is a bit more than we need for
* this, since it will also write out dirty buffers for blocks we
* aren't deleting, but it's the closest thing in bufmgr's API.
* delete. FlushRelationBuffers is a bit more than we need
* for this, since it will also write out dirty buffers for
* blocks we aren't deleting, but it's the closest thing in
* bufmgr's API.
*/
i = FlushRelationBuffers(rel, new_pages);
if (i < 0)
@ -822,7 +825,8 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
* Do the physical truncation.
*/
new_pages = smgrtruncate(DEFAULT_SMGR, rel, new_pages);
rel->rd_nblocks = new_pages; /* update relcache immediately */
rel->rd_nblocks = new_pages; /* update relcache
* immediately */
rel->rd_targblock = InvalidBlockNumber;
num_pages = new_pages;
}
@ -877,8 +881,8 @@ _bt_restscan(IndexScanDesc scan)
BlockNumber blkno;
/*
* Reacquire read lock on the buffer. (We should still have
* a reference-count pin on it, so need not get that.)
* Reacquire read lock on the buffer. (We should still have a
* reference-count pin on it, so need not get that.)
*/
LockBuffer(buf, BT_READ);
@ -922,10 +926,10 @@ _bt_restscan(IndexScanDesc scan)
/*
* The item we're looking for moved right at least one page, so
* move right. We are careful here to pin and read-lock the next
* non-dead page before releasing the current one. This ensures that
* a concurrent btbulkdelete scan cannot pass our position --- if it
* did, it might be able to reach and delete our target item before
* we can find it again.
* non-dead page before releasing the current one. This ensures
* that a concurrent btbulkdelete scan cannot pass our position
* --- if it did, it might be able to reach and delete our target
* item before we can find it again.
*/
if (P_RIGHTMOST(opaque))
elog(ERROR, "failed to re-find previous key in \"%s\"",

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.77 2003/07/29 22:18:38 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.78 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -64,8 +64,8 @@ _bt_search(Relation rel, int keysz, ScanKey scankey,
/*
* Race -- the page we just grabbed may have split since we read
* its pointer in the parent (or metapage). If it has, we may need
* to move right to its new sibling. Do that.
* its pointer in the parent (or metapage). If it has, we may
* need to move right to its new sibling. Do that.
*/
*bufP = _bt_moveright(rel, *bufP, keysz, scankey, BT_READ);
@ -87,14 +87,14 @@ _bt_search(Relation rel, int keysz, ScanKey scankey,
par_blkno = BufferGetBlockNumber(*bufP);
/*
* We need to save the location of the index entry we chose in
* the parent page on a stack. In case we split the tree, we'll
* use the stack to work back up to the parent page. We also save
* the actual downlink (TID) to uniquely identify the index entry,
* in case it moves right while we're working lower in the
* tree. See the paper by Lehman and Yao for how this is detected
* and handled. (We use the child link to disambiguate duplicate
* keys in the index -- Lehman and Yao disallow duplicate keys.)
* We need to save the location of the index entry we chose in the
* parent page on a stack. In case we split the tree, we'll use
* the stack to work back up to the parent page. We also save the
* actual downlink (TID) to uniquely identify the index entry, in
* case it moves right while we're working lower in the tree. See
* the paper by Lehman and Yao for how this is detected and
* handled. (We use the child link to disambiguate duplicate keys
* in the index -- Lehman and Yao disallow duplicate keys.)
*/
new_stack = (BTStack) palloc(sizeof(BTStackData));
new_stack->bts_blkno = par_blkno;
@ -151,8 +151,8 @@ _bt_moveright(Relation rel,
* might not need to move right; have to scan the page first anyway.)
* It could even have split more than once, so scan as far as needed.
*
* We also have to move right if we followed a link that brought us to
* a dead page.
* We also have to move right if we followed a link that brought us to a
* dead page.
*/
while (!P_RIGHTMOST(opaque) &&
(P_IGNORE(opaque) ||
@ -599,8 +599,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
/*
* At this point we are positioned at the first item >= scan key, or
* possibly at the end of a page on which all the existing items are
* less than the scan key and we know that everything on later
* pages is greater than or equal to scan key.
* less than the scan key and we know that everything on later pages
* is greater than or equal to scan key.
*
* We could step forward in the latter case, but that'd be a waste of
* time if we want to scan backwards. So, it's now time to examine
@ -851,7 +851,8 @@ _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
}
}
}
else /* backwards scan */
else
/* backwards scan */
{
if (offnum > P_FIRSTDATAKEY(opaque))
offnum = OffsetNumberPrev(offnum);
@ -860,9 +861,9 @@ _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
/*
* Walk left to the next page with data. This is much more
* complex than the walk-right case because of the possibility
* that the page to our left splits while we are in flight to it,
* plus the possibility that the page we were on gets deleted
* after we leave it. See nbtree/README for details.
* that the page to our left splits while we are in flight to
* it, plus the possibility that the page we were on gets
* deleted after we leave it. See nbtree/README for details.
*/
for (;;)
{
@ -877,10 +878,11 @@ _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
}
page = BufferGetPage(*bufP);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
/*
* Okay, we managed to move left to a non-deleted page.
* Done if it's not half-dead and not empty. Else loop back
* and do it all again.
* Done if it's not half-dead and not empty. Else loop
* back and do it all again.
*/
if (!P_IGNORE(opaque))
{
@ -946,17 +948,18 @@ _bt_walk_left(Relation rel, Buffer buf)
buf = _bt_getbuf(rel, blkno, BT_READ);
page = BufferGetPage(buf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
/*
* If this isn't the page we want, walk right till we find
* what we want --- but go no more than four hops (an
* arbitrary limit). If we don't find the correct page by then,
* the most likely bet is that the original page got deleted
* and isn't in the sibling chain at all anymore, not that its
* left sibling got split more than four times.
* If this isn't the page we want, walk right till we find what we
* want --- but go no more than four hops (an arbitrary limit).
* If we don't find the correct page by then, the most likely bet
* is that the original page got deleted and isn't in the sibling
* chain at all anymore, not that its left sibling got split more
* than four times.
*
* Note that it is correct to test P_ISDELETED not P_IGNORE
* here, because half-dead pages are still in the sibling
* chain. Caller must reject half-dead pages if wanted.
* Note that it is correct to test P_ISDELETED not P_IGNORE here,
* because half-dead pages are still in the sibling chain. Caller
* must reject half-dead pages if wanted.
*/
tries = 0;
for (;;)
@ -983,8 +986,8 @@ _bt_walk_left(Relation rel, Buffer buf)
if (P_ISDELETED(opaque))
{
/*
* It was deleted. Move right to first nondeleted page
* (there must be one); that is the page that has acquired the
* It was deleted. Move right to first nondeleted page (there
* must be one); that is the page that has acquired the
* deleted one's keyspace, so stepping left from it will take
* us where we want to be.
*/
@ -1001,18 +1004,18 @@ _bt_walk_left(Relation rel, Buffer buf)
if (!P_ISDELETED(opaque))
break;
}
/*
* Now return to top of loop, resetting obknum to
* point to this nondeleted page, and try again.
* Now return to top of loop, resetting obknum to point to
* this nondeleted page, and try again.
*/
}
else
{
/*
* It wasn't deleted; the explanation had better be
* that the page to the left got split or deleted.
* Without this check, we'd go into an infinite loop
* if there's anything wrong.
* It wasn't deleted; the explanation had better be that the
* page to the left got split or deleted. Without this check,
* we'd go into an infinite loop if there's anything wrong.
*/
if (opaque->btpo_prev == lblkno)
elog(ERROR, "could not find left sibling in \"%s\"",
@ -1045,8 +1048,8 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
/*
* If we are looking for a leaf page, okay to descend from fast root;
* otherwise better descend from true root. (There is no point in being
* smarter about intermediate levels.)
* otherwise better descend from true root. (There is no point in
* being smarter about intermediate levels.)
*/
if (level == 0)
buf = _bt_getroot(rel, BT_READ);
@ -1066,9 +1069,9 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
{
/*
* If we landed on a deleted page, step right to find a live page
* (there must be one). Also, if we want the rightmost page,
* step right if needed to get to it (this could happen if the
* page split since we obtained a pointer to it).
* (there must be one). Also, if we want the rightmost page, step
* right if needed to get to it (this could happen if the page
* split since we obtained a pointer to it).
*/
while (P_IGNORE(opaque) ||
(rightmost && !P_RIGHTMOST(opaque)))

View File

@ -36,7 +36,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.73 2003/07/21 20:29:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.74 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.3 2003/02/23 22:43:08 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.4 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -183,9 +183,7 @@ btree_xlog_insert(bool redo, bool isleaf, bool ismeta,
if (redo)
{
if (XLByteLE(lsn, PageGetLSN(page)))
{
UnlockAndReleaseBuffer(buffer);
}
else
{
if (PageAddItem(page, (Item) datapos, datalen,
@ -204,15 +202,11 @@ btree_xlog_insert(bool redo, bool isleaf, bool ismeta,
elog(PANIC, "btree_insert_undo: bad page LSN");
if (!P_ISLEAF(pageop))
{
UnlockAndReleaseBuffer(buffer);
}
else
{
elog(PANIC, "btree_insert_undo: unimplemented");
}
}
}
if (redo) /* metapage changes not undoable */
{
@ -338,9 +332,7 @@ btree_xlog_split(bool redo, bool onleft, bool isroot,
elog(PANIC, "btree_split_redo: uninitialized next right page");
if (XLByteLE(lsn, PageGetLSN(page)))
{
UnlockAndReleaseBuffer(buffer);
}
else
{
pageop = (BTPageOpaque) PageGetSpecialPointer(page);
@ -451,9 +443,7 @@ btree_xlog_delete_page(bool redo, bool ismeta,
if (PageIsNew((PageHeader) page))
elog(PANIC, "btree_delete_page_redo: uninitialized parent page");
if (XLByteLE(lsn, PageGetLSN(page)))
{
UnlockAndReleaseBuffer(buffer);
}
else
{
OffsetNumber poffset;
@ -494,9 +484,7 @@ btree_xlog_delete_page(bool redo, bool ismeta,
if (PageIsNew((PageHeader) page))
elog(PANIC, "btree_delete_page_redo: uninitialized right sibling");
if (XLByteLE(lsn, PageGetLSN(page)))
{
UnlockAndReleaseBuffer(buffer);
}
else
{
pageop = (BTPageOpaque) PageGetSpecialPointer(page);
@ -520,9 +508,7 @@ btree_xlog_delete_page(bool redo, bool ismeta,
if (PageIsNew((PageHeader) page))
elog(PANIC, "btree_delete_page_redo: uninitialized left sibling");
if (XLByteLE(lsn, PageGetLSN(page)))
{
UnlockAndReleaseBuffer(buffer);
}
else
{
pageop = (BTPageOpaque) PageGetSpecialPointer(page);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.45 2003/07/28 00:09:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.46 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -109,10 +109,10 @@ rtrescan(PG_FUNCTION_ARGS)
s->numberOfKeys * sizeof(ScanKeyData));
/*
* Scans on internal pages use different operators than they
* do on leaf pages. For example, if the user wants all boxes
* that exactly match (x1,y1,x2,y2), then on internal pages we
* need to find all boxes that contain (x1,y1,x2,y2).
* Scans on internal pages use different operators than they do on
* leaf pages. For example, if the user wants all boxes that
* exactly match (x1,y1,x2,y2), then on internal pages we need to
* find all boxes that contain (x1,y1,x2,y2).
*/
for (i = 0; i < s->numberOfKeys; i++)
{

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.16 2003/06/11 22:37:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.17 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -3,7 +3,7 @@
*
* Resource managers definition
*
* $Header: /cvsroot/pgsql/src/backend/access/transam/rmgr.c,v 1.10 2003/02/21 00:06:22 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/rmgr.c,v 1.11 2003/08/04 00:43:15 momjian Exp $
*/
#include "postgres.h"

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/access/transam/slru.c,v 1.3 2003/07/28 00:09:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/slru.c,v 1.4 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -183,12 +183,14 @@ SimpleLruInit(SlruCtl ctl, const char *name, const char *subdir)
shared = (SlruShared) ptr;
#ifdef EXEC_BACKEND
/*
* Locks are in shared memory
*/
locks = (SlruLock) (ptr + MAXALIGN(sizeof(SlruSharedData)) +
BLCKSZ * NUM_CLOG_BUFFERS);
#else
/*
* Locks are in private memory
*/
@ -539,13 +541,13 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno)
* possible for this to need to happen when writing a page that's not
* first in its segment; we assume the OS can cope with that. (Note:
* it might seem that it'd be okay to create files only when
* SimpleLruZeroPage is called for the first page of a segment. However,
* if after a crash and restart the REDO logic elects to replay the
* log from a checkpoint before the latest one, then it's possible
* that we will get commands to set transaction status of transactions
* that have already been truncated from the commit log. Easiest way
* to deal with that is to accept references to nonexistent files here
* and in SlruPhysicalReadPage.)
* SimpleLruZeroPage is called for the first page of a segment.
* However, if after a crash and restart the REDO logic elects to
* replay the log from a checkpoint before the latest one, then it's
* possible that we will get commands to set transaction status of
* transactions that have already been truncated from the commit log.
* Easiest way to deal with that is to accept references to
* nonexistent files here and in SlruPhysicalReadPage.)
*/
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR);
if (fd < 0)
@ -665,6 +667,7 @@ static int
SlruSelectLRUPage(SlruCtl ctl, int pageno)
{
SlruShared shared = (SlruShared) ctl->shared;
/* Outer loop handles restart after I/O */
for (;;)
{
@ -705,8 +708,8 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno)
/*
* We need to do I/O. Normal case is that we have to write it
* out, but it's possible in the worst case to have selected a
* read-busy page. In that case we use SimpleLruReadPage to wait for
* the read to complete.
* read-busy page. In that case we use SimpleLruReadPage to wait
* for the read to complete.
*/
if (shared->page_status[bestslot] == SLRU_PAGE_READ_IN_PROGRESS)
(void) SimpleLruReadPage(ctl, shared->page_number[bestslot],
@ -747,10 +750,11 @@ SimpleLruFlush(SlruCtl ctl, bool checkpoint)
for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
{
SimpleLruWritePage(ctl, slotno);
/*
* When called during a checkpoint,
* we cannot assert that the slot is clean now, since another
* process might have re-dirtied it already. That's okay.
* When called during a checkpoint, we cannot assert that the slot
* is clean now, since another process might have re-dirtied it
* already. That's okay.
*/
Assert(checkpoint ||
shared->page_status[slotno] == SLRU_PAGE_EMPTY ||
@ -792,10 +796,10 @@ SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
CreateCheckPoint(false, true);
/*
* Scan shared memory and remove any pages preceding the cutoff
* page, to ensure we won't rewrite them later. (Any dirty pages
* should have been flushed already during the checkpoint, we're just
* being extra careful here.)
* Scan shared memory and remove any pages preceding the cutoff page,
* to ensure we won't rewrite them later. (Any dirty pages should
* have been flushed already during the checkpoint, we're just being
* extra careful here.)
*/
LWLockAcquire(ctl->locks->ControlLock, LW_EXCLUSIVE);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.149 2003/07/21 20:29:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.150 2003/08/04 00:43:15 momjian Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@ -197,8 +197,8 @@ static TransactionStateData CurrentTransactionStateData = {
0, /* scan command id */
0x0, /* start time */
TRANS_DEFAULT, /* transaction state */
TBLOCK_DEFAULT /* transaction block state from
the client perspective */
TBLOCK_DEFAULT /* transaction block state from the client
* perspective */
};
TransactionState CurrentTransactionState = &CurrentTransactionStateData;
@ -561,13 +561,13 @@ RecordTransactionCommit(void)
/*
* We must mark the transaction committed in clog if its XID
* appears either in permanent rels or in local temporary rels.
* We test this by seeing if we made transaction-controlled
* entries *OR* local-rel tuple updates. Note that if we made
* only the latter, we have not emitted an XLOG record for our
* commit, and so in the event of a crash the clog update might be
* lost. This is okay because no one else will ever care whether
* we committed.
* appears either in permanent rels or in local temporary rels. We
* test this by seeing if we made transaction-controlled entries
* *OR* local-rel tuple updates. Note that if we made only the
* latter, we have not emitted an XLOG record for our commit, and
* so in the event of a crash the clog update might be lost. This
* is okay because no one else will ever care whether we
* committed.
*/
if (MyLastRecPtr.xrecoff != 0 || MyXactMadeTempRelUpdate)
TransactionIdCommit(xid);
@ -755,9 +755,9 @@ AtAbort_Memory(void)
{
/*
* Make sure we are in a valid context (not a child of
* TopTransactionContext...). Note that it is possible for this
* code to be called when we aren't in a transaction at all; go
* directly to TopMemoryContext in that case.
* TopTransactionContext...). Note that it is possible for this code
* to be called when we aren't in a transaction at all; go directly to
* TopMemoryContext in that case.
*/
if (TopTransactionContext != NULL)
{
@ -891,8 +891,8 @@ CommitTransaction(void)
DeferredTriggerEndXact();
/*
* Similarly, let ON COMMIT management do its thing before we start
* to commit.
* Similarly, let ON COMMIT management do its thing before we start to
* commit.
*/
PreCommit_on_commit_actions();
@ -953,10 +953,10 @@ CommitTransaction(void)
* noncritical resource releasing.
*
* The ordering of operations is not entirely random. The idea is:
* release resources visible to other backends (eg, files, buffer pins);
* then release locks; then release backend-local resources. We want
* to release locks at the point where any backend waiting for us will
* see our transaction as being fully cleaned up.
* release resources visible to other backends (eg, files, buffer
* pins); then release locks; then release backend-local resources.
* We want to release locks at the point where any backend waiting for
* us will see our transaction as being fully cleaned up.
*/
smgrDoPendingDeletes(true);
@ -1194,8 +1194,8 @@ StartTransactionCommand(void)
}
/*
* We must switch to TopTransactionContext before returning. This
* is already done if we called StartTransaction, otherwise not.
* We must switch to TopTransactionContext before returning. This is
* already done if we called StartTransaction, otherwise not.
*/
Assert(TopTransactionContext != NULL);
MemoryContextSwitchTo(TopTransactionContext);
@ -1373,6 +1373,7 @@ PreventTransactionChain(void *stmtNode, const char *stmtType)
/* translator: %s represents an SQL statement name */
errmsg("%s cannot run inside a transaction block",
stmtType)));
/*
* Are we inside a function call? If the statement's parameter block
* was allocated in QueryContext, assume it is an interactive command.
@ -1414,6 +1415,7 @@ RequireTransactionChain(void *stmtNode, const char *stmtType)
*/
if (IsTransactionBlock())
return;
/*
* Are we inside a function call? If the statement's parameter block
* was allocated in QueryContext, assume it is an interactive command.

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.120 2003/07/28 00:09:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.121 2003/08/04 00:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -2665,11 +2665,12 @@ StartupXLOG(void)
ShmemVariableCache->oidCount = 0;
/*
* If it was a shutdown checkpoint, then any following WAL entries were
* created under the next StartUpID; if it was a regular checkpoint then
* any following WAL entries were created under the same StartUpID.
* We must replay WAL entries using the same StartUpID they were created
* under, so temporarily adopt that SUI (see also xlog_redo()).
* If it was a shutdown checkpoint, then any following WAL entries
* were created under the next StartUpID; if it was a regular
* checkpoint then any following WAL entries were created under the
* same StartUpID. We must replay WAL entries using the same StartUpID
* they were created under, so temporarily adopt that SUI (see also
* xlog_redo()).
*/
if (wasShutdown)
ThisStartUpID = checkPoint.ThisStartUpID + 1;
@ -2791,8 +2792,8 @@ StartupXLOG(void)
/*
* Tricky point here: readBuf contains the *last* block that the
* LastRec record spans, not the one it starts in. The last block
* is indeed the one we want to use.
* LastRec record spans, not the one it starts in. The last block is
* indeed the one we want to use.
*/
Assert(readOff == (XLogCtl->xlblocks[0].xrecoff - BLCKSZ) % XLogSegSize);
memcpy((char *) Insert->currpage, readBuf, BLCKSZ);
@ -2818,11 +2819,12 @@ StartupXLOG(void)
else
{
/*
* Whenever Write.LogwrtResult points to exactly the end of a page,
* Write.curridx must point to the *next* page (see XLogWrite()).
* Whenever Write.LogwrtResult points to exactly the end of a
* page, Write.curridx must point to the *next* page (see
* XLogWrite()).
*
* Note: it might seem we should do AdvanceXLInsertBuffer() here,
* but we can't since we haven't yet determined the correct StartUpID
* Note: it might seem we should do AdvanceXLInsertBuffer() here, but
* we can't since we haven't yet determined the correct StartUpID
* to put into the new page's header. The first actual attempt to
* insert a log record will advance the insert state.
*/
@ -2885,14 +2887,15 @@ StartupXLOG(void)
ThisStartUpID = ControlFile->checkPointCopy.ThisStartUpID;
/*
* Perform a new checkpoint to update our recovery activity to disk.
* Perform a new checkpoint to update our recovery activity to
* disk.
*
* Note that we write a shutdown checkpoint. This is correct since
* the records following it will use SUI one more than what is shown
* in the checkpoint's ThisStartUpID.
* the records following it will use SUI one more than what is
* shown in the checkpoint's ThisStartUpID.
*
* In case we had to use the secondary checkpoint, make sure that
* it will still be shown as the secondary checkpoint after this
* In case we had to use the secondary checkpoint, make sure that it
* will still be shown as the secondary checkpoint after this
* CreateCheckPoint operation; we don't want the broken primary
* checkpoint to become prevCheckPoint...
*/
@ -2907,10 +2910,10 @@ StartupXLOG(void)
else
{
/*
* If we are not doing recovery, then we saw a checkpoint with nothing
* after it, and we can safely use StartUpID equal to one more than
* the checkpoint's SUI. But just for paranoia's sake, check against
* pg_control too.
* If we are not doing recovery, then we saw a checkpoint with
* nothing after it, and we can safely use StartUpID equal to one
* more than the checkpoint's SUI. But just for paranoia's sake,
* check against pg_control too.
*/
ThisStartUpID = checkPoint.ThisStartUpID;
if (ThisStartUpID < ControlFile->checkPointCopy.ThisStartUpID)
@ -2923,7 +2926,8 @@ StartupXLOG(void)
PreallocXlogFiles(EndOfLog);
/*
* Advance StartUpID to one more than the highest value used previously.
* Advance StartUpID to one more than the highest value used
* previously.
*/
ThisStartUpID++;
XLogCtl->ThisStartUpID = ThisStartUpID;
@ -3115,7 +3119,8 @@ CreateCheckPoint(bool shutdown, bool force)
errmsg("checkpoint cannot be made inside transaction block")));
/*
* Acquire CheckpointLock to ensure only one checkpoint happens at a time.
* Acquire CheckpointLock to ensure only one checkpoint happens at a
* time.
*
* The CheckpointLock can be held for quite a while, which is not good
* because we won't respond to a cancel/die request while waiting for
@ -3149,14 +3154,15 @@ CreateCheckPoint(bool shutdown, bool force)
LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
/*
* If this isn't a shutdown or forced checkpoint, and we have not inserted
* any XLOG records since the start of the last checkpoint, skip the
* checkpoint. The idea here is to avoid inserting duplicate checkpoints
* when the system is idle. That wastes log space, and more importantly it
* exposes us to possible loss of both current and previous checkpoint
* records if the machine crashes just as we're writing the update.
* (Perhaps it'd make even more sense to checkpoint only when the previous
* checkpoint record is in a different xlog page?)
* If this isn't a shutdown or forced checkpoint, and we have not
* inserted any XLOG records since the start of the last checkpoint,
* skip the checkpoint. The idea here is to avoid inserting duplicate
* checkpoints when the system is idle. That wastes log space, and
* more importantly it exposes us to possible loss of both current and
* previous checkpoint records if the machine crashes just as we're
* writing the update. (Perhaps it'd make even more sense to
* checkpoint only when the previous checkpoint record is in a
* different xlog page?)
*
* We have to make two tests to determine that nothing has happened since
* the start of the last checkpoint: current insertion point must
@ -3204,12 +3210,13 @@ CreateCheckPoint(bool shutdown, bool force)
* Here we update the shared RedoRecPtr for future XLogInsert calls;
* this must be done while holding the insert lock AND the info_lck.
*
* Note: if we fail to complete the checkpoint, RedoRecPtr will be
* left pointing past where it really needs to point. This is okay;
* the only consequence is that XLogInsert might back up whole buffers
* that it didn't really need to. We can't postpone advancing RedoRecPtr
* because XLogInserts that happen while we are dumping buffers must
* assume that their buffer changes are not included in the checkpoint.
* Note: if we fail to complete the checkpoint, RedoRecPtr will be left
* pointing past where it really needs to point. This is okay; the
* only consequence is that XLogInsert might back up whole buffers
* that it didn't really need to. We can't postpone advancing
* RedoRecPtr because XLogInserts that happen while we are dumping
* buffers must assume that their buffer changes are not included in
* the checkpoint.
*/
{
/* use volatile pointer to prevent code rearrangement */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.163 2003/07/27 21:49:53 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.164 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -347,9 +347,7 @@ BootstrapMain(int argc, char *argv[])
if (IsUnderPostmaster && ExecBackend && MyProc /* ordinary backend */ )
{
AttachSharedMemoryAndSemaphores();
}
if (!IsUnderPostmaster /* when exec || ExecBackend */ )
{
@ -473,8 +471,8 @@ BootstrapMain(int argc, char *argv[])
/*
* In NOP mode, all we really want to do is create shared memory and
* semaphores (just to prove we can do it with the current GUC settings).
* So, quit now.
* semaphores (just to prove we can do it with the current GUC
* settings). So, quit now.
*/
if (xlogop == BS_XLOG_NOP)
proc_exit(0);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.85 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.86 2003/08/04 00:43:16 momjian Exp $
*
* NOTES
* See acl.h.
@ -98,25 +98,28 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
if (grantee->username)
{
aclitem. ai_grantee = get_usesysid(grantee->username);
idtype = ACL_IDTYPE_UID;
}
else if (grantee->groupname)
{
aclitem. ai_grantee = get_grosysid(grantee->groupname);
idtype = ACL_IDTYPE_GID;
}
else
{
aclitem. ai_grantee = ACL_ID_WORLD;
idtype = ACL_IDTYPE_WORLD;
}
/*
* Grant options can only be granted to individual users, not
* groups or public. The reason is that if a user would
* re-grant a privilege that he held through a group having a
* grant option, and later the user is removed from the group,
* the situation is impossible to clean up.
* groups or public. The reason is that if a user would re-grant
* a privilege that he held through a group having a grant option,
* and later the user is removed from the group, the situation is
* impossible to clean up.
*/
if (is_grant && idtype != ACL_IDTYPE_UID && grant_option)
ereport(ERROR,
@ -835,8 +838,8 @@ aclcheck(Acl *acl, AclId userid, AclMode mode)
}
/*
* See if he has the permission via any group (do this in a
* separate pass to avoid expensive(?) lookups in pg_group)
* See if he has the permission via any group (do this in a separate
* pass to avoid expensive(?) lookups in pg_group)
*/
for (i = 0; i < num; i++)
if (ACLITEM_GET_IDTYPE(aidat[i]) == ACL_IDTYPE_GID

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.28 2003/07/28 00:09:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.29 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -158,9 +158,9 @@ performDeletion(const ObjectAddress *object,
/*
* Construct a list of objects that are reachable by AUTO or INTERNAL
* dependencies from the target object. These should be deleted silently,
* even if the actual deletion pass first reaches one of them via a
* non-auto dependency.
* dependencies from the target object. These should be deleted
* silently, even if the actual deletion pass first reaches one of
* them via a non-auto dependency.
*/
init_object_addresses(&oktodelete);
@ -212,9 +212,9 @@ deleteWhatDependsOn(const ObjectAddress *object,
/*
* Construct a list of objects that are reachable by AUTO or INTERNAL
* dependencies from the target object. These should be deleted silently,
* even if the actual deletion pass first reaches one of them via a
* non-auto dependency.
* dependencies from the target object. These should be deleted
* silently, even if the actual deletion pass first reaches one of
* them via a non-auto dependency.
*/
init_object_addresses(&oktodelete);
@ -266,9 +266,9 @@ findAutoDeletableObjects(const ObjectAddress *object,
ObjectAddress otherObject;
/*
* If this object is already in oktodelete, then we already visited it;
* don't do so again (this prevents infinite recursion if there's a loop
* in pg_depend). Otherwise, add it.
* If this object is already in oktodelete, then we already visited
* it; don't do so again (this prevents infinite recursion if there's
* a loop in pg_depend). Otherwise, add it.
*/
if (object_address_present(object, oktodelete))
return;
@ -276,8 +276,8 @@ findAutoDeletableObjects(const ObjectAddress *object,
/*
* Scan pg_depend records that link to this object, showing the things
* that depend on it. For each one that is AUTO or INTERNAL, visit the
* referencing object.
* that depend on it. For each one that is AUTO or INTERNAL, visit
* the referencing object.
*
* When dropping a whole object (subId = 0), find pg_depend records for
* its sub-objects too.
@ -319,6 +319,7 @@ findAutoDeletableObjects(const ObjectAddress *object,
findAutoDeletableObjects(&otherObject, oktodelete, depRel);
break;
case DEPENDENCY_PIN:
/*
* For a PIN dependency we just ereport immediately; there
* won't be any others to examine, and we aren't ever
@ -559,10 +560,9 @@ recursiveDeletion(const ObjectAddress *object,
/*
* Step 2: scan pg_depend records that link to this object, showing
* the things that depend on it. Recursively delete those things.
* Note it's important to delete the dependent objects
* before the referenced one, since the deletion routines might do
* things like try to update the pg_class record when deleting a check
* constraint.
* Note it's important to delete the dependent objects before the
* referenced one, since the deletion routines might do things like
* try to update the pg_class record when deleting a check constraint.
*/
if (!deleteDependentObjects(object, objDescription,
behavior, msglevel,
@ -674,11 +674,12 @@ deleteDependentObjects(const ObjectAddress *object,
switch (foundDep->deptype)
{
case DEPENDENCY_NORMAL:
/*
* Perhaps there was another dependency path that would
* have allowed silent deletion of the otherObject, had
* we only taken that path first.
* In that case, act like this link is AUTO, too.
* have allowed silent deletion of the otherObject, had we
* only taken that path first. In that case, act like this
* link is AUTO, too.
*/
if (object_address_present(&otherObject, oktodelete))
ereport(DEBUG2,
@ -1092,7 +1093,8 @@ find_expr_references_walker(Node *node,
* Add whole-relation refs for each plain relation mentioned in
* the subquery's rtable. (Note: query_tree_walker takes care of
* recursing into RTE_FUNCTION and RTE_SUBQUERY RTEs, so no need
* to do that here. But keep it from looking at join alias lists.)
* to do that here. But keep it from looking at join alias
* lists.)
*/
foreach(rtable, query->rtable)
{

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.249 2003/07/29 17:21:20 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.250 2003/08/04 00:43:16 momjian Exp $
*
*
* INTERFACE ROUTINES
@ -418,8 +418,8 @@ CheckAttributeType(const char *attname, Oid atttypid)
* Warn user, but don't fail, if column to be created has UNKNOWN type
* (usually as a result of a 'retrieve into' - jolly)
*
* Refuse any attempt to create a pseudo-type column or one that uses
* a standalone composite type. (Eventually we should probably refuse
* Refuse any attempt to create a pseudo-type column or one that uses a
* standalone composite type. (Eventually we should probably refuse
* all references to complex types, but for now there's still some
* Berkeley-derived code that thinks it can do this...)
*/
@ -975,12 +975,13 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
attStruct->attisdropped = true;
/*
* Set the type OID to invalid. A dropped attribute's type link cannot
* be relied on (once the attribute is dropped, the type might be too).
* Fortunately we do not need the type row --- the only really essential
* information is the type's typlen and typalign, which are preserved in
* the attribute's attlen and attalign. We set atttypid to zero here
* as a means of catching code that incorrectly expects it to be valid.
* Set the type OID to invalid. A dropped attribute's type link
* cannot be relied on (once the attribute is dropped, the type might
* be too). Fortunately we do not need the type row --- the only
* really essential information is the type's typlen and typalign,
* which are preserved in the attribute's attlen and attalign. We set
* atttypid to zero here as a means of catching code that incorrectly
* expects it to be valid.
*/
attStruct->atttypid = InvalidOid;
@ -1773,9 +1774,9 @@ cookDefault(ParseState *pstate,
errmsg("cannot use aggregate in DEFAULT clause")));
/*
* Coerce the expression to the correct type and typmod, if given. This
* should match the parser's processing of non-defaulted expressions ---
* see updateTargetListEntry().
* Coerce the expression to the correct type and typmod, if given.
* This should match the parser's processing of non-defaulted
* expressions --- see updateTargetListEntry().
*/
if (OidIsValid(atttypid))
{

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.212 2003/07/21 01:59:08 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.213 2003/08/04 00:43:16 momjian Exp $
*
*
* INTERFACE ROUTINES
@ -162,8 +162,8 @@ ConstructTupleDescriptor(Relation heapRelation,
}
/*
* now that we've determined the "from", let's copy the tuple desc
* data...
* now that we've determined the "from", let's copy the tuple
* desc data...
*/
memcpy(to, from, ATTRIBUTE_TUPLE_SIZE);
@ -197,7 +197,8 @@ ConstructTupleDescriptor(Relation heapRelation,
sprintf(NameStr(to->attname), "pg_expression_%d", i + 1);
/*
* Lookup the expression type in pg_type for the type length etc.
* Lookup the expression type in pg_type for the type length
* etc.
*/
keyType = exprType(indexkey);
tuple = SearchSysCache(TYPEOID,
@ -831,8 +832,8 @@ index_drop(Oid indexId)
/*
* We are presently too lazy to attempt to compute the new correct
* value of relhasindex (the next VACUUM will fix it if necessary).
* So there is no need to update the pg_class tuple for the owning
* value of relhasindex (the next VACUUM will fix it if necessary). So
* there is no need to update the pg_class tuple for the owning
* relation. But we must send out a shared-cache-inval notice on the
* owning relation to ensure other backends update their relcache
* lists of indexes.
@ -1326,8 +1327,8 @@ UpdateStats(Oid relid, double reltuples)
/*
* Update statistics in pg_class, if they changed. (Avoiding an
* unnecessary update is not just a tiny performance improvement;
* it also reduces the window wherein concurrent CREATE INDEX commands
* unnecessary update is not just a tiny performance improvement; it
* also reduces the window wherein concurrent CREATE INDEX commands
* may conflict.)
*/
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
@ -1338,8 +1339,9 @@ UpdateStats(Oid relid, double reltuples)
if (in_place_upd)
{
/*
* At bootstrap time, we don't need to worry about concurrency or
* visibility of changes, so we cheat. Also cheat if REINDEX.
* At bootstrap time, we don't need to worry about concurrency
* or visibility of changes, so we cheat. Also cheat if
* REINDEX.
*/
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
rd_rel->relpages = (int32) relpages;
@ -1454,8 +1456,8 @@ IndexBuildHeapScan(Relation heapRelation,
heapDescriptor = RelationGetDescr(heapRelation);
/*
* Need an EState for evaluation of index expressions
* and partial-index predicates.
* Need an EState for evaluation of index expressions and
* partial-index predicates.
*/
estate = CreateExecutorState();
econtext = GetPerTupleExprContext(estate);
@ -1463,7 +1465,8 @@ IndexBuildHeapScan(Relation heapRelation,
/*
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. Likewise if there are any expressions.
* be in a slot of a TupleTable. Likewise if there are any
* expressions.
*/
if (indexInfo->ii_Predicate != NIL || indexInfo->ii_Expressions != NIL)
{
@ -1741,8 +1744,8 @@ reindex_index(Oid indexId, bool force, bool inplace)
* it's a nailed-in-cache index, we must do inplace processing because
* the relcache can't cope with changing its relfilenode.
*
* In either of these cases, we are definitely processing a system
* index, so we'd better be ignoring system indexes.
* In either of these cases, we are definitely processing a system index,
* so we'd better be ignoring system indexes.
*/
if (iRel->rd_rel->relisshared)
{

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.55 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.56 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -1115,8 +1115,8 @@ ConversionIsVisible(Oid conid)
/*
* If it is in the path, it might still not be visible; it could
* be hidden by another conversion of the same name earlier in the
* path. So we must do a slow check to see if this conversion would
* be found by ConversionGetConid.
* path. So we must do a slow check to see if this conversion
* would be found by ConversionGetConid.
*/
char *conname = NameStr(conform->conname);
@ -1720,8 +1720,8 @@ RemoveTempRelations(Oid tempNamespaceId)
/*
* We want to get rid of everything in the target namespace, but not
* the namespace itself (deleting it only to recreate it later would be
* a waste of cycles). We do this by finding everything that has a
* the namespace itself (deleting it only to recreate it later would
* be a waste of cycles). We do this by finding everything that has a
* dependency on the namespace.
*/
object.classId = get_system_catalog_relid(NamespaceRelationName);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.61 2003/07/21 01:59:10 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.62 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -99,8 +99,8 @@ AggregateCreate(const char *aggName,
* enforce_generic_type_consistency, if transtype isn't polymorphic)
* must exactly match declared transtype.
*
* In the non-polymorphic-transtype case, it might be okay to allow
* a rettype that's binary-coercible to transtype, but I'm not quite
* In the non-polymorphic-transtype case, it might be okay to allow a
* rettype that's binary-coercible to transtype, but I'm not quite
* convinced that it's either safe or useful. When transtype is
* polymorphic we *must* demand exact equality.
*/
@ -151,9 +151,9 @@ AggregateCreate(const char *aggName,
Assert(OidIsValid(finaltype));
/*
* If finaltype (i.e. aggregate return type) is polymorphic,
* basetype must be polymorphic also, else parser will fail to deduce
* result type. (Note: given the previous test on transtype and basetype,
* If finaltype (i.e. aggregate return type) is polymorphic, basetype
* must be polymorphic also, else parser will fail to deduce result
* type. (Note: given the previous test on transtype and basetype,
* this cannot happen, unless someone has snuck a finalfn definition
* into the catalogs that itself violates the rule against polymorphic
* result with no polymorphic input.)
@ -286,9 +286,9 @@ lookup_agg_function(List *fnName,
func_signature_string(fnName, nargs, input_types))));
/*
* If the given type(s) are all polymorphic, there's nothing we
* can check. Otherwise, enforce consistency, and possibly refine
* the result type.
* If the given type(s) are all polymorphic, there's nothing we can
* check. Otherwise, enforce consistency, and possibly refine the
* result type.
*/
if ((input_types[0] == ANYARRAYOID || input_types[0] == ANYELEMENTOID) &&
(nargs == 1 ||
@ -305,8 +305,8 @@ lookup_agg_function(List *fnName,
}
/*
* func_get_detail will find functions requiring run-time argument type
* coercion, but nodeAgg.c isn't prepared to deal with that
* func_get_detail will find functions requiring run-time argument
* type coercion, but nodeAgg.c isn't prepared to deal with that
*/
if (true_oid_array[0] != ANYARRAYOID &&
true_oid_array[0] != ANYELEMENTOID &&

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.14 2003/07/21 01:59:10 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.15 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -234,8 +234,8 @@ CreateConstraintEntry(const char *constraintName,
if (OidIsValid(indexRelId))
{
/*
* Register normal dependency on the unique index that supports
* a foreign-key constraint.
* Register normal dependency on the unique index that supports a
* foreign-key constraint.
*/
ObjectAddress relobject;
@ -438,8 +438,8 @@ RemoveConstraintById(Oid conId)
Relation rel;
/*
* If the constraint is for a relation, open and exclusive-lock the
* relation it's for.
* If the constraint is for a relation, open and exclusive-lock
* the relation it's for.
*/
rel = heap_open(con->conrelid, AccessExclusiveLock);
@ -483,16 +483,15 @@ RemoveConstraintById(Oid conId)
else if (OidIsValid(con->contypid))
{
/*
* XXX for now, do nothing special when dropping a domain constraint
* XXX for now, do nothing special when dropping a domain
* constraint
*
* Probably there should be some form of locking on the domain type,
* but we have no such concept at the moment.
*/
}
else
{
elog(ERROR, "constraint %u is not of a known type", conId);
}
/* Fry the constraint itself */
simple_heap_delete(conDesc, &tup->t_self);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.13 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.14 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.81 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.82 2003/08/04 00:43:16 momjian Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.102 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.103 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -696,13 +696,13 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp));
/*
* We can't do full prechecking of the function definition if there are
* any polymorphic input types, because actual datatypes of expression
* results will be unresolvable. The check will be done at runtime
* instead.
* We can't do full prechecking of the function definition if there
* are any polymorphic input types, because actual datatypes of
* expression results will be unresolvable. The check will be done at
* runtime instead.
*
* We can run the text through the raw parser though; this will at
* least catch silly syntactic errors.
* We can run the text through the raw parser though; this will at least
* catch silly syntactic errors.
*/
if (!haspolyarg)
{
@ -712,9 +712,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
check_sql_fn_retval(proc->prorettype, functyptype, querytree_list);
}
else
{
querytree_list = pg_parse_query(prosrc);
}
ReleaseSysCache(tuple);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.88 2003/07/21 01:59:11 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.89 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -359,7 +359,8 @@ TypeCreate(const char *typeName,
void
GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId,
Oid relationOid, /* only for 'c'atalog types */
Oid relationOid, /* only for 'c'atalog
* types */
char relationKind, /* ditto */
Oid inputProcedure,
Oid outputProcedure,
@ -426,13 +427,13 @@ GenerateTypeDependencies(Oid typeNamespace,
/*
* If the type is a rowtype for a relation, mark it as internally
* dependent on the relation, *unless* it is a stand-alone
* composite type relation. For the latter case, we have to
* reverse the dependency.
* dependent on the relation, *unless* it is a stand-alone composite
* type relation. For the latter case, we have to reverse the
* dependency.
*
* In the former case, this allows the type to be auto-dropped when
* the relation is, and not otherwise. And in the latter, of
* course we get the opposite effect.
* In the former case, this allows the type to be auto-dropped when the
* relation is, and not otherwise. And in the latter, of course we get
* the opposite effect.
*/
if (OidIsValid(relationOid))
{
@ -447,11 +448,11 @@ GenerateTypeDependencies(Oid typeNamespace,
}
/*
* If the type is an array type, mark it auto-dependent on the
* base type. (This is a compromise between the typical case
* where the array type is automatically generated and the case
* where it is manually created: we'd prefer INTERNAL for the
* former case and NORMAL for the latter.)
* If the type is an array type, mark it auto-dependent on the base
* type. (This is a compromise between the typical case where the
* array type is automatically generated and the case where it is
* manually created: we'd prefer INTERNAL for the former case and
* NORMAL for the latter.)
*/
if (OidIsValid(elementType))
{

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.12 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.13 2003/08/04 00:43:16 momjian Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/alter.c,v 1.4 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/alter.c,v 1.5 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -92,8 +92,8 @@ ExecRenameStmt(RenameStmt *stmt)
{
/*
* RENAME TABLE requires that we (still) hold
* CREATE rights on the containing namespace, as
* well as ownership of the table.
* CREATE rights on the containing namespace,
* as well as ownership of the table.
*/
Oid namespaceId = get_rel_namespace(relid);
AclResult aclresult;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.56 2003/07/20 21:56:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.57 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -220,9 +220,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
/*
* Silently ignore tables that are temp tables of other backends ---
* trying to analyze these is rather pointless, since their
* contents are probably not up-to-date on disk. (We don't throw a
* warning here; it would just lead to chatter during a database-wide
* trying to analyze these is rather pointless, since their contents
* are probably not up-to-date on disk. (We don't throw a warning
* here; it would just lead to chatter during a database-wide
* ANALYZE.)
*/
if (isOtherTempNamespace(RelationGetNamespace(onerel)))

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.96 2003/07/20 21:56:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.97 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -603,10 +603,10 @@ Async_NotifyHandler(SIGNAL_ARGS)
bool save_ImmediateInterruptOK = ImmediateInterruptOK;
/*
* We may be called while ImmediateInterruptOK is true; turn it off
* while messing with the NOTIFY state. (We would have to save
* and restore it anyway, because PGSemaphore operations inside
* ProcessIncomingNotify() might reset it.)
* We may be called while ImmediateInterruptOK is true; turn it
* off while messing with the NOTIFY state. (We would have to
* save and restore it anyway, because PGSemaphore operations
* inside ProcessIncomingNotify() might reset it.)
*/
ImmediateInterruptOK = false;
@ -639,7 +639,8 @@ Async_NotifyHandler(SIGNAL_ARGS)
}
/*
* Restore ImmediateInterruptOK, and check for interrupts if needed.
* Restore ImmediateInterruptOK, and check for interrupts if
* needed.
*/
ImmediateInterruptOK = save_ImmediateInterruptOK;
if (save_ImmediateInterruptOK)

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.112 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.113 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -152,7 +152,10 @@ cluster(ClusterStmt *stmt)
}
else
{
/* The index is expected to be in the same namespace as the relation. */
/*
* The index is expected to be in the same namespace as the
* relation.
*/
indexOid = get_relname_relid(stmt->indexname,
rel->rd_rel->relnamespace);
if (!OidIsValid(indexOid))
@ -175,16 +178,16 @@ cluster(ClusterStmt *stmt)
else
{
/*
* This is the "multi relation" case. We need to cluster all tables
* that have some index with indisclustered set.
* This is the "multi relation" case. We need to cluster all
* tables that have some index with indisclustered set.
*/
MemoryContext cluster_context;
List *rv,
*rvs;
/*
* We cannot run this form of CLUSTER inside a user transaction block;
* we'd be holding locks way too long.
* We cannot run this form of CLUSTER inside a user transaction
* block; we'd be holding locks way too long.
*/
PreventTransactionChain((void *) stmt, "CLUSTER");
@ -201,8 +204,8 @@ cluster(ClusterStmt *stmt)
ALLOCSET_DEFAULT_MAXSIZE);
/*
* Build the list of relations to cluster. Note that this lives in
* cluster_context.
* Build the list of relations to cluster. Note that this lives
* in cluster_context.
*/
rvs = get_tables_to_cluster(cluster_context);
@ -216,7 +219,8 @@ cluster(ClusterStmt *stmt)
/* Start a new transaction for each relation. */
StartTransactionCommand();
SetQuerySnapshot(); /* might be needed for functions in indexes */
SetQuerySnapshot(); /* might be needed for functions in
* indexes */
cluster_rel(rvtc, true);
CommitTransactionCommand();
}
@ -256,8 +260,8 @@ cluster_rel(RelToCluster *rvtc, bool recheck)
* Since we may open a new transaction for each relation, we have to
* check that the relation still is what we think it is.
*
* If this is a single-transaction CLUSTER, we can skip these tests.
* We *must* skip the one on indisclustered since it would reject an
* If this is a single-transaction CLUSTER, we can skip these tests. We
* *must* skip the one on indisclustered since it would reject an
* attempt to cluster a not-previously-clustered index.
*/
if (recheck)
@ -319,10 +323,10 @@ cluster_rel(RelToCluster *rvtc, bool recheck)
RelationGetRelationName(OldHeap))));
/*
* Disallow clustering on incomplete indexes (those that might not index
* every row of the relation). We could relax this by making a separate
* seqscan pass over the table to copy the missing rows, but that seems
* expensive and tedious.
* Disallow clustering on incomplete indexes (those that might not
* index every row of the relation). We could relax this by making a
* separate seqscan pass over the table to copy the missing rows, but
* that seems expensive and tedious.
*/
if (!heap_attisnull(OldIndex->rd_indextuple, Anum_pg_index_indpred))
ereport(ERROR,
@ -432,6 +436,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid)
snprintf(NewHeapName, sizeof(NewHeapName), "pg_temp_%u", tableOid);
OIDNewHeap = make_new_heap(tableOid, NewHeapName);
/*
* We don't need CommandCounterIncrement() because make_new_heap did
* it.
@ -868,9 +873,9 @@ get_tables_to_cluster(MemoryContext cluster_context)
/*
* Get all indexes that have indisclustered set and are owned by
* appropriate user. System relations or nailed-in relations cannot ever
* have indisclustered set, because CLUSTER will refuse to set it when
* called with one of them as argument.
* appropriate user. System relations or nailed-in relations cannot
* ever have indisclustered set, because CLUSTER will refuse to set it
* when called with one of them as argument.
*/
indRelation = relation_openr(IndexRelationName, AccessShareLock);
ScanKeyEntryInitialize(&entry, 0,
@ -886,8 +891,8 @@ get_tables_to_cluster(MemoryContext cluster_context)
continue;
/*
* We have to build the list in a different memory context so
* it will survive the cross-transaction processing
* We have to build the list in a different memory context so it
* will survive the cross-transaction processing
*/
old_context = MemoryContextSwitchTo(cluster_context);

View File

@ -7,7 +7,7 @@
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.67 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.68 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -418,16 +418,17 @@ CommentDatabase(List *qualname, char *comment)
database = strVal(lfirst(qualname));
/*
* We cannot currently support cross-database comments (since other DBs
* cannot see pg_description of this database). So, we reject attempts
* to comment on a database other than the current one. Someday this
* might be improved, but it would take a redesigned infrastructure.
* We cannot currently support cross-database comments (since other
* DBs cannot see pg_description of this database). So, we reject
* attempts to comment on a database other than the current one.
* Someday this might be improved, but it would take a redesigned
* infrastructure.
*
* When loading a dump, we may see a COMMENT ON DATABASE for the old name
* of the database. Erroring out would prevent pg_restore from completing
* (which is really pg_restore's fault, but for now we will work around
* the problem here). Consensus is that the best fix is to treat wrong
* database name as a WARNING not an ERROR.
* of the database. Erroring out would prevent pg_restore from
* completing (which is really pg_restore's fault, but for now we will
* work around the problem here). Consensus is that the best fix is
* to treat wrong database name as a WARNING not an ERROR.
*/
/* First get the database OID */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.9 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.10 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.205 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.206 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -136,6 +136,7 @@ static void CopySendChar(char c);
static void CopySendEndOfRow(bool binary);
static void CopyGetData(void *databuf, int datasize);
static int CopyGetChar(void);
#define CopyGetEof() (fe_eof)
static int CopyPeekChar(void);
static void CopyDonePeek(int c, bool pickup);
@ -537,7 +538,11 @@ CopyDonePeek(int c, bool pickup)
/* We want to pick it up */
(void) pq_getbyte();
}
/* If we didn't want to pick it up, just leave it where it sits */
/*
* If we didn't want to pick it up, just leave it where it
* sits
*/
break;
case COPY_NEW_FE:
if (!pickup)
@ -955,8 +960,8 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
}
/*
* Create a temporary memory context that we can reset once per row
* to recover palloc'd memory. This avoids any problems with leaks
* Create a temporary memory context that we can reset once per row to
* recover palloc'd memory. This avoids any problems with leaks
* inside datatype output routines, and should be faster than retail
* pfree's anyway. (We don't need a whole econtext as CopyFrom does.)
*/
@ -1219,10 +1224,10 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
/*
* Easiest way to do this is to use parse_coerce.c to set up
* an expression that checks the constraints. (At present,
* the expression might contain a length-coercion-function call
* and/or CoerceToDomain nodes.) The bottom of the expression
* is a Param node so that we can fill in the actual datum during
* the data input loop.
* the expression might contain a length-coercion-function
* call and/or CoerceToDomain nodes.) The bottom of the
* expression is a Param node so that we can fill in the
* actual datum during the data input loop.
*/
prm = makeNode(Param);
prm->paramkind = PARAM_EXEC;
@ -1241,11 +1246,11 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
}
/*
* Check BEFORE STATEMENT insertion triggers. It's debateable
* whether we should do this for COPY, since it's not really an
* "INSERT" statement as such. However, executing these triggers
* maintains consistency with the EACH ROW triggers that we already
* fire on COPY.
* Check BEFORE STATEMENT insertion triggers. It's debateable whether
* we should do this for COPY, since it's not really an "INSERT"
* statement as such. However, executing these triggers maintains
* consistency with the EACH ROW triggers that we already fire on
* COPY.
*/
ExecBSInsertTriggers(estate, resultRelInfo);
@ -1418,9 +1423,9 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
/*
* Complain if there are more fields on the input line.
*
* Special case: if we're reading a zero-column table, we
* won't yet have called CopyReadAttribute() at all; so do that
* and check we have an empty line. Fortunately we can keep that
* Special case: if we're reading a zero-column table, we won't
* yet have called CopyReadAttribute() at all; so do that and
* check we have an empty line. Fortunately we can keep that
* silly corner case out of the main line of execution.
*/
if (result == NORMAL_ATTR)
@ -1531,9 +1536,9 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
prmdata->isnull = (nulls[i] == 'n');
/*
* Execute the constraint expression. Allow the expression
* to replace the value (consider e.g. a timestamp precision
* restriction).
* Execute the constraint expression. Allow the
* expression to replace the value (consider e.g. a
* timestamp precision restriction).
*/
values[i] = ExecEvalExpr(exprstate, econtext,
&isnull, NULL);
@ -1679,6 +1684,7 @@ CopyReadAttribute(const char *delim, CopyReadResult *result)
if (copy_lineno == 1 || eol_type == EOL_CRNL)
{
int c2 = CopyPeekChar();
if (c2 == '\n')
{
CopyDonePeek(c2, true); /* eat newline */
@ -1692,7 +1698,11 @@ CopyReadAttribute(const char *delim, CopyReadResult *result)
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("literal carriage return found in data"),
errhint("Use \"\\r\" to represent carriage return.")));
/* if we got here, it is the first line and we didn't get \n, so put it back */
/*
* if we got here, it is the first line and we didn't
* get \n, so put it back
*/
CopyDonePeek(c2, false);
eol_type = EOL_CR;
}
@ -1820,18 +1830,17 @@ CopyReadAttribute(const char *delim, CopyReadResult *result)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
errmsg("end-of-copy marker does not match previous newline style")));
/*
* In protocol version 3, we should ignore anything after
* \. up to the protocol end of copy data. (XXX maybe
* better not to treat \. as special?)
* In protocol version 3, we should ignore anything
* after \. up to the protocol end of copy data. (XXX
* maybe better not to treat \. as special?)
*/
if (copy_dest == COPY_NEW_FE)
{
while (c != EOF)
{
c = CopyGetChar();
}
}
*result = END_OF_FILE;
goto copy_eof;
}

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.119 2003/08/01 00:15:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.120 2003/08/04 00:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -577,10 +577,13 @@ dropdb(const char *dbname)
void
RenameDatabase(const char *oldname, const char *newname)
{
HeapTuple tup, newtup;
HeapTuple tup,
newtup;
Relation rel;
SysScanDesc scan, scan2;
ScanKeyData key, key2;
SysScanDesc scan,
scan2;
ScanKeyData key,
key2;
/*
* Obtain AccessExclusiveLock so that no new session gets started
@ -610,9 +613,8 @@ RenameDatabase(const char *oldname, const char *newname)
errmsg("current database may not be renamed")));
/*
* Make sure the database does not have active sessions. Might
* not be necessary, but it's consistent with other database
* operations.
* Make sure the database does not have active sessions. Might not be
* necessary, but it's consistent with other database operations.
*/
if (DatabaseHasActiveBackends(HeapTupleGetOid(tup), false))
ereport(ERROR,
@ -651,10 +653,10 @@ RenameDatabase(const char *oldname, const char *newname)
heap_close(rel, NoLock);
/*
* Force dirty buffers out to disk, so that newly-connecting
* backends will see the renamed database in pg_database right
* away. (They'll see an uncommitted tuple, but they don't care;
* see GetRawDatabaseInfo.)
* Force dirty buffers out to disk, so that newly-connecting backends
* will see the renamed database in pg_database right away. (They'll
* see an uncommitted tuple, but they don't care; see
* GetRawDatabaseInfo.)
*/
BufferSync();
}

Some files were not shown because too many files have changed in this diff Show More