/[pgestraier]/trunk/pgest.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/pgest.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 19 by dpavlin, Thu May 26 17:56:53 2005 UTC revision 40 by dpavlin, Sat Sep 10 18:51:13 2005 UTC
# Line 34  Line 34 
34  #define GET_STR(textp) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp)))  #define GET_STR(textp) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp)))
35  #define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))  #define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))
36    
37  /* prototype */  /* SortMem got renamed in PostgreSQL 8.0 */
38  char *attr2text(ESTDOC *doc, char *attr);  #ifndef SortMem
39     #define SortMem 16 * 1024
40  ESTDB *db;  #endif
 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);  
 Datum pgest(PG_FUNCTION_ARGS) {  
   
         FuncCallContext *funcctx;  
         int             call_cntr;  
         int             max_calls;  
         TupleDesc       tupdesc;  
         TupleTableSlot  *slot;  
         AttInMetadata   *attinmeta;  
         char            *index_path;  
         char            *query;  
         char            *attr;  
   
         /* stuff done only on the first call of the function */  
         if (SRF_IS_FIRSTCALL()) {  
                 MemoryContext   oldcontext;  
   
                 /* create a function context for cross-call persistence */  
                 funcctx = SRF_FIRSTCALL_INIT();  
   
                 /* switch to memory context appropriate for multiple function calls */  
                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);  
                 /* take arguments from function */  
   
                 /* index path */  
                 if (PG_ARGISNULL(0)) {  
                         elog(ERROR, "index path can't be null");  
                         SRF_RETURN_DONE(funcctx);  
                 }  
                 index_path = _textout(PG_GETARG_TEXT_P(0));  
   
                 /* query string */  
                 if (PG_ARGISNULL(0)) {  
                         query = "";  
                 } else {  
                         query = _textout(PG_GETARG_TEXT_P(1));  
                 }  
   
                 /* atribute filter */  
                 if (PG_ARGISNULL(2)) {  
                         attr = "";  
                 } else {  
                         attr = _textout(PG_GETARG_TEXT_P(2));  
                 }  
   
                 /* limit */  
                 if (PG_ARGISNULL(3)) {  
                         limit = 0;  
                 } else {  
                         limit = PG_GETARG_INT32(3);  
                 }  
   
                 /* offset */  
                 if (PG_ARGISNULL(4)) {  
                         offset = 0;  
                 } else {  
                         offset = PG_GETARG_INT32(4);  
                 }  
   
41    
42                  /* open the database */  #define ATTR_DELIMITER "{{!}}"
                 elog(DEBUG1, "pgest: est_db_open(%s)", index_path);  
                   
                 if(!(db = est_db_open(index_path, ESTDBREADER, &ecode))){  
                         elog(ERROR, "est_db_open: can't open %s [%d]: %s", index_path, ecode, est_err_msg(ecode));  
                         SRF_RETURN_DONE(funcctx);  
                 }  
                   
                 elog(INFO, "pgest: query[%s] attr[%s] limit %d offset %d", query, (PG_ARGISNULL(2) ? "NULL" : attr), limit, offset);  
                   
                 /* create a search condition object */  
                 if (!(cond = est_cond_new())) {  
                         elog(INFO, "pgest: est_cond_new failed");  
                         SRF_RETURN_DONE(funcctx);  
                 }  
                   
                 /* set the search phrase to the search condition object */  
                 if (! PG_ARGISNULL(1) && strlen(query) > 0)  
                         est_cond_set_phrase(cond, query);  
   
                 /* minimum valid attribute length is 10: @a STREQ a */  
                 if (! PG_ARGISNULL(2) && 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 */  
                 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 );  
43    
44                  elog(DEBUG1, "pgest: found %d hits for %s", resnum, query);  /* prototype */
45    char *attr2text(ESTDOC *doc, char *attr);
                 /* Build a tuple description for a __pgest tuple */  
                 tupdesc = RelationNameGetTupleDesc("__pgest");  
   
                 /* allocate a slot for a tuple with this tupdesc */  
                 slot = TupleDescGetSlot(tupdesc);  
   
                 /* assign slot to function context */  
                 funcctx->slot = slot;  
   
                 /*  
                  * generate attribute metadata needed later to produce tuples from raw  
                  * C strings  
                  */  
                 attinmeta = TupleDescGetAttInMetadata(tupdesc);  
                 funcctx->attinmeta = attinmeta;  
   
                 MemoryContextSwitchTo(oldcontext);  
   
                 elog(DEBUG1, "SRF_IS_FIRSTCALL done");  
         }  
   
         /* stuff done on every call of the function */  
         funcctx = SRF_PERCALL_SETUP();  
   
         call_cntr = funcctx->call_cntr;  
         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;  
                 Datum           result;  
   
                 elog(DEBUG1, "pgest: loop count %d", call_cntr);  
   
                 if (! est_result) {  
                         elog(ERROR, "pgest: no estraier results");  
                         SRF_RETURN_DONE(funcctx);  
                 }  
                   
                 /*  
                  * Prepare a values array for storage in our slot.  
                  * This should be an array of C strings which will  
                  * be processed later by the type input functions.  
                  */  
   
                 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"),  
                                 est_doc_attr(doc, "@title")  
                         );  
   
                         values = (char **) palloc(4 * sizeof(char *));  
   
 //                      values[0] = (char *) palloc(strlen(_estval) * sizeof(char));  
   
                         values[0] = (char *) attr2text(doc,"@id");  
                         values[1] = (char *) attr2text(doc,"@uri");  
                         values[2] = (char *) attr2text(doc,"@title");  
                         values[3] = (char *) attr2text(doc,"@size");  
   
                         /* destloy the document object */  
                         elog(DEBUG2, "est_doc_delete");  
                         est_doc_delete(doc);  
                 } else {  
                         elog(INFO, "no result from estraier");  
                         values[0] = DatumGetCString( "" );  
                         values[1] = DatumGetCString( "" );  
                         values[2] = DatumGetCString( "" );  
                         values[3] = DatumGetCString( "" );  
                 }  
   
   
                 elog(DEBUG2, "build tuple");  
                 /* build a tuple */  
                 tuple = BuildTupleFromCStrings(attinmeta, values);  
   
                 elog(DEBUG2, "make tuple into datum");  
                 /* make the tuple into a datum */  
                 result = TupleGetDatum(slot, tuple);  
   
                 elog(DEBUG2, "cleanup");  
                 /* clean up ? */  
 /*  
                 pfree(values[0]);  
                 pfree(values[1]);  
                 pfree(values[2]);  
                 pfree(values[3]);  
                 pfree(values);  
 */  
                   
                 elog(DEBUG2, "cleanup over");  
           
                 SRF_RETURN_NEXT(funcctx, result);  
         } else {  
                 elog(DEBUG1, "loop over");  
   
                 if(!est_db_close(db, &ecode)){  
                         elog(INFO, "est_db_close error: %s", est_err_msg(ecode));  
                 }  
46    
                 /* do when there is no more left */  
                 SRF_RETURN_DONE(funcctx);  
         }  
 }  
