--- trunk/pgest.c 2005/05/20 13:00:46 2 +++ trunk/pgest.c 2005/05/20 19:44:09 5 @@ -34,12 +34,16 @@ #define GET_STR(textp) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp))) #define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp))) +/* prototype */ +char *attr2text(ESTDOC *doc, char *attr); ESTDB *db; ESTCOND *cond; ESTDOC *doc; const CBLIST *texts; int ecode, *est_result, resnum, i, j; +int limit = 0; +int offset = 0; /* define PostgreSQL v1 function */ PG_FUNCTION_INFO_V1(pgest); @@ -53,6 +57,7 @@ AttInMetadata *attinmeta; char *index_path; char *query; + char *attr; /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) { @@ -62,6 +67,9 @@ //index_path = _textout(PG_GETARG_TEXT_P(0)); index_path = _textout(PG_GETARG_TEXT_P(0)); query = _textout(PG_GETARG_TEXT_P(1)); + attr = _textout(PG_GETARG_TEXT_P(2)); + limit = PG_GETARG_INT32(3); + offset = PG_GETARG_INT32(4); /* create a function context for cross-call persistence */ funcctx = SRF_FIRSTCALL_INIT(); @@ -77,7 +85,7 @@ SRF_RETURN_DONE(funcctx); } - elog(DEBUG2, "pgest: query=%s", query); + elog(INFO, "pgest: query[%s] attr[%s] limit %d offset %d", query, attr, limit, offset); /* create a search condition object */ if (!(cond = est_cond_new())) { @@ -88,17 +96,27 @@ /* set the search phrase to the search condition object */ est_cond_set_phrase(cond, query); + /* minimum valid attribute length is 10: @a STREQ a */ + if (attr != NULL && strlen(attr) >= 10) { + elog(INFO,"est_cond_add_attr(%s)", attr); + est_cond_add_attr(cond, attr); + } + /* get the result of search */ est_result = est_db_search(db, cond, &resnum, NULL); /* total number of tuples to be returned */ - funcctx->max_calls = resnum; + if (limit && limit < resnum) { + funcctx->max_calls = limit - offset; + } else { + funcctx->max_calls = resnum - offset; + } /* check if results exists */ if ( 0 == funcctx->max_calls ) elog(INFO, "pgest: no results for: %s", query ); - elog(DEBUG1, "pgest: found %d hits for %s", funcctx->max_calls, query); + elog(DEBUG1, "pgest: found %d hits for %s", resnum, query); /* Build a tuple description for a __pgest tuple */ tupdesc = RelationNameGetTupleDesc("__pgest"); @@ -128,7 +146,12 @@ max_calls = funcctx->max_calls; slot = funcctx->slot; attinmeta = funcctx->attinmeta; - + + if (limit && call_cntr > limit - 1) { + elog(INFO, "call_cntr: %d limit: %d", call_cntr, limit); + SRF_RETURN_DONE(funcctx); + } + if (call_cntr < max_calls) { char **values; HeapTuple tuple; @@ -147,7 +170,7 @@ * be processed later by the type input functions. */ - if (doc = est_db_get_doc(db, est_result[call_cntr], 0)) { + if (doc = est_db_get_doc(db, est_result[call_cntr + offset], 0)) { elog(DEBUG1, "URI: %s\n Title: %s\n", est_doc_attr(doc, "@uri"), @@ -158,10 +181,10 @@ // values[0] = (char *) palloc(strlen(_estval) * sizeof(char)); - values[0] = attr2text(doc,"@id"); - values[1] = attr2text(doc,"@uri"); - values[2] = attr2text(doc,"@title"); - values[3] = attr2text(doc,"@type"); + values[0] = (char *) attr2text(doc,"@id"); + values[1] = (char *) attr2text(doc,"@uri"); + values[2] = (char *) attr2text(doc,"@title"); + values[3] = (char *) attr2text(doc,"@type"); /* destloy the document object */ elog(DEBUG2, "est_doc_delete"); @@ -292,11 +315,12 @@ char *val; const char *attrval; int len; + int attrlen; elog(DEBUG1, "doc: %08x, attr: %s", doc, attr); - if (attrval = est_doc_attr(doc, attr)) { - val = (char *) palloc(strlen(attrval) * sizeof(char)); + if ( (attrval = est_doc_attr(doc, attr)) && (attrlen = strlen(attrval)) ) { + val = (char *) palloc(attrlen * sizeof(char)); } else { return (Datum) NULL; }