File: address_parser.c

package info (click to toggle)
postgis 3.1.1%2Bdfsg-1%2Bdeb11u2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 83,792 kB
  • sloc: ansic: 151,982; sql: 146,734; xml: 51,051; sh: 6,186; cpp: 6,110; perl: 4,852; makefile: 3,002; python: 1,205; yacc: 447; lex: 133; javascript: 6
file content (113 lines) | stat: -rw-r--r-- 2,844 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "postgres.h"
#include "fmgr.h"
#include "funcapi.h"
#include "catalog/pg_type.h"
#include "utils/builtins.h"

#include "parseaddress-api.h"
#include <pcre.h>
#include <string.h>

#undef DEBUG
//#define DEBUG 1

#ifdef DEBUG
#define DBG(format, arg...)                     \
    elog(NOTICE, format , ## arg)
#else
#define DBG(format, arg...) do { ; } while (0)
#endif

Datum parse_address(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(parse_address);

Datum parse_address(PG_FUNCTION_ARGS)
{
    TupleDesc            tupdesc;
    AttInMetadata       *attinmeta;
    Datum                result;
    ADDRESS             *paddr;
    HHash               *stH;
    char                *str;
    char               **values;
    int                  err;
    HeapTuple            tuple;


    DBG("Start standardize_address");

    str = text_to_cstring(PG_GETARG_TEXT_P(0));

    DBG("str='%s'", str);

    if (get_call_result_type( fcinfo, NULL, &tupdesc ) != TYPEFUNC_COMPOSITE ) {
        elog(ERROR, "function returning record called in context"
            " that cannot accept type record");
        return -1;
    }
    BlessTupleDesc(tupdesc);
    attinmeta = TupleDescGetAttInMetadata(tupdesc);

    DBG("Got tupdesc, allocating HHash");

    stH = (HHash *) palloc0(sizeof(HHash));
    if (!stH) {
         elog(ERROR, "parse_address: Failed to allocate memory for hash!");
         return -1;
    }

    DBG("going to load_state_hash");

    err = load_state_hash(stH);
    if (err) {
        DBG("got err=%d from load_state_hash().", err);
#ifdef USE_HSEARCH
        DBG("calling hdestroy_r(stH).");
        hdestroy_r(stH);
#endif
        elog(ERROR, "parse_address: load_state_hash() failed(%d)!", err);
        return -1;
    }

    DBG("calling parseaddress()");
    paddr = parseaddress(stH, str, &err);
    if (!paddr) {
        elog(ERROR, "parse_address: parseaddress() failed!");
        return -1;
    }

    DBG("setup values array for natts=%d", tupdesc->natts);
    values = (char **) palloc(9 * sizeof(char *));
    if (!values) {
        elog(ERROR, "parse_address: out of memory!");
        return -1;
    }
    values[0] = paddr->num;
    values[1] = paddr->street;
    values[2] = paddr->street2;
    values[3] = paddr->address1;
    values[4] = paddr->city;
    values[5] = paddr->st;
    values[6] = paddr->zip;
    values[7] = paddr->zipplus;
    values[8] = paddr->cc;

    DBG("calling heap_form_tuple");
    tuple = BuildTupleFromCStrings(attinmeta, values);

    /* make the tuple into a datum */
    DBG("calling HeapTupleGetDatum");
    result = HeapTupleGetDatum(tuple);

    /* clean up (this is not really necessary */
    DBG("freeing values, hash, and paddr");
    free_state_hash(stH);

    DBG("returning parsed address result");
    return result;
}