mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Array mega-patch.
Joe Conway
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.417 2003/06/17 23:12:36 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.418 2003/06/24 23:14:43 momjian Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -5490,6 +5490,7 @@ r_expr: row IN_P select_with_parens
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = ANY_SUBLINK;
|
||||
n->isExpr = false;
|
||||
n->lefthand = $1;
|
||||
n->operName = makeList1(makeString("="));
|
||||
n->subselect = $3;
|
||||
@@ -5500,6 +5501,7 @@ r_expr: row IN_P select_with_parens
|
||||
/* Make an IN node */
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = ANY_SUBLINK;
|
||||
n->isExpr = false;
|
||||
n->lefthand = $1;
|
||||
n->operName = makeList1(makeString("="));
|
||||
n->subselect = $4;
|
||||
@@ -5511,6 +5513,7 @@ r_expr: row IN_P select_with_parens
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = $3;
|
||||
n->isExpr = false;
|
||||
n->lefthand = $1;
|
||||
n->operName = $2;
|
||||
n->subselect = $4;
|
||||
@@ -5521,6 +5524,7 @@ r_expr: row IN_P select_with_parens
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = MULTIEXPR_SUBLINK;
|
||||
n->isExpr = false;
|
||||
n->lefthand = $1;
|
||||
n->operName = $2;
|
||||
n->subselect = $3;
|
||||
@@ -5904,6 +5908,7 @@ a_expr: c_expr { $$ = $1; }
|
||||
{
|
||||
SubLink *n = (SubLink *)$3;
|
||||
n->subLinkType = ANY_SUBLINK;
|
||||
n->isExpr = false;
|
||||
n->lefthand = makeList1($1);
|
||||
n->operName = makeList1(makeString("="));
|
||||
$$ = (Node *)n;
|
||||
@@ -5931,6 +5936,7 @@ a_expr: c_expr { $$ = $1; }
|
||||
{
|
||||
/* Make an IN node */
|
||||
SubLink *n = (SubLink *)$4;
|
||||
n->isExpr = false;
|
||||
n->subLinkType = ANY_SUBLINK;
|
||||
n->lefthand = makeList1($1);
|
||||
n->operName = makeList1(makeString("="));
|
||||
@@ -5957,11 +5963,38 @@ a_expr: c_expr { $$ = $1; }
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = $3;
|
||||
n->isExpr = false;
|
||||
n->lefthand = makeList1($1);
|
||||
n->operName = $2;
|
||||
n->subselect = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| a_expr qual_all_Op sub_type '(' a_expr ')' %prec Op
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
SelectStmt *s = makeNode(SelectStmt);
|
||||
ResTarget *r = makeNode(ResTarget);
|
||||
|
||||
r->name = NULL;
|
||||
r->indirection = NIL;
|
||||
r->val = (Node *)$5;
|
||||
|
||||
s->distinctClause = NIL;
|
||||
s->targetList = makeList1(r);
|
||||
s->into = NULL;
|
||||
s->intoColNames = NIL;
|
||||
s->fromClause = NIL;
|
||||
s->whereClause = NULL;
|
||||
s->groupClause = NIL;
|
||||
s->havingClause = NULL;
|
||||
|
||||
n->subLinkType = $3;
|
||||
n->isExpr = true;
|
||||
n->lefthand = makeList1($1);
|
||||
n->operName = $2;
|
||||
n->subselect = (Node *) s;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| UNIQUE select_with_parens %prec Op
|
||||
{
|
||||
/* Not sure how to get rid of the parentheses
|
||||
@@ -6538,6 +6571,7 @@ c_expr: columnref { $$ = (Node *) $1; }
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = EXPR_SUBLINK;
|
||||
n->isExpr = false;
|
||||
n->lefthand = NIL;
|
||||
n->operName = NIL;
|
||||
n->subselect = $1;
|
||||
@@ -6547,6 +6581,7 @@ c_expr: columnref { $$ = (Node *) $1; }
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = EXISTS_SUBLINK;
|
||||
n->isExpr = false;
|
||||
n->lefthand = NIL;
|
||||
n->operName = NIL;
|
||||
n->subselect = $2;
|
||||
@@ -6556,6 +6591,7 @@ c_expr: columnref { $$ = (Node *) $1; }
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->subLinkType = ARRAY_SUBLINK;
|
||||
n->isExpr = false;
|
||||
n->lefthand = NIL;
|
||||
n->operName = NIL;
|
||||
n->subselect = $2;
|
||||
@@ -6730,6 +6766,7 @@ trim_list: a_expr FROM expr_list { $$ = lappend($3, $1); }
|
||||
in_expr: select_with_parens
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->isExpr = false;
|
||||
n->subselect = $1;
|
||||
/* other fields will be filled later */
|
||||
$$ = (Node *)n;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.97 2003/05/26 00:11:27 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.98 2003/06/24 23:14:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -859,7 +859,11 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
|
||||
/* Get the element type based on the array type, if we have one */
|
||||
if (OidIsValid(array_typeid))
|
||||
{
|
||||
array_typelem = get_element_type(array_typeid);
|
||||
if (array_typeid != ANYARRAYOID)
|
||||
array_typelem = get_element_type(array_typeid);
|
||||
else
|
||||
array_typelem = ANYELEMENTOID;
|
||||
|
||||
if (!OidIsValid(array_typelem))
|
||||
elog(ERROR, "Argument declared ANYARRAY is not an array: %s",
|
||||
format_type_be(array_typeid));
|
||||
@@ -919,7 +923,11 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
|
||||
{
|
||||
if (!OidIsValid(array_typeid))
|
||||
{
|
||||
array_typeid = get_array_type(elem_typeid);
|
||||
if (elem_typeid != ANYELEMENTOID)
|
||||
array_typeid = get_array_type(elem_typeid);
|
||||
else
|
||||
array_typeid = ANYARRAYOID;
|
||||
|
||||
if (!OidIsValid(array_typeid))
|
||||
elog(ERROR, "Cannot find array type for datatype %s",
|
||||
format_type_be(elem_typeid));
|
||||
@@ -1170,6 +1178,11 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
|
||||
if (srctype == targettype)
|
||||
return true;
|
||||
|
||||
/* Last of the fast-paths: check for matching polymorphic arrays */
|
||||
if (targettype == ANYARRAYOID)
|
||||
if (get_element_type(srctype) != InvalidOid)
|
||||
return true;
|
||||
|
||||
/* Else look in pg_cast */
|
||||
tuple = SearchSysCache(CASTSOURCETARGET,
|
||||
ObjectIdGetDatum(srctype),
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.148 2003/04/29 22:13:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.149 2003/06/24 23:14:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -436,6 +436,7 @@ transformExpr(ParseState *pstate, Node *expr)
|
||||
sublink->operName = NIL;
|
||||
sublink->operOids = NIL;
|
||||
sublink->useOr = FALSE;
|
||||
sublink->isExpr = FALSE;
|
||||
}
|
||||
else if (sublink->subLinkType == EXPR_SUBLINK ||
|
||||
sublink->subLinkType == ARRAY_SUBLINK)
|
||||
@@ -463,6 +464,7 @@ transformExpr(ParseState *pstate, Node *expr)
|
||||
sublink->operName = NIL;
|
||||
sublink->operOids = NIL;
|
||||
sublink->useOr = FALSE;
|
||||
sublink->isExpr = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -538,10 +540,30 @@ transformExpr(ParseState *pstate, Node *expr)
|
||||
* here, because make_subplan() will insert type
|
||||
* coercion calls if needed.
|
||||
*/
|
||||
optup = oper(op,
|
||||
exprType(lexpr),
|
||||
exprType((Node *) tent->expr),
|
||||
false);
|
||||
if (!sublink->isExpr)
|
||||
{
|
||||
optup = oper(op,
|
||||
exprType(lexpr),
|
||||
exprType((Node *) tent->expr),
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Oid exprtype = exprType((Node *) tent->expr);
|
||||
Oid elemtype = get_element_type(exprtype);
|
||||
|
||||
if (elemtype != InvalidOid)
|
||||
optup = oper(op,
|
||||
exprType(lexpr),
|
||||
elemtype,
|
||||
false);
|
||||
else
|
||||
optup = oper(op,
|
||||
exprType(lexpr),
|
||||
exprtype,
|
||||
false);
|
||||
}
|
||||
|
||||
opform = (Form_pg_operator) GETSTRUCT(optup);
|
||||
|
||||
if (opform->oprresult != BOOLOID)
|
||||
@@ -743,7 +765,7 @@ transformExpr(ParseState *pstate, Node *expr)
|
||||
ArrayExpr *e = (ArrayExpr *) lfirst(element);
|
||||
|
||||
if (!IsA(e, ArrayExpr))
|
||||
elog(ERROR, "Multi-dimensional ARRAY[] must be built from nested array expressions");
|
||||
elog(ERROR, "Multidimensional ARRAY[] must be built from nested array expressions");
|
||||
if (ndims == 0)
|
||||
ndims = e->ndims;
|
||||
else if (e->ndims != ndims)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.149 2003/06/06 15:04:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.150 2003/06/24 23:14:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -336,6 +336,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
|
||||
aggref->target = lfirst(fargs);
|
||||
aggref->aggstar = agg_star;
|
||||
aggref->aggdistinct = agg_distinct;
|
||||
aggref->args = fargs;
|
||||
|
||||
/* parse_agg.c does additional aggregate-specific processing */
|
||||
transformAggregateCall(pstate, aggref);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.64 2003/05/26 00:11:27 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.65 2003/06/24 23:14:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -137,6 +137,33 @@ Operator
|
||||
equality_oper(Oid argtype, bool noError)
|
||||
{
|
||||
Operator optup;
|
||||
Oid elem_type = get_element_type(argtype);
|
||||
|
||||
if (OidIsValid(elem_type))
|
||||
{
|
||||
bool found = false;
|
||||
/*
|
||||
* If the datatype is an array, look for an "=" operator for the
|
||||
* element datatype. We require it to be an exact or binary-compatible
|
||||
* match, since most callers are not prepared to cope with adding any
|
||||
* run-time type coercion steps.
|
||||
*/
|
||||
optup = equality_oper(elem_type, true);
|
||||
if (optup != NULL)
|
||||
{
|
||||
found = true;
|
||||
ReleaseSysCache(optup);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (!noError)
|
||||
elog(ERROR, "Unable to identify an equality operator for " \
|
||||
"array type's element type %s",
|
||||
format_type_be(elem_type));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for an "=" operator for the datatype. We require it to be
|
||||
@@ -175,6 +202,33 @@ Operator
|
||||
ordering_oper(Oid argtype, bool noError)
|
||||
{
|
||||
Operator optup;
|
||||
Oid elem_type = get_element_type(argtype);
|
||||
|
||||
if (OidIsValid(elem_type))
|
||||
{
|
||||
bool found = false;
|
||||
/*
|
||||
* If the datatype is an array, find the array element type's equality
|
||||
* operator, and use its lsortop (it *must* be mergejoinable). We use
|
||||
* this definition because for sorting and grouping purposes, it's
|
||||
* important that the equality and ordering operators are consistent.
|
||||
*/
|
||||
optup = ordering_oper(elem_type, true);
|
||||
if (optup != NULL)
|
||||
{
|
||||
found = true;
|
||||
ReleaseSysCache(optup);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (!noError)
|
||||
elog(ERROR, "Unable to identify an ordering operator for " \
|
||||
"array type's element type %s",
|
||||
format_type_be(elem_type));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the type's equality operator, and use its lsortop (it *must*
|
||||
@@ -220,6 +274,21 @@ equality_oper_funcid(Oid argtype)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ordering_oper_funcid - convenience routine for oprfuncid(ordering_oper())
|
||||
*/
|
||||
Oid
|
||||
ordering_oper_funcid(Oid argtype)
|
||||
{
|
||||
Operator optup;
|
||||
Oid result;
|
||||
|
||||
optup = ordering_oper(argtype, false);
|
||||
result = oprfuncid(optup);
|
||||
ReleaseSysCache(optup);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ordering_oper_opid - convenience routine for oprid(ordering_oper())
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user