1
0
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:
Bruce Momjian
2003-06-24 23:14:49 +00:00
parent 50e53236af
commit 46bf651480
42 changed files with 2617 additions and 678 deletions

View File

@@ -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;

View File

@@ -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),

View File

@@ -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)

View File

@@ -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);

View File

@@ -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())
*