/[pgswish]/trunk/pgswish.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/pgswish.c

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

revision 18 by dpavlin, Sun Feb 20 22:58:25 2005 UTC revision 20 by dpavlin, Sun May 29 20:30:18 2005 UTC
# Line 6  Line 6 
6   * TODO:   * TODO:
7   * - check null input using PG_ARGISNULL before using PG_GETARG_xxxx   * - check null input using PG_ARGISNULL before using PG_GETARG_xxxx
8   * - support composite type arguments   * - support composite type arguments
9     * - split error_or_abort
10     * - use getResultPropValue not SwishResultPropertyStr
11   *   *
12   * NOTES:   * NOTES:
13   * - clear structures with memset to support hash indexes (who whould like   * - clear structures with memset to support hash indexes (who whould like
# Line 34  Line 36 
36  #define GET_STR(textp) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp)))  #define GET_STR(textp) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp)))
37  #define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))  #define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))
38    
39    /* Globals */
40  SW_HANDLE   swish_handle = NULL;/* Database handle */  static SW_HANDLE   swish_handle = NULL; /* Database handle */
41  SW_SEARCH   search = NULL;      /* search handle -- holds search parameters */  static SW_SEARCH   search = NULL;       /* search handle -- search parameters */
42  SW_RESULTS  swish_results = NULL;       /* results handle -- holds list of results */  static SW_RESULTS  swish_results = NULL; /* results handle -- list of results */
43  SW_RESULT   *sw_res = NULL;     /* one row from swish-e results */  static SW_RESULT   *sw_res = NULL;      /* one row from swish-e results */
44    
45  /* define PostgreSQL v1 function */  /* define PostgreSQL v1 function */
46  PG_FUNCTION_INFO_V1(pgswish);  PG_FUNCTION_INFO_V1(pgswish);
# Line 52  Datum pgswish(PG_FUNCTION_ARGS) { Line 54  Datum pgswish(PG_FUNCTION_ARGS) {
54          AttInMetadata   *attinmeta;          AttInMetadata   *attinmeta;
55          char            *index_path;          char            *index_path;
56          char            *query;          char            *query;
57            FILE            *logfh;
58    
59          /* stuff done only on the first call of the function */          /* stuff done only on the first call of the function */
60          if (SRF_IS_FIRSTCALL()) {          if (SRF_IS_FIRSTCALL()) {
# Line 69  Datum pgswish(PG_FUNCTION_ARGS) { Line 72  Datum pgswish(PG_FUNCTION_ARGS) {
72                  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);                  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
73    
74                                    
75                  /* Send any errors or warnings to stderr (default is stdout) */                  /* Send any errors or warnings to log, as well as
76                  SwishErrorsToStderr();                   * STDOUT and STDERR (just to be sure) */
77                    if ( logfh = fopen("/tmp/pgswish.log", "a") ) {
78                            set_error_handle( logfh );
79                            elog(INFO, "loggin swish-e errors to /tmp/pgswish.log");
80                            /* redirect STDOUT and STDERR to log */
81                            dup2(1, logfh);
82                            dup2(2, logfh);
83                    } else {
84                            elog(INFO, "can't open /tmp/pgswish.log -- errors from swish-e won't be cought and may result in back-end crashes!");
85                    }
86    
87                  elog(INFO, "pgswish: SwishInit(%s)", index_path);                  elog(INFO, "pgswish: SwishInit(%s)", index_path);
88                    
89                  swish_handle = SwishInit( index_path );                  swish_handle = SwishInit( index_path );
90    
91                    if ( SwishError( swish_handle ) )
92                            elog(INFO, "pgswish: SwishInit(%s) failed: %s", index_path, SwishErrorString( swish_handle ));
93                    
94                    elog(INFO, "handle: %08x", swish_handle);
95    
96                  if (! swish_handle) {                  if (! swish_handle) {
97                          elog(ERROR, "pgswish: can't open %s", index_path);                          elog(ERROR, "pgswish: can't open %s", index_path);
98                          SRF_RETURN_DONE(funcctx);                          SRF_RETURN_DONE(funcctx);
99                  }                  }
100                                    
101                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
102                  /* set ranking scheme. default is 0 */                  /* set ranking scheme. default is 0 */
103                  SwishRankScheme( swish_handle, 0 );                  SwishRankScheme( swish_handle, 0 );
104                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
105    
106                  elog(INFO, "pgswish: SwishQuery(%s)", query);                  elog(INFO, "pgswish: SwishQuery(%s)", query);
107                  /* Here's a short-cut to searching that creates a search object and searches at the same time */                  /* Here's a short-cut to searching that creates a search object and searches at the same time */
108                  swish_results = SwishQuery( swish_handle, query);                  swish_results = SwishQuery( swish_handle, query);
109                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
110    
111                  /* total number of tuples to be returned */                  /* total number of tuples to be returned */
112                  funcctx->max_calls = SwishHits( swish_results );                  funcctx->max_calls = SwishHits( swish_results );
# Line 142  Datum pgswish(PG_FUNCTION_ARGS) { Line 159  Datum pgswish(PG_FUNCTION_ARGS) {
159                  }                  }
160                                    
161                  elog(DEBUG1, "pgswish: check for swish-e error");                  elog(DEBUG1, "pgswish: check for swish-e error");
162                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
163    
164                  /*                  /*
165                   * Prepare a values array for storage in our slot.                   * Prepare a values array for storage in our slot.
# Line 153  Datum pgswish(PG_FUNCTION_ARGS) { Line 170  Datum pgswish(PG_FUNCTION_ARGS) {
170                  sw_res = SwishNextResult( swish_results );                  sw_res = SwishNextResult( swish_results );
171                  if (! sw_res) {                  if (! sw_res) {
172                          elog(ERROR, "pgswish: swish-e sort result list: %d rows expected %d", call_cntr, max_calls - 1);                          elog(ERROR, "pgswish: swish-e sort result list: %d rows expected %d", call_cntr, max_calls - 1);
173                            Free_Results_Object( swish_results );
174                            Free_Search_Object( search );
175                          SRF_RETURN_DONE(funcctx);                          SRF_RETURN_DONE(funcctx);
176                  }                  }
177                                    
# Line 213  Datum pgswish(PG_FUNCTION_ARGS) { Line 232  Datum pgswish(PG_FUNCTION_ARGS) {
232          }          }
233  }  }
234    
 /* work in progress */  
 PG_FUNCTION_INFO_V1(pgswish2);  
 Datum pgswish2(PG_FUNCTION_ARGS)  
 {  
         int             nrows = 3;  
         int16           typlen;  
         bool            typbyval;  
         char            typalign;  
         ReturnSetInfo   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;  
         AttInMetadata   *attinmeta;  
         TupleDesc       tupdesc;  
         Tuplestorestate *tupstore = NULL;  
         HeapTuple       tuple;  
         MemoryContext   per_query_ctx;  
         MemoryContext   oldcontext;  
         Datum           dvalue;  
         char            **values;  
         int             ncols;  
         int             i, j;  
   
         /* check to see if caller supports us returning a tuplestore */  
         if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))  
                 ereport(ERROR,  
                                 (errcode(ERRCODE_SYNTAX_ERROR),  
                                  errmsg("materialize mode required, but it is not " \  
                                                 "allowed in this context")));  
   
         /* get the requested return tuple description */  
         tupdesc = rsinfo->expectedDesc;  
         ncols = tupdesc->natts;  
   
         /*  
          * The requested tuple description better match up with the array  
          * we were given.  
          */  
         /* OK, use it */  
         attinmeta = TupleDescGetAttInMetadata(tupdesc);  
   
         /* Now go to work */  
         rsinfo->returnMode = SFRM_Materialize;  
   
         per_query_ctx = fcinfo->flinfo->fn_mcxt;  
         oldcontext = MemoryContextSwitchTo(per_query_ctx);  
   
         /* initialize our tuplestore */  
         tupstore = tuplestore_begin_heap(true, false, SortMem);  
   
         values = (char **) palloc(ncols * sizeof(char *));  
   
         for (i = 0; i < nrows; i++)  
         {  
                 for (j = 0; j < ncols; j++)  
                 {  
                         values[j] = DatumGetCString( "foo" );  
                 }  
                 /* construct the tuple */  
                 tuple = BuildTupleFromCStrings(attinmeta, values);  
   
                 /* now store it */  
                 tuplestore_puttuple(tupstore, tuple);  
         }  
   
         tuplestore_donestoring(tupstore);  
         rsinfo->setResult = tupstore;  
   
         /*  
          * SFRM_Materialize mode expects us to return a NULL Datum. The actual  
          * tuples are in our tuplestore and passed back through  
          * rsinfo->setResult. rsinfo->setDesc is set to the tuple description  
          * that we actually used to build our tuples with, so the caller can  
          * verify we did what it was expecting.  
          */  
         rsinfo->setDesc = tupdesc;  
         MemoryContextSwitchTo(oldcontext);  
   
         return (Datum) 0;  
 }  
   
