Commit f45df8c0 authored by Tom Lane's avatar Tom Lane

Cause CHAR(n) to TEXT or VARCHAR conversion to automatically strip trailing

blanks, in hopes of reducing the surprise factor for newbies.  Remove
redundant operators for VARCHAR (it depends wholly on TEXT operations now).
Clean up resolution of ambiguous operators/functions to avoid surprising
choices for domains: domains are treated as equivalent to their base types
and binary-coercibility is no longer considered a preference item when
choosing among multiple operators/functions.  IsBinaryCoercible now correctly
reflects the notion that you need *only* relabel the type to get from type
A to type B: that is, a domain is binary-coercible to its base type, but
not vice versa.  Various marginal cleanup, including merging the essentially
duplicate resolution code in parse_func.c and parse_oper.c.  Improve opr_sanity
regression test to understand about binary compatibility (using pg_cast),
and fix a couple of small errors in the catalogs revealed thereby.
Restructure "special operator" handling to fetch operators via index opclasses
rather than hardwiring assumptions about names (cleans up the pattern_ops
stuff a little).
parent 297c1658
...@@ -145,43 +145,6 @@ array_all_textregexeq(ArrayType *array, void *value) ...@@ -145,43 +145,6 @@ array_all_textregexeq(ArrayType *array, void *value)
array, (Datum) value); array, (Datum) value);
} }
/*
* Iterator functions for type _varchar. Note that the regexp
* operators take the second argument of type text.
*/
int32
array_varchareq(ArrayType *array, void *value)
{
return array_iterator(F_VARCHAREQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varchareq(ArrayType *array, void *value)
{
return array_iterator(F_VARCHAREQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_varcharregexeq(ArrayType *array, void *value)
{
return array_iterator(F_TEXTREGEXEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varcharregexeq(ArrayType *array, void *value)
{
return array_iterator(F_TEXTREGEXEQ,
1, /* logical and */
array, (Datum) value);
}
/* /*
* Iterator functions for type _bpchar. Note that the regexp * Iterator functions for type _bpchar. Note that the regexp
* operators take the second argument of type text. * operators take the second argument of type text.
......
...@@ -9,11 +9,6 @@ int32 array_all_texteq(ArrayType *array, void *value); ...@@ -9,11 +9,6 @@ int32 array_all_texteq(ArrayType *array, void *value);
int32 array_textregexeq(ArrayType *array, void *value); int32 array_textregexeq(ArrayType *array, void *value);
int32 array_all_textregexeq(ArrayType *array, void *value); int32 array_all_textregexeq(ArrayType *array, void *value);
int32 array_varchareq(ArrayType *array, void *value);
int32 array_all_varchareq(ArrayType *array, void *value);
int32 array_varcharregexeq(ArrayType *array, void *value);
int32 array_all_varcharregexeq(ArrayType *array, void *value);
int32 array_bpchareq(ArrayType *array, void *value); int32 array_bpchareq(ArrayType *array, void *value);
int32 array_all_bpchareq(ArrayType *array, void *value); int32 array_all_bpchareq(ArrayType *array, void *value);
int32 array_bpcharregexeq(ArrayType *array, void *value); int32 array_bpcharregexeq(ArrayType *array, void *value);
......
...@@ -55,59 +55,6 @@ CREATE OPERATOR **~ ( ...@@ -55,59 +55,6 @@ CREATE OPERATOR **~ (
); );
-- define the array operators *=, **=, *~ and **~ for type _varchar
--
-- NOTE: "varchar" is also a reserved word and must be quoted.
--
CREATE OR REPLACE FUNCTION array_varchareq(_varchar, varchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_varchareq(_varchar, varchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_varcharregexeq(_varchar, varchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_varcharregexeq(_varchar, varchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
DROP OPERATOR *=(_varchar,"varchar");
CREATE OPERATOR *= (
LEFTARG=_varchar,
RIGHTARG="varchar",
PROCEDURE=array_varchareq
);
DROP OPERATOR **=(_varchar,"varchar");
CREATE OPERATOR **= (
LEFTARG=_varchar,
RIGHTARG="varchar",
PROCEDURE=array_all_varchareq
);
DROP OPERATOR *~(_varchar,"varchar");
CREATE OPERATOR *~ (
LEFTARG=_varchar,
RIGHTARG="varchar",
PROCEDURE=array_varcharregexeq
);
DROP OPERATOR **~(_varchar,"varchar");
CREATE OPERATOR **~ (
LEFTARG=_varchar,
RIGHTARG="varchar",
PROCEDURE=array_all_varcharregexeq
);
-- define the array operators *=, **=, *~ and **~ for type _bpchar -- define the array operators *=, **=, *~ and **~ for type _bpchar
-- --
CREATE OR REPLACE FUNCTION array_bpchareq(_bpchar, bpchar) CREATE OR REPLACE FUNCTION array_bpchareq(_bpchar, bpchar)
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.189 2003/05/22 18:31:45 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.190 2003/05/26 00:11:27 tgl Exp $
--> -->
<appendix id="release"> <appendix id="release">
...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without ...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters. worries about funny characters.
--> -->
<literallayout><![CDATA[ <literallayout><![CDATA[
CHAR(n) to TEXT conversion automatically strips trailing blanks
Pattern matching operations can use indexes regardless of locale Pattern matching operations can use indexes regardless of locale
New frontend/backend protocol supports many long-requested features New frontend/backend protocol supports many long-requested features
SET AUTOCOMMIT TO OFF is no longer supported SET AUTOCOMMIT TO OFF is no longer supported
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/typeconv.sgml,v 1.30 2003/03/25 16:15:38 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/typeconv.sgml,v 1.31 2003/05/26 00:11:27 tgl Exp $
--> -->
<chapter Id="typeconv"> <chapter Id="typeconv">
...@@ -45,7 +45,7 @@ mixed-type expressions to be meaningful even with user-defined types. ...@@ -45,7 +45,7 @@ mixed-type expressions to be meaningful even with user-defined types.
<para> <para>
The <productname>PostgreSQL</productname> scanner/parser decodes lexical The <productname>PostgreSQL</productname> scanner/parser decodes lexical
elements into only five fundamental categories: integers, floating-point numbers, strings, elements into only five fundamental categories: integers, floating-point numbers, strings,
names, and key words. Most extended types are first classified as names, and key words. Constants of most non-numeric types are first classified as
strings. The <acronym>SQL</acronym> language definition allows specifying type strings. The <acronym>SQL</acronym> language definition allows specifying type
names with strings, and this mechanism can be used in names with strings, and this mechanism can be used in
<productname>PostgreSQL</productname> to start the parser down the correct <productname>PostgreSQL</productname> to start the parser down the correct
...@@ -134,8 +134,8 @@ The system catalogs store information about which conversions, called ...@@ -134,8 +134,8 @@ The system catalogs store information about which conversions, called
perform those conversions. Additional casts can be added by the user perform those conversions. Additional casts can be added by the user
with the <command>CREATE CAST</command> command. (This is usually with the <command>CREATE CAST</command> command. (This is usually
done in conjunction with defining new data types. The set of casts done in conjunction with defining new data types. The set of casts
between the built-in types has been carefully crafted and should not between the built-in types has been carefully crafted and is best not
be altered.) altered.)
</para> </para>
<para> <para>
...@@ -144,8 +144,8 @@ at proper behavior for <acronym>SQL</acronym> standard types. There are ...@@ -144,8 +144,8 @@ at proper behavior for <acronym>SQL</acronym> standard types. There are
several basic <firstterm>type categories</firstterm> defined: <type>boolean</type>, several basic <firstterm>type categories</firstterm> defined: <type>boolean</type>,
<type>numeric</type>, <type>string</type>, <type>bitstring</type>, <type>datetime</type>, <type>timespan</type>, <type>geometric</type>, <type>network</type>, <type>numeric</type>, <type>string</type>, <type>bitstring</type>, <type>datetime</type>, <type>timespan</type>, <type>geometric</type>, <type>network</type>,
and user-defined. Each category, with the exception of user-defined, has and user-defined. Each category, with the exception of user-defined, has
a <firstterm>preferred type</firstterm> which is preferentially selected one or more <firstterm>preferred types</firstterm> which are preferentially
when there is ambiguity. selected when there is ambiguity.
In the user-defined category, each type is its own preferred type. In the user-defined category, each type is its own preferred type.
Ambiguous expressions (those with multiple candidate parsing solutions) Ambiguous expressions (those with multiple candidate parsing solutions)
can therefore often be resolved when there are multiple possible built-in types, but can therefore often be resolved when there are multiple possible built-in types, but
...@@ -175,7 +175,8 @@ be converted to a user-defined type (of course, only if conversion is necessary) ...@@ -175,7 +175,8 @@ be converted to a user-defined type (of course, only if conversion is necessary)
<para> <para>
User-defined types are not related. Currently, <productname>PostgreSQL</productname> User-defined types are not related. Currently, <productname>PostgreSQL</productname>
does not have information available to it on relationships between types, other than does not have information available to it on relationships between types, other than
hardcoded heuristics for built-in types and implicit relationships based on available functions. hardcoded heuristics for built-in types and implicit relationships based on
available functions and casts.
</para> </para>
</listitem> </listitem>
...@@ -203,14 +204,15 @@ should use this new function and will no longer do the implicit conversion using ...@@ -203,14 +204,15 @@ should use this new function and will no longer do the implicit conversion using
<title>Operators</title> <title>Operators</title>
<para> <para>
The operand types of an operator invocation are resolved following The specific operator to be used in an operator invocation is determined
by following
the procedure below. Note that this procedure is indirectly affected the procedure below. Note that this procedure is indirectly affected
by the precedence of the involved operators. See <xref by the precedence of the involved operators. See <xref
linkend="sql-precedence"> for more information. linkend="sql-precedence"> for more information.
</para> </para>
<procedure> <procedure>
<title>Operand Type Resolution</title> <title>Operator Type Resolution</title>
<step performance="required"> <step performance="required">
<para> <para>
...@@ -271,22 +273,16 @@ candidate remains, use it; else continue to the next step. ...@@ -271,22 +273,16 @@ candidate remains, use it; else continue to the next step.
<step performance="required"> <step performance="required">
<para> <para>
Run through all candidates and keep those with the most exact matches Run through all candidates and keep those with the most exact matches
on input types. Keep all candidates if none have any exact matches. on input types. (Domain types are considered the same as their base type
for this purpose.) Keep all candidates if none have any exact matches.
If only one candidate remains, use it; else continue to the next step. If only one candidate remains, use it; else continue to the next step.
</para> </para>
</step> </step>
<step performance="required"> <step performance="required">
<para> <para>
Run through all candidates and keep those with the most exact or Run through all candidates and keep those that accept preferred types (of the
binary-compatible matches on input types. Keep all candidates if none have input datatype's type category) at the most positions where type conversion
any exact or binary-compatible matches. will be required.
If only one candidate remains, use it; else continue to the next step.
</para>
</step>
<step performance="required">
<para>
Run through all candidates and keep those that accept preferred types at
the most positions where type conversion will be required.
Keep all candidates if none accept preferred types. Keep all candidates if none accept preferred types.
If only one candidate remains, use it; else continue to the next step. If only one candidate remains, use it; else continue to the next step.
</para> </para>
...@@ -295,12 +291,13 @@ If only one candidate remains, use it; else continue to the next step. ...@@ -295,12 +291,13 @@ If only one candidate remains, use it; else continue to the next step.
<para> <para>
If any input arguments are <type>unknown</type>, check the type If any input arguments are <type>unknown</type>, check the type
categories accepted at those argument positions by the remaining categories accepted at those argument positions by the remaining
candidates. At each position, select the <literal>string</literal> category if any candidates. At each position, select the <type>string</type> category
if any
candidate accepts that category. (This bias towards string is appropriate candidate accepts that category. (This bias towards string is appropriate
since an unknown-type literal does look like a string.) Otherwise, if since an unknown-type literal does look like a string.) Otherwise, if
all the remaining candidates accept the same type category, select that all the remaining candidates accept the same type category, select that
category; otherwise fail because the correct choice cannot be deduced category; otherwise fail because the correct choice cannot be deduced
without more clues. Now discard operator without more clues. Now discard
candidates that do not accept the selected type category. Furthermore, candidates that do not accept the selected type category. Furthermore,
if any candidate accepts a preferred type at a given argument position, if any candidate accepts a preferred type at a given argument position,
discard candidates that accept non-preferred types for that argument. discard candidates that accept non-preferred types for that argument.
...@@ -455,12 +452,12 @@ SELECT CAST('20' AS int8) ! AS "factorial"; ...@@ -455,12 +452,12 @@ SELECT CAST('20' AS int8) ! AS "factorial";
<title>Functions</title> <title>Functions</title>
<para> <para>
The argument types of function calls are resolved according to the The specific function to be used in a function invocation is determined
following steps. according to the following steps.
</para> </para>
<procedure> <procedure>
<title>Function Argument Type Resolution</title> <title>Function Type Resolution</title>
<step performance="required"> <step performance="required">
<para> <para>
...@@ -523,29 +520,24 @@ candidate remains, use it; else continue to the next step. ...@@ -523,29 +520,24 @@ candidate remains, use it; else continue to the next step.
<step performance="required"> <step performance="required">
<para> <para>
Run through all candidates and keep those with the most exact matches Run through all candidates and keep those with the most exact matches
on input types. Keep all candidates if none have any exact matches. on input types. (Domain types are considered the same as their base type
If only one candidate remains, use it; else continue to the next step. for this purpose.) Keep all candidates if none have any exact matches.
</para>
</step>
<step performance="required">
<para>
Run through all candidates and keep those with the most exact or
binary-compatible matches on input types. Keep all candidates if none have
any exact or binary-compatible matches.
If only one candidate remains, use it; else continue to the next step. If only one candidate remains, use it; else continue to the next step.
</para> </para>
</step> </step>
<step performance="required"> <step performance="required">
<para> <para>
Run through all candidates and keep those that accept preferred types at Run through all candidates and keep those that accept preferred types (of the
the most positions where type conversion will be required. input datatype's type category) at the most positions where type conversion
will be required.
Keep all candidates if none accept preferred types. Keep all candidates if none accept preferred types.
If only one candidate remains, use it; else continue to the next step. If only one candidate remains, use it; else continue to the next step.
</para> </para>
</step> </step>
<step performance="required"> <step performance="required">
<para> <para>
If any input arguments are <type>unknown</type>, check the type categories accepted If any input arguments are <type>unknown</type>, check the type categories
accepted
at those argument positions by the remaining candidates. At each position, at those argument positions by the remaining candidates. At each position,
select the <type>string</type> category if any candidate accepts that category. select the <type>string</type> category if any candidate accepts that category.
(This bias towards string (This bias towards string
...@@ -553,8 +545,8 @@ is appropriate since an unknown-type literal does look like a string.) ...@@ -553,8 +545,8 @@ is appropriate since an unknown-type literal does look like a string.)
Otherwise, if all the remaining candidates accept the same type category, Otherwise, if all the remaining candidates accept the same type category,
select that category; otherwise fail because select that category; otherwise fail because
the correct choice cannot be deduced without more clues. the correct choice cannot be deduced without more clues.
Now discard candidates that do not accept the selected type category; Now discard candidates that do not accept the selected type category.
furthermore, if any candidate accepts a preferred type at a given argument Furthermore, if any candidate accepts a preferred type at a given argument
position, discard candidates that accept non-preferred types for that position, discard candidates that accept non-preferred types for that
argument. argument.
</para> </para>
...@@ -571,6 +563,8 @@ then fail. ...@@ -571,6 +563,8 @@ then fail.
</procedure> </procedure>
<para> <para>
Note that the <quote>best match</> rules are identical for operator and
function type resolution.
Some examples follow. Some examples follow.
</para> </para>
...@@ -649,7 +643,8 @@ SELECT substr(CAST (varchar '1234' AS text), 3); ...@@ -649,7 +643,8 @@ SELECT substr(CAST (varchar '1234' AS text), 3);
<para> <para>
<note> <note>
<para> <para>
The parser is aware that <type>text</type> and <type>varchar</type> The parser learns from the <structname>pg_cast</> catalog that
<type>text</type> and <type>varchar</type>
are binary-compatible, meaning that one can be passed to a function that are binary-compatible, meaning that one can be passed to a function that
accepts the other without doing any physical conversion. Therefore, no accepts the other without doing any physical conversion. Therefore, no
explicit type conversion call is really inserted in this case. explicit type conversion call is really inserted in this case.
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.88 2003/02/15 20:12:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.89 2003/05/26 00:11:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -328,7 +328,7 @@ create_seqscan_path(Query *root, RelOptInfo *rel) ...@@ -328,7 +328,7 @@ create_seqscan_path(Query *root, RelOptInfo *rel)
* *
* 'rel' is the parent rel * 'rel' is the parent rel
* 'index' is an index on 'rel' * 'index' is an index on 'rel'
* 'restriction_clauses' is a list of RestrictInfo nodes * 'restriction_clauses' is a list of lists of RestrictInfo nodes
* to be used as index qual conditions in the scan. * to be used as index qual conditions in the scan.
* 'pathkeys' describes the ordering of the path. * 'pathkeys' describes the ordering of the path.
* 'indexscandir' is ForwardScanDirection or BackwardScanDirection * 'indexscandir' is ForwardScanDirection or BackwardScanDirection
...@@ -352,9 +352,8 @@ create_index_path(Query *root, ...@@ -352,9 +352,8 @@ create_index_path(Query *root,
pathnode->path.parent = rel; pathnode->path.parent = rel;
pathnode->path.pathkeys = pathkeys; pathnode->path.pathkeys = pathkeys;
indexquals = get_actual_clauses(restriction_clauses); /* Convert RestrictInfo nodes to indexquals the executor can handle */
/* expand special operators to indexquals the executor can handle */ indexquals = expand_indexqual_conditions(index, restriction_clauses);
indexquals = expand_indexqual_conditions(indexquals);
/* /*
* We are making a pathnode for a single-scan indexscan; therefore, * We are making a pathnode for a single-scan indexscan; therefore,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.96 2003/04/29 22:13:10 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.97 2003/05/26 00:11:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
static Node *coerce_type_typmod(Node *node, static Node *coerce_type_typmod(Node *node,
Oid targetTypeId, int32 targetTypMod, Oid targetTypeId, int32 targetTypMod,
CoercionForm cformat, bool isExplicit); CoercionForm cformat, bool isExplicit);
static Oid PreferredType(CATEGORY category, Oid type);
static Node *build_func_call(Oid funcid, Oid rettype, List *args, static Node *build_func_call(Oid funcid, Oid rettype, List *args,
CoercionForm fformat); CoercionForm fformat);
...@@ -66,28 +65,43 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, ...@@ -66,28 +65,43 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
if (can_coerce_type(1, &exprtype, &targettype, ccontext)) if (can_coerce_type(1, &exprtype, &targettype, ccontext))
expr = coerce_type(pstate, expr, exprtype, targettype, expr = coerce_type(pstate, expr, exprtype, targettype,
ccontext, cformat); ccontext, cformat);
/* else if (ccontext >= COERCION_ASSIGNMENT)
* String hacks to get transparent conversions for char and varchar:
* if a coercion to text is available, use it for forced coercions to
* char(n) or varchar(n).
*
* This is pretty grotty, but seems easier to maintain than providing
* entries in pg_cast that parallel all the ones for text.
*/
else if (ccontext >= COERCION_ASSIGNMENT &&
(targettype == BPCHAROID || targettype == VARCHAROID))
{ {
Oid text_id = TEXTOID; /*
* String hacks to get transparent conversions for char and varchar:
* if a coercion to text is available, use it for forced coercions to
* char(n) or varchar(n) or domains thereof.
*
* This is pretty grotty, but seems easier to maintain than providing
* entries in pg_cast that parallel all the ones for text.
*/
Oid targetbasetype = getBaseType(targettype);
if (can_coerce_type(1, &exprtype, &text_id, ccontext)) if (targetbasetype == BPCHAROID || targetbasetype == VARCHAROID)
{ {
expr = coerce_type(pstate, expr, exprtype, text_id, Oid text_id = TEXTOID;
ccontext, cformat);
/* Need a RelabelType if no typmod coercion is performed */ if (can_coerce_type(1, &exprtype, &text_id, ccontext))
if (targettypmod < 0) {
expr = (Node *) makeRelabelType((Expr *) expr, expr = coerce_type(pstate, expr, exprtype, text_id,
targettype, -1, ccontext, cformat);
cformat); if (targetbasetype != targettype)
{
/* need to coerce to domain over char or varchar */
expr = coerce_to_domain(expr, targetbasetype, targettype,
cformat);
}
else
{
/* need a RelabelType if no typmod coercion will be performed */
if (targettypmod < 0)
expr = (Node *) makeRelabelType((Expr *) expr,
targettype, -1,
cformat);
}
}
else
expr = NULL;
} }
else else
expr = NULL; expr = NULL;
...@@ -923,7 +937,10 @@ enforce_generic_type_consistency(Oid *actual_arg_types, ...@@ -923,7 +937,10 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
/* TypeCategory() /* TypeCategory()
* Assign a category to the specified OID. * Assign a category to the specified type OID.
*
* NB: this must not return INVALID_TYPE.
*
* XXX This should be moved to system catalog lookups * XXX This should be moved to system catalog lookups
* to allow for better type extensibility. * to allow for better type extensibility.
* - thomas 2001-09-30 * - thomas 2001-09-30
...@@ -1026,7 +1043,11 @@ TypeCategory(Oid inType) ...@@ -1026,7 +1043,11 @@ TypeCategory(Oid inType)
/* IsPreferredType() /* IsPreferredType()
* Check if this type is a preferred type. * Check if this type is a preferred type for the given category.
*
* If category is INVALID_TYPE, then we'll return TRUE for preferred types
* of any category; otherwise, only for preferred types of that category.
*
* XXX This should be moved to system catalog lookups * XXX This should be moved to system catalog lookups
* to allow for better type extensibility. * to allow for better type extensibility.
* - thomas 2001-09-30 * - thomas 2001-09-30
...@@ -1034,39 +1055,34 @@ TypeCategory(Oid inType) ...@@ -1034,39 +1055,34 @@ TypeCategory(Oid inType)
bool bool
IsPreferredType(CATEGORY category, Oid type) IsPreferredType(CATEGORY category, Oid type)
{ {
return (type == PreferredType(category, type)); Oid preftype;
} /* IsPreferredType() */
if (category == INVALID_TYPE)
category = TypeCategory(type);
else if (category != TypeCategory(type))
return false;
/* PreferredType() /*
* Return the preferred type OID for the specified category. * This switch should agree with TypeCategory(), above. Note that
* XXX This should be moved to system catalog lookups * at this point, category certainly matches the type.
* to allow for better type extensibility. */
* - thomas 2001-09-30
*/
static Oid
PreferredType(CATEGORY category, Oid type)
{
Oid result;
switch (category) switch (category)
{ {
case (INVALID_TYPE):
case (UNKNOWN_TYPE): case (UNKNOWN_TYPE):
case (GENERIC_TYPE): case (GENERIC_TYPE):
result = UNKNOWNOID; preftype = UNKNOWNOID;
break; break;
case (BOOLEAN_TYPE): case (BOOLEAN_TYPE):
result = BOOLOID; preftype = BOOLOID;
break; break;
case (STRING_TYPE): case (STRING_TYPE):
result = TEXTOID; preftype = TEXTOID;
break; break;
case (BITSTRING_TYPE): case (BITSTRING_TYPE):
result = VARBITOID; preftype = VARBITOID;
break; break;
case (NUMERIC_TYPE): case (NUMERIC_TYPE):
...@@ -1077,52 +1093,59 @@ PreferredType(CATEGORY category, Oid type) ...@@ -1077,52 +1093,59 @@ PreferredType(CATEGORY category, Oid type)
type == REGOPERATOROID || type == REGOPERATOROID ||
type == REGCLASSOID || type == REGCLASSOID ||
type == REGTYPEOID) type == REGTYPEOID)
result = OIDOID; preftype = OIDOID;
else else
result = FLOAT8OID; preftype = FLOAT8OID;
break; break;
case (DATETIME_TYPE): case (DATETIME_TYPE):
if (type == DATEOID) if (type == DATEOID)
result = TIMESTAMPOID; preftype = TIMESTAMPOID;
else else
result = TIMESTAMPTZOID; preftype = TIMESTAMPTZOID;
break; break;
case (TIMESPAN_TYPE): case (TIMESPAN_TYPE):
result = INTERVALOID; preftype = INTERVALOID;
break; break;
case (GEOMETRIC_TYPE): case (GEOMETRIC_TYPE):
result = type; preftype = type;
break; break;
case (NETWORK_TYPE): case (NETWORK_TYPE):
result = INETOID; preftype = INETOID;
break; break;
case (USER_TYPE): case (USER_TYPE):
result = type; preftype = type;
break; break;
default: default:
elog(ERROR, "PreferredType: unknown category"); elog(ERROR, "IsPreferredType: unknown category");
result = UNKNOWNOID; preftype = UNKNOWNOID;
break; break;
} }
return result;
} /* PreferredType() */ return (type == preftype);
} /* IsPreferredType() */
/* IsBinaryCoercible() /* IsBinaryCoercible()
* Check if srctype is binary-coercible to targettype. * Check if srctype is binary-coercible to targettype.
* *
* This notion allows us to cheat and directly exchange values without * This notion allows us to cheat and directly exchange values without
* going through the trouble of calling a conversion function. * going through the trouble of calling a conversion function. Note that
* in general, this should only be an implementation shortcut. Before 7.4,
* this was also used as a heuristic for resolving overloaded functions and
* operators, but that's basically a bad idea.
* *
* As of 7.3, binary coercibility isn't hardwired into the code anymore. * As of 7.3, binary coercibility isn't hardwired into the code anymore.
* We consider two types binary-coercible if there is an implicitly * We consider two types binary-coercible if there is an implicitly
* invokable, no-function-needed pg_cast entry. * invokable, no-function-needed pg_cast entry. Also, a domain is always
* binary-coercible to its base type, though *not* vice versa (in the other
* direction, one must apply domain constraint checks before accepting the
* value as legitimate).
* *
* This function replaces IsBinaryCompatible(), which was an inherently * This function replaces IsBinaryCompatible(), which was an inherently
* symmetric test. Since the pg_cast entries aren't necessarily symmetric, * symmetric test. Since the pg_cast entries aren't necessarily symmetric,
...@@ -1139,13 +1162,11 @@ IsBinaryCoercible(Oid srctype, Oid targettype) ...@@ -1139,13 +1162,11 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
if (srctype == targettype) if (srctype == targettype)
return true; return true;
/* Perhaps the types are domains; if so, look at their base types */ /* If srctype is a domain, reduce to its base type */
if (OidIsValid(srctype)) if (OidIsValid(srctype))
srctype = getBaseType(srctype); srctype = getBaseType(srctype);
if (OidIsValid(targettype))
targettype = getBaseType(targettype);
/* Somewhat-fast path if same base type */ /* Somewhat-fast path for domain -> base type case */
if (srctype == targettype) if (srctype == targettype)
return true; return true;
...@@ -1174,8 +1195,13 @@ IsBinaryCoercible(Oid srctype, Oid targettype) ...@@ -1174,8 +1195,13 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
* ccontext determines the set of available casts. * ccontext determines the set of available casts.
* *
* If we find a suitable entry in pg_cast, return TRUE, and set *funcid * If we find a suitable entry in pg_cast, return TRUE, and set *funcid
* to the castfunc value (which may be InvalidOid for a binary-compatible * to the castfunc value, which may be InvalidOid for a binary-compatible
* coercion). * coercion.
*
* NOTE: *funcid == InvalidOid does not necessarily mean that no work is
* needed to do the coercion; if the target is a domain then we may need to
* apply domain constraint checking. If you want to check for a zero-effort
* conversion then use IsBinaryCoercible().
*/ */
bool bool
find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
...@@ -1193,7 +1219,7 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, ...@@ -1193,7 +1219,7 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
if (OidIsValid(targetTypeId)) if (OidIsValid(targetTypeId))
targetTypeId = getBaseType(targetTypeId); targetTypeId = getBaseType(targetTypeId);
/* Domains are automatically binary-compatible with their base type */ /* Domains are always coercible to and from their base type */
if (sourceTypeId == targetTypeId) if (sourceTypeId == targetTypeId)
return true; return true;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.96 2003/05/12 23:08:50 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.97 2003/05/26 00:11:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -343,7 +343,10 @@ name_bpchar(PG_FUNCTION_ARGS) ...@@ -343,7 +343,10 @@ name_bpchar(PG_FUNCTION_ARGS)
/***************************************************************************** /*****************************************************************************
* varchar - varchar() * * varchar - varchar(n)
*
* Note: varchar piggybacks on type text for most operations, and so has no
* C-coded functions except for I/O and typmod checking.
*****************************************************************************/ *****************************************************************************/
/* /*
...@@ -700,7 +703,7 @@ bpcharcmp(PG_FUNCTION_ARGS) ...@@ -700,7 +703,7 @@ bpcharcmp(PG_FUNCTION_ARGS)
/* /*
* bpchar needs a specialized hash function because we want to ignore * bpchar needs a specialized hash function because we want to ignore
* trailing blanks in comparisons. (varchar can use plain hashvarlena.) * trailing blanks in comparisons.
*/ */
Datum Datum
hashbpchar(PG_FUNCTION_ARGS) hashbpchar(PG_FUNCTION_ARGS)
...@@ -720,187 +723,3 @@ hashbpchar(PG_FUNCTION_ARGS) ...@@ -720,187 +723,3 @@ hashbpchar(PG_FUNCTION_ARGS)
return result; return result;
} }
/*****************************************************************************
* Functions used for varchar
*****************************************************************************/
Datum
varcharlen(PG_FUNCTION_ARGS)
{
VarChar *arg = PG_GETARG_VARCHAR_P(0);
/* optimization for single byte encoding */
if (pg_database_encoding_max_length() <= 1)
PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
PG_RETURN_INT32(
pg_mbstrlen_with_len(VARDATA(arg), VARSIZE(arg) - VARHDRSZ)
);
}
Datum
varcharoctetlen(PG_FUNCTION_ARGS)
{
VarChar *arg = PG_GETARG_VARCHAR_P(0);
PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
}
/*****************************************************************************
* Comparison Functions used for varchar
*
* Note: btree indexes need these routines not to leak memory; therefore,
* be careful to free working copies of toasted datums. Most places don't
* need to be so careful.
*****************************************************************************/
Datum
varchareq(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
bool result;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
/* fast path for different-length inputs */
if (len1 != len2)
result = false;
else
result = (varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2) == 0);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
Datum
varcharne(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
bool result;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
/* fast path for different-length inputs */
if (len1 != len2)
result = true;
else
result = (varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2) != 0);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
Datum
varcharlt(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp < 0);
}
Datum
varcharle(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp <= 0);
}
Datum
varchargt(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp > 0);
}
Datum
varcharge(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp >= 0);
}
Datum
varcharcmp(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_INT32(cmp);
}
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.94 2003/05/13 04:38:58 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.95 2003/05/26 00:11:27 tgl Exp $
* *
* NOTES * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
...@@ -80,6 +80,33 @@ op_requires_recheck(Oid opno, Oid opclass) ...@@ -80,6 +80,33 @@ op_requires_recheck(Oid opno, Oid opclass)
return result; return result;
} }
/*
* get_opclass_member
* Get the OID of the operator that implements the specified strategy
* for the specified opclass.
*
* Returns InvalidOid if there is no pg_amop entry for the given keys.
*/
Oid
get_opclass_member(Oid opclass, int16 strategy)
{
HeapTuple tp;
Form_pg_amop amop_tup;
Oid result;
tp = SearchSysCache(AMOPSTRATEGY,
ObjectIdGetDatum(opclass),
Int16GetDatum(strategy),
0, 0);
if (!HeapTupleIsValid(tp))
return InvalidOid;
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
result = amop_tup->amopopr;
ReleaseSysCache(tp);
return result;
}
/* ---------- ATTRIBUTE CACHES ---------- */ /* ---------- ATTRIBUTE CACHES ---------- */
/* /*
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.195 2003/05/23 22:33:22 tgl Exp $ * $Id: catversion.h,v 1.196 2003/05/26 00:11:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200305231 #define CATALOG_VERSION_NO 200305241
#endif #endif
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_amop.h,v 1.48 2003/05/15 15:50:19 petere Exp $ * $Id: pg_amop.h,v 1.49 2003/05/26 00:11:27 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -219,14 +219,14 @@ DATA(insert ( 426 4 f 1061 )); ...@@ -219,14 +219,14 @@ DATA(insert ( 426 4 f 1061 ));
DATA(insert ( 426 5 f 1060 )); DATA(insert ( 426 5 f 1060 ));
/* /*
* btree varchar_ops * btree varchar_ops (same operators as text_ops)
*/ */
DATA(insert ( 2003 1 f 1066 )); DATA(insert ( 2003 1 f 664 ));
DATA(insert ( 2003 2 f 1067 )); DATA(insert ( 2003 2 f 665 ));
DATA(insert ( 2003 3 f 1062 )); DATA(insert ( 2003 3 f 98 ));
DATA(insert ( 2003 4 f 1069 )); DATA(insert ( 2003 4 f 667 ));
DATA(insert ( 2003 5 f 1068 )); DATA(insert ( 2003 5 f 666 ));
/* /*
* btree bytea_ops * btree bytea_ops
...@@ -389,14 +389,14 @@ DATA(insert ( 2095 4 f 2317 )); ...@@ -389,14 +389,14 @@ DATA(insert ( 2095 4 f 2317 ));
DATA(insert ( 2095 5 f 2318 )); DATA(insert ( 2095 5 f 2318 ));
/* /*
* btree varchar pattern * btree varchar pattern (same operators as text)
*/ */
DATA(insert ( 2096 1 f 2320 )); DATA(insert ( 2096 1 f 2314 ));
DATA(insert ( 2096 2 f 2321 )); DATA(insert ( 2096 2 f 2315 ));
DATA(insert ( 2096 3 f 2322 )); DATA(insert ( 2096 3 f 2316 ));
DATA(insert ( 2096 4 f 2323 )); DATA(insert ( 2096 4 f 2317 ));
DATA(insert ( 2096 5 f 2324 )); DATA(insert ( 2096 5 f 2318 ));
/* /*
* btree bpchar pattern * btree bpchar pattern
...@@ -462,7 +462,7 @@ DATA(insert ( 1999 1 f 1320 )); ...@@ -462,7 +462,7 @@ DATA(insert ( 1999 1 f 1320 ));
/* timetz_ops */ /* timetz_ops */
DATA(insert ( 2001 1 f 1550 )); DATA(insert ( 2001 1 f 1550 ));
/* varchar_ops */ /* varchar_ops */
DATA(insert ( 2004 1 f 1062 )); DATA(insert ( 2004 1 f 98 ));
/* timestamp_ops */ /* timestamp_ops */
DATA(insert ( 2040 1 f 2060 )); DATA(insert ( 2040 1 f 2060 ));
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_amproc.h,v 1.36 2003/05/15 15:50:19 petere Exp $ * $Id: pg_amproc.h,v 1.37 2003/05/26 00:11:27 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -103,10 +103,10 @@ DATA(insert ( 1996 1 1107 )); ...@@ -103,10 +103,10 @@ DATA(insert ( 1996 1 1107 ));
DATA(insert ( 1998 1 1314 )); DATA(insert ( 1998 1 1314 ));
DATA(insert ( 2000 1 1358 )); DATA(insert ( 2000 1 1358 ));
DATA(insert ( 2002 1 1672 )); DATA(insert ( 2002 1 1672 ));
DATA(insert ( 2003 1 1079 )); DATA(insert ( 2003 1 360 ));
DATA(insert ( 2039 1 1314 )); DATA(insert ( 2039 1 2045 ));
DATA(insert ( 2095 1 2166 )); DATA(insert ( 2095 1 2166 ));
DATA(insert ( 2096 1 2173 )); DATA(insert ( 2096 1 2166 ));
DATA(insert ( 2097 1 2180 )); DATA(insert ( 2097 1 2180 ));
DATA(insert ( 2098 1 2187 )); DATA(insert ( 2098 1 2187 ));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Copyright (c) 2002, PostgreSQL Global Development Group * Copyright (c) 2002, PostgreSQL Global Development Group
* *
* $Id: pg_cast.h,v 1.6 2003/05/14 18:08:15 tgl Exp $ * $Id: pg_cast.h,v 1.7 2003/05/26 00:11:27 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -161,8 +161,8 @@ DATA(insert ( 2206 23 0 a )); ...@@ -161,8 +161,8 @@ DATA(insert ( 2206 23 0 a ));
*/ */
DATA(insert ( 25 1042 0 i )); DATA(insert ( 25 1042 0 i ));
DATA(insert ( 25 1043 0 i )); DATA(insert ( 25 1043 0 i ));
DATA(insert ( 1042 25 0 i )); DATA(insert ( 1042 25 401 i ));
DATA(insert ( 1042 1043 0 i )); DATA(insert ( 1042 1043 401 i ));
DATA(insert ( 1043 25 0 i )); DATA(insert ( 1043 25 0 i ));
DATA(insert ( 1043 1042 0 i )); DATA(insert ( 1043 1042 0 i ));
DATA(insert ( 18 25 946 i )); DATA(insert ( 18 25 946 i ));
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* of opclass name and index access method type. This row specifies the * of opclass name and index access method type. This row specifies the
* expected input data type for the opclass (the type of the heap column, * expected input data type for the opclass (the type of the heap column,
* or the function output type in the case of a functional index). Note * or the function output type in the case of a functional index). Note
* that types binary-compatible with the specified type will be accepted too. * that types binary-coercible to the specified type will be accepted too.
* *
* For a given <opcamid, opcintype> pair, there can be at most one row that * For a given <opcamid, opcintype> pair, there can be at most one row that
* has opcdefault = true; this row is the default opclass for such data in * has opcdefault = true; this row is the default opclass for such data in
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_opclass.h,v 1.48 2003/05/15 15:50:19 petere Exp $ * $Id: pg_opclass.h,v 1.49 2003/05/26 00:11:27 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -92,11 +92,14 @@ DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 )); ...@@ -92,11 +92,14 @@ DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 ));
DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 )); DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 ));
DATA(insert OID = 425 ( 402 box_ops PGNSP PGUID 603 t 0 )); DATA(insert OID = 425 ( 402 box_ops PGNSP PGUID 603 t 0 ));
DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID 1042 t 0 )); DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID 1042 t 0 ));
#define BPCHAR_BTREE_OPS_OID 426
DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID 1042 t 0 )); DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID 1042 t 0 ));
DATA(insert OID = 428 ( 403 bytea_ops PGNSP PGUID 17 t 0 )); DATA(insert OID = 428 ( 403 bytea_ops PGNSP PGUID 17 t 0 ));
#define BYTEA_BTREE_OPS_OID 428
DATA(insert OID = 429 ( 403 char_ops PGNSP PGUID 18 t 0 )); DATA(insert OID = 429 ( 403 char_ops PGNSP PGUID 18 t 0 ));
DATA(insert OID = 431 ( 405 char_ops PGNSP PGUID 18 t 0 )); DATA(insert OID = 431 ( 405 char_ops PGNSP PGUID 18 t 0 ));
DATA(insert OID = 432 ( 403 cidr_ops PGNSP PGUID 650 t 0 )); DATA(insert OID = 432 ( 403 cidr_ops PGNSP PGUID 650 t 0 ));
#define CIDR_BTREE_OPS_OID 432
DATA(insert OID = 433 ( 405 cidr_ops PGNSP PGUID 650 t 0 )); DATA(insert OID = 433 ( 405 cidr_ops PGNSP PGUID 650 t 0 ));
DATA(insert OID = 434 ( 403 date_ops PGNSP PGUID 1082 t 0 )); DATA(insert OID = 434 ( 403 date_ops PGNSP PGUID 1082 t 0 ));
DATA(insert OID = 435 ( 405 date_ops PGNSP PGUID 1082 t 0 )); DATA(insert OID = 435 ( 405 date_ops PGNSP PGUID 1082 t 0 ));
...@@ -105,6 +108,7 @@ DATA(insert OID = 1971 ( 405 float4_ops PGNSP PGUID 700 t 0 )); ...@@ -105,6 +108,7 @@ DATA(insert OID = 1971 ( 405 float4_ops PGNSP PGUID 700 t 0 ));
DATA(insert OID = 1972 ( 403 float8_ops PGNSP PGUID 701 t 0 )); DATA(insert OID = 1972 ( 403 float8_ops PGNSP PGUID 701 t 0 ));
DATA(insert OID = 1973 ( 405 float8_ops PGNSP PGUID 701 t 0 )); DATA(insert OID = 1973 ( 405 float8_ops PGNSP PGUID 701 t 0 ));
DATA(insert OID = 1974 ( 403 inet_ops PGNSP PGUID 869 t 0 )); DATA(insert OID = 1974 ( 403 inet_ops PGNSP PGUID 869 t 0 ));
#define INET_BTREE_OPS_OID 1974
DATA(insert OID = 1975 ( 405 inet_ops PGNSP PGUID 869 t 0 )); DATA(insert OID = 1975 ( 405 inet_ops PGNSP PGUID 869 t 0 ));
DATA(insert OID = 1976 ( 403 int2_ops PGNSP PGUID 21 t 0 )); DATA(insert OID = 1976 ( 403 int2_ops PGNSP PGUID 21 t 0 ));
#define INT2_BTREE_OPS_OID 1976 #define INT2_BTREE_OPS_OID 1976
...@@ -119,6 +123,7 @@ DATA(insert OID = 1983 ( 405 interval_ops PGNSP PGUID 1186 t 0 )); ...@@ -119,6 +123,7 @@ DATA(insert OID = 1983 ( 405 interval_ops PGNSP PGUID 1186 t 0 ));
DATA(insert OID = 1984 ( 403 macaddr_ops PGNSP PGUID 829 t 0 )); DATA(insert OID = 1984 ( 403 macaddr_ops PGNSP PGUID 829 t 0 ));
DATA(insert OID = 1985 ( 405 macaddr_ops PGNSP PGUID 829 t 0 )); DATA(insert OID = 1985 ( 405 macaddr_ops PGNSP PGUID 829 t 0 ));
DATA(insert OID = 1986 ( 403 name_ops PGNSP PGUID 19 t 0 )); DATA(insert OID = 1986 ( 403 name_ops PGNSP PGUID 19 t 0 ));
#define NAME_BTREE_OPS_OID 1986
DATA(insert OID = 1987 ( 405 name_ops PGNSP PGUID 19 t 0 )); DATA(insert OID = 1987 ( 405 name_ops PGNSP PGUID 19 t 0 ));
DATA(insert OID = 1988 ( 403 numeric_ops PGNSP PGUID 1700 t 0 )); DATA(insert OID = 1988 ( 403 numeric_ops PGNSP PGUID 1700 t 0 ));
DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID 26 t 0 )); DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID 26 t 0 ));
...@@ -128,6 +133,7 @@ DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID 30 t 0 )); ...@@ -128,6 +133,7 @@ DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID 30 t 0 ));
DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID 30 t 0 )); DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID 30 t 0 ));
DATA(insert OID = 1993 ( 402 poly_ops PGNSP PGUID 604 t 0 )); DATA(insert OID = 1993 ( 402 poly_ops PGNSP PGUID 604 t 0 ));
DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID 25 t 0 )); DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID 25 t 0 ));
#define TEXT_BTREE_OPS_OID 1994
DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID 25 t 0 )); DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID 25 t 0 ));
DATA(insert OID = 1996 ( 403 time_ops PGNSP PGUID 1083 t 0 )); DATA(insert OID = 1996 ( 403 time_ops PGNSP PGUID 1083 t 0 ));
DATA(insert OID = 1997 ( 405 time_ops PGNSP PGUID 1083 t 0 )); DATA(insert OID = 1997 ( 405 time_ops PGNSP PGUID 1083 t 0 ));
...@@ -137,12 +143,17 @@ DATA(insert OID = 2000 ( 403 timetz_ops PGNSP PGUID 1266 t 0 )); ...@@ -137,12 +143,17 @@ DATA(insert OID = 2000 ( 403 timetz_ops PGNSP PGUID 1266 t 0 ));
DATA(insert OID = 2001 ( 405 timetz_ops PGNSP PGUID 1266 t 0 )); DATA(insert OID = 2001 ( 405 timetz_ops PGNSP PGUID 1266 t 0 ));
DATA(insert OID = 2002 ( 403 varbit_ops PGNSP PGUID 1562 t 0 )); DATA(insert OID = 2002 ( 403 varbit_ops PGNSP PGUID 1562 t 0 ));
DATA(insert OID = 2003 ( 403 varchar_ops PGNSP PGUID 1043 t 0 )); DATA(insert OID = 2003 ( 403 varchar_ops PGNSP PGUID 1043 t 0 ));
#define VARCHAR_BTREE_OPS_OID 2003
DATA(insert OID = 2004 ( 405 varchar_ops PGNSP PGUID 1043 t 0 )); DATA(insert OID = 2004 ( 405 varchar_ops PGNSP PGUID 1043 t 0 ));
DATA(insert OID = 2039 ( 403 timestamp_ops PGNSP PGUID 1114 t 0 )); DATA(insert OID = 2039 ( 403 timestamp_ops PGNSP PGUID 1114 t 0 ));
DATA(insert OID = 2040 ( 405 timestamp_ops PGNSP PGUID 1114 t 0 )); DATA(insert OID = 2040 ( 405 timestamp_ops PGNSP PGUID 1114 t 0 ));
DATA(insert OID = 2095 ( 403 text_pattern_ops PGNSP PGUID 25 f 0 )); DATA(insert OID = 2095 ( 403 text_pattern_ops PGNSP PGUID 25 f 0 ));
#define TEXT_PATTERN_BTREE_OPS_OID 2095
DATA(insert OID = 2096 ( 403 varchar_pattern_ops PGNSP PGUID 1043 f 0 )); DATA(insert OID = 2096 ( 403 varchar_pattern_ops PGNSP PGUID 1043 f 0 ));
#define VARCHAR_PATTERN_BTREE_OPS_OID 2096
DATA(insert OID = 2097 ( 403 bpchar_pattern_ops PGNSP PGUID 1042 f 0 )); DATA(insert OID = 2097 ( 403 bpchar_pattern_ops PGNSP PGUID 1042 f 0 ));
#define BPCHAR_PATTERN_BTREE_OPS_OID 2097
DATA(insert OID = 2098 ( 403 name_pattern_ops PGNSP PGUID 19 f 0 )); DATA(insert OID = 2098 ( 403 name_pattern_ops PGNSP PGUID 19 f 0 ));
#define NAME_PATTERN_BTREE_OPS_OID 2098
#endif /* PG_OPCLASS_H */ #endif /* PG_OPCLASS_H */
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: paths.h,v 1.66 2003/02/15 20:12:41 tgl Exp $ * $Id: paths.h,v 1.67 2003/05/26 00:11:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -41,7 +41,8 @@ extern Path *best_inner_indexscan(Query *root, RelOptInfo *rel, ...@@ -41,7 +41,8 @@ extern Path *best_inner_indexscan(Query *root, RelOptInfo *rel,
extern List *extract_or_indexqual_conditions(RelOptInfo *rel, extern List *extract_or_indexqual_conditions(RelOptInfo *rel,
IndexOptInfo *index, IndexOptInfo *index,
Expr *orsubclause); Expr *orsubclause);
extern List *expand_indexqual_conditions(List *indexquals); extern List *expand_indexqual_conditions(IndexOptInfo *index,
List *clausegroups);
/* /*
* orindxpath.c * orindxpath.c
......
...@@ -7,13 +7,14 @@ ...@@ -7,13 +7,14 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parse_func.h,v 1.45 2003/04/29 22:13:11 tgl Exp $ * $Id: parse_func.h,v 1.46 2003/05/26 00:11:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef PARSER_FUNC_H #ifndef PARSER_FUNC_H
#define PARSER_FUNC_H #define PARSER_FUNC_H
#include "catalog/namespace.h"
#include "parser/parse_node.h" #include "parser/parse_node.h"
...@@ -48,6 +49,15 @@ extern FuncDetailCode func_get_detail(List *funcname, List *fargs, ...@@ -48,6 +49,15 @@ extern FuncDetailCode func_get_detail(List *funcname, List *fargs,
Oid *funcid, Oid *rettype, Oid *funcid, Oid *rettype,
bool *retset, Oid **true_typeids); bool *retset, Oid **true_typeids);
extern int func_match_argtypes(int nargs,
Oid *input_typeids,
FuncCandidateList raw_candidates,
FuncCandidateList *candidates);
extern FuncCandidateList func_select_candidate(int nargs,
Oid *input_typeids,
FuncCandidateList candidates);
extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId); extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);
extern void make_fn_arguments(ParseState *pstate, extern void make_fn_arguments(ParseState *pstate,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: builtins.h,v 1.218 2003/05/23 22:33:23 tgl Exp $ * $Id: builtins.h,v 1.219 2003/05/26 00:11:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -496,15 +496,6 @@ extern Datum varcharout(PG_FUNCTION_ARGS); ...@@ -496,15 +496,6 @@ extern Datum varcharout(PG_FUNCTION_ARGS);
extern Datum varcharrecv(PG_FUNCTION_ARGS); extern Datum varcharrecv(PG_FUNCTION_ARGS);
extern Datum varcharsend(PG_FUNCTION_ARGS); extern Datum varcharsend(PG_FUNCTION_ARGS);
extern Datum varchar(PG_FUNCTION_ARGS); extern Datum varchar(PG_FUNCTION_ARGS);
extern Datum varchareq(PG_FUNCTION_ARGS);
extern Datum varcharne(PG_FUNCTION_ARGS);
extern Datum varcharlt(PG_FUNCTION_ARGS);
extern Datum varcharle(PG_FUNCTION_ARGS);
extern Datum varchargt(PG_FUNCTION_ARGS);
extern Datum varcharge(PG_FUNCTION_ARGS);
extern Datum varcharcmp(PG_FUNCTION_ARGS);
extern Datum varcharlen(PG_FUNCTION_ARGS);
extern Datum varcharoctetlen(PG_FUNCTION_ARGS);
/* varlena.c */ /* varlena.c */
extern Datum textin(PG_FUNCTION_ARGS); extern Datum textin(PG_FUNCTION_ARGS);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: lsyscache.h,v 1.69 2003/05/09 18:08:48 tgl Exp $ * $Id: lsyscache.h,v 1.70 2003/05/26 00:11:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
extern bool op_in_opclass(Oid opno, Oid opclass); extern bool op_in_opclass(Oid opno, Oid opclass);
extern bool op_requires_recheck(Oid opno, Oid opclass); extern bool op_requires_recheck(Oid opno, Oid opclass);
extern Oid get_opclass_member(Oid opclass, int16 strategy);
extern char *get_attname(Oid relid, AttrNumber attnum); extern char *get_attname(Oid relid, AttrNumber attnum);
extern AttrNumber get_attnum(Oid relid, const char *attname); extern AttrNumber get_attnum(Oid relid, const char *attname);
extern Oid get_atttype(Oid relid, AttrNumber attnum); extern Oid get_atttype(Oid relid, AttrNumber attnum);
......
...@@ -27,7 +27,7 @@ INSERT INTO NAME_TBL(f1) VALUES ('d34aaasdf'); ...@@ -27,7 +27,7 @@ INSERT INTO NAME_TBL(f1) VALUES ('d34aaasdf');
INSERT INTO NAME_TBL(f1) VALUES (''); INSERT INTO NAME_TBL(f1) VALUES ('');
INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'); INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ');
SELECT '' AS seven, NAME_TBL.*; SELECT '' AS seven, NAME_TBL.*;
seven | f1 seven | f1
-------+----------------------------------------------------------------- -------+-----------------------------------------------------------------
| 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ | 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ
| 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq | 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq
...@@ -39,7 +39,7 @@ SELECT '' AS seven, NAME_TBL.*; ...@@ -39,7 +39,7 @@ SELECT '' AS seven, NAME_TBL.*;
(7 rows) (7 rows)
SELECT '' AS six, c.f1 FROM NAME_TBL c WHERE c.f1 <> '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; SELECT '' AS six, c.f1 FROM NAME_TBL c WHERE c.f1 <> '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR';
six | f1 six | f1
-----+----------------------------------------------------------------- -----+-----------------------------------------------------------------
| 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq | 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq
| asdfghjkl; | asdfghjkl;
...@@ -49,20 +49,20 @@ SELECT '' AS six, c.f1 FROM NAME_TBL c WHERE c.f1 <> '1234567890ABCDEFGHIJKLMNOP ...@@ -49,20 +49,20 @@ SELECT '' AS six, c.f1 FROM NAME_TBL c WHERE c.f1 <> '1234567890ABCDEFGHIJKLMNOP
(5 rows) (5 rows)
SELECT '' AS one, c.f1 FROM NAME_TBL c WHERE c.f1 = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; SELECT '' AS one, c.f1 FROM NAME_TBL c WHERE c.f1 = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR';
one | f1 one | f1
-----+----------------------------------------------------------------- -----+-----------------------------------------------------------------
| 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ | 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ
| 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ | 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ
(2 rows) (2 rows)
SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 < '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 < '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR';
three | f1 three | f1
-------+---- -------+----
| |
(1 row) (1 row)
SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 <= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 <= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR';
four | f1 four | f1
------+----------------------------------------------------------------- ------+-----------------------------------------------------------------
| 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ | 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ
| |
...@@ -70,7 +70,7 @@ SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 <= '1234567890ABCDEFGHIJKLMNO ...@@ -70,7 +70,7 @@ SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 <= '1234567890ABCDEFGHIJKLMNO
(3 rows) (3 rows)
SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 > '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 > '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR';
three | f1 three | f1
-------+----------------------------------------------------------------- -------+-----------------------------------------------------------------
| 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq | 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq
| asdfghjkl; | asdfghjkl;
...@@ -79,7 +79,7 @@ SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 > '1234567890ABCDEFGHIJKLMNO ...@@ -79,7 +79,7 @@ SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 > '1234567890ABCDEFGHIJKLMNO
(4 rows) (4 rows)
SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 >= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 >= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR';
four | f1 four | f1
------+----------------------------------------------------------------- ------+-----------------------------------------------------------------
| 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ | 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ
| 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq | 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq
...@@ -90,7 +90,7 @@ SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 >= '1234567890ABCDEFGHIJKLMNO ...@@ -90,7 +90,7 @@ SELECT '' AS four, c.f1 FROM NAME_TBL c WHERE c.f1 >= '1234567890ABCDEFGHIJKLMNO
(6 rows) (6 rows)
SELECT '' AS seven, c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*'; SELECT '' AS seven, c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*';
seven | f1 seven | f1
-------+----------------------------------------------------------------- -------+-----------------------------------------------------------------
| 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ | 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ
| 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq | 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq
...@@ -107,7 +107,7 @@ SELECT '' AS zero, c.f1 FROM NAME_TBL c WHERE c.f1 !~ '.*'; ...@@ -107,7 +107,7 @@ SELECT '' AS zero, c.f1 FROM NAME_TBL c WHERE c.f1 !~ '.*';
(0 rows) (0 rows)
SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 ~ '[0-9]'; SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 ~ '[0-9]';
three | f1 three | f1
-------+----------------------------------------------------------------- -------+-----------------------------------------------------------------
| 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ | 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQ
| 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq | 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopq
......
This diff is collapsed.
...@@ -1317,9 +1317,9 @@ SELECT tablename, rulename, definition FROM pg_rules ...@@ -1317,9 +1317,9 @@ SELECT tablename, rulename, definition FROM pg_rules
---------------+-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pg_settings | pg_settings_n | CREATE RULE pg_settings_n AS ON UPDATE TO pg_settings DO INSTEAD NOTHING; pg_settings | pg_settings_n | CREATE RULE pg_settings_n AS ON UPDATE TO pg_settings DO INSTEAD NOTHING;
pg_settings | pg_settings_u | CREATE RULE pg_settings_u AS ON UPDATE TO pg_settings WHERE (new.name = old.name) DO SELECT set_config(old.name, new.setting, false) AS set_config; pg_settings | pg_settings_u | CREATE RULE pg_settings_u AS ON UPDATE TO pg_settings WHERE (new.name = old.name) DO SELECT set_config(old.name, new.setting, false) AS set_config;
rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired '::bpchar, '$0.00'::money, old.salary); rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired'::bpchar, '$0.00'::money, old.salary);
rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired '::bpchar, new.salary, '$0.00'::money); rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired'::bpchar, new.salary, '$0.00'::money);
rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored '::bpchar, new.salary, old.salary); rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored'::bpchar, new.salary, old.salary);
rtest_nothn1 | rtest_nothn_r1 | CREATE RULE rtest_nothn_r1 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 10) AND (new.a < 20)) DO INSTEAD NOTHING; rtest_nothn1 | rtest_nothn_r1 | CREATE RULE rtest_nothn_r1 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 10) AND (new.a < 20)) DO INSTEAD NOTHING;
rtest_nothn1 | rtest_nothn_r2 | CREATE RULE rtest_nothn_r2 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 30) AND (new.a < 40)) DO INSTEAD NOTHING; rtest_nothn1 | rtest_nothn_r2 | CREATE RULE rtest_nothn_r2 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 30) AND (new.a < 40)) DO INSTEAD NOTHING;
rtest_nothn2 | rtest_nothn_r3 | CREATE RULE rtest_nothn_r3 AS ON INSERT TO rtest_nothn2 WHERE (new.a >= 100) DO INSTEAD INSERT INTO rtest_nothn3 (a, b) VALUES (new.a, new.b); rtest_nothn2 | rtest_nothn_r3 | CREATE RULE rtest_nothn_r3 AS ON INSERT TO rtest_nothn2 WHERE (new.a >= 100) DO INSTEAD INSERT INTO rtest_nothn3 (a, b) VALUES (new.a, new.b);
......
...@@ -33,11 +33,11 @@ SELECT b, c FROM test_having ...@@ -33,11 +33,11 @@ SELECT b, c FROM test_having
SELECT lower(c), count(c) FROM test_having SELECT lower(c), count(c) FROM test_having
GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a) GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a)
ORDER BY lower(c); ORDER BY lower(c);
lower | count lower | count
----------+------- -------+-------
bbbb | 3 bbbb | 3
cccc | 4 cccc | 4
xxxx | 1 xxxx | 1
(3 rows) (3 rows)
SELECT c, max(a) FROM test_having SELECT c, max(a) FROM test_having
......
...@@ -33,11 +33,11 @@ SELECT b, c FROM test_having ...@@ -33,11 +33,11 @@ SELECT b, c FROM test_having
SELECT lower(c), count(c) FROM test_having SELECT lower(c), count(c) FROM test_having
GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a) GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a)
ORDER BY lower(c); ORDER BY lower(c);
lower | count lower | count
----------+------- -------+-------
bbbb | 3 bbbb | 3
cccc | 4 cccc | 4
xxxx | 1 xxxx | 1
(3 rows) (3 rows)
SELECT c, max(a) FROM test_having SELECT c, max(a) FROM test_having
......
...@@ -248,12 +248,12 @@ SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2; ...@@ -248,12 +248,12 @@ SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2;
-- w/ existing GROUP BY target using a relation name in target -- w/ existing GROUP BY target using a relation name in target
SELECT lower(test_missing_target.c), count(c) SELECT lower(test_missing_target.c), count(c)
FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c); FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c);
lower | count lower | count
----------+------- -------+-------
aaaa | 2 aaaa | 2
bbbb | 3 bbbb | 3
cccc | 4 cccc | 4
xxxx | 1 xxxx | 1
(4 rows) (4 rows)
-- w/o existing GROUP BY target -- w/o existing GROUP BY target
......
...@@ -248,12 +248,12 @@ SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2; ...@@ -248,12 +248,12 @@ SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2;
-- w/ existing GROUP BY target using a relation name in target -- w/ existing GROUP BY target using a relation name in target
SELECT lower(test_missing_target.c), count(c) SELECT lower(test_missing_target.c), count(c)
FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c); FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c);
lower | count lower | count
----------+------- -------+-------
aaaa | 2 aaaa | 2
bbbb | 3 bbbb | 3
cccc | 4 cccc | 4
xxxx | 1 xxxx | 1
(4 rows) (4 rows)
-- w/o existing GROUP BY target -- w/o existing GROUP BY target
......
...@@ -26,8 +26,8 @@ ERROR: parser: parse error at or near "' - third line'" at character 75 ...@@ -26,8 +26,8 @@ ERROR: parser: parse error at or near "' - third line'" at character 75
SELECT CAST(f1 AS text) AS "text(char)" FROM CHAR_TBL; SELECT CAST(f1 AS text) AS "text(char)" FROM CHAR_TBL;
text(char) text(char)
------------ ------------
a a
ab ab
abcd abcd
abcd abcd
(4 rows) (4 rows)
...@@ -88,8 +88,8 @@ SELECT CAST(f1 AS varchar) AS "varchar(text)" FROM TEXT_TBL; ...@@ -88,8 +88,8 @@ SELECT CAST(f1 AS varchar) AS "varchar(text)" FROM TEXT_TBL;
SELECT CAST(f1 AS varchar) AS "varchar(char)" FROM CHAR_TBL; SELECT CAST(f1 AS varchar) AS "varchar(char)" FROM CHAR_TBL;
varchar(char) varchar(char)
--------------- ---------------
a a
ab ab
abcd abcd
abcd abcd
(4 rows) (4 rows)
...@@ -570,16 +570,16 @@ SELECT text 'text' || ' and unknown' AS "Concat text to unknown type"; ...@@ -570,16 +570,16 @@ SELECT text 'text' || ' and unknown' AS "Concat text to unknown type";
text and unknown text and unknown
(1 row) (1 row)
SELECT char(20) 'characters' || 'and text' AS "Concat char to unknown type"; SELECT char(20) 'characters' || ' and text' AS "Concat char to unknown type";
Concat char to unknown type Concat char to unknown type
------------------------------ -----------------------------
characters and text characters and text
(1 row) (1 row)
SELECT text 'text' || char(20) ' and characters' AS "Concat text to char"; SELECT text 'text' || char(20) ' and characters' AS "Concat text to char";
Concat text to char Concat text to char
-------------------------- ---------------------
text and characters text and characters
(1 row) (1 row)
SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar"; SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
......
...@@ -203,21 +203,19 @@ SELECT f1 FROM INT4_TBL ...@@ -203,21 +203,19 @@ SELECT f1 FROM INT4_TBL
123456 123456
(5 rows) (5 rows)
SELECT f1 AS five FROM VARCHAR_TBL SELECT CAST(f1 AS char(4)) AS three FROM VARCHAR_TBL
UNION UNION
SELECT f1 FROM CHAR_TBL; SELECT f1 FROM CHAR_TBL;
five three
------ -------
a
a a
ab
ab ab
abcd abcd
(5 rows) (3 rows)
SELECT f1 AS three FROM VARCHAR_TBL SELECT f1 AS three FROM VARCHAR_TBL
UNION UNION
SELECT TRIM(TRAILING FROM f1) FROM CHAR_TBL; SELECT CAST(f1 AS varchar) FROM CHAR_TBL;
three three
------- -------
a a
...@@ -234,8 +232,8 @@ SELECT f1 FROM CHAR_TBL; ...@@ -234,8 +232,8 @@ SELECT f1 FROM CHAR_TBL;
ab ab
abcd abcd
abcd abcd
a a
ab ab
abcd abcd
abcd abcd
(8 rows) (8 rows)
......
This diff is collapsed.
...@@ -199,7 +199,7 @@ SELECT 'unknown' || ' and unknown' AS "Concat unknown types"; ...@@ -199,7 +199,7 @@ SELECT 'unknown' || ' and unknown' AS "Concat unknown types";
SELECT text 'text' || ' and unknown' AS "Concat text to unknown type"; SELECT text 'text' || ' and unknown' AS "Concat text to unknown type";
SELECT char(20) 'characters' || 'and text' AS "Concat char to unknown type"; SELECT char(20) 'characters' || ' and text' AS "Concat char to unknown type";
SELECT text 'text' || char(20) ' and characters' AS "Concat text to char"; SELECT text 'text' || char(20) ' and characters' AS "Concat text to char";
......
...@@ -66,13 +66,13 @@ UNION ...@@ -66,13 +66,13 @@ UNION
SELECT f1 FROM INT4_TBL SELECT f1 FROM INT4_TBL
WHERE f1 BETWEEN 0 AND 1000000; WHERE f1 BETWEEN 0 AND 1000000;
SELECT f1 AS five FROM VARCHAR_TBL SELECT CAST(f1 AS char(4)) AS three FROM VARCHAR_TBL
UNION UNION
SELECT f1 FROM CHAR_TBL; SELECT f1 FROM CHAR_TBL;
SELECT f1 AS three FROM VARCHAR_TBL SELECT f1 AS three FROM VARCHAR_TBL
UNION UNION
SELECT TRIM(TRAILING FROM f1) FROM CHAR_TBL; SELECT CAST(f1 AS varchar) FROM CHAR_TBL;
SELECT f1 AS eight FROM VARCHAR_TBL SELECT f1 AS eight FROM VARCHAR_TBL
UNION ALL UNION ALL
......
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