Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions

dict_ispell.c File Reference

#include "postgres.h"
#include "commands/defrem.h"
#include "tsearch/dicts/spell.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_utils.h"
Include dependency graph for dict_ispell.c:

Go to the source code of this file.

Data Structures

struct  DictISpell

Functions

Datum dispell_init (PG_FUNCTION_ARGS)
Datum dispell_lexize (PG_FUNCTION_ARGS)

Function Documentation

Datum dispell_init ( PG_FUNCTION_ARGS   ) 

Definition at line 29 of file dict_ispell.c.

References defGetString(), DefElem::defname, ereport, errcode(), errmsg(), ERROR, get_tsearch_config_filename(), lfirst, lowerstr(), NIFinishBuild(), NIImportAffixes(), NIImportDictionary(), NISortAffixes(), NISortDictionary(), NIStartBuild(), DictISpell::obj, palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, pg_strcasecmp(), readstoplist(), and DictISpell::stoplist.

{
    List       *dictoptions = (List *) PG_GETARG_POINTER(0);
    DictISpell *d;
    bool        affloaded = false,
                dictloaded = false,
                stoploaded = false;
    ListCell   *l;

    d = (DictISpell *) palloc0(sizeof(DictISpell));

    NIStartBuild(&(d->obj));

    foreach(l, dictoptions)
    {
        DefElem    *defel = (DefElem *) lfirst(l);

        if (pg_strcasecmp(defel->defname, "DictFile") == 0)
        {
            if (dictloaded)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("multiple DictFile parameters")));
            NIImportDictionary(&(d->obj),
                             get_tsearch_config_filename(defGetString(defel),
                                                         "dict"));
            dictloaded = true;
        }
        else if (pg_strcasecmp(defel->defname, "AffFile") == 0)
        {
            if (affloaded)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("multiple AffFile parameters")));
            NIImportAffixes(&(d->obj),
                            get_tsearch_config_filename(defGetString(defel),
                                                        "affix"));
            affloaded = true;
        }
        else if (pg_strcasecmp(defel->defname, "StopWords") == 0)
        {
            if (stoploaded)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("multiple StopWords parameters")));
            readstoplist(defGetString(defel), &(d->stoplist), lowerstr);
            stoploaded = true;
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("unrecognized Ispell parameter: \"%s\"",
                            defel->defname)));
        }
    }

    if (affloaded && dictloaded)
    {
        NISortDictionary(&(d->obj));
        NISortAffixes(&(d->obj));
    }
    else if (!affloaded)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("missing AffFile parameter")));
    }
    else
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("missing DictFile parameter")));
    }

    NIFinishBuild(&(d->obj));

    PG_RETURN_POINTER(d);
}

Datum dispell_lexize ( PG_FUNCTION_ARGS   ) 

Definition at line 110 of file dict_ispell.c.

References TSLexeme::lexeme, lowerstr_with_len(), NINormalizeWord(), NULL, DictISpell::obj, pfree(), PG_GETARG_INT32, PG_GETARG_POINTER, PG_RETURN_POINTER, searchstoplist(), and DictISpell::stoplist.

{
    DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
    char       *in = (char *) PG_GETARG_POINTER(1);
    int32       len = PG_GETARG_INT32(2);
    char       *txt;
    TSLexeme   *res;
    TSLexeme   *ptr,
               *cptr;

    if (len <= 0)
        PG_RETURN_POINTER(NULL);

    txt = lowerstr_with_len(in, len);
    res = NINormalizeWord(&(d->obj), txt);

    if (res == NULL)
        PG_RETURN_POINTER(NULL);

    ptr = cptr = res;
    while (ptr->lexeme)
    {
        if (searchstoplist(&(d->stoplist), ptr->lexeme))
        {
            pfree(ptr->lexeme);
            ptr->lexeme = NULL;
            ptr++;
        }
        else
        {
            memcpy(cptr, ptr, sizeof(TSLexeme));
            cptr++;
            ptr++;
        }
    }
    cptr->lexeme = NULL;

    PG_RETURN_POINTER(res);
}