235    
236  /* make text var prom property */  /* make text var from property */
237  char *prop2text(SW_RESULT sw_res, char *propname) {  char *prop2text(SW_RESULT sw_res, char *propname) {
238          char *val;          char *val;
239          char *prop;          char *prop;
# Line 301  char *prop2text(SW_RESULT sw_res, char * Line 242  char *prop2text(SW_RESULT sw_res, char *
242          elog(DEBUG2, "prop2text(%s)", propname);          elog(DEBUG2, "prop2text(%s)", propname);
243    
244          prop = SwishResultPropertyStr( sw_res, propname );          prop = SwishResultPropertyStr( sw_res, propname );
245          error_or_abort( swish_handle );          if (error_or_abort( swish_handle )) return NULL;
246    
247          len = strlen(prop);          len = strlen(prop);
248          elog(DEBUG1, "prop2text(%s) = '%s' %d bytes", propname, prop, len);          elog(DEBUG1, "prop2text(%s) = '%s' %d bytes", propname, prop, len);
# Line 330  char *prop2int(SW_RESULT sw_res, char *p Line 271  char *prop2int(SW_RESULT sw_res, char *p
271          elog(DEBUG2, "prop2int(%s)", propname);          elog(DEBUG2, "prop2int(%s)", propname);
272    
273          prop = SwishResultPropertyULong( sw_res, propname );          prop = SwishResultPropertyULong( sw_res, propname );
274          error_or_abort( swish_handle );          if (error_or_abort( swish_handle )) return NULL;
275    
276          elog(DEBUG1, "prop2int(%s) = %lu", propname, prop);          elog(DEBUG1, "prop2int(%s) = %lu", propname, prop);
277    
# Line 351  char *prop2int(SW_RESULT sw_res, char *p Line 292  char *prop2int(SW_RESULT sw_res, char *p
292  /*  /*
293   * check if swish has returned error, and elog it.   * check if swish has returned error, and elog it.
294   */   */
295  static void error_or_abort( SW_HANDLE swish_handle ) {  static int error_or_abort( SW_HANDLE swish_handle ) {
296          if ( !SwishError( swish_handle ) )          if ( !SwishError( swish_handle ) )
297                  return;                  return 0;
298    
299          /* print a message */          /* print a message */
300          elog(ERROR,          elog(ERROR,
# Line 362  static void error_or_abort( SW_HANDLE sw Line 303  static void error_or_abort( SW_HANDLE sw
303                          SwishErrorString( swish_handle ),                          SwishErrorString( swish_handle ),
304                          SwishLastErrorMsg( swish_handle )                          SwishLastErrorMsg( swish_handle )
305          );          );
306            if ( swish_results ) Free_Results_Object( swish_results );
307          if ( search ) Free_Search_Object( search );          if ( search ) Free_Search_Object( search );
308          SwishClose( swish_handle );          SwishClose( swish_handle );
309    
310            return 1;
311  }  }
312    

Legend:
Removed from v.18  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26