/[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 13 by dpavlin, Sat Feb 19 16:01:46 2005 UTC revision 19 by dpavlin, Sun Mar 6 21:13:39 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 25  Line 27 
27  #include "fmgr.h"  #include "fmgr.h"
28  #include "funcapi.h"  #include "funcapi.h"
29  #include "utils/builtins.h"  #include "utils/builtins.h"
30    #include "utils/array.h"
31    #include "miscadmin.h"
32  #include <swish-e.h>  #include <swish-e.h>
33    
34  #define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))  #define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
# Line 32  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  SW_HANDLE   swish_handle = NULL;/* Database handle */  SW_HANDLE   swish_handle = NULL;/* Database handle */
40  SW_SEARCH   search = NULL;      /* search handle -- holds search parameters */  SW_SEARCH   search = NULL;      /* search handle -- holds search parameters */
41  SW_RESULTS  swish_results = NULL;       /* results handle -- holds list of results */  SW_RESULTS  swish_results = NULL;       /* results handle -- holds list of results */
42    SW_RESULT   *sw_res = NULL;     /* one row from swish-e results */
43    
44  /* define PostgreSQL v1 function */  /* define PostgreSQL v1 function */
45  PG_FUNCTION_INFO_V1(pgswish);  PG_FUNCTION_INFO_V1(pgswish);
# Line 78  Datum pgswish(PG_FUNCTION_ARGS) { Line 82  Datum pgswish(PG_FUNCTION_ARGS) {
82                          SRF_RETURN_DONE(funcctx);                          SRF_RETURN_DONE(funcctx);
83                  }                  }
84                                    
85                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
86                  /* set ranking scheme. default is 0 */                  /* set ranking scheme. default is 0 */
87                  SwishRankScheme( swish_handle, 0 );                  SwishRankScheme( swish_handle, 0 );
88                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
89    
90                  elog(INFO, "pgswish: SwishQuery(%s)", query);                  elog(INFO, "pgswish: SwishQuery(%s)", query);
91                  /* 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 */
92                  swish_results = SwishQuery( swish_handle, query);                  swish_results = SwishQuery( swish_handle, query);
93                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
94    
95                  /* total number of tuples to be returned */                  /* total number of tuples to be returned */
96                  funcctx->max_calls = SwishHits( swish_results );                  funcctx->max_calls = SwishHits( swish_results );
# Line 130  Datum pgswish(PG_FUNCTION_ARGS) { Line 134  Datum pgswish(PG_FUNCTION_ARGS) {
134                  char            **values;                  char            **values;
135                  HeapTuple       tuple;                  HeapTuple       tuple;
136                  Datum           result;                  Datum           result;
                 SW_RESULT       *sw_res;        /* one row from swish-e results */  
