--- trunk/pgswish.c 2005/02/19 20:59:17 14 +++ trunk/pgswish.c 2005/05/29 20:30:18 20 @@ -6,6 +6,8 @@ * TODO: * - check null input using PG_ARGISNULL before using PG_GETARG_xxxx * - support composite type arguments + * - split error_or_abort + * - use getResultPropValue not SwishResultPropertyStr * * NOTES: * - clear structures with memset to support hash indexes (who whould like @@ -25,6 +27,8 @@ #include "fmgr.h" #include "funcapi.h" #include "utils/builtins.h" +#include "utils/array.h" +#include "miscadmin.h" #include #define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str)) @@ -32,11 +36,11 @@ #define GET_STR(textp) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp))) #define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp))) - -SW_HANDLE swish_handle = NULL;/* Database handle */ -SW_SEARCH search = NULL; /* search handle -- holds search parameters */ -SW_RESULTS swish_results = NULL; /* results handle -- holds list of results */ -SW_RESULT *sw_res = NULL; /* one row from swish-e results */ +/* Globals */ +static SW_HANDLE swish_handle = NULL; /* Database handle */ +static SW_SEARCH search = NULL; /* search handle -- search parameters */ +static SW_RESULTS swish_results = NULL; /* results handle -- list of results */ +static SW_RESULT *sw_res = NULL; /* one row from swish-e results */ /* define PostgreSQL v1 function */ PG_FUNCTION_INFO_V1(pgswish); @@ -50,6 +54,7 @@ AttInMetadata *attinmeta; char *index_path; char *query; + FILE *logfh; /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) { @@ -67,27 +72,41 @@ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - /* Send any errors or warnings to stderr (default is stdout) */ - SwishErrorsToStderr(); + /* Send any errors or warnings to log, as well as + * STDOUT and STDERR (just to be sure) */ + if ( logfh = fopen("/tmp/pgswish.log", "a") ) { + set_error_handle( logfh ); + elog(INFO, "loggin swish-e errors to /tmp/pgswish.log"); + /* redirect STDOUT and STDERR to log */ + dup2(1, logfh); + dup2(2, logfh); + } else { + elog(INFO, "can't open /tmp/pgswish.log -- errors from swish-e won't be cought and may result in back-end crashes!"); + } elog(INFO, "pgswish: SwishInit(%s)", index_path); - + swish_handle = SwishInit( index_path ); + if ( SwishError( swish_handle ) ) + elog(INFO, "pgswish: SwishInit(%s) failed: %s", index_path, SwishErrorString( swish_handle )); + + elog(INFO, "handle: %08x", swish_handle); + if (! swish_handle) { elog(ERROR, "pgswish: can't open %s", index_path); SRF_RETURN_DONE(funcctx); } - error_or_abort( swish_handle ); + if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx); /* set ranking scheme. default is 0 */ SwishRankScheme( swish_handle, 0 ); - error_or_abort( swish_handle ); + if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx); elog(INFO, "pgswish: SwishQuery(%s)", query); /* Here's a short-cut to searching that creates a search object and searches at the same time */ swish_results = SwishQuery( swish_handle, query); - error_or_abort( swish_handle ); + if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx); /* total number of tuples to be returned */ funcctx->max_calls = SwishHits( swish_results ); @@ -140,7 +159,7 @@ } elog(DEBUG1, "pgswish: check for swish-e error"); - error_or_abort( swish_handle ); + if (error_or_abort( swish_handle )) SRF_RETURN_DONE(funcctx); /* * Prepare a values array for storage in our slot. @@ -151,6 +170,8 @@ sw_res = SwishNextResult( swish_results ); if (! sw_res) { elog(ERROR, "pgswish: swish-e sort result list: %d rows expected %d", call_cntr, max_calls - 1); + Free_Results_Object( swish_results ); + Free_Search_Object( search ); SRF_RETURN_DONE(funcctx); } @@ -182,7 +203,7 @@ values[3] = (char *) palloc(16 * sizeof(char)); snprintf(values[3], 16, "%d", 4); */ - + /* build a tuple */ tuple = BuildTupleFromCStrings(attinmeta, values); @@ -196,7 +217,7 @@ pfree(values[3]); pfree(values); - 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]); SRF_RETURN_NEXT(funcctx, result); } else { @@ -211,47 +232,32 @@ } } -Datum swtextprop(PG_FUNCTION_ARGS) { - char *prop; - char *val; - - prop = _textout(PG_GETARG_TEXT_P(0)); - elog(INFO, "pgswish: swextprop(%s)", prop); - - val = prop2int( sw_res, prop ); - error_or_abort( swish_handle ); - - elog(INFO, "pgswish: swextprop(%s) = '%s'", prop, val ); - PG_FREE_IF_COPY(prop, 0); - PG_RETURN_TEXT_P( _textin(val) ); -} - -/* make text var prom property */ +/* make text var from property */ char *prop2text(SW_RESULT sw_res, char *propname) { char *val; char *prop; int len; - elog(DEBUG1, "prop2text(%s)", propname); + elog(DEBUG2, "prop2text(%s)", propname); prop = SwishResultPropertyStr( sw_res, propname ); - error_or_abort( swish_handle ); + if (error_or_abort( swish_handle )) return NULL; len = strlen(prop); - elog(INFO, "prop2text(%s) = '%s' %d bytes", propname, prop, len); + elog(DEBUG1, "prop2text(%s) = '%s' %d bytes", propname, prop, len); len++; len *= sizeof(char); - elog(DEBUG1, "palloc(%d)", len); + elog(DEBUG2, "palloc(%d)", len); val = palloc(len); memset(val, 0, len); strncpy(val, prop, len); - elog(DEBUG1, "val=%s", val); + elog(DEBUG2, "val=%s", val); return val; } @@ -262,22 +268,22 @@ unsigned long prop; int len; - elog(DEBUG1, "prop2int(%s)", propname); + elog(DEBUG2, "prop2int(%s)", propname); prop = SwishResultPropertyULong( sw_res, propname ); - error_or_abort( swish_handle ); + if (error_or_abort( swish_handle )) return NULL; - elog(INFO, "prop2int(%s) = %lu", propname, prop); + elog(DEBUG1, "prop2int(%s) = %lu", propname, prop); len = 128 * sizeof(char); - elog(DEBUG1, "palloc(%d)", len); + elog(DEBUG2, "palloc(%d)", len); val = palloc(len); memset(val, 0, len); snprintf(val, len, "%lu", prop); - elog(DEBUG1, "val=%s", val); + elog(DEBUG2, "val=%s", val); return val; } @@ -286,9 +292,9 @@ /* * check if swish has returned error, and elog it. */ -static void error_or_abort( SW_HANDLE swish_handle ) { +static int error_or_abort( SW_HANDLE swish_handle ) { if ( !SwishError( swish_handle ) ) - return; + return 0; /* print a message */ elog(ERROR, @@ -297,7 +303,10 @@ SwishErrorString( swish_handle ), SwishLastErrorMsg( swish_handle ) ); + if ( swish_results ) Free_Results_Object( swish_results ); if ( search ) Free_Search_Object( search ); SwishClose( swish_handle ); + + return 1; }