utf8proc
view pgsql/utf8proc_pgsql.c @ 1:61a89ecc2fb9
Version 0.2
- changed behaviour of PostgreSQL function to return NULL in case of invalid input, rather than raising an exceptional condition
- improved efficiency of PostgreSQL function (no transformation to C string is done)
- added -fpic compiler flag in Makefile
- fixed bug in the C code for the ruby library (usage of non-existent function)
- changed behaviour of PostgreSQL function to return NULL in case of invalid input, rather than raising an exceptional condition
- improved efficiency of PostgreSQL function (no transformation to C string is done)
- added -fpic compiler flag in Makefile
- fixed bug in the C code for the ruby library (usage of non-existent function)
| author | jbe | 
|---|---|
| date | Tue Jun 20 12:00:00 2006 +0200 (2006-06-20) | 
| parents | a0368662434c | 
| children | aaad485d5335 | 
 line source
     1 /*
     2  *  Copyright (c) 2006, FlexiGuided GmbH, Berlin, Germany
     3  *  Author: Jan Behrens <jan.behrens@flexiguided.de>
     4  *  All rights reserved.
     5  *
     6  *  Redistribution and use in source and binary forms, with or without
     7  *  modification, are permitted provided that the following conditions are
     8  *  met:
     9  *
    10  *  1. Redistributions of source code must retain the above copyright
    11  *     notice, this list of conditions and the following disclaimer.
    12  *  2. Redistributions in binary form must reproduce the above copyright
    13  *     notice, this list of conditions and the following disclaimer in the
    14  *     documentation and/or other materials provided with the distribution.
    15  *  3. Neither the name of the FlexiGuided GmbH nor the names of its
    16  *     contributors may be used to endorse or promote products derived from
    17  *     this software without specific prior written permission.
    18  *
    19  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    20  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    21  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    22  *  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
    23  *  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    24  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    25  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    26  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    27  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    28  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    29  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    30  *
    31  */
    34 /*
    35  *  File name:    pgsql/utf8proc_pgsql.c
    36  *  Version:      0.2
    37  *  Last changed: 2006-06-05
    38  *
    39  *  Description:
    40  *  PostgreSQL extension to provide a function 'unifold', which can be used
    41  *  to case-fold and normalize index fields.
    42  */
    45 #include "../utf8proc.c"
    47 #include <postgres.h>
    48 #include <utils/elog.h>
    49 #include <fmgr.h>
    50 #include <string.h>
    51 #include <unistd.h>
    52 #include <utils/builtins.h>
    54 #define UTF8PROC_PGSQL_OPTS ( UTF8PROC_REJECTNA | \
    55   UTF8PROC_COMPOSE | UTF8PROC_IGNORE | UTF8PROC_STRIPCC | UTF8PROC_CASEFOLD)
    57 PG_FUNCTION_INFO_V1(utf8proc_pgsql_unifold);
    58 Datum utf8proc_pgsql_unifold(PG_FUNCTION_ARGS) {
    59   text *input_string;
    60   text *output_string = NULL;
    61   ssize_t result;
    62   input_string = PG_GETARG_TEXT_P(0);
    63   do {
    64     result = utf8proc_decompose(
    65       VARDATA(input_string), VARSIZE(input_string) - VARHDRSZ,
    66       NULL, 0, UTF8PROC_PGSQL_OPTS
    67     );
    68     if (result < 0) break;
    69     if (result > (SIZE_MAX-1-VARHDRSZ)/sizeof(int32_t)) {
    70       result = UTF8PROC_ERROR_OVERFLOW;
    71       break;
    72     }
    73     output_string = palloc(result * sizeof(int32_t) + 1 + VARHDRSZ);
    74     // reserve one extra byte for termination
    75     if (!output_string) {
    76       result = UTF8PROC_ERROR_NOMEM;
    77       break;
    78     }
    79     result = utf8proc_decompose(
    80       VARDATA(input_string), VARSIZE(input_string) - VARHDRSZ,
    81       (int32_t *)VARDATA(output_string), result, UTF8PROC_PGSQL_OPTS);
    82     if (result < 0) break;
    83     result = utf8proc_reencode((int32_t *)VARDATA(output_string), result,
    84       UTF8PROC_PGSQL_OPTS);
    85   } while (0);
    86   PG_FREE_IF_COPY(input_string, 0);
    87   if (result < 0) {
    88     int sqlerrcode;
    89     if (output_string) pfree(output_string);
    90     switch(result) {
    91       case UTF8PROC_ERROR_NOMEM:
    92       sqlerrcode = ERRCODE_OUT_OF_MEMORY; break;
    93       case UTF8PROC_ERROR_OVERFLOW:
    94       sqlerrcode = ERRCODE_PROGRAM_LIMIT_EXCEEDED; break;
    95       case UTF8PROC_ERROR_INVALIDUTF8:
    96       case UTF8PROC_ERROR_NOTASSIGNED:
    97       PG_RETURN_NULL();
    98       default:
    99       sqlerrcode = ERRCODE_INTERNAL_ERROR;
   100     }
   101     ereport(ERROR, (
   102       errcode(sqlerrcode),
   103       errmsg("%s", utf8proc_errmsg(result))
   104     ));
   105   } else {
   106     VARATT_SIZEP(output_string) = result + VARHDRSZ;
   107     PG_RETURN_TEXT_P(output_string);
   108   }
   109   PG_RETURN_NULL();  // prohibit compiler warning
   110 }