137    
138                  elog(INFO, "pgswish: loop count %d", call_cntr);                  elog(INFO, "pgswish: loop count %d", call_cntr);
139    
# Line 139  Datum pgswish(PG_FUNCTION_ARGS) { Line 142  Datum pgswish(PG_FUNCTION_ARGS) {
142                          SRF_RETURN_DONE(funcctx);                          SRF_RETURN_DONE(funcctx);
143                  }                  }
144                                    
145                  elog(INFO, "pgswish: check for swish-e error");                  elog(DEBUG1, "pgswish: check for swish-e error");
146                  error_or_abort( swish_handle );                  if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx);
147    
148                  /*                  /*
149                   * Prepare a values array for storage in our slot.                   * Prepare a values array for storage in our slot.
# Line 151  Datum pgswish(PG_FUNCTION_ARGS) { Line 154  Datum pgswish(PG_FUNCTION_ARGS) {
154                  sw_res = SwishNextResult( swish_results );                  sw_res = SwishNextResult( swish_results );
155                  if (! sw_res) {                  if (! sw_res) {
156                          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);
157                            Free_Results_Object( swish_results );
158                            Free_Search_Object( search );
159                          SRF_RETURN_DONE(funcctx);                          SRF_RETURN_DONE(funcctx);
160                  }                  }
161                                    
# Line 182  Datum pgswish(PG_FUNCTION_ARGS) { Line 187  Datum pgswish(PG_FUNCTION_ARGS) {
187                  values[3] = (char *) palloc(16 * sizeof(char));                  values[3] = (char *) palloc(16 * sizeof(char));
188                  snprintf(values[3], 16, "%d", 4);                  snprintf(values[3], 16, "%d", 4);
189  */  */
190                    
191                  /* build a tuple */                  /* build a tuple */
192                  tuple = BuildTupleFromCStrings(attinmeta, values);                  tuple = BuildTupleFromCStrings(attinmeta, values);
193    
# Line 196  Datum pgswish(PG_FUNCTION_ARGS) { Line 201  Datum pgswish(PG_FUNCTION_ARGS) {
201                  pfree(values[3]);                  pfree(values[3]);
202                  pfree(values);                  pfree(values);
203                                    
204                  elog(INFO, "row: %s|%s|%s|%s",values[0],values[1],values[2],values[3]);                  elog(DEBUG1, "row: %s|%s|%s|%s",values[0],values[1],values[2],values[3]);
205                    
206                  SRF_RETURN_NEXT(funcctx, result);                  SRF_RETURN_NEXT(funcctx, result);
207          } else {          } else {
# Line 211  Datum pgswish(PG_FUNCTION_ARGS) { Line 216  Datum pgswish(PG_FUNCTION_ARGS) {
216          }          }
217  }  }
218    
219  /*  /* work in progress */
220   * elog errors  PG_FUNCTION_INFO_V1(pgswish2);
221   *  Datum pgswish2(PG_FUNCTION_ARGS)
222   */  {
223            int             nrows = 3;
224            int16           typlen;
225            bool            typbyval;
226            char            typalign;
227            ReturnSetInfo   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
228            AttInMetadata   *attinmeta;
229            TupleDesc       tupdesc;
230            Tuplestorestate *tupstore = NULL;
231            HeapTuple       tuple;
232            MemoryContext   per_query_ctx;
233            MemoryContext   oldcontext;
234            Datum           dvalue;
235            char            **values;
236            int             ncols;
237            int             i, j;
238    
239            /* check to see if caller supports us returning a tuplestore */
240            if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))
241                    ereport(ERROR,
242                                    (errcode(ERRCODE_SYNTAX_ERROR),
243                                     errmsg("materialize mode required, but it is not " \
244                                                    "allowed in this context")));
245    
246            /* get the requested return tuple description */
247            tupdesc = rsinfo->expectedDesc;
248            ncols = tupdesc->natts;
249    
250            /*
251             * The requested tuple description better match up with the array
252             * we were given.
253             */
254            /* OK, use it */
255            attinmeta = TupleDescGetAttInMetadata(tupdesc);
256    
257            /* Now go to work */
258            rsinfo->returnMode = SFRM_Materialize;
259    
260            per_query_ctx = fcinfo->flinfo->fn_mcxt;
261            oldcontext = MemoryContextSwitchTo(per_query_ctx);
262    
263            /* initialize our tuplestore */
264            tupstore = tuplestore_begin_heap(true, false, SortMem);
265    
266            values = (char **) palloc(ncols * sizeof(char *));
267    
268            for (i = 0; i < nrows; i++)
269            {
270                    for (j = 0; j < ncols; j++)
271                    {
272                            values[j] = DatumGetCString( "foo" );
273                    }
274                    /* construct the tuple */
275                    tuple = BuildTupleFromCStrings(attinmeta, values);
276    
277                    /* now store it */
278                    tuplestore_puttuple(tupstore, tuple);
279            }
280    
281            tuplestore_donestoring(tupstore);
282            rsinfo->setResult = tupstore;
283    
284            /*
285             * SFRM_Materialize mode expects us to return a NULL Datum. The actual
286             * tuples are in our tuplestore and passed back through
287             * rsinfo->setResult. rsinfo->setDesc is set to the tuple description
288             * that we actually used to build our tuples with, so the caller can
289             * verify we did what it was expecting.
290             */
291            rsinfo->setDesc = tupdesc;
292            MemoryContextSwitchTo(oldcontext);
293    
294            return (Datum) 0;
295    }
296    
297    
298    /* make text var from property */
299  char *prop2text(SW_RESULT sw_res, char *propname) {  char *prop2text(SW_RESULT sw_res, char *propname) {
300          char *val;          char *val;
301          char *prop;          char *prop;
302          int len;          int len;
303    
304          elog(INFO, "prop2text(%s)", propname);          elog(DEBUG2, "prop2text(%s)", propname);
305    
306          prop = SwishResultPropertyStr( sw_res, propname );          prop = SwishResultPropertyStr( sw_res, propname );
307          error_or_abort( swish_handle );          if (error_or_abort( swish_handle )) return NULL;
308    
309          len = strlen(prop);          len = strlen(prop);
310          elog(INFO, "prop2text(%s) = '%s' %d bytes", propname, prop, len);          elog(DEBUG1, "prop2text(%s) = '%s' %d bytes", propname, prop, len);
311    
312          len++;          len++;
313          len *= sizeof(char);          len *= sizeof(char);
314    
315          elog(INFO, "palloc(%d)", len);          elog(DEBUG2, "palloc(%d)", len);
316    
317          val = palloc(len);          val = palloc(len);
318    
319          memset(val, 0, len);          memset(val, 0, len);
320          strncpy(val, prop, len);          strncpy(val, prop, len);
321    
322          elog(INFO, "val=%s", val);          elog(DEBUG2, "val=%s", val);
323    
324          return val;          return val;
325  }  }
326    
327    /* make integer variable from property */
328  char *prop2int(SW_RESULT sw_res, char *propname) {  char *prop2int(SW_RESULT sw_res, char *propname) {
329          char *val;          char *val;
330          unsigned long prop;          unsigned long prop;
331          int len;          int len;
332    
333          elog(INFO, "prop2int(%s)", propname);          elog(DEBUG2, "prop2int(%s)", propname);
334    
335          prop = SwishResultPropertyULong( sw_res, propname );          prop = SwishResultPropertyULong( sw_res, propname );
336          error_or_abort( swish_handle );          if (error_or_abort( swish_handle )) return NULL;
337    
338          elog(INFO, "prop2int(%s) = %lu", propname, prop);          elog(DEBUG1, "prop2int(%s) = %lu", propname, prop);
339    
340          len = 128 * sizeof(char);          len = 128 * sizeof(char);
341          elog(INFO, "palloc(%d)", len);          elog(DEBUG2, "palloc(%d)", len);
342    
343          val = palloc(len);          val = palloc(len);
344          memset(val, 0, len);          memset(val, 0, len);
345    
346          snprintf(val, len, "%lu", prop);          snprintf(val, len, "%lu", prop);
347    
348          elog(INFO, "val=%s", val);          elog(DEBUG2, "val=%s", val);
349    
350          return val;          return val;
351  }  }
352    
353    
354  static void error_or_abort( SW_HANDLE swish_handle ) {  /*
355     * check if swish has returned error, and elog it.
356     */
357    static int error_or_abort( SW_HANDLE swish_handle ) {
358          if ( !SwishError( swish_handle ) )          if ( !SwishError( swish_handle ) )
359                  return;                  return 0;
360    
361          /* print a message */          /* print a message */
362          elog(ERROR,          elog(ERROR,
# Line 281  static void error_or_abort( SW_HANDLE sw Line 365  static void error_or_abort( SW_HANDLE sw
365                          SwishErrorString( swish_handle ),                          SwishErrorString( swish_handle ),
366                          SwishLastErrorMsg( swish_handle )                          SwishLastErrorMsg( swish_handle )
367          );          );
368            if ( swish_results ) Free_Results_Object( swish_results );
369          if ( search ) Free_Search_Object( search );          if ( search ) Free_Search_Object( search );
370          SwishClose( swish_handle );          SwishClose( swish_handle );
371    
372          /* do when there is no more left */          return 1;
373  }  }
374    

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

  ViewVC Help
Powered by ViewVC 1.1.26