47    
48  /* work in progress */  /* work in progress */
49  PG_FUNCTION_INFO_V1(pgest_attr);  PG_FUNCTION_INFO_V1(pgest_attr);
50  Datum pgest_attr(PG_FUNCTION_ARGS)  Datum pgest_attr(PG_FUNCTION_ARGS)
51  {  {
52          ArrayType       *attr_arr = PG_GETARG_ARRAYTYPE_P(5);          ArrayType       *attr_arr = PG_GETARG_ARRAYTYPE_P(6);
53          Oid             element_type = ARR_ELEMTYPE(attr_arr);          Oid             attr_element_type = ARR_ELEMTYPE(attr_arr);
54          int             ndims = ARR_NDIM(attr_arr);          int             attr_ndims = ARR_NDIM(attr_arr);
55          int             *dim_counts = ARR_DIMS(attr_arr);          int             *attr_dim_counts = ARR_DIMS(attr_arr);
56          int             *dim_lower_bounds = ARR_LBOUND(attr_arr);          int             *attr_dim_lower_bounds = ARR_LBOUND(attr_arr);
57          int             ncols = 0;          int             ncols = 0;
58          int             nrows = 0;          int             nrows = 0;
59          int             indx[MAXDIM];          int             indx[MAXDIM];
60          int16           typlen;          int16           attr_len;
61          bool            typbyval;          bool            attr_byval;
62          char            typalign;          char            attr_align;
63          ReturnSetInfo   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;          ReturnSetInfo   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
64          AttInMetadata   *attinmeta;          AttInMetadata   *attinmeta;
65          TupleDesc       tupdesc;          TupleDesc       tupdesc;
# Line 288  Datum pgest_attr(PG_FUNCTION_ARGS) Line 72  Datum pgest_attr(PG_FUNCTION_ARGS)
72          int             rsinfo_ncols;          int             rsinfo_ncols;
73          int             i, j;          int             i, j;
74          /* estvars */          /* estvars */
75            ESTDB *db;
76            ESTCOND *cond;
77            ESTDOC *doc;
78            const CBLIST *texts;
79            int ecode, *est_result, resnum;
80            int limit = 0;
81            int offset = 0;
82    
83          char            *index_path;          char            *index_path;
84          char            *query;          char            *query;
85          char            *attr;          char            *attr;
86            char            *order;
87    
88    
89          /* only allow 1D input array */          /* only allow 1D input array */
90          if (ndims == 1)          if (attr_ndims == 1)
91          {          {
92                  ncols = dim_counts[0];                  ncols = attr_dim_counts[0];
93          }          }
94          else          else
95                  ereport(ERROR,                  ereport(ERROR,
# Line 312  Datum pgest_attr(PG_FUNCTION_ARGS) Line 105  Datum pgest_attr(PG_FUNCTION_ARGS)
105                                                  "allowed in this context")));                                                  "allowed in this context")));
106    
107          /* get info about element type needed to construct the array */          /* get info about element type needed to construct the array */
108          get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);          get_typlenbyvalalign(attr_element_type, &attr_len, &attr_byval, &attr_align);
109    
110          /* get the requested return tuple description */          /* get the requested return tuple description */
111          tupdesc = rsinfo->expectedDesc;          tupdesc = rsinfo->expectedDesc;
# Line 353  Datum pgest_attr(PG_FUNCTION_ARGS) Line 146  Datum pgest_attr(PG_FUNCTION_ARGS)
146          index_path = _textout(PG_GETARG_TEXT_P(0));          index_path = _textout(PG_GETARG_TEXT_P(0));
147    
148          /* query string */          /* query string */
149          if (PG_ARGISNULL(0)) {          if (PG_ARGISNULL(1)) {
150                  query = "";                  query = "";
151          } else {          } else {
152                  query = _textout(PG_GETARG_TEXT_P(1));                  query = _textout(PG_GETARG_TEXT_P(1));
# Line 365  Datum pgest_attr(PG_FUNCTION_ARGS) Line 158  Datum pgest_attr(PG_FUNCTION_ARGS)
158          } else {          } else {
159                  attr = _textout(PG_GETARG_TEXT_P(2));                  attr = _textout(PG_GETARG_TEXT_P(2));
160          }          }
161            
162            /* sort order */
163            if (PG_ARGISNULL(3)) {
164                    order = "";
165            } else {
166                    order = _textout(PG_GETARG_TEXT_P(3));
167            }
168    
169    
170          /* limit */          /* limit */
171          if (PG_ARGISNULL(3)) {          if (PG_ARGISNULL(4)) {
172                  limit = 0;                  limit = 0;
173          } else {          } else {
174                  limit = PG_GETARG_INT32(3);                  limit = PG_GETARG_INT32(4);
175          }          }
176    
177          /* offset */          /* offset */
178          if (PG_ARGISNULL(4)) {          if (PG_ARGISNULL(5)) {
179                  offset = 0;                  offset = 0;
180          } else {          } else {
181                  offset = PG_GETARG_INT32(4);                  offset = PG_GETARG_INT32(5);
182          }          }
183    
184    
# Line 390  Datum pgest_attr(PG_FUNCTION_ARGS) Line 191  Datum pgest_attr(PG_FUNCTION_ARGS)
191                          errdetail(est_err_msg(ecode))));                          errdetail(est_err_msg(ecode))));
192          }          }
193                                    
194          elog(INFO, "pgest_attr: query[%s] attr[%s] limit %d offset %d", query, (PG_ARGISNULL(2) ? "NULL" : attr), limit, offset);          elog(DEBUG1, "pgest_attr: query[%s] attr[%s] limit %d offset %d", query, (PG_ARGISNULL(2) ? "NULL" : attr), limit, offset);
195                    
196          /* create a search condition object */          /* create a search condition object */
197          if (!(cond = est_cond_new())) {          if (!(cond = est_cond_new())) {
# Line 404  Datum pgest_attr(PG_FUNCTION_ARGS) Line 205  Datum pgest_attr(PG_FUNCTION_ARGS)
205    
206          /* minimum valid attribute length is 10: @a STREQ a */          /* minimum valid attribute length is 10: @a STREQ a */
207          if (! PG_ARGISNULL(2) && strlen(attr) >= 10) {          if (! PG_ARGISNULL(2) && strlen(attr) >= 10) {
208                  elog(INFO,"est_cond_add_attr(%s)", attr);                  elog(DEBUG1,"attributes: %s", attr);
209                  est_cond_add_attr(cond, attr);                  char *curr_attr;
210                    curr_attr = strtok(attr, ATTR_DELIMITER);
211                    while (curr_attr) {
212                            elog(DEBUG1,"est_cond_add_attr(%s)", curr_attr);
213                            est_cond_add_attr(cond, curr_attr);
214                            curr_attr = strtok(NULL, ATTR_DELIMITER);
215                    }
216            }
217    
218            /* set the search phrase to the search condition object */
219            if (! PG_ARGISNULL(3) && strlen(order) > 0) {
220                    elog(DEBUG1,"est_cond_set_order(%s)", order);
221                    est_cond_set_order(cond, order);
222            }
223    
224            if (limit) {
225                    elog(DEBUG1,"est_cond_set_max(%d)", limit + offset);
226                    est_cond_set_max(cond, limit + offset);
227          }          }
228    
229          /* get the result of search */          /* get the result of search */
# Line 418  Datum pgest_attr(PG_FUNCTION_ARGS) Line 236  Datum pgest_attr(PG_FUNCTION_ARGS)
236    
237          /* total number of tuples to be returned */          /* total number of tuples to be returned */
238          if (limit && limit < resnum) {          if (limit && limit < resnum) {
239                  nrows = limit - offset;                  nrows = limit;
240          } else {          } else {
241                  nrows = resnum - offset;                  nrows = resnum - offset;
242          }          }
# Line 448  Datum pgest_attr(PG_FUNCTION_ARGS) Line 266  Datum pgest_attr(PG_FUNCTION_ARGS)
266                          bool    isnull;                          bool    isnull;
267    
268                          /* array value of this position */                          /* array value of this position */
269                          indx[0] = j + dim_lower_bounds[0];                          indx[0] = j + attr_dim_lower_bounds[0];
270    
271                          dvalue = array_ref(attr_arr, ndims, indx, -1, typlen, typbyval, typalign, &isnull);                          dvalue = array_ref(attr_arr, attr_ndims, indx, -1, attr_len, attr_byval, attr_align, &isnull);
272    
273                          if (!isnull && doc)                          if (!isnull && doc)
274                                  values[j] = DatumGetCString(                                  values[j] = DatumGetCString(
275                                          attr2text(doc,                                          attr2text(doc,
276                                                  DirectFunctionCall1(textout, dvalue)                                                  (char *)DirectFunctionCall1(textout, dvalue)
277                                          ));                                          ));
278                          else                          else
279                                  values[j] = NULL;                                  values[j] = NULL;
# Line 484  Datum pgest_attr(PG_FUNCTION_ARGS) Line 302  Datum pgest_attr(PG_FUNCTION_ARGS)
302          rsinfo->setDesc = tupdesc;          rsinfo->setDesc = tupdesc;
303          MemoryContextSwitchTo(oldcontext);          MemoryContextSwitchTo(oldcontext);
304    
305            est_cond_delete(cond);
306    
307          if(!est_db_close(db, &ecode)){          if(!est_db_close(db, &ecode)){
308                  ereport(ERROR, (errcode(ERRCODE_IO_ERROR),                  ereport(ERROR, (errcode(ERRCODE_IO_ERROR),
309                          errmsg("est_db_close: %d", ecode),                          errmsg("est_db_close: %d", ecode),

Legend:
Removed from v.19  
changed lines
  Added in v.40

  ViewVC Help
Powered by ViewVC 1.1.26