diff options
| author | Heikki Linnakangas | 2011-11-03 11:16:28 +0000 |
|---|---|---|
| committer | Heikki Linnakangas | 2011-11-03 11:42:15 +0000 |
| commit | 4429f6a9e3e12bb4af6e3677fbc78cd80f160252 (patch) | |
| tree | a2e272129e5515f7ef2f4e09989bddf0fd8158ea /src/backend/utils/fmgr/funcapi.c | |
| parent | 43342891861cc2d08dea2b1c8b190e15e5a36551 (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.c | 115 |
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) |
