Fix compiler warnings
[smlar.git] / smlar_gin.c
1 #include <math.h>
2
3 #include "smlar.h"
4
5 #include "fmgr.h"
6 #include "access/gin.h"
7 #include "access/skey.h"
8 #if PG_VERSION_NUM < 130000
9 #include "access/tuptoaster.h"
10 #else
11 #include "access/heaptoast.h"
12 #endif
13
14 PG_FUNCTION_INFO_V1(smlararrayextract);
15 Datum smlararrayextract(PG_FUNCTION_ARGS);
16 Datum
17 smlararrayextract(PG_FUNCTION_ARGS)
18 {
19         ArrayType       *array;
20         int32           *nentries = (int32 *) PG_GETARG_POINTER(1);
21         SimpleArray     *sa;
22
23         /*
24          * we should guarantee that array will not be destroyed during all
25          * operation
26          */
27         array = PG_GETARG_ARRAYTYPE_P_COPY(0);
28
29         CHECKARRVALID(array);
30
31         sa = Array2SimpleArrayU(NULL, array, NULL);
32
33         *nentries = sa->nelems;
34
35         if (sa->nelems == 0 && PG_NARGS() == 3)
36         {
37                 switch (PG_GETARG_UINT16(2))    /* StrategyNumber */
38                 {
39                         case    SmlarOverlapStrategy:
40                         case    SmlarSimilarityStrategy:
41                                 *nentries = -1; /* nobody can be found */
42                                 break;
43                         default:
44                                 break;
45                 }
46         }
47
48         PG_RETURN_POINTER( sa->elems );
49 }
50
51 PG_FUNCTION_INFO_V1(smlarqueryarrayextract);
52 Datum smlarqueryarrayextract(PG_FUNCTION_ARGS);
53 Datum
54 smlarqueryarrayextract(PG_FUNCTION_ARGS)
55 {
56         PG_RETURN_DATUM(DirectFunctionCall3(smlararrayextract,
57                                                                                 PG_GETARG_DATUM(0),
58                                                                                 PG_GETARG_DATUM(1),
59                                                                                 PG_GETARG_DATUM(2)));
60 }
61
62 PG_FUNCTION_INFO_V1(smlararrayconsistent);
63 Datum smlararrayconsistent(PG_FUNCTION_ARGS);
64 Datum
65 smlararrayconsistent(PG_FUNCTION_ARGS)
66 {
67         bool                    *check = (bool *) PG_GETARG_POINTER(0);
68         StrategyNumber  strategy = PG_GETARG_UINT16(1);
69         SimpleArray             *sa;
70         bool                    res = false;
71         int                             i,
72                                         cnt = 0;
73         bool                    *recheck = (bool *) PG_GETARG_POINTER(5);
74
75         *recheck = true;
76
77         switch (strategy)
78         {
79                 case SmlarOverlapStrategy:
80                         /* at least one element in check[] is true, so result = true */
81                         res = true;
82                         *recheck = false;
83                         break;
84                 case SmlarSimilarityStrategy:
85
86                         fcinfo->flinfo->fn_extra = SearchArrayCache(
87                                                                                                 fcinfo->flinfo->fn_extra,
88                                                                                                 fcinfo->flinfo->fn_mcxt,
89                                                                                                 PG_GETARG_DATUM(2), NULL, &sa, NULL );
90
91                         for(i=0; i<sa->nelems; i++)
92                                 cnt += check[i];
93
94                         /*
95                          * cnt is a lower limit of elements's number in indexed array;
96                          */
97
98                         switch(getSmlType())
99                         {
100                                 case ST_TFIDF:
101                                                 {
102                                                         double  weight = 0.0, /* exact weight of union */
103                                                                         saSum = 0.0,  /* exact length of query */
104                                                                         siSum = 0.0;  /* lower limit of length of indexed value */ 
105
106                                                         if ( getTFMethod() != TF_CONST )
107                                                                 elog(ERROR,"GIN supports only smlar.tf_method = \"const\"" );
108
109                                                         Assert(sa->df);
110
111                                                         for(i=0; i<sa->nelems; i++)
112                                                         {
113                                                                 /*
114                                                                  * With smlar.tf_method = "const"   sa->df[i] is 
115                                                                  * equal to its idf, so lookup of StatElem is not needed
116                                                                  */
117                                                                 if ( check[i] )
118                                                                 {
119                                                                         weight += sa->df[i] * sa->df[i];
120                                                                         siSum += sa->df[i] * sa->df[i];
121                                                                 }
122                                                                 saSum += sa->df[i] * sa->df[i];
123                                                         }
124
125                                                         if ( saSum > 0.0 && siSum > 0.0 && weight / sqrt(saSum * siSum ) > GetSmlarLimit() )
126                                                                 res = true;
127                                                 }
128                                                 break;
129                                 case ST_COSINE:
130                                                 {
131                                                         double                  power;
132
133                                                         power = sqrt( ((double)(sa->nelems)) * ((double)(cnt)) );
134
135                                                         if (  ((double)cnt) / power >= GetSmlarLimit()  )
136                                                                 res = true;
137                                                 }
138                                                 break;
139                                 case ST_OVERLAP:
140                                                 if (cnt >= GetSmlarLimit())
141                                                         res = true;
142                                                 break;
143                                 default:
144                                         elog(ERROR,"GIN doesn't support current formula type of similarity");
145                         }
146                         break;
147                 default:
148                         elog(ERROR, "smlararrayconsistent: unknown strategy number: %d", strategy);
149         }
150
151         PG_RETURN_BOOL(res);
152 }