summaryrefslogtreecommitdiff
path: root/src/backend/utils/fmgr/funcapi.c
diff options
context:
space:
mode:
authorHeikki Linnakangas2011-11-03 11:16:28 +0000
committerHeikki Linnakangas2011-11-03 11:42:15 +0000
commit4429f6a9e3e12bb4af6e3677fbc78cd80f160252 (patch)
treea2e272129e5515f7ef2f4e09989bddf0fd8158ea /src/backend/utils/fmgr/funcapi.c
parent43342891861cc2d08dea2b1c8b190e15e5a36551 (diff)
Support range data types.
Selectivity estimation functions are missing for some range type operators, which is a TODO. Jeff Davis
Diffstat (limited to 'src/backend/utils/fmgr/funcapi.c')
-rw-r--r--src/backend/utils/fmgr/funcapi.c115
1 files changed, 103 insertions, 12 deletions
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 0911c8083be..3cc2a7ee075 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -407,11 +407,13 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
int nargs = declared_args->dim1;
bool have_anyelement_result = false;
bool have_anyarray_result = false;
+ bool have_anyrange_result = false;
bool have_anynonarray = false;
bool have_anyenum = false;
Oid anyelement_type = InvalidOid;
Oid anyarray_type = InvalidOid;
- Oid anycollation;
+ Oid anyrange_type = InvalidOid;
+ Oid anycollation = InvalidOid;
int i;
/* See if there are any polymorphic outputs; quick out if not */
@@ -433,11 +435,15 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
have_anyelement_result = true;
have_anyenum = true;
break;
+ case ANYRANGEOID:
+ have_anyrange_result = true;
+ break;
default:
break;
}
}
- if (!have_anyelement_result && !have_anyarray_result)
+ if (!have_anyelement_result && !have_anyarray_result &&
+ !have_anyrange_result)
return true;
/*
@@ -461,20 +467,47 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
if (!OidIsValid(anyarray_type))
anyarray_type = get_call_expr_argtype(call_expr, i);
break;
+ case ANYRANGEOID:
+ if (!OidIsValid(anyrange_type))
+ anyrange_type = get_call_expr_argtype(call_expr, i);
+ break;
default:
break;
}
}
/* If nothing found, parser messed up */
- if (!OidIsValid(anyelement_type) && !OidIsValid(anyarray_type))
+ if (!OidIsValid(anyelement_type) && !OidIsValid(anyarray_type) &&
+ !OidIsValid(anyrange_type))
+ return false;
+
+ /*
+ * We can't deduce a range type from the subtype, because there may be
+ * multiple range types for a single subtype.
+ */
+ if (have_anyrange_result && !OidIsValid(anyrange_type))
return false;
/* If needed, deduce one polymorphic type from the other */
if (have_anyelement_result && !OidIsValid(anyelement_type))
- anyelement_type = resolve_generic_type(ANYELEMENTOID,
- anyarray_type,
- ANYARRAYOID);
+ {
+ if (OidIsValid(anyarray_type))
+ anyelement_type = resolve_generic_type(ANYELEMENTOID,
+ anyarray_type,
+ ANYARRAYOID);
+ if (OidIsValid(anyrange_type))
+ {
+ Oid subtype = resolve_generic_type(ANYELEMENTOID,
+ anyrange_type,
+ ANYRANGEOID);
+ if (OidIsValid(anyelement_type) &&
+ anyelement_type != subtype)
+ return false;
+ else
+ anyelement_type = subtype;
+ }
+ }
+
if (have_anyarray_result && !OidIsValid(anyarray_type))
anyarray_type = resolve_generic_type(ANYARRAYOID,
anyelement_type,
@@ -492,7 +525,12 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
* Identify the collation to use for polymorphic OUT parameters. (It'll
* necessarily be the same for both anyelement and anyarray.)
*/
- anycollation = get_typcollation(OidIsValid(anyelement_type) ? anyelement_type : anyarray_type);
+
+ if (OidIsValid(anyelement_type))
+ anycollation = get_typcollation(anyelement_type);
+ else if (OidIsValid(anyarray_type))
+ anycollation = get_typcollation(anyarray_type);
+
if (OidIsValid(anycollation))
{
/*
@@ -529,6 +567,14 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
0);
TupleDescInitEntryCollation(tupdesc, i + 1, anycollation);
break;
+ case ANYRANGEOID:
+ TupleDescInitEntry(tupdesc, i + 1,
+ NameStr(tupdesc->attrs[i]->attname),
+ anyrange_type,
+ -1,
+ 0);
+ TupleDescInitEntryCollation(tupdesc, i + 1, anycollation);
+ break;
default:
break;
}
@@ -552,8 +598,10 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes,
{
bool have_anyelement_result = false;
bool have_anyarray_result = false;
+ bool have_anyrange_result = false;
Oid anyelement_type = InvalidOid;
Oid anyarray_type = InvalidOid;
+ Oid anyrange_type = InvalidOid;
int inargno;
int i;
@@ -597,6 +645,21 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes,
argtypes[i] = anyarray_type;
}
break;
+ case ANYRANGEOID:
+ if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
+ have_anyrange_result = true;
+ else
+ {
+ if (!OidIsValid(anyrange_type))
+ {
+ anyrange_type = get_call_expr_argtype(call_expr,
+ inargno);
+ if (!OidIsValid(anyrange_type))
+ return false;
+ }
+ argtypes[i] = anyrange_type;
+ }
+ break;
default:
break;
}
@@ -605,18 +668,42 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes,
}
/* Done? */
- if (!have_anyelement_result && !have_anyarray_result)
+ if (!have_anyelement_result && !have_anyarray_result &&
+ !have_anyrange_result)
return true;
+ /*
+ * We can't deduce a range type from the subtype, because there may be
+ * multiple range types for a single subtype.
+ */
+ if (have_anyrange_result && !OidIsValid(anyrange_type))
+ return false;
+
/* If no input polymorphics, parser messed up */
- if (!OidIsValid(anyelement_type) && !OidIsValid(anyarray_type))
+ if (!OidIsValid(anyelement_type) && !OidIsValid(anyarray_type) &&
+ !OidIsValid(anyrange_type))
return false;
/* If needed, deduce one polymorphic type from the other */
if (have_anyelement_result && !OidIsValid(anyelement_type))
- anyelement_type = resolve_generic_type(ANYELEMENTOID,
- anyarray_type,
- ANYARRAYOID);
+ {
+ if (OidIsValid(anyarray_type))
+ anyelement_type = resolve_generic_type(ANYELEMENTOID,
+ anyarray_type,
+ ANYARRAYOID);
+ if (OidIsValid(anyrange_type))
+ {
+ Oid subtype = resolve_generic_type(ANYELEMENTOID,
+ anyrange_type,
+ ANYRANGEOID);
+ if (OidIsValid(anyelement_type) &&
+ anyelement_type != subtype)
+ return false;
+ else
+ anyelement_type = subtype;
+ }
+ }
+
if (have_anyarray_result && !OidIsValid(anyarray_type))
anyarray_type = resolve_generic_type(ANYARRAYOID,
anyelement_type,
@@ -637,6 +724,9 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes,
case ANYARRAYOID:
argtypes[i] = anyarray_type;
break;
+ case ANYRANGEOID:
+ argtypes[i] = anyrange_type;
+ break;
default:
break;
}
@@ -663,6 +753,7 @@ get_type_func_class(Oid typid)
case TYPTYPE_BASE:
case TYPTYPE_DOMAIN:
case TYPTYPE_ENUM:
+ case TYPTYPE_RANGE:
return TYPEFUNC_SCALAR;
case TYPTYPE_PSEUDO:
if (typid == RECORDOID)