Commit cdaa45fd authored by Bruce Momjian's avatar Bruce Momjian

Run pgindent on range type files, per request from Tom.

parent 5b5985e6
...@@ -36,23 +36,23 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, ...@@ -36,23 +36,23 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
Oid rangeSubOpclass, RegProcedure rangeCanonical, Oid rangeSubOpclass, RegProcedure rangeCanonical,
RegProcedure rangeSubDiff) RegProcedure rangeSubDiff)
{ {
Relation pg_range; Relation pg_range;
Datum values[Natts_pg_range]; Datum values[Natts_pg_range];
bool nulls[Natts_pg_range]; bool nulls[Natts_pg_range];
HeapTuple tup; HeapTuple tup;
ObjectAddress myself; ObjectAddress myself;
ObjectAddress referenced; ObjectAddress referenced;
pg_range = heap_open(RangeRelationId, RowExclusiveLock); pg_range = heap_open(RangeRelationId, RowExclusiveLock);
memset(nulls, 0, Natts_pg_range * sizeof(bool)); memset(nulls, 0, Natts_pg_range * sizeof(bool));
values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid); values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType); values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation); values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation);
values[Anum_pg_range_rngsubopc - 1] = ObjectIdGetDatum(rangeSubOpclass); values[Anum_pg_range_rngsubopc - 1] = ObjectIdGetDatum(rangeSubOpclass);
values[Anum_pg_range_rngcanonical - 1] = ObjectIdGetDatum(rangeCanonical); values[Anum_pg_range_rngcanonical - 1] = ObjectIdGetDatum(rangeCanonical);
values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff); values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff);
tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls); tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls);
simple_heap_insert(pg_range, tup); simple_heap_insert(pg_range, tup);
...@@ -61,40 +61,40 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, ...@@ -61,40 +61,40 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
/* record dependencies */ /* record dependencies */
myself.classId = TypeRelationId; myself.classId = TypeRelationId;
myself.objectId = rangeTypeOid; myself.objectId = rangeTypeOid;
myself.objectSubId = 0; myself.objectSubId = 0;
referenced.classId = TypeRelationId; referenced.classId = TypeRelationId;
referenced.objectId = rangeSubType; referenced.objectId = rangeSubType;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
referenced.classId = OperatorClassRelationId; referenced.classId = OperatorClassRelationId;
referenced.objectId = rangeSubOpclass; referenced.objectId = rangeSubOpclass;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
if (OidIsValid(rangeCollation)) if (OidIsValid(rangeCollation))
{ {
referenced.classId = CollationRelationId; referenced.classId = CollationRelationId;
referenced.objectId = rangeCollation; referenced.objectId = rangeCollation;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
if (OidIsValid(rangeCanonical)) if (OidIsValid(rangeCanonical))
{ {
referenced.classId = ProcedureRelationId; referenced.classId = ProcedureRelationId;
referenced.objectId = rangeCanonical; referenced.objectId = rangeCanonical;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
if (OidIsValid(rangeSubDiff)) if (OidIsValid(rangeSubDiff))
{ {
referenced.classId = ProcedureRelationId; referenced.classId = ProcedureRelationId;
referenced.objectId = rangeSubDiff; referenced.objectId = rangeSubDiff;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
......
...@@ -92,10 +92,10 @@ static Oid findTypeSendFunction(List *procname, Oid typeOid); ...@@ -92,10 +92,10 @@ static Oid findTypeSendFunction(List *procname, Oid typeOid);
static Oid findTypeTypmodinFunction(List *procname); static Oid findTypeTypmodinFunction(List *procname);
static Oid findTypeTypmodoutFunction(List *procname); static Oid findTypeTypmodoutFunction(List *procname);
static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid); static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid);
static Oid findRangeCanonicalFunction(List *procname, Oid typeOid); static Oid findRangeCanonicalFunction(List *procname, Oid typeOid);
static Oid findRangeSubOpclass(List *procname, Oid typeOid); static Oid findRangeSubOpclass(List *procname, Oid typeOid);
static Oid findRangeSubtypeDiffFunction(List *procname, Oid typeOid); static Oid findRangeSubtypeDiffFunction(List *procname, Oid typeOid);
static void validateDomainConstraint(Oid domainoid, char *ccbin); static void validateDomainConstraint(Oid domainoid, char *ccbin);
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode); static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
static void checkDomainOwner(HeapTuple tup); static void checkDomainOwner(HeapTuple tup);
static void checkEnumOwner(HeapTuple tup); static void checkEnumOwner(HeapTuple tup);
...@@ -104,7 +104,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace, ...@@ -104,7 +104,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
int typMod, Constraint *constr, int typMod, Constraint *constr,
char *domainName); char *domainName);
static void makeRangeConstructor(char *name, Oid namespace, Oid rettype, static void makeRangeConstructor(char *name, Oid namespace, Oid rettype,
Oid subtype); Oid subtype);
/* /*
...@@ -654,9 +654,9 @@ RemoveTypeById(Oid typeOid) ...@@ -654,9 +654,9 @@ RemoveTypeById(Oid typeOid)
EnumValuesDelete(typeOid); EnumValuesDelete(typeOid);
/* /*
* If it is a range type, delete the pg_range entries too; we * If it is a range type, delete the pg_range entries too; we don't bother
* don't bother with making dependency entries for those, so it * with making dependency entries for those, so it has to be done "by
* has to be done "by hand" here. * hand" here.
*/ */
if (((Form_pg_type) GETSTRUCT(tup))->typtype == TYPTYPE_RANGE) if (((Form_pg_type) GETSTRUCT(tup))->typtype == TYPTYPE_RANGE)
RangeDelete(typeOid); RangeDelete(typeOid);
...@@ -744,7 +744,8 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -744,7 +744,8 @@ DefineDomain(CreateDomainStmt *stmt)
/* /*
* Base type must be a plain base type, another domain, an enum or a range * Base type must be a plain base type, another domain, an enum or a range
* type. Domains over pseudotypes would create a security hole. Domains * type. Domains over pseudotypes would create a security hole. Domains
* over composite types might be made to work in the future, but not today. * over composite types might be made to work in the future, but not
* today.
*/ */
typtype = baseType->typtype; typtype = baseType->typtype;
if (typtype != TYPTYPE_BASE && if (typtype != TYPTYPE_BASE &&
...@@ -1158,27 +1159,27 @@ DefineEnum(CreateEnumStmt *stmt) ...@@ -1158,27 +1159,27 @@ DefineEnum(CreateEnumStmt *stmt)
* Registers a new range type. * Registers a new range type.
*/ */
void void
DefineRange(CreateRangeStmt *stmt) DefineRange(CreateRangeStmt * stmt)
{ {
char *typeName; char *typeName;
char *rangeArrayName; char *rangeArrayName;
Oid typeNamespace; Oid typeNamespace;
Oid typoid; Oid typoid;
Oid rangeArrayOid; Oid rangeArrayOid;
List *parameters = stmt->params; List *parameters = stmt->params;
ListCell *lc; ListCell *lc;
List *rangeSubOpclassName = NIL; List *rangeSubOpclassName = NIL;
List *rangeSubtypeDiffName = NIL; List *rangeSubtypeDiffName = NIL;
List *rangeCollationName = NIL; List *rangeCollationName = NIL;
Oid rangeCollation = InvalidOid; Oid rangeCollation = InvalidOid;
regproc rangeAnalyze = InvalidOid; regproc rangeAnalyze = InvalidOid;
Oid rangeSubtype = InvalidOid; Oid rangeSubtype = InvalidOid;
regproc rangeSubOpclass = InvalidOid; regproc rangeSubOpclass = InvalidOid;
regproc rangeCanonical = InvalidOid; regproc rangeCanonical = InvalidOid;
regproc rangeSubtypeDiff = InvalidOid; regproc rangeSubtypeDiff = InvalidOid;
AclResult aclresult; AclResult aclresult;
/* Convert list of names to a name and namespace */ /* Convert list of names to a name and namespace */
typeNamespace = QualifiedNameGetCreationNamespace(stmt->typeName, typeNamespace = QualifiedNameGetCreationNamespace(stmt->typeName,
...@@ -1236,7 +1237,7 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1236,7 +1237,7 @@ DefineRange(CreateRangeStmt *stmt)
foreach(lc, stmt->params) foreach(lc, stmt->params)
{ {
DefElem *defel = lfirst(lc); DefElem *defel = lfirst(lc);
if (pg_strcasecmp(defel->defname, "subtype") == 0) if (pg_strcasecmp(defel->defname, "subtype") == 0)
{ {
...@@ -1253,7 +1254,7 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1253,7 +1254,7 @@ DefineRange(CreateRangeStmt *stmt)
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options"))); errmsg("conflicting or redundant options")));
rangeCanonical = findRangeCanonicalFunction( rangeCanonical = findRangeCanonicalFunction(
defGetQualifiedName(defel), typoid); defGetQualifiedName(defel), typoid);
} }
else if (pg_strcasecmp(defel->defname, "collation") == 0) else if (pg_strcasecmp(defel->defname, "collation") == 0)
{ {
...@@ -1299,9 +1300,9 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1299,9 +1300,9 @@ DefineRange(CreateRangeStmt *stmt)
} }
if (!OidIsValid(rangeSubtype)) if (!OidIsValid(rangeSubtype))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("type attribute \"subtype\" is required"))); errmsg("type attribute \"subtype\" is required")));
if (type_is_collatable(rangeSubtype)) if (type_is_collatable(rangeSubtype))
{ {
...@@ -1319,7 +1320,7 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1319,7 +1320,7 @@ DefineRange(CreateRangeStmt *stmt)
if (rangeSubtypeDiffName != NIL) if (rangeSubtypeDiffName != NIL)
rangeSubtypeDiff = findRangeSubtypeDiffFunction( rangeSubtypeDiff = findRangeSubtypeDiffFunction(
rangeSubtypeDiffName, rangeSubtype); rangeSubtypeDiffName, rangeSubtype);
rangeArrayOid = AssignTypeArrayOid(); rangeArrayOid = AssignTypeArrayOid();
...@@ -1332,20 +1333,20 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1332,20 +1333,20 @@ DefineRange(CreateRangeStmt *stmt)
0, /* relation kind (ditto) */ 0, /* relation kind (ditto) */
GetUserId(), /* owner's ID */ GetUserId(), /* owner's ID */
-1, /* internal size */ -1, /* internal size */
TYPTYPE_RANGE, /* type-type (range type) */ TYPTYPE_RANGE, /* type-type (range type) */
TYPCATEGORY_RANGE, /* type-category (range type) */ TYPCATEGORY_RANGE, /* type-category (range type) */
false, /* range types are never preferred */ false, /* range types are never preferred */
DEFAULT_TYPDELIM, /* array element delimiter */ DEFAULT_TYPDELIM, /* array element delimiter */
F_RANGE_IN, /* input procedure */ F_RANGE_IN, /* input procedure */
F_RANGE_OUT, /* output procedure */ F_RANGE_OUT, /* output procedure */
F_RANGE_RECV, /* receive procedure */ F_RANGE_RECV, /* receive procedure */
F_RANGE_SEND, /* send procedure */ F_RANGE_SEND, /* send procedure */
InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodin procedure - none */
InvalidOid, /* typmodout procedure - none */ InvalidOid, /* typmodout procedure - none */
rangeAnalyze, /* analyze procedure - default */ rangeAnalyze, /* analyze procedure - default */
InvalidOid, /* element type ID */ InvalidOid, /* element type ID */
false, /* this is not an array type */ false, /* this is not an array type */
rangeArrayOid, /* array type we are about to create */ rangeArrayOid, /* array type we are about to create */
InvalidOid, /* base type ID (only for domains) */ InvalidOid, /* base type ID (only for domains) */
NULL, /* never a default type value */ NULL, /* never a default type value */
NULL, /* binary default isn't sent either */ NULL, /* binary default isn't sent either */
...@@ -1355,7 +1356,7 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1355,7 +1356,7 @@ DefineRange(CreateRangeStmt *stmt)
-1, /* typMod (Domains only) */ -1, /* typMod (Domains only) */
0, /* Array dimensions of typbasetype */ 0, /* Array dimensions of typbasetype */
false, /* Type NOT NULL */ false, /* Type NOT NULL */
InvalidOid); /* typcollation */ InvalidOid); /* typcollation */
/* create the entry in pg_range */ /* create the entry in pg_range */
RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass, RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass,
...@@ -1384,7 +1385,7 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1384,7 +1385,7 @@ DefineRange(CreateRangeStmt *stmt)
InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodin procedure - none */
InvalidOid, /* typmodout procedure - none */ InvalidOid, /* typmodout procedure - none */
InvalidOid, /* analyze procedure - default */ InvalidOid, /* analyze procedure - default */
typoid, /* element type ID */ typoid, /* element type ID */
true, /* yes this is an array type */ true, /* yes this is an array type */
InvalidOid, /* no further array type */ InvalidOid, /* no further array type */
InvalidOid, /* base type ID */ InvalidOid, /* base type ID */
...@@ -1415,12 +1416,12 @@ DefineRange(CreateRangeStmt *stmt) ...@@ -1415,12 +1416,12 @@ DefineRange(CreateRangeStmt *stmt)
static void static void
makeRangeConstructor(char *name, Oid namespace, Oid rangeOid, Oid subtype) makeRangeConstructor(char *name, Oid namespace, Oid rangeOid, Oid subtype)
{ {
ObjectAddress referenced; ObjectAddress referenced;
Oid constructorArgTypes[3]; Oid constructorArgTypes[3];
int i; int i;
referenced.classId = TypeRelationId; referenced.classId = TypeRelationId;
referenced.objectId = rangeOid; referenced.objectId = rangeOid;
referenced.objectSubId = 0; referenced.objectSubId = 0;
constructorArgTypes[0] = subtype; constructorArgTypes[0] = subtype;
...@@ -1429,46 +1430,46 @@ makeRangeConstructor(char *name, Oid namespace, Oid rangeOid, Oid subtype) ...@@ -1429,46 +1430,46 @@ makeRangeConstructor(char *name, Oid namespace, Oid rangeOid, Oid subtype)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
oidvector *constructorArgTypesVector; oidvector *constructorArgTypesVector;
ObjectAddress myself; ObjectAddress myself;
Oid procOid; Oid procOid;
char *prosrc[4] = { "range_constructor0", char *prosrc[4] = {"range_constructor0",
"range_constructor1", "range_constructor1",
"range_constructor2", "range_constructor2",
"range_constructor3"}; "range_constructor3"};
constructorArgTypesVector = buildoidvector(constructorArgTypes, i); constructorArgTypesVector = buildoidvector(constructorArgTypes, i);
procOid = ProcedureCreate( procOid = ProcedureCreate(
name, /* name */ name, /* name */
namespace, /* namespace */ namespace, /* namespace */
false, /* replace */ false, /* replace */
false, /* return set */ false, /* return set */
rangeOid, /* return type */ rangeOid, /* return type */
INTERNALlanguageId, /* language */ INTERNALlanguageId, /* language */
F_FMGR_INTERNAL_VALIDATOR, /* language validator */ F_FMGR_INTERNAL_VALIDATOR, /* language validator */
prosrc[i], /* prosrc */ prosrc[i], /* prosrc */
NULL, /* probin */ NULL, /* probin */
false, /* agg */ false, /* agg */
false, /* window */ false, /* window */
false, /* security definer */ false, /* security definer */
false, /* strict */ false, /* strict */
PROVOLATILE_IMMUTABLE, /* volatility */ PROVOLATILE_IMMUTABLE, /* volatility */
constructorArgTypesVector, /* param types */ constructorArgTypesVector, /* param types */
PointerGetDatum(NULL), /* allParameterTypes */ PointerGetDatum(NULL), /* allParameterTypes */
PointerGetDatum(NULL), /* parameterModes */ PointerGetDatum(NULL), /* parameterModes */
PointerGetDatum(NULL), /* parameterNames */ PointerGetDatum(NULL), /* parameterNames */
NIL, /* parameterDefaults */ NIL, /* parameterDefaults */
PointerGetDatum(NULL), /* proconfig */ PointerGetDatum(NULL), /* proconfig */
1.0, /* procost */ 1.0, /* procost */
0.0); /* prorows */ 0.0); /* prorows */
/* /*
* Make the constructor internally-dependent on the range type so that * Make the constructor internally-dependent on the range type so that
* the user doesn't have to treat them as separate objects. * the user doesn't have to treat them as separate objects.
*/ */
myself.classId = ProcedureRelationId; myself.classId = ProcedureRelationId;
myself.objectId = procOid; myself.objectId = procOid;
myself.objectSubId = 0; myself.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
} }
...@@ -1840,8 +1841,8 @@ findRangeSubtypeDiffFunction(List *procname, Oid typeOid) ...@@ -1840,8 +1841,8 @@ findRangeSubtypeDiffFunction(List *procname, Oid typeOid)
if (get_func_rettype(procOid) != FLOAT8OID) if (get_func_rettype(procOid) != FLOAT8OID)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("range subtype diff function %s must return type \"float8\"", errmsg("range subtype diff function %s must return type \"float8\"",
func_signature_string(procname, 2, NIL, argList)))); func_signature_string(procname, 2, NIL, argList))));
if (func_volatile(procOid) != PROVOLATILE_IMMUTABLE) if (func_volatile(procOid) != PROVOLATILE_IMMUTABLE)
ereport(ERROR, ereport(ERROR,
...@@ -2395,13 +2396,13 @@ AlterDomainValidateConstraint(List *names, char *constrName) ...@@ -2395,13 +2396,13 @@ AlterDomainValidateConstraint(List *names, char *constrName)
Form_pg_constraint con = NULL; Form_pg_constraint con = NULL;
Form_pg_constraint copy_con; Form_pg_constraint copy_con;
char *conbin; char *conbin;
SysScanDesc scan; SysScanDesc scan;
Datum val; Datum val;
bool found = false; bool found = false;
bool isnull; bool isnull;
HeapTuple tuple; HeapTuple tuple;
HeapTuple copyTuple; HeapTuple copyTuple;
ScanKeyData key; ScanKeyData key;
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names); typename = makeTypeNameFromNameList(names);
...@@ -2447,8 +2448,8 @@ AlterDomainValidateConstraint(List *names, char *constrName) ...@@ -2447,8 +2448,8 @@ AlterDomainValidateConstraint(List *names, char *constrName)
if (con->contype != CONSTRAINT_CHECK) if (con->contype != CONSTRAINT_CHECK)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE), (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("constraint \"%s\" of domain \"%s\" is not a check constraint", errmsg("constraint \"%s\" of domain \"%s\" is not a check constraint",
constrName, TypeNameToString(typename)))); constrName, TypeNameToString(typename))));
val = SysCacheGetAttr(CONSTROID, tuple, val = SysCacheGetAttr(CONSTROID, tuple,
Anum_pg_constraint_conbin, Anum_pg_constraint_conbin,
...@@ -2549,6 +2550,7 @@ validateDomainConstraint(Oid domainoid, char *ccbin) ...@@ -2549,6 +2550,7 @@ validateDomainConstraint(Oid domainoid, char *ccbin)
FreeExecutorState(estate); FreeExecutorState(estate);
} }
/* /*
* get_rels_with_domain * get_rels_with_domain
* *
...@@ -2868,7 +2870,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, ...@@ -2868,7 +2870,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
CONSTRAINT_CHECK, /* Constraint Type */ CONSTRAINT_CHECK, /* Constraint Type */
false, /* Is Deferrable */ false, /* Is Deferrable */
false, /* Is Deferred */ false, /* Is Deferred */
!constr->skip_validation, /* Is Validated */ !constr->skip_validation, /* Is Validated */
InvalidOid, /* not a relation constraint */ InvalidOid, /* not a relation constraint */
NULL, NULL,
0, 0,
......
...@@ -37,34 +37,34 @@ ...@@ -37,34 +37,34 @@
/* flags */ /* flags */
#define RANGE_EMPTY 0x01 #define RANGE_EMPTY 0x01
#define RANGE_LB_INC 0x02 #define RANGE_LB_INC 0x02
#define RANGE_LB_NULL 0x04 /* NOT USED */ #define RANGE_LB_NULL 0x04 /* NOT USED */
#define RANGE_LB_INF 0x08 #define RANGE_LB_INF 0x08
#define RANGE_UB_INC 0x10 #define RANGE_UB_INC 0x10
#define RANGE_UB_NULL 0x20 /* NOT USED */ #define RANGE_UB_NULL 0x20 /* NOT USED */
#define RANGE_UB_INF 0x40 #define RANGE_UB_INF 0x40
#define RANGE_HAS_LBOUND(flags) (!(flags & (RANGE_EMPTY | \ #define RANGE_HAS_LBOUND(flags) (!(flags & (RANGE_EMPTY | \
RANGE_LB_NULL | \ RANGE_LB_NULL | \
RANGE_LB_INF))) RANGE_LB_INF)))
#define RANGE_HAS_UBOUND(flags) (!(flags & (RANGE_EMPTY | \ #define RANGE_HAS_UBOUND(flags) (!(flags & (RANGE_EMPTY | \
RANGE_UB_NULL | \ RANGE_UB_NULL | \
RANGE_UB_INF))) RANGE_UB_INF)))
#define RANGE_EMPTY_LITERAL "empty" #define RANGE_EMPTY_LITERAL "empty"
static void range_parse(char *input_str, char *flags, char **lbound_str, static void range_parse(char *input_str, char *flags, char **lbound_str,
char **ubound_str); char **ubound_str);
static char *range_parse_bound(char *string, char *ptr, char **bound_str, static char *range_parse_bound(char *string, char *ptr, char **bound_str,
bool *infinite); bool *infinite);
static char *range_deparse(char flags, char *lbound_str, char *ubound_str); static char *range_deparse(char flags, char *lbound_str, char *ubound_str);
static char *range_bound_escape(char *in_str); static char *range_bound_escape(char *in_str);
static bool range_contains_internal(FunctionCallInfo fcinfo, RangeType *r1, static bool range_contains_internal(FunctionCallInfo fcinfo, RangeType * r1,
RangeType *r2); RangeType * r2);
static Size datum_compute_size(Size sz, Datum datum, bool typbyval, static Size datum_compute_size(Size sz, Datum datum, bool typbyval,
char typalign, int16 typlen, char typstorage); char typalign, int16 typlen, char typstorage);
static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval,
char typalign, int16 typlen, char typstorage); char typalign, int16 typlen, char typstorage);
/* /*
*---------------------------------------------------------- *----------------------------------------------------------
...@@ -75,22 +75,22 @@ static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, ...@@ -75,22 +75,22 @@ static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval,
Datum Datum
range_in(PG_FUNCTION_ARGS) range_in(PG_FUNCTION_ARGS)
{ {
char *input_str = PG_GETARG_CSTRING(0); char *input_str = PG_GETARG_CSTRING(0);
Oid rngtypoid = PG_GETARG_OID(1); Oid rngtypoid = PG_GETARG_OID(1);
Oid typmod = PG_GETARG_INT32(2); Oid typmod = PG_GETARG_INT32(2);
char flags; char flags;
Datum range; Datum range;
char *lbound_str; char *lbound_str;
char *ubound_str; char *ubound_str;
regproc subInput; regproc subInput;
FmgrInfo subInputFn; FmgrInfo subInputFn;
Oid ioParam; Oid ioParam;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
if (rngtypoid == ANYRANGEOID) if (rngtypoid == ANYRANGEOID)
ereport(ERROR, ereport(ERROR,
...@@ -106,21 +106,21 @@ range_in(PG_FUNCTION_ARGS) ...@@ -106,21 +106,21 @@ range_in(PG_FUNCTION_ARGS)
getTypeInputInfo(rngtypinfo.subtype, &subInput, &ioParam); getTypeInputInfo(rngtypinfo.subtype, &subInput, &ioParam);
fmgr_info(subInput, &subInputFn); fmgr_info(subInput, &subInputFn);
lower.rngtypid = rngtypoid; lower.rngtypid = rngtypoid;
lower.infinite = (flags & RANGE_LB_INF) != 0; lower.infinite = (flags & RANGE_LB_INF) != 0;
lower.inclusive = (flags & RANGE_LB_INC) != 0; lower.inclusive = (flags & RANGE_LB_INC) != 0;
lower.lower = true; lower.lower = true;
upper.rngtypid = rngtypoid; upper.rngtypid = rngtypoid;
upper.infinite = (flags & RANGE_UB_INF) != 0; upper.infinite = (flags & RANGE_UB_INF) != 0;
upper.inclusive = (flags & RANGE_UB_INC) != 0; upper.inclusive = (flags & RANGE_UB_INC) != 0;
upper.lower = false; upper.lower = false;
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
lower.val = InputFunctionCall(&subInputFn, lbound_str, lower.val = InputFunctionCall(&subInputFn, lbound_str,
ioParam, typmod); ioParam, typmod);
if (RANGE_HAS_UBOUND(flags)) if (RANGE_HAS_UBOUND(flags))
upper.val = InputFunctionCall(&subInputFn, ubound_str, upper.val = InputFunctionCall(&subInputFn, ubound_str,
ioParam, typmod); ioParam, typmod);
/* serialize and canonicalize */ /* serialize and canonicalize */
range = make_range(fcinfo, &lower, &upper, flags & RANGE_EMPTY); range = make_range(fcinfo, &lower, &upper, flags & RANGE_EMPTY);
...@@ -144,9 +144,9 @@ range_out(PG_FUNCTION_ARGS) ...@@ -144,9 +144,9 @@ range_out(PG_FUNCTION_ARGS)
bool empty; bool empty;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
/* deserialize */ /* deserialize */
range_deserialize(fcinfo, range, &lower, &upper, &empty); range_deserialize(fcinfo, range, &lower, &upper, &empty);
...@@ -159,10 +159,10 @@ range_out(PG_FUNCTION_ARGS) ...@@ -159,10 +159,10 @@ range_out(PG_FUNCTION_ARGS)
if (empty) if (empty)
flags |= RANGE_EMPTY; flags |= RANGE_EMPTY;
flags |= (lower.inclusive) ? RANGE_LB_INC : 0; flags |= (lower.inclusive) ? RANGE_LB_INC : 0;
flags |= (lower.infinite) ? RANGE_LB_INF : 0; flags |= (lower.infinite) ? RANGE_LB_INF : 0;
flags |= (upper.inclusive) ? RANGE_UB_INC : 0; flags |= (upper.inclusive) ? RANGE_UB_INC : 0;
flags |= (upper.infinite) ? RANGE_UB_INF : 0; flags |= (upper.infinite) ? RANGE_UB_INF : 0;
/* output */ /* output */
getTypeOutputInfo(rngtypinfo.subtype, &subOutput, &isVarlena); getTypeOutputInfo(rngtypinfo.subtype, &subOutput, &isVarlena);
...@@ -190,9 +190,9 @@ range_out(PG_FUNCTION_ARGS) ...@@ -190,9 +190,9 @@ range_out(PG_FUNCTION_ARGS)
Datum Datum
range_recv(PG_FUNCTION_ARGS) range_recv(PG_FUNCTION_ARGS)
{ {
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
Oid rngtypid = PG_GETARG_OID(1); Oid rngtypid = PG_GETARG_OID(1);
int32 typmod = PG_GETARG_INT32(2); int32 typmod = PG_GETARG_INT32(2);
Oid subrecv; Oid subrecv;
Oid ioparam; Oid ioparam;
Datum range; Datum range;
...@@ -210,9 +210,9 @@ range_recv(PG_FUNCTION_ARGS) ...@@ -210,9 +210,9 @@ range_recv(PG_FUNCTION_ARGS)
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
{ {
uint32 bound_len = pq_getmsgint(buf, 4); uint32 bound_len = pq_getmsgint(buf, 4);
const char *bound_data = pq_getmsgbytes(buf, bound_len); const char *bound_data = pq_getmsgbytes(buf, bound_len);
StringInfoData bound_buf; StringInfoData bound_buf;
initStringInfo(&bound_buf); initStringInfo(&bound_buf);
appendBinaryStringInfo(&bound_buf, bound_data, bound_len); appendBinaryStringInfo(&bound_buf, bound_data, bound_len);
...@@ -228,9 +228,9 @@ range_recv(PG_FUNCTION_ARGS) ...@@ -228,9 +228,9 @@ range_recv(PG_FUNCTION_ARGS)
if (RANGE_HAS_UBOUND(flags)) if (RANGE_HAS_UBOUND(flags))
{ {
uint32 bound_len = pq_getmsgint(buf, 4); uint32 bound_len = pq_getmsgint(buf, 4);
const char *bound_data = pq_getmsgbytes(buf, bound_len); const char *bound_data = pq_getmsgbytes(buf, bound_len);
StringInfoData bound_buf; StringInfoData bound_buf;
initStringInfo(&bound_buf); initStringInfo(&bound_buf);
appendBinaryStringInfo(&bound_buf, bound_data, bound_len); appendBinaryStringInfo(&bound_buf, bound_data, bound_len);
...@@ -246,21 +246,21 @@ range_recv(PG_FUNCTION_ARGS) ...@@ -246,21 +246,21 @@ range_recv(PG_FUNCTION_ARGS)
pq_getmsgend(buf); pq_getmsgend(buf);
lower.rngtypid = rngtypid; lower.rngtypid = rngtypid;
lower.infinite = (flags & RANGE_LB_INF) != 0; lower.infinite = (flags & RANGE_LB_INF) != 0;
lower.inclusive = (flags & RANGE_LB_INC) != 0; lower.inclusive = (flags & RANGE_LB_INC) != 0;
lower.lower = true; lower.lower = true;
upper.rngtypid = rngtypid; upper.rngtypid = rngtypid;
upper.infinite = (flags & RANGE_UB_INF) != 0; upper.infinite = (flags & RANGE_UB_INF) != 0;
upper.inclusive = (flags & RANGE_UB_INC) != 0; upper.inclusive = (flags & RANGE_UB_INC) != 0;
upper.lower = false; upper.lower = false;
/* serialize and canonicalize */ /* serialize and canonicalize */
range = make_range(fcinfo, &lower, &upper, flags & RANGE_EMPTY); range = make_range(fcinfo, &lower, &upper, flags & RANGE_EMPTY);
/* /*
* XXX if the subtype is pass-by-val, we should pfree the upper and * XXX if the subtype is pass-by-val, we should pfree the upper and lower
* lower bounds here. * bounds here.
*/ */
PG_RETURN_RANGE(range); PG_RETURN_RANGE(range);
...@@ -269,14 +269,14 @@ range_recv(PG_FUNCTION_ARGS) ...@@ -269,14 +269,14 @@ range_recv(PG_FUNCTION_ARGS)
Datum Datum
range_send(PG_FUNCTION_ARGS) range_send(PG_FUNCTION_ARGS)
{ {
RangeType *range = PG_GETARG_RANGE(0); RangeType *range = PG_GETARG_RANGE(0);
StringInfo buf = makeStringInfo(); StringInfo buf = makeStringInfo();
char flags = 0; char flags = 0;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
Oid subsend; Oid subsend;
bool typIsVarlena; bool typIsVarlena;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
...@@ -287,10 +287,10 @@ range_send(PG_FUNCTION_ARGS) ...@@ -287,10 +287,10 @@ range_send(PG_FUNCTION_ARGS)
if (empty) if (empty)
flags |= RANGE_EMPTY; flags |= RANGE_EMPTY;
flags |= (lower.inclusive) ? RANGE_LB_INC : 0; flags |= (lower.inclusive) ? RANGE_LB_INC : 0;
flags |= (lower.infinite) ? RANGE_LB_INF : 0; flags |= (lower.infinite) ? RANGE_LB_INF : 0;
flags |= (upper.inclusive) ? RANGE_UB_INC : 0; flags |= (upper.inclusive) ? RANGE_UB_INC : 0;
flags |= (upper.infinite) ? RANGE_UB_INF : 0; flags |= (upper.infinite) ? RANGE_UB_INF : 0;
range_gettypinfo(fcinfo, lower.rngtypid, &rngtypinfo); range_gettypinfo(fcinfo, lower.rngtypid, &rngtypinfo);
...@@ -301,10 +301,10 @@ range_send(PG_FUNCTION_ARGS) ...@@ -301,10 +301,10 @@ range_send(PG_FUNCTION_ARGS)
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
{ {
Datum bound = PointerGetDatum( Datum bound = PointerGetDatum(
OidSendFunctionCall(subsend, lower.val)); OidSendFunctionCall(subsend, lower.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ; uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound); char *bound_data = VARDATA(bound);
pq_sendint(buf, bound_len, 4); pq_sendint(buf, bound_len, 4);
pq_sendbytes(buf, bound_data, bound_len); pq_sendbytes(buf, bound_data, bound_len);
...@@ -312,10 +312,10 @@ range_send(PG_FUNCTION_ARGS) ...@@ -312,10 +312,10 @@ range_send(PG_FUNCTION_ARGS)
if (RANGE_HAS_UBOUND(flags)) if (RANGE_HAS_UBOUND(flags))
{ {
Datum bound = PointerGetDatum( Datum bound = PointerGetDatum(
OidSendFunctionCall(subsend, upper.val)); OidSendFunctionCall(subsend, upper.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ; uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound); char *bound_data = VARDATA(bound);
pq_sendint(buf, bound_len, 4); pq_sendint(buf, bound_len, 4);
pq_sendbytes(buf, bound_data, bound_len); pq_sendbytes(buf, bound_data, bound_len);
...@@ -334,22 +334,22 @@ range_send(PG_FUNCTION_ARGS) ...@@ -334,22 +334,22 @@ range_send(PG_FUNCTION_ARGS)
Datum Datum
range_constructor0(PG_FUNCTION_ARGS) range_constructor0(PG_FUNCTION_ARGS)
{ {
Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo); Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
RangeType *range; RangeType *range;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
lower.rngtypid = rngtypid; lower.rngtypid = rngtypid;
lower.val = (Datum) 0; lower.val = (Datum) 0;
lower.inclusive = false; lower.inclusive = false;
lower.infinite = false; lower.infinite = false;
lower.lower = true; lower.lower = true;
upper.rngtypid = rngtypid; upper.rngtypid = rngtypid;
upper.val = (Datum) 0; upper.val = (Datum) 0;
upper.inclusive = false; upper.inclusive = false;
upper.infinite = false; upper.infinite = false;
upper.lower = false; upper.lower = false;
range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, true)); range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, true));
...@@ -359,28 +359,28 @@ range_constructor0(PG_FUNCTION_ARGS) ...@@ -359,28 +359,28 @@ range_constructor0(PG_FUNCTION_ARGS)
Datum Datum
range_constructor1(PG_FUNCTION_ARGS) range_constructor1(PG_FUNCTION_ARGS)
{ {
Datum arg1 = PG_GETARG_DATUM(0); Datum arg1 = PG_GETARG_DATUM(0);
Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo); Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
RangeType *range; RangeType *range;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
if (PG_ARGISNULL(0)) if (PG_ARGISNULL(0))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION), (errcode(ERRCODE_DATA_EXCEPTION),
errmsg("argument must not be NULL"))); errmsg("argument must not be NULL")));
lower.rngtypid = rngtypid; lower.rngtypid = rngtypid;
lower.val = arg1; lower.val = arg1;
lower.inclusive = true; lower.inclusive = true;
lower.infinite = false; lower.infinite = false;
lower.lower = true; lower.lower = true;
upper.rngtypid = rngtypid; upper.rngtypid = rngtypid;
upper.val = arg1; upper.val = arg1;
upper.inclusive = true; upper.inclusive = true;
upper.infinite = false; upper.infinite = false;
upper.lower = false; upper.lower = false;
range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, false)); range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, false));
...@@ -390,27 +390,27 @@ range_constructor1(PG_FUNCTION_ARGS) ...@@ -390,27 +390,27 @@ range_constructor1(PG_FUNCTION_ARGS)
Datum Datum
range_constructor2(PG_FUNCTION_ARGS) range_constructor2(PG_FUNCTION_ARGS)
{ {
Datum arg1 = PG_GETARG_DATUM(0); Datum arg1 = PG_GETARG_DATUM(0);
Datum arg2 = PG_GETARG_DATUM(1); Datum arg2 = PG_GETARG_DATUM(1);
Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo); Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
RangeType *range; RangeType *range;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
char flags; char flags;
flags = range_parse_flags(RANGE_DEFAULT_FLAGS); flags = range_parse_flags(RANGE_DEFAULT_FLAGS);
lower.rngtypid = rngtypid; lower.rngtypid = rngtypid;
lower.val = PG_ARGISNULL(0) ? (Datum)0 : arg1; lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
lower.inclusive = flags & RANGE_LB_INC; lower.inclusive = flags & RANGE_LB_INC;
lower.infinite = PG_ARGISNULL(0); lower.infinite = PG_ARGISNULL(0);
lower.lower = true; lower.lower = true;
upper.rngtypid = rngtypid; upper.rngtypid = rngtypid;
upper.val = PG_ARGISNULL(1) ? (Datum)0 : arg2; upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
upper.inclusive = flags & RANGE_UB_INC; upper.inclusive = flags & RANGE_UB_INC;
upper.infinite = PG_ARGISNULL(1); upper.infinite = PG_ARGISNULL(1);
upper.lower = false; upper.lower = false;
range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, false)); range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, false));
...@@ -420,13 +420,13 @@ range_constructor2(PG_FUNCTION_ARGS) ...@@ -420,13 +420,13 @@ range_constructor2(PG_FUNCTION_ARGS)
Datum Datum
range_constructor3(PG_FUNCTION_ARGS) range_constructor3(PG_FUNCTION_ARGS)
{ {
Datum arg1 = PG_GETARG_DATUM(0); Datum arg1 = PG_GETARG_DATUM(0);
Datum arg2 = PG_GETARG_DATUM(1); Datum arg2 = PG_GETARG_DATUM(1);
Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo); Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
RangeType *range; RangeType *range;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
char flags; char flags;
if (PG_ARGISNULL(2)) if (PG_ARGISNULL(2))
ereport(ERROR, ereport(ERROR,
...@@ -434,17 +434,17 @@ range_constructor3(PG_FUNCTION_ARGS) ...@@ -434,17 +434,17 @@ range_constructor3(PG_FUNCTION_ARGS)
errmsg("flags argument must not be NULL"))); errmsg("flags argument must not be NULL")));
flags = range_parse_flags(text_to_cstring(PG_GETARG_TEXT_P(2))); flags = range_parse_flags(text_to_cstring(PG_GETARG_TEXT_P(2)));
lower.rngtypid = rngtypid; lower.rngtypid = rngtypid;
lower.val = PG_ARGISNULL(0) ? (Datum)0 : arg1; lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
lower.inclusive = flags & RANGE_LB_INC; lower.inclusive = flags & RANGE_LB_INC;
lower.infinite = PG_ARGISNULL(0); lower.infinite = PG_ARGISNULL(0);
lower.lower = true; lower.lower = true;
upper.rngtypid = rngtypid; upper.rngtypid = rngtypid;
upper.val = PG_ARGISNULL(1) ? (Datum)0 : arg2; upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
upper.inclusive = flags & RANGE_UB_INC; upper.inclusive = flags & RANGE_UB_INC;
upper.infinite = PG_ARGISNULL(1); upper.infinite = PG_ARGISNULL(1);
upper.lower = false; upper.lower = false;
range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, false)); range = DatumGetRangeType(make_range(fcinfo, &lower, &upper, false));
...@@ -455,10 +455,10 @@ range_constructor3(PG_FUNCTION_ARGS) ...@@ -455,10 +455,10 @@ range_constructor3(PG_FUNCTION_ARGS)
Datum Datum
range_lower(PG_FUNCTION_ARGS) range_lower(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
range_deserialize(fcinfo, r1, &lower, &upper, &empty); range_deserialize(fcinfo, r1, &lower, &upper, &empty);
...@@ -477,10 +477,10 @@ range_lower(PG_FUNCTION_ARGS) ...@@ -477,10 +477,10 @@ range_lower(PG_FUNCTION_ARGS)
Datum Datum
range_upper(PG_FUNCTION_ARGS) range_upper(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
range_deserialize(fcinfo, r1, &lower, &upper, &empty); range_deserialize(fcinfo, r1, &lower, &upper, &empty);
...@@ -501,10 +501,10 @@ range_upper(PG_FUNCTION_ARGS) ...@@ -501,10 +501,10 @@ range_upper(PG_FUNCTION_ARGS)
Datum Datum
range_empty(PG_FUNCTION_ARGS) range_empty(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
range_deserialize(fcinfo, r1, &lower, &upper, &empty); range_deserialize(fcinfo, r1, &lower, &upper, &empty);
...@@ -514,10 +514,10 @@ range_empty(PG_FUNCTION_ARGS) ...@@ -514,10 +514,10 @@ range_empty(PG_FUNCTION_ARGS)
Datum Datum
range_lower_inc(PG_FUNCTION_ARGS) range_lower_inc(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
range_deserialize(fcinfo, r1, &lower, &upper, &empty); range_deserialize(fcinfo, r1, &lower, &upper, &empty);
...@@ -527,10 +527,10 @@ range_lower_inc(PG_FUNCTION_ARGS) ...@@ -527,10 +527,10 @@ range_lower_inc(PG_FUNCTION_ARGS)
Datum Datum
range_upper_inc(PG_FUNCTION_ARGS) range_upper_inc(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
range_deserialize(fcinfo, r1, &lower, &upper, &empty); range_deserialize(fcinfo, r1, &lower, &upper, &empty);
...@@ -540,10 +540,10 @@ range_upper_inc(PG_FUNCTION_ARGS) ...@@ -540,10 +540,10 @@ range_upper_inc(PG_FUNCTION_ARGS)
Datum Datum
range_lower_inf(PG_FUNCTION_ARGS) range_lower_inf(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
range_deserialize(fcinfo, r1, &lower, &upper, &empty); range_deserialize(fcinfo, r1, &lower, &upper, &empty);
...@@ -553,10 +553,10 @@ range_lower_inf(PG_FUNCTION_ARGS) ...@@ -553,10 +553,10 @@ range_lower_inf(PG_FUNCTION_ARGS)
Datum Datum
range_upper_inf(PG_FUNCTION_ARGS) range_upper_inf(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
range_deserialize(fcinfo, r1, &lower, &upper, &empty); range_deserialize(fcinfo, r1, &lower, &upper, &empty);
...@@ -568,12 +568,15 @@ range_upper_inf(PG_FUNCTION_ARGS) ...@@ -568,12 +568,15 @@ range_upper_inf(PG_FUNCTION_ARGS)
Datum Datum
range_eq(PG_FUNCTION_ARGS) range_eq(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -600,7 +603,7 @@ range_eq(PG_FUNCTION_ARGS) ...@@ -600,7 +603,7 @@ range_eq(PG_FUNCTION_ARGS)
Datum Datum
range_ne(PG_FUNCTION_ARGS) range_ne(PG_FUNCTION_ARGS)
{ {
bool eq = DatumGetBool(range_eq(fcinfo)); bool eq = DatumGetBool(range_eq(fcinfo));
PG_RETURN_BOOL(!eq); PG_RETURN_BOOL(!eq);
} }
...@@ -608,27 +611,29 @@ range_ne(PG_FUNCTION_ARGS) ...@@ -608,27 +611,29 @@ range_ne(PG_FUNCTION_ARGS)
Datum Datum
range_contains_elem(PG_FUNCTION_ARGS) range_contains_elem(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2; RangeType *r2;
Datum val = PG_GETARG_DATUM(1); Datum val = PG_GETARG_DATUM(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
RangeBound upper1,
upper2;
bool empty1; bool empty1;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
lower2.rngtypid = lower1.rngtypid; lower2.rngtypid = lower1.rngtypid;
lower2.inclusive = true; lower2.inclusive = true;
lower2.infinite = false; lower2.infinite = false;
lower2.lower = true; lower2.lower = true;
lower2.val = val; lower2.val = val;
upper2.rngtypid = lower1.rngtypid; upper2.rngtypid = lower1.rngtypid;
upper2.inclusive = true; upper2.inclusive = true;
upper2.infinite = false; upper2.infinite = false;
upper2.lower = false; upper2.lower = false;
upper2.val = val; upper2.val = val;
r2 = DatumGetRangeType(make_range(fcinfo, &lower2, &upper2, false)); r2 = DatumGetRangeType(make_range(fcinfo, &lower2, &upper2, false));
...@@ -638,8 +643,8 @@ range_contains_elem(PG_FUNCTION_ARGS) ...@@ -638,8 +643,8 @@ range_contains_elem(PG_FUNCTION_ARGS)
Datum Datum
range_contains(PG_FUNCTION_ARGS) range_contains(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
PG_RETURN_BOOL(range_contains_internal(fcinfo, r1, r2)); PG_RETURN_BOOL(range_contains_internal(fcinfo, r1, r2));
} }
...@@ -647,27 +652,29 @@ range_contains(PG_FUNCTION_ARGS) ...@@ -647,27 +652,29 @@ range_contains(PG_FUNCTION_ARGS)
Datum Datum
elem_contained_by_range(PG_FUNCTION_ARGS) elem_contained_by_range(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(1); RangeType *r1 = PG_GETARG_RANGE(1);
RangeType *r2; RangeType *r2;
Datum val = PG_GETARG_DATUM(0); Datum val = PG_GETARG_DATUM(0);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
RangeBound upper1,
upper2;
bool empty1; bool empty1;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
lower2.rngtypid = lower1.rngtypid; lower2.rngtypid = lower1.rngtypid;
lower2.inclusive = true; lower2.inclusive = true;
lower2.infinite = false; lower2.infinite = false;
lower2.lower = true; lower2.lower = true;
lower2.val = val; lower2.val = val;
upper2.rngtypid = lower1.rngtypid; upper2.rngtypid = lower1.rngtypid;
upper2.inclusive = true; upper2.inclusive = true;
upper2.infinite = false; upper2.infinite = false;
upper2.lower = false; upper2.lower = false;
upper2.val = val; upper2.val = val;
r2 = DatumGetRangeType(make_range(fcinfo, &lower2, &upper2, false)); r2 = DatumGetRangeType(make_range(fcinfo, &lower2, &upper2, false));
...@@ -677,8 +684,8 @@ elem_contained_by_range(PG_FUNCTION_ARGS) ...@@ -677,8 +684,8 @@ elem_contained_by_range(PG_FUNCTION_ARGS)
Datum Datum
range_contained_by(PG_FUNCTION_ARGS) range_contained_by(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
PG_RETURN_BOOL(range_contains_internal(fcinfo, r2, r1)); PG_RETURN_BOOL(range_contains_internal(fcinfo, r2, r1));
} }
...@@ -686,12 +693,15 @@ range_contained_by(PG_FUNCTION_ARGS) ...@@ -686,12 +693,15 @@ range_contained_by(PG_FUNCTION_ARGS)
Datum Datum
range_before(PG_FUNCTION_ARGS) range_before(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -715,12 +725,15 @@ range_before(PG_FUNCTION_ARGS) ...@@ -715,12 +725,15 @@ range_before(PG_FUNCTION_ARGS)
Datum Datum
range_after(PG_FUNCTION_ARGS) range_after(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -741,16 +754,20 @@ range_after(PG_FUNCTION_ARGS) ...@@ -741,16 +754,20 @@ range_after(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);
} }
Datum range_adjacent(PG_FUNCTION_ARGS) Datum
range_adjacent(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -766,12 +783,12 @@ Datum range_adjacent(PG_FUNCTION_ARGS) ...@@ -766,12 +783,12 @@ Datum range_adjacent(PG_FUNCTION_ARGS)
errmsg("undefined for empty ranges"))); errmsg("undefined for empty ranges")));
/* /*
* For two ranges to be adjacent, the lower boundary of one range * For two ranges to be adjacent, the lower boundary of one range has to
* has to match the upper boundary of the other. However, the * match the upper boundary of the other. However, the inclusivity of
* inclusivity of those two boundaries must also be different. * those two boundaries must also be different.
* *
* The semantics for range_cmp_bounds aren't quite what we need * The semantics for range_cmp_bounds aren't quite what we need here, so
* here, so we do the comparison more directly. * we do the comparison more directly.
*/ */
range_gettypinfo(fcinfo, lower1.rngtypid, &rngtypinfo); range_gettypinfo(fcinfo, lower1.rngtypid, &rngtypinfo);
...@@ -798,12 +815,15 @@ Datum range_adjacent(PG_FUNCTION_ARGS) ...@@ -798,12 +815,15 @@ Datum range_adjacent(PG_FUNCTION_ARGS)
Datum Datum
range_overlaps(PG_FUNCTION_ARGS) range_overlaps(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -830,12 +850,15 @@ range_overlaps(PG_FUNCTION_ARGS) ...@@ -830,12 +850,15 @@ range_overlaps(PG_FUNCTION_ARGS)
Datum Datum
range_overleft(PG_FUNCTION_ARGS) range_overleft(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -857,12 +880,15 @@ range_overleft(PG_FUNCTION_ARGS) ...@@ -857,12 +880,15 @@ range_overleft(PG_FUNCTION_ARGS)
Datum Datum
range_overright(PG_FUNCTION_ARGS) range_overright(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -886,14 +912,20 @@ range_overright(PG_FUNCTION_ARGS) ...@@ -886,14 +912,20 @@ range_overright(PG_FUNCTION_ARGS)
Datum Datum
range_minus(PG_FUNCTION_ARGS) range_minus(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
int cmp_l1l2, cmp_l1u2, cmp_u1l2, cmp_u1u2; int cmp_l1l2,
cmp_l1u2,
cmp_u1l2,
cmp_u1u2;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -925,14 +957,14 @@ range_minus(PG_FUNCTION_ARGS) ...@@ -925,14 +957,14 @@ range_minus(PG_FUNCTION_ARGS)
if (cmp_l1l2 <= 0 && cmp_u1l2 >= 0 && cmp_u1u2 <= 0) if (cmp_l1l2 <= 0 && cmp_u1l2 >= 0 && cmp_u1u2 <= 0)
{ {
lower2.inclusive = !lower2.inclusive; lower2.inclusive = !lower2.inclusive;
lower2.lower = false; /* it will become the upper bound */ lower2.lower = false; /* it will become the upper bound */
PG_RETURN_RANGE(make_range(fcinfo, &lower1, &lower2, false)); PG_RETURN_RANGE(make_range(fcinfo, &lower1, &lower2, false));
} }
if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0) if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0)
{ {
upper2.inclusive = !upper2.inclusive; upper2.inclusive = !upper2.inclusive;
upper2.lower = true; /* it will become the lower bound */ upper2.lower = true; /* it will become the lower bound */
PG_RETURN_RANGE(make_range(fcinfo, &upper2, &upper1, false)); PG_RETURN_RANGE(make_range(fcinfo, &upper2, &upper1, false));
} }
...@@ -943,14 +975,17 @@ range_minus(PG_FUNCTION_ARGS) ...@@ -943,14 +975,17 @@ range_minus(PG_FUNCTION_ARGS)
Datum Datum
range_union(PG_FUNCTION_ARGS) range_union(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
RangeBound *result_lower; upper2;
RangeBound *result_upper; bool empty1,
empty2;
RangeBound *result_lower;
RangeBound *result_upper;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -982,14 +1017,17 @@ range_union(PG_FUNCTION_ARGS) ...@@ -982,14 +1017,17 @@ range_union(PG_FUNCTION_ARGS)
Datum Datum
range_intersect(PG_FUNCTION_ARGS) range_intersect(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
RangeBound *result_lower; upper2;
RangeBound *result_upper; bool empty1,
empty2;
RangeBound *result_lower;
RangeBound *result_upper;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -1015,14 +1053,17 @@ range_intersect(PG_FUNCTION_ARGS) ...@@ -1015,14 +1053,17 @@ range_intersect(PG_FUNCTION_ARGS)
Datum Datum
range_cmp(PG_FUNCTION_ARGS) range_cmp(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
int cmp; int cmp;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -1048,28 +1089,32 @@ range_cmp(PG_FUNCTION_ARGS) ...@@ -1048,28 +1089,32 @@ range_cmp(PG_FUNCTION_ARGS)
Datum Datum
range_lt(PG_FUNCTION_ARGS) range_lt(PG_FUNCTION_ARGS)
{ {
int cmp = range_cmp(fcinfo); int cmp = range_cmp(fcinfo);
PG_RETURN_BOOL(cmp < 0); PG_RETURN_BOOL(cmp < 0);
} }
Datum Datum
range_le(PG_FUNCTION_ARGS) range_le(PG_FUNCTION_ARGS)
{ {
int cmp = range_cmp(fcinfo); int cmp = range_cmp(fcinfo);
PG_RETURN_BOOL(cmp <= 0); PG_RETURN_BOOL(cmp <= 0);
} }
Datum Datum
range_ge(PG_FUNCTION_ARGS) range_ge(PG_FUNCTION_ARGS)
{ {
int cmp = range_cmp(fcinfo); int cmp = range_cmp(fcinfo);
PG_RETURN_BOOL(cmp >= 0); PG_RETURN_BOOL(cmp >= 0);
} }
Datum Datum
range_gt(PG_FUNCTION_ARGS) range_gt(PG_FUNCTION_ARGS)
{ {
int cmp = range_cmp(fcinfo); int cmp = range_cmp(fcinfo);
PG_RETURN_BOOL(cmp > 0); PG_RETURN_BOOL(cmp > 0);
} }
...@@ -1077,19 +1122,19 @@ range_gt(PG_FUNCTION_ARGS) ...@@ -1077,19 +1122,19 @@ range_gt(PG_FUNCTION_ARGS)
Datum Datum
hash_range(PG_FUNCTION_ARGS) hash_range(PG_FUNCTION_ARGS)
{ {
RangeType *r = PG_GETARG_RANGE(0); RangeType *r = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
char flags = 0; char flags = 0;
uint32 lower_hash = 0; uint32 lower_hash = 0;
uint32 upper_hash = 0; uint32 upper_hash = 0;
uint32 result = 0; uint32 result = 0;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
TypeCacheEntry *typentry; TypeCacheEntry *typentry;
Oid subtype; Oid subtype;
FunctionCallInfoData locfcinfo; FunctionCallInfoData locfcinfo;
...@@ -1101,19 +1146,19 @@ hash_range(PG_FUNCTION_ARGS) ...@@ -1101,19 +1146,19 @@ hash_range(PG_FUNCTION_ARGS)
if (empty) if (empty)
flags |= RANGE_EMPTY; flags |= RANGE_EMPTY;
flags |= (lower.inclusive) ? RANGE_LB_INC : 0; flags |= (lower.inclusive) ? RANGE_LB_INC : 0;
flags |= (lower.infinite) ? RANGE_LB_INF : 0; flags |= (lower.infinite) ? RANGE_LB_INF : 0;
flags |= (upper.inclusive) ? RANGE_UB_INC : 0; flags |= (upper.inclusive) ? RANGE_UB_INC : 0;
flags |= (upper.infinite) ? RANGE_UB_INF : 0; flags |= (upper.infinite) ? RANGE_UB_INF : 0;
range_gettypinfo(fcinfo, lower.rngtypid, &rngtypinfo); range_gettypinfo(fcinfo, lower.rngtypid, &rngtypinfo);
subtype = rngtypinfo.subtype; subtype = rngtypinfo.subtype;
/* /*
* We arrange to look up the hash function only once per series of * We arrange to look up the hash function only once per series of calls,
* calls, assuming the subtype doesn't change underneath us. The * assuming the subtype doesn't change underneath us. The typcache is
* typcache is used so that we have no memory leakage when being * used so that we have no memory leakage when being used as an index
* used as an index support function. * support function.
*/ */
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra; typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
if (typentry == NULL || typentry->type_id != subtype) if (typentry == NULL || typentry->type_id != subtype)
...@@ -1128,30 +1173,30 @@ hash_range(PG_FUNCTION_ARGS) ...@@ -1128,30 +1173,30 @@ hash_range(PG_FUNCTION_ARGS)
} }
/* /*
* Apply the hash function to each bound (the hash function shouldn't * Apply the hash function to each bound (the hash function shouldn't care
* care about the collation). * about the collation).
*/ */
InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1, InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1,
InvalidOid, NULL, NULL); InvalidOid, NULL, NULL);
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
{ {
locfcinfo.arg[0] = lower.val; locfcinfo.arg[0] = lower.val;
locfcinfo.argnull[0] = false; locfcinfo.argnull[0] = false;
locfcinfo.isnull = false; locfcinfo.isnull = false;
lower_hash = DatumGetUInt32(FunctionCallInvoke(&locfcinfo)); lower_hash = DatumGetUInt32(FunctionCallInvoke(&locfcinfo));
} }
if (RANGE_HAS_UBOUND(flags)) if (RANGE_HAS_UBOUND(flags))
{ {
locfcinfo.arg[0] = upper.val; locfcinfo.arg[0] = upper.val;
locfcinfo.argnull[0] = false; locfcinfo.argnull[0] = false;
locfcinfo.isnull = false; locfcinfo.isnull = false;
upper_hash = DatumGetUInt32(FunctionCallInvoke(&locfcinfo)); upper_hash = DatumGetUInt32(FunctionCallInvoke(&locfcinfo));
} }
result = hash_uint32((uint32) flags); result = hash_uint32((uint32) flags);
result ^= lower_hash; result ^= lower_hash;
result = (result << 1) | (result >> 31); result = (result << 1) | (result >> 31);
result ^= upper_hash; result ^= upper_hash;
PG_RETURN_INT32(result); PG_RETURN_INT32(result);
...@@ -1161,14 +1206,14 @@ hash_range(PG_FUNCTION_ARGS) ...@@ -1161,14 +1206,14 @@ hash_range(PG_FUNCTION_ARGS)
*---------------------------------------------------------- *----------------------------------------------------------
* CANONICAL FUNCTIONS * CANONICAL FUNCTIONS
* *
* Functions for specific built-in range types. * Functions for specific built-in range types.
*---------------------------------------------------------- *----------------------------------------------------------
*/ */
Datum Datum
int4range_canonical(PG_FUNCTION_ARGS) int4range_canonical(PG_FUNCTION_ARGS)
{ {
RangeType *r = PG_GETARG_RANGE(0); RangeType *r = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
...@@ -1197,7 +1242,7 @@ int4range_canonical(PG_FUNCTION_ARGS) ...@@ -1197,7 +1242,7 @@ int4range_canonical(PG_FUNCTION_ARGS)
Datum Datum
int8range_canonical(PG_FUNCTION_ARGS) int8range_canonical(PG_FUNCTION_ARGS)
{ {
RangeType *r = PG_GETARG_RANGE(0); RangeType *r = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
...@@ -1226,7 +1271,7 @@ int8range_canonical(PG_FUNCTION_ARGS) ...@@ -1226,7 +1271,7 @@ int8range_canonical(PG_FUNCTION_ARGS)
Datum Datum
daterange_canonical(PG_FUNCTION_ARGS) daterange_canonical(PG_FUNCTION_ARGS)
{ {
RangeType *r = PG_GETARG_RANGE(0); RangeType *r = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
...@@ -1256,35 +1301,35 @@ daterange_canonical(PG_FUNCTION_ARGS) ...@@ -1256,35 +1301,35 @@ daterange_canonical(PG_FUNCTION_ARGS)
*---------------------------------------------------------- *----------------------------------------------------------
* SUBTYPE_DIFF FUNCTIONS * SUBTYPE_DIFF FUNCTIONS
* *
* Functions for specific built-in range types. * Functions for specific built-in range types.
*---------------------------------------------------------- *----------------------------------------------------------
*/ */
Datum Datum
int4range_subdiff(PG_FUNCTION_ARGS) int4range_subdiff(PG_FUNCTION_ARGS)
{ {
int32 v1 = PG_GETARG_INT32(0); int32 v1 = PG_GETARG_INT32(0);
int32 v2 = PG_GETARG_INT32(1); int32 v2 = PG_GETARG_INT32(1);
PG_RETURN_FLOAT8((float8)(v1-v2)); PG_RETURN_FLOAT8((float8) (v1 - v2));
} }
Datum Datum
int8range_subdiff(PG_FUNCTION_ARGS) int8range_subdiff(PG_FUNCTION_ARGS)
{ {
int64 v1 = PG_GETARG_INT64(0); int64 v1 = PG_GETARG_INT64(0);
int64 v2 = PG_GETARG_INT64(1); int64 v2 = PG_GETARG_INT64(1);
PG_RETURN_FLOAT8((float8)(v1-v2)); PG_RETURN_FLOAT8((float8) (v1 - v2));
} }
Datum Datum
daterange_subdiff(PG_FUNCTION_ARGS) daterange_subdiff(PG_FUNCTION_ARGS)
{ {
int32 v1 = PG_GETARG_INT32(0); int32 v1 = PG_GETARG_INT32(0);
int32 v2 = PG_GETARG_INT32(1); int32 v2 = PG_GETARG_INT32(1);
PG_RETURN_FLOAT8((float8)(v1-v2)); PG_RETURN_FLOAT8((float8) (v1 - v2));
} }
Datum Datum
...@@ -1298,7 +1343,7 @@ numrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1298,7 +1343,7 @@ numrange_subdiff(PG_FUNCTION_ARGS)
numresult = DirectFunctionCall2(numeric_sub, v1, v2); numresult = DirectFunctionCall2(numeric_sub, v1, v2);
floatresult = DatumGetFloat8( floatresult = DatumGetFloat8(
DirectFunctionCall1(numeric_float8, numresult)); DirectFunctionCall1(numeric_float8, numresult));
PG_RETURN_FLOAT8(floatresult); PG_RETURN_FLOAT8(floatresult);
} }
...@@ -1311,7 +1356,7 @@ tsrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1311,7 +1356,7 @@ tsrange_subdiff(PG_FUNCTION_ARGS)
float8 result; float8 result;
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
result = ((float8)(v1-v2)) / USECS_PER_SEC; result = ((float8) (v1 - v2)) / USECS_PER_SEC;
#else #else
result = v1 - v2; result = v1 - v2;
#endif #endif
...@@ -1327,7 +1372,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1327,7 +1372,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS)
float8 result; float8 result;
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
result = ((float8)(v1-v2)) / USECS_PER_SEC; result = ((float8) (v1 - v2)) / USECS_PER_SEC;
#else #else
result = v1 - v2; result = v1 - v2;
#endif #endif
...@@ -1339,18 +1384,18 @@ tstzrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1339,18 +1384,18 @@ tstzrange_subdiff(PG_FUNCTION_ARGS)
*---------------------------------------------------------- *----------------------------------------------------------
* SUPPORT FUNCTIONS * SUPPORT FUNCTIONS
* *
* These functions aren't in pg_proc, but are useful if * These functions aren't in pg_proc, but are useful if
* defining new generic range functions in C. * defining new generic range functions in C.
*---------------------------------------------------------- *----------------------------------------------------------
*/ */
/* /*
* Serialized format is: * Serialized format is:
* *
* 4 bytes: Range type Oid * 4 bytes: Range type Oid
* Lower boundary, if any, aligned according to subtype's typalign * Lower boundary, if any, aligned according to subtype's typalign
* Upper boundary, if any, aligned according to subtype's typalign * Upper boundary, if any, aligned according to subtype's typalign
* 1 byte for flags * 1 byte for flags
* *
* This representation is chosen to be compact when the boundary * This representation is chosen to be compact when the boundary
* values need to be MAXALIGNed. A palloc chunk always starts out * values need to be MAXALIGNed. A palloc chunk always starts out
...@@ -1369,7 +1414,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1369,7 +1414,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS)
* only be called by a canonicalization function. * only be called by a canonicalization function.
*/ */
Datum Datum
range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, range_serialize(FunctionCallInfo fcinfo, RangeBound * lower, RangeBound * upper,
bool empty) bool empty)
{ {
Datum range; Datum range;
...@@ -1379,7 +1424,7 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, ...@@ -1379,7 +1424,7 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
char typalign; char typalign;
bool typbyval; bool typbyval;
char typstorage; char typstorage;
char flags = 0; char flags = 0;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
...@@ -1388,9 +1433,9 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, ...@@ -1388,9 +1433,9 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
range_gettypinfo(fcinfo, lower->rngtypid, &rngtypinfo); range_gettypinfo(fcinfo, lower->rngtypid, &rngtypinfo);
typlen = rngtypinfo.subtyplen; typlen = rngtypinfo.subtyplen;
typalign = rngtypinfo.subtypalign; typalign = rngtypinfo.subtypalign;
typbyval = rngtypinfo.subtypbyval; typbyval = rngtypinfo.subtypbyval;
typstorage = rngtypinfo.subtypstorage; typstorage = rngtypinfo.subtypstorage;
if (empty) if (empty)
...@@ -1400,12 +1445,12 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, ...@@ -1400,12 +1445,12 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
(errcode(ERRCODE_DATA_EXCEPTION), (errcode(ERRCODE_DATA_EXCEPTION),
errmsg("range lower bound must be less than or equal to range upper bound"))); errmsg("range lower bound must be less than or equal to range upper bound")));
flags |= (lower->inclusive) ? RANGE_LB_INC : 0; flags |= (lower->inclusive) ? RANGE_LB_INC : 0;
flags |= (lower->infinite) ? RANGE_LB_INF : 0; flags |= (lower->infinite) ? RANGE_LB_INF : 0;
flags |= (upper->inclusive) ? RANGE_UB_INC : 0; flags |= (upper->inclusive) ? RANGE_UB_INC : 0;
flags |= (upper->infinite) ? RANGE_UB_INF : 0; flags |= (upper->infinite) ? RANGE_UB_INF : 0;
msize = VARHDRSZ; msize = VARHDRSZ;
msize += sizeof(Oid); msize += sizeof(Oid);
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
...@@ -1452,10 +1497,10 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, ...@@ -1452,10 +1497,10 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
} }
void void
range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, range_deserialize(FunctionCallInfo fcinfo, RangeType * range, RangeBound * lower,
RangeBound *upper, bool *empty) RangeBound * upper, bool *empty)
{ {
Pointer ptr = VARDATA(range); Pointer ptr = VARDATA(range);
char typalign; char typalign;
int16 typlen; int16 typlen;
int16 typbyval; int16 typbyval;
...@@ -1485,7 +1530,7 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, ...@@ -1485,7 +1530,7 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower,
range_gettypinfo(fcinfo, rngtypid, &rngtypinfo); range_gettypinfo(fcinfo, rngtypid, &rngtypinfo);
typalign = rngtypinfo.subtypalign; typalign = rngtypinfo.subtypalign;
typlen = rngtypinfo.subtyplen; typlen = rngtypinfo.subtyplen;
typbyval = rngtypinfo.subtypbyval; typbyval = rngtypinfo.subtypbyval;
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
...@@ -1512,17 +1557,17 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, ...@@ -1512,17 +1557,17 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower,
*empty = flags & RANGE_EMPTY; *empty = flags & RANGE_EMPTY;
lower->rngtypid = rngtypid; lower->rngtypid = rngtypid;
lower->val = lbound; lower->val = lbound;
lower->inclusive = flags & RANGE_LB_INC; lower->inclusive = flags & RANGE_LB_INC;
lower->infinite = flags & RANGE_LB_INF; lower->infinite = flags & RANGE_LB_INF;
lower->lower = true; lower->lower = true;
upper->rngtypid = rngtypid; upper->rngtypid = rngtypid;
upper->val = ubound; upper->val = ubound;
upper->inclusive = flags & RANGE_UB_INC; upper->inclusive = flags & RANGE_UB_INC;
upper->infinite = flags & RANGE_UB_INF; upper->infinite = flags & RANGE_UB_INF;
upper->lower = false; upper->lower = false;
} }
/* /*
...@@ -1530,10 +1575,10 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, ...@@ -1530,10 +1575,10 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower,
* range. This should be used by most callers. * range. This should be used by most callers.
*/ */
Datum Datum
make_range(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, make_range(FunctionCallInfo fcinfo, RangeBound * lower, RangeBound * upper,
bool empty) bool empty)
{ {
Datum range; Datum range;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
...@@ -1551,7 +1596,7 @@ make_range(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, ...@@ -1551,7 +1596,7 @@ make_range(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
} }
int int
range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2) range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound * b1, RangeBound * b2)
{ {
int result; int result;
...@@ -1588,8 +1633,8 @@ range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2) ...@@ -1588,8 +1633,8 @@ range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2)
RangeType * RangeType *
make_empty_range(FunctionCallInfo fcinfo, Oid rngtypid) make_empty_range(FunctionCallInfo fcinfo, Oid rngtypid)
{ {
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
memset(&lower, 0, sizeof(RangeBound)); memset(&lower, 0, sizeof(RangeBound));
memset(&upper, 0, sizeof(RangeBound)); memset(&upper, 0, sizeof(RangeBound));
...@@ -1607,7 +1652,7 @@ make_empty_range(FunctionCallInfo fcinfo, Oid rngtypid) ...@@ -1607,7 +1652,7 @@ make_empty_range(FunctionCallInfo fcinfo, Oid rngtypid)
*/ */
void void
range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
RangeTypeInfo *rngtypinfo) RangeTypeInfo * rngtypinfo)
{ {
RangeTypeInfo *cached = (RangeTypeInfo *) fcinfo->flinfo->fn_extra; RangeTypeInfo *cached = (RangeTypeInfo *) fcinfo->flinfo->fn_extra;
...@@ -1621,23 +1666,23 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1621,23 +1666,23 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
if (cached->rngtypid != rngtypid) if (cached->rngtypid != rngtypid)
{ {
Form_pg_range pg_range; Form_pg_range pg_range;
Form_pg_opclass pg_opclass; Form_pg_opclass pg_opclass;
Form_pg_type pg_type; Form_pg_type pg_type;
HeapTuple tup; HeapTuple tup;
Oid subtypeOid; Oid subtypeOid;
Oid collationOid; Oid collationOid;
Oid canonicalOid; Oid canonicalOid;
Oid subdiffOid; Oid subdiffOid;
Oid opclassOid; Oid opclassOid;
Oid cmpFnOid; Oid cmpFnOid;
Oid opfamilyOid; Oid opfamilyOid;
Oid opcintype; Oid opcintype;
int16 subtyplen; int16 subtyplen;
char subtypalign; char subtypalign;
char subtypstorage; char subtypstorage;
bool subtypbyval; bool subtypbyval;
/* get information from pg_range */ /* get information from pg_range */
tup = SearchSysCache1(RANGETYPE, ObjectIdGetDatum(rngtypid)); tup = SearchSysCache1(RANGETYPE, ObjectIdGetDatum(rngtypid));
...@@ -1646,11 +1691,11 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1646,11 +1691,11 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
pg_range = (Form_pg_range) GETSTRUCT(tup); pg_range = (Form_pg_range) GETSTRUCT(tup);
subtypeOid = pg_range->rngsubtype; subtypeOid = pg_range->rngsubtype;
collationOid = pg_range->rngcollation; collationOid = pg_range->rngcollation;
canonicalOid = pg_range->rngcanonical; canonicalOid = pg_range->rngcanonical;
opclassOid = pg_range->rngsubopc; opclassOid = pg_range->rngsubopc;
subdiffOid = pg_range->rngsubdiff; subdiffOid = pg_range->rngsubdiff;
ReleaseSysCache(tup); ReleaseSysCache(tup);
...@@ -1665,7 +1710,7 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1665,7 +1710,7 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
pg_opclass = (Form_pg_opclass) GETSTRUCT(tup); pg_opclass = (Form_pg_opclass) GETSTRUCT(tup);
opfamilyOid = pg_opclass->opcfamily; opfamilyOid = pg_opclass->opcfamily;
opcintype = pg_opclass->opcintype; opcintype = pg_opclass->opcintype;
ReleaseSysCache(tup); ReleaseSysCache(tup);
...@@ -1683,10 +1728,10 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1683,10 +1728,10 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
pg_type = (Form_pg_type) GETSTRUCT(tup); pg_type = (Form_pg_type) GETSTRUCT(tup);
subtyplen = pg_type->typlen; subtyplen = pg_type->typlen;
subtypalign = pg_type->typalign; subtypalign = pg_type->typalign;
subtypstorage = pg_type->typstorage; subtypstorage = pg_type->typstorage;
subtypbyval = pg_type->typbyval; subtypbyval = pg_type->typbyval;
ReleaseSysCache(tup); ReleaseSysCache(tup);
...@@ -1703,13 +1748,13 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1703,13 +1748,13 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
cached->subdiffFn.fn_addr = NULL; cached->subdiffFn.fn_addr = NULL;
fmgr_info(cmpFnOid, &cached->cmpFn); fmgr_info(cmpFnOid, &cached->cmpFn);
cached->subtype = subtypeOid; cached->subtype = subtypeOid;
cached->collation = collationOid; cached->collation = collationOid;
cached->subtyplen = subtyplen; cached->subtyplen = subtyplen;
cached->subtypalign = subtypalign; cached->subtypalign = subtypalign;
cached->subtypstorage = subtypstorage; cached->subtypstorage = subtypstorage;
cached->subtypbyval = subtypbyval; cached->subtypbyval = subtypbyval;
cached->rngtypid = rngtypid; cached->rngtypid = rngtypid;
} }
memcpy(rngtypinfo, cached, sizeof(RangeTypeInfo)); memcpy(rngtypinfo, cached, sizeof(RangeTypeInfo));
...@@ -1724,7 +1769,7 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1724,7 +1769,7 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
char char
range_parse_flags(char *flags_str) range_parse_flags(char *flags_str)
{ {
char flags = 0; char flags = 0;
if (flags_str[0] == '\0' || if (flags_str[0] == '\0' ||
flags_str[1] == '\0' || flags_str[1] == '\0' ||
...@@ -1745,7 +1790,7 @@ range_parse_flags(char *flags_str) ...@@ -1745,7 +1790,7 @@ range_parse_flags(char *flags_str)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid range bound flags"), errmsg("invalid range bound flags"),
errhint("Valid values are '[]', '[)', '(]', and '()'."))); errhint("Valid values are '[]', '[)', '(]', and '()'.")));
} }
switch (flags_str[1]) switch (flags_str[1])
...@@ -1759,7 +1804,7 @@ range_parse_flags(char *flags_str) ...@@ -1759,7 +1804,7 @@ range_parse_flags(char *flags_str)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid range bound flags"), errmsg("invalid range bound flags"),
errhint("Valid values are '[]', '[)', '(]', and '()'."))); errhint("Valid values are '[]', '[)', '(]', and '()'.")));
} }
return flags; return flags;
...@@ -1774,10 +1819,10 @@ range_parse_flags(char *flags_str) ...@@ -1774,10 +1819,10 @@ range_parse_flags(char *flags_str)
/* /*
* Parse range input, modeled after record_in in rowtypes.c. * Parse range input, modeled after record_in in rowtypes.c.
* *
* <range> := EMPTY * <range> := EMPTY
* | <lb-inc> <string>, <string> <ub-inc> * | <lb-inc> <string>, <string> <ub-inc>
* <lb-inc> := '[' | '(' * <lb-inc> := '[' | '('
* <ub-inc> := ']' | ')' * <ub-inc> := ']' | ')'
* *
* Whitespace before or after <range> is ignored. Whitespace within a <string> * Whitespace before or after <range> is ignored. Whitespace within a <string>
* is taken literally and becomes the input string for that bound. * is taken literally and becomes the input string for that bound.
...@@ -1791,11 +1836,11 @@ range_parse_flags(char *flags_str) ...@@ -1791,11 +1836,11 @@ range_parse_flags(char *flags_str)
* double-quotes, a double-quote can be escaped with double-quote or backslash. * double-quotes, a double-quote can be escaped with double-quote or backslash.
*/ */
static void static void
range_parse(char *string, char *flags, char **lbound_str, range_parse(char *string, char *flags, char **lbound_str,
char **ubound_str) char **ubound_str)
{ {
char *ptr = string; char *ptr = string;
bool infinite; bool infinite;
*flags = 0; *flags = 0;
...@@ -1897,13 +1942,13 @@ range_parse(char *string, char *flags, char **lbound_str, ...@@ -1897,13 +1942,13 @@ range_parse(char *string, char *flags, char **lbound_str,
static char * static char *
range_parse_bound(char *string, char *ptr, char **bound_str, bool *infinite) range_parse_bound(char *string, char *ptr, char **bound_str, bool *infinite)
{ {
StringInfoData buf; StringInfoData buf;
/* Check for null: completely empty input means null */ /* Check for null: completely empty input means null */
if (*ptr == ',' || *ptr == ')' || *ptr == ']') if (*ptr == ',' || *ptr == ')' || *ptr == ']')
{ {
*bound_str = NULL; *bound_str = NULL;
*infinite = true; *infinite = true;
} }
else else
{ {
...@@ -1948,7 +1993,7 @@ range_parse_bound(char *string, char *ptr, char **bound_str, bool *infinite) ...@@ -1948,7 +1993,7 @@ range_parse_bound(char *string, char *ptr, char **bound_str, bool *infinite)
} }
*bound_str = buf.data; *bound_str = buf.data;
*infinite = false; *infinite = false;
} }
return ptr; return ptr;
...@@ -1957,7 +2002,7 @@ range_parse_bound(char *string, char *ptr, char **bound_str, bool *infinite) ...@@ -1957,7 +2002,7 @@ range_parse_bound(char *string, char *ptr, char **bound_str, bool *infinite)
static char * static char *
range_deparse(char flags, char *lbound_str, char *ubound_str) range_deparse(char flags, char *lbound_str, char *ubound_str)
{ {
StringInfoData buf; StringInfoData buf;
initStringInfo(&buf); initStringInfo(&buf);
...@@ -1982,9 +2027,9 @@ range_deparse(char flags, char *lbound_str, char *ubound_str) ...@@ -1982,9 +2027,9 @@ range_deparse(char flags, char *lbound_str, char *ubound_str)
static char * static char *
range_bound_escape(char *value) range_bound_escape(char *value)
{ {
bool nq; bool nq;
char *tmp; char *tmp;
StringInfoData buf; StringInfoData buf;
initStringInfo(&buf); initStringInfo(&buf);
...@@ -2023,7 +2068,7 @@ range_bound_escape(char *value) ...@@ -2023,7 +2068,7 @@ range_bound_escape(char *value)
} }
static bool static bool
range_contains_internal(FunctionCallInfo fcinfo, RangeType *r1, RangeType *r2) range_contains_internal(FunctionCallInfo fcinfo, RangeType * r1, RangeType * r2)
{ {
RangeBound lower1; RangeBound lower1;
RangeBound upper1; RangeBound upper1;
...@@ -2066,8 +2111,8 @@ datum_compute_size(Size data_length, Datum val, bool typbyval, char typalign, ...@@ -2066,8 +2111,8 @@ datum_compute_size(Size data_length, Datum val, bool typbyval, char typalign,
VARATT_CAN_MAKE_SHORT(DatumGetPointer(val))) VARATT_CAN_MAKE_SHORT(DatumGetPointer(val)))
{ {
/* /*
* we're anticipating converting to a short varlena header, so * we're anticipating converting to a short varlena header, so adjust
* adjust length and don't count any alignment * length and don't count any alignment
*/ */
data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val)); data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val));
} }
......
...@@ -33,37 +33,38 @@ ...@@ -33,37 +33,38 @@
#define RANGESTRAT_OVERRIGHT 11 #define RANGESTRAT_OVERRIGHT 11
#define RANGESTRAT_ADJACENT 12 #define RANGESTRAT_ADJACENT 12
static RangeType *range_super_union(FunctionCallInfo fcinfo, RangeType *r1, static RangeType *range_super_union(FunctionCallInfo fcinfo, RangeType * r1,
RangeType *r2); RangeType * r2);
static bool range_gist_consistent_int(FunctionCallInfo fcinfo, static bool range_gist_consistent_int(FunctionCallInfo fcinfo,
StrategyNumber strategy, RangeType *key, StrategyNumber strategy, RangeType * key,
RangeType *query); RangeType * query);
static bool range_gist_consistent_leaf(FunctionCallInfo fcinfo, static bool range_gist_consistent_leaf(FunctionCallInfo fcinfo,
StrategyNumber strategy, RangeType *key, StrategyNumber strategy, RangeType * key,
RangeType *query); RangeType * query);
static int sort_item_cmp(const void *a, const void *b); static int sort_item_cmp(const void *a, const void *b);
/* /*
* Auxiliary structure for picksplit method. * Auxiliary structure for picksplit method.
*/ */
typedef struct typedef struct
{ {
int index; int index;
RangeType *data; RangeType *data;
FunctionCallInfo fcinfo; FunctionCallInfo fcinfo;
} PickSplitSortItem; } PickSplitSortItem;
Datum Datum
range_gist_consistent(PG_FUNCTION_ARGS) range_gist_consistent(PG_FUNCTION_ARGS)
{ {
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Datum dquery = PG_GETARG_DATUM(1); Datum dquery = PG_GETARG_DATUM(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */ /* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(4);
RangeType *key = DatumGetRangeType(entry->key); RangeType *key = DatumGetRangeType(entry->key);
RangeType *query; RangeType *query;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
...@@ -76,50 +77,50 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -76,50 +77,50 @@ range_gist_consistent(PG_FUNCTION_ARGS)
switch (strategy) switch (strategy)
{ {
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
/* /*
* For contains and contained by operators, the other operand is a * For contains and contained by operators, the other operand is a
* "point" of the subtype. Construct a singleton range containing just * "point" of the subtype. Construct a singleton range containing
* that value. * just that value.
*/ */
case RANGESTRAT_CONTAINS_ELEM: case RANGESTRAT_CONTAINS_ELEM:
case RANGESTRAT_ELEM_CONTAINED_BY: case RANGESTRAT_ELEM_CONTAINED_BY:
lower.rngtypid = rngtypid; lower.rngtypid = rngtypid;
lower.inclusive = true; lower.inclusive = true;
lower.val = dquery; lower.val = dquery;
lower.lower = true; lower.lower = true;
lower.infinite = false; lower.infinite = false;
upper.rngtypid = rngtypid; upper.rngtypid = rngtypid;
upper.inclusive = true; upper.inclusive = true;
upper.val = dquery; upper.val = dquery;
upper.lower = false; upper.lower = false;
upper.infinite = false; upper.infinite = false;
query = DatumGetRangeType( query = DatumGetRangeType(
make_range(fcinfo, &lower, &upper, false)); make_range(fcinfo, &lower, &upper, false));
break; break;
default: default:
query = DatumGetRangeType(dquery); query = DatumGetRangeType(dquery);
break; break;
} }
if (GIST_LEAF(entry)) if (GIST_LEAF(entry))
PG_RETURN_BOOL(range_gist_consistent_leaf( PG_RETURN_BOOL(range_gist_consistent_leaf(
fcinfo, strategy, key, query)); fcinfo, strategy, key, query));
else else
PG_RETURN_BOOL(range_gist_consistent_int( PG_RETURN_BOOL(range_gist_consistent_int(
fcinfo, strategy, key, query)); fcinfo, strategy, key, query));
} }
Datum Datum
range_gist_union(PG_FUNCTION_ARGS) range_gist_union(PG_FUNCTION_ARGS)
{ {
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GISTENTRY *ent = entryvec->vector; GISTENTRY *ent = entryvec->vector;
RangeType *result_range; RangeType *result_range;
int i; int i;
result_range = DatumGetRangeType(ent[0].key); result_range = DatumGetRangeType(ent[0].key);
...@@ -136,6 +137,7 @@ Datum ...@@ -136,6 +137,7 @@ Datum
range_gist_compress(PG_FUNCTION_ARGS) range_gist_compress(PG_FUNCTION_ARGS)
{ {
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
PG_RETURN_POINTER(entry); PG_RETURN_POINTER(entry);
} }
...@@ -143,26 +145,31 @@ Datum ...@@ -143,26 +145,31 @@ Datum
range_gist_decompress(PG_FUNCTION_ARGS) range_gist_decompress(PG_FUNCTION_ARGS)
{ {
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
PG_RETURN_POINTER(entry); PG_RETURN_POINTER(entry);
} }
Datum Datum
range_gist_penalty(PG_FUNCTION_ARGS) range_gist_penalty(PG_FUNCTION_ARGS)
{ {
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
float *penalty = (float *) PG_GETARG_POINTER(2); float *penalty = (float *) PG_GETARG_POINTER(2);
RangeType *orig = DatumGetRangeType(origentry->key); RangeType *orig = DatumGetRangeType(origentry->key);
RangeType *new = DatumGetRangeType(newentry->key); RangeType *new = DatumGetRangeType(newentry->key);
RangeType *s_union = range_super_union(fcinfo, orig, new); RangeType *s_union = range_super_union(fcinfo, orig, new);
FmgrInfo *subtype_diff; FmgrInfo *subtype_diff;
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
float lower_diff, upper_diff; float lower_diff,
upper_diff;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
...@@ -203,7 +210,7 @@ range_gist_penalty(PG_FUNCTION_ARGS) ...@@ -203,7 +210,7 @@ range_gist_penalty(PG_FUNCTION_ARGS)
if (lower_diff < 0) if (lower_diff < 0)
lower_diff = 0; /* subtype_diff is broken */ lower_diff = 0; /* subtype_diff is broken */
} }
else /* only know whether there is a difference or not */ else /* only know whether there is a difference or not */
lower_diff = (float) range_cmp_bounds(fcinfo, &lower1, &lower2); lower_diff = (float) range_cmp_bounds(fcinfo, &lower1, &lower2);
Assert(upper2.infinite || !upper1.infinite); Assert(upper2.infinite || !upper1.infinite);
...@@ -219,7 +226,7 @@ range_gist_penalty(PG_FUNCTION_ARGS) ...@@ -219,7 +226,7 @@ range_gist_penalty(PG_FUNCTION_ARGS)
if (upper_diff < 0) if (upper_diff < 0)
upper_diff = 0; /* subtype_diff is broken */ upper_diff = 0; /* subtype_diff is broken */
} }
else /* only know whether there is a difference or not */ else /* only know whether there is a difference or not */
upper_diff = (float) range_cmp_bounds(fcinfo, &upper2, &upper1); upper_diff = (float) range_cmp_bounds(fcinfo, &upper2, &upper1);
Assert(lower_diff >= 0 && upper_diff >= 0); Assert(lower_diff >= 0 && upper_diff >= 0);
...@@ -238,22 +245,22 @@ range_gist_penalty(PG_FUNCTION_ARGS) ...@@ -238,22 +245,22 @@ range_gist_penalty(PG_FUNCTION_ARGS)
Datum Datum
range_gist_picksplit(PG_FUNCTION_ARGS) range_gist_picksplit(PG_FUNCTION_ARGS)
{ {
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
OffsetNumber i; OffsetNumber i;
RangeType *pred_left; RangeType *pred_left;
RangeType *pred_right; RangeType *pred_right;
PickSplitSortItem *sortItems; PickSplitSortItem *sortItems;
int nbytes; int nbytes;
OffsetNumber split_idx; OffsetNumber split_idx;
OffsetNumber *left; OffsetNumber *left;
OffsetNumber *right; OffsetNumber *right;
OffsetNumber maxoff; OffsetNumber maxoff;
maxoff = entryvec->n - 1; maxoff = entryvec->n - 1;
nbytes = (maxoff + 1) * sizeof(OffsetNumber); nbytes = (maxoff + 1) * sizeof(OffsetNumber);
sortItems = (PickSplitSortItem *) palloc( sortItems = (PickSplitSortItem *) palloc(
maxoff * sizeof(PickSplitSortItem)); maxoff * sizeof(PickSplitSortItem));
v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_left = (OffsetNumber *) palloc(nbytes);
v->spl_right = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes);
...@@ -262,8 +269,8 @@ range_gist_picksplit(PG_FUNCTION_ARGS) ...@@ -262,8 +269,8 @@ range_gist_picksplit(PG_FUNCTION_ARGS)
*/ */
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{ {
sortItems[i - 1].index = i; sortItems[i - 1].index = i;
sortItems[i - 1].data = DatumGetRangeType(entryvec->vector[i].key); sortItems[i - 1].data = DatumGetRangeType(entryvec->vector[i].key);
sortItems[i - 1].fcinfo = fcinfo; sortItems[i - 1].fcinfo = fcinfo;
} }
qsort(sortItems, maxoff, sizeof(PickSplitSortItem), sort_item_cmp); qsort(sortItems, maxoff, sizeof(PickSplitSortItem), sort_item_cmp);
...@@ -313,9 +320,9 @@ range_gist_picksplit(PG_FUNCTION_ARGS) ...@@ -313,9 +320,9 @@ range_gist_picksplit(PG_FUNCTION_ARGS)
Datum Datum
range_gist_same(PG_FUNCTION_ARGS) range_gist_same(PG_FUNCTION_ARGS)
{ {
Datum r1 = PG_GETARG_DATUM(0); Datum r1 = PG_GETARG_DATUM(0);
Datum r2 = PG_GETARG_DATUM(1); Datum r2 = PG_GETARG_DATUM(1);
bool *result = (bool *) PG_GETARG_POINTER(2); bool *result = (bool *) PG_GETARG_POINTER(2);
*result = DatumGetBool(OidFunctionCall2(F_RANGE_EQ, r1, r2)); *result = DatumGetBool(OidFunctionCall2(F_RANGE_EQ, r1, r2));
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
...@@ -329,13 +336,16 @@ range_gist_same(PG_FUNCTION_ARGS) ...@@ -329,13 +336,16 @@ range_gist_same(PG_FUNCTION_ARGS)
/* return the smallest range that contains r1 and r2 */ /* return the smallest range that contains r1 and r2 */
static RangeType * static RangeType *
range_super_union(FunctionCallInfo fcinfo, RangeType *r1, RangeType *r2) range_super_union(FunctionCallInfo fcinfo, RangeType * r1, RangeType * r2)
{ {
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
RangeBound *result_lower; upper2;
RangeBound *result_upper; bool empty1,
empty2;
RangeBound *result_lower;
RangeBound *result_upper;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -362,21 +372,24 @@ range_super_union(FunctionCallInfo fcinfo, RangeType *r1, RangeType *r2) ...@@ -362,21 +372,24 @@ range_super_union(FunctionCallInfo fcinfo, RangeType *r1, RangeType *r2)
return r2; return r2;
return DatumGetRangeType( return DatumGetRangeType(
make_range(fcinfo, result_lower, result_upper, false)); make_range(fcinfo, result_lower, result_upper, false));
} }
static bool static bool
range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
RangeType *key, RangeType *query) RangeType * key, RangeType * query)
{ {
Oid proc = InvalidOid; Oid proc = InvalidOid;
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
bool retval; bool retval;
bool negate = false; bool negate = false;
range_deserialize(fcinfo, key, &lower1, &upper1, &empty1); range_deserialize(fcinfo, key, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, query, &lower2, &upper2, &empty2); range_deserialize(fcinfo, query, &lower2, &upper2, &empty2);
...@@ -384,17 +397,17 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, ...@@ -384,17 +397,17 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
switch (strategy) switch (strategy)
{ {
case RANGESTRAT_EQ: case RANGESTRAT_EQ:
proc = F_RANGE_CONTAINS; proc = F_RANGE_CONTAINS;
break; break;
case RANGESTRAT_NE: case RANGESTRAT_NE:
return true; return true;
break; break;
case RANGESTRAT_OVERLAPS: case RANGESTRAT_OVERLAPS:
proc = F_RANGE_OVERLAPS; proc = F_RANGE_OVERLAPS;
break; break;
case RANGESTRAT_CONTAINS_ELEM: case RANGESTRAT_CONTAINS_ELEM:
case RANGESTRAT_CONTAINS: case RANGESTRAT_CONTAINS:
proc = F_RANGE_CONTAINS; proc = F_RANGE_CONTAINS;
break; break;
case RANGESTRAT_ELEM_CONTAINED_BY: case RANGESTRAT_ELEM_CONTAINED_BY:
case RANGESTRAT_CONTAINED_BY: case RANGESTRAT_CONTAINED_BY:
...@@ -403,19 +416,19 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, ...@@ -403,19 +416,19 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
case RANGESTRAT_BEFORE: case RANGESTRAT_BEFORE:
if (empty1) if (empty1)
return false; return false;
proc = F_RANGE_OVERRIGHT; proc = F_RANGE_OVERRIGHT;
negate = true; negate = true;
break; break;
case RANGESTRAT_AFTER: case RANGESTRAT_AFTER:
if (empty1) if (empty1)
return false; return false;
proc = F_RANGE_OVERLEFT; proc = F_RANGE_OVERLEFT;
negate = true; negate = true;
break; break;
case RANGESTRAT_OVERLEFT: case RANGESTRAT_OVERLEFT:
if (empty1) if (empty1)
return false; return false;
proc = F_RANGE_AFTER; proc = F_RANGE_AFTER;
negate = true; negate = true;
break; break;
case RANGESTRAT_OVERRIGHT: case RANGESTRAT_OVERRIGHT:
...@@ -428,9 +441,9 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, ...@@ -428,9 +441,9 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
if (empty1 || empty2) if (empty1 || empty2)
return false; return false;
if (DatumGetBool( if (DatumGetBool(
OidFunctionCall2(F_RANGE_ADJACENT, OidFunctionCall2(F_RANGE_ADJACENT,
RangeTypeGetDatum(key), RangeTypeGetDatum(key),
RangeTypeGetDatum(query)))) RangeTypeGetDatum(query))))
return true; return true;
proc = F_RANGE_OVERLAPS; proc = F_RANGE_OVERLAPS;
break; break;
...@@ -447,13 +460,16 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, ...@@ -447,13 +460,16 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
static bool static bool
range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy, range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy,
RangeType *key, RangeType *query) RangeType * key, RangeType * query)
{ {
Oid proc = InvalidOid; Oid proc = InvalidOid;
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
range_deserialize(fcinfo, key, &lower1, &upper1, &empty1); range_deserialize(fcinfo, key, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, query, &lower2, &upper2, &empty2); range_deserialize(fcinfo, query, &lower2, &upper2, &empty2);
...@@ -525,18 +541,21 @@ range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy, ...@@ -525,18 +541,21 @@ range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy,
static int static int
sort_item_cmp(const void *a, const void *b) sort_item_cmp(const void *a, const void *b)
{ {
PickSplitSortItem *i1 = (PickSplitSortItem *)a; PickSplitSortItem *i1 = (PickSplitSortItem *) a;
PickSplitSortItem *i2 = (PickSplitSortItem *)b; PickSplitSortItem *i2 = (PickSplitSortItem *) b;
RangeType *r1 = i1->data; RangeType *r1 = i1->data;
RangeType *r2 = i2->data; RangeType *r2 = i2->data;
RangeBound lower1, lower2; RangeBound lower1,
RangeBound upper1, upper2; lower2;
bool empty1, empty2; RangeBound upper1,
upper2;
bool empty1,
empty2;
FunctionCallInfo fcinfo = i1->fcinfo; FunctionCallInfo fcinfo = i1->fcinfo;
int cmp; int cmp;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2); range_deserialize(fcinfo, r2, &lower2, &upper2, &empty2);
...@@ -554,12 +573,11 @@ sort_item_cmp(const void *a, const void *b) ...@@ -554,12 +573,11 @@ sort_item_cmp(const void *a, const void *b)
} }
/* /*
* If both lower or both upper bounds are infinite, we sort by * If both lower or both upper bounds are infinite, we sort by ascending
* ascending range size. That means that if both upper bounds are * range size. That means that if both upper bounds are infinite, we sort
* infinite, we sort by the lower bound _descending_. That creates * by the lower bound _descending_. That creates a slightly odd total
* a slightly odd total order, but keeps the pages with very * order, but keeps the pages with very unselective predicates grouped
* unselective predicates grouped more closely together on the * more closely together on the right.
* right.
*/ */
if (lower1.infinite || upper1.infinite || if (lower1.infinite || upper1.infinite ||
lower2.infinite || upper2.infinite) lower2.infinite || upper2.infinite)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment