Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfdf2dbd

Browse files
committed
Fix assorted corner-case bugs in contrib/intarray.
The array containment operators now behave per mathematical expectationfor empty arrays (ie, an empty array is contained in anything).Both these operators and the query_int operators now work as expected inGiST and GIN index searches, rather than having corner cases where theindex searches gave different answers.Also, fix unexpected failures where the operators would claim that an arraycontained nulls, when in fact there was no longer any null present (similarto bug #5784). The restriction to not have nulls is still there, asremoving it would take a lot of added code complexity and probably slowthings down significantly.Also, remove the arbitrary restriction to 1-D arrays; unlike the otherrestriction, this was buying us nothing performance-wise.Assorted cosmetic improvements and marginal performance improvements, too.
1 parentadf328c commitfdf2dbd

File tree

9 files changed

+332
-460
lines changed

9 files changed

+332
-460
lines changed

‎contrib/intarray/_int.h

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,36 @@
99
/* number ranges for compression */
1010
#defineMAXNUMRANGE 100
1111

12-
/* dimension of array */
13-
#defineNDIM 1
14-
1512
/* useful macros for accessing int4 arrays */
1613
#defineARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) )
1714
#defineARRNELEMS(x) ArrayGetNItems(ARR_NDIM(x), ARR_DIMS(x))
1815

19-
/* reject arrays we can't handle;but allow a NULL or empty array */
16+
/* reject arrays we can't handle;to wit, those containing nulls */
2017
#defineCHECKARRVALID(x) \
2118
do { \
22-
if (x) { \
23-
if (ARR_NDIM(x) != NDIM && ARR_NDIM(x) != 0) \
24-
ereport(ERROR, \
25-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), \
26-
errmsg("array must be one-dimensional"))); \
27-
if (ARR_HASNULL(x)) \
28-
ereport(ERROR, \
29-
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
30-
errmsg("array must not contain nulls"))); \
31-
} \
19+
if (ARR_HASNULL(x) && array_contains_nulls(x)) \
20+
ereport(ERROR, \
21+
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
22+
errmsg("array must not contain nulls"))); \
3223
} while(0)
3324

34-
#defineARRISVOID(x) ((x) == NULL ||ARRNELEMS(x) == 0)
25+
#defineARRISEMPTY(x) (ARRNELEMS(x) == 0)
3526

27+
/* sort the elements of the array */
3628
#defineSORT(x) \
3729
do { \
38-
if ( ARRNELEMS( x ) > 1 ) \
39-
isort( ARRPTR( x ), ARRNELEMS( x ) ); \
30+
int_nelems_ = ARRNELEMS(x); \
31+
if (_nelems_ > 1) \
32+
isort(ARRPTR(x), _nelems_); \
4033
} while(0)
4134

35+
/* sort the elements of the array and remove duplicates */
4236
#definePREPAREARR(x) \
4337
do { \
44-
if ( ARRNELEMS( x ) > 1 ) \
45-
if ( isort( ARRPTR( x ), ARRNELEMS( x ) ) ) \
46-
x = _int_unique( x ); \
38+
int_nelems_ = ARRNELEMS(x); \
39+
if (_nelems_ > 1) \
40+
if (isort(ARRPTR(x), _nelems_)) \
41+
(x) = _int_unique(x); \
4742
} while(0)
4843

4944
/* "wish" function */
@@ -90,14 +85,14 @@ typedef struct
9085
#defineGETSIGN(x)( (BITVECP)( (char*)x+GTHDRSIZE ) )
9186

9287
/*
93-
** types for functions
94-
*/
88+
* types for functions
89+
*/
9590
typedefArrayType*(*formarray) (ArrayType*,ArrayType*);
9691
typedefvoid (*formfloat) (ArrayType*,float*);
9792

9893
/*
99-
** usefulfunction
100-
*/
94+
* usefulfunctions
95+
*/
10196
boolisort(int4*a,intlen);
10297
ArrayType*new_intArrayType(intnum);
10398
ArrayType*copy_intArrayType(ArrayType*a);
@@ -133,36 +128,47 @@ typedef struct ITEM
133128
int4val;
134129
}ITEM;
135130

136-
typedefstruct
131+
typedefstructQUERYTYPE
137132
{
138133
int32vl_len_;/* varlena header (do not touch directly!) */
139-
int4size;
140-
chardata[1];
134+
int4size;/* number of ITEMs */
135+
ITEMitems[1];/* variable length array */
141136
}QUERYTYPE;
142137

143-
#defineHDRSIZEQT(VARHDRSZ + sizeof(int4))
144-
#defineCOMPUTESIZE(size)( HDRSIZEQT + size * sizeof(ITEM) )
145-
#defineGETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT )
138+
#defineHDRSIZEQToffsetof(QUERYTYPE, items)
139+
#defineCOMPUTESIZE(size)( HDRSIZEQT +(size) * sizeof(ITEM) )
140+
#defineGETQUERY(x) ( (x)->items )
146141

142+
/* "type" codes for ITEM */
147143
#defineEND0
148144
#defineERR1
149145
#defineVAL2
150146
#defineOPR3
151147
#defineOPEN4
152148
#defineCLOSE5
153149

150+
/* fmgr macros for QUERYTYPE objects */
151+
#defineDatumGetQueryTypeP(X) ((QUERYTYPE *) PG_DETOAST_DATUM(X))
152+
#defineDatumGetQueryTypePCopy(X) ((QUERYTYPE *) PG_DETOAST_DATUM_COPY(X))
153+
#definePG_GETARG_QUERYTYPE_P(n) DatumGetQueryTypeP(PG_GETARG_DATUM(n))
154+
#definePG_GETARG_QUERYTYPE_P_COPY(n) DatumGetQueryTypePCopy(PG_GETARG_DATUM(n))
155+
154156
boolsignconsistent(QUERYTYPE*query,BITVECsign,boolcalcnot);
155157
boolexecconsistent(QUERYTYPE*query,ArrayType*array,boolcalcnot);
156-
boolginconsistent(QUERYTYPE*query,bool*check);
157-
int4shorterquery(ITEM*q,int4len);
158158

159-
intcompASC(constvoid*a,constvoid*b);
159+
boolgin_bool_consistent(QUERYTYPE*query,bool*check);
160+
boolquery_has_required_values(QUERYTYPE*query);
160161

162+
intcompASC(constvoid*a,constvoid*b);
161163
intcompDESC(constvoid*a,constvoid*b);
162164

163-
#defineQSORT(a,direction)\
164-
if (ARRNELEMS(a) > 1)\
165-
qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4),\
166-
(direction) ? compASC : compDESC )
165+
/* sort, either ascending or descending */
166+
#defineQSORT(a,direction) \
167+
do { \
168+
int_nelems_ = ARRNELEMS(a); \
169+
if (_nelems_ > 1) \
170+
qsort((void*) ARRPTR(a), _nelems_, sizeof(int4), \
171+
(direction) ? compASC : compDESC ); \
172+
} while(0)
167173

168174
#endif/* ___INT_H__ */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp