Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit730840c

Browse files
committed
First phase of work on array improvements. ARRAY[x,y,z] constructor
expressions, ARRAY(sub-SELECT) expressions, some array functions.Polymorphic functions using ANYARRAY/ANYELEMENT argument and returntypes. Some regression tests in place, documentation is lacking.Joe Conway, with some kibitzing from Tom Lane.
1 parent6fb5115 commit730840c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2597
-479
lines changed

‎src/backend/catalog/pg_proc.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.95 2002/12/12 15:49:24 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.96 2003/04/08 23:20:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -86,6 +86,29 @@ ProcedureCreate(const char *procedureName,
8686
elog(ERROR,"functions cannot have more than %d arguments",
8787
FUNC_MAX_ARGS);
8888

89+
/*
90+
* Do not allow return type ANYARRAY or ANYELEMENT unless at least one
91+
* argument is also ANYARRAY or ANYELEMENT
92+
*/
93+
if (returnType==ANYARRAYOID||returnType==ANYELEMENTOID)
94+
{
95+
boolgenericParam= false;
96+
97+
for (i=0;i<parameterCount;i++)
98+
{
99+
if (parameterTypes[i]==ANYARRAYOID||
100+
parameterTypes[i]==ANYELEMENTOID)
101+
{
102+
genericParam= true;
103+
break;
104+
}
105+
}
106+
107+
if (!genericParam)
108+
elog(ERROR,"functions returning ANYARRAY or ANYELEMENT must " \
109+
"have at least one argument of either type");
110+
}
111+
89112
/* Make sure we have a zero-padded param type array */
90113
MemSet(typev,0,FUNC_MAX_ARGS*sizeof(Oid));
91114
if (parameterCount>0)

‎src/backend/executor/execQual.c

Lines changed: 208 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.127 2003/03/27 16:51:27 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.128 2003/04/08 23:20:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -75,6 +75,9 @@ static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
7575
bool*isNull);
7676
staticDatumExecEvalCase(CaseExprState*caseExpr,ExprContext*econtext,
7777
bool*isNull,ExprDoneCond*isDone);
78+
staticDatumExecEvalArray(ArrayExprState*astate,
79+
ExprContext*econtext,
80+
bool*isNull);
7881
staticDatumExecEvalCoalesce(CoalesceExprState*coalesceExpr,
7982
ExprContext*econtext,
8083
bool*isNull);
@@ -246,38 +249,38 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
246249
resultArray=array_set(array_source,i,
247250
upper.indx,
248251
sourceData,
249-
arrayRef->refattrlength,
250-
arrayRef->refelemlength,
251-
arrayRef->refelembyval,
252-
arrayRef->refelemalign,
252+
astate->refattrlength,
253+
astate->refelemlength,
254+
astate->refelembyval,
255+
astate->refelemalign,
253256
isNull);
254257
else
255258
resultArray=array_set_slice(array_source,i,
256259
upper.indx,lower.indx,
257260
(ArrayType*)DatumGetPointer(sourceData),
258-
arrayRef->refattrlength,
259-
arrayRef->refelemlength,
260-
arrayRef->refelembyval,
261-
arrayRef->refelemalign,
261+
astate->refattrlength,
262+
astate->refelemlength,
263+
astate->refelembyval,
264+
astate->refelemalign,
262265
isNull);
263266
returnPointerGetDatum(resultArray);
264267
}
265268

266269
if (lIndex==NULL)
267270
returnarray_ref(array_source,i,upper.indx,
268-
arrayRef->refattrlength,
269-
arrayRef->refelemlength,
270-
arrayRef->refelembyval,
271-
arrayRef->refelemalign,
271+
astate->refattrlength,
272+
astate->refelemlength,
273+
astate->refelembyval,
274+
astate->refelemalign,
272275
isNull);
273276
else
274277
{
275278
resultArray=array_get_slice(array_source,i,
276279
upper.indx,lower.indx,
277-
arrayRef->refattrlength,
278-
arrayRef->refelemlength,
279-
arrayRef->refelembyval,
280-
arrayRef->refelemalign,
280+
astate->refattrlength,
281+
astate->refelemlength,
282+
astate->refelembyval,
283+
astate->refelemalign,
281284
isNull);
282285
returnPointerGetDatum(resultArray);
283286
}
@@ -613,6 +616,7 @@ init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt)
613616

614617
/* Initialize additional info */
615618
fcache->setArgsValid= false;
619+
fcache->func.fn_expr= (Node*)fcache->xprstate.expr;
616620
}
617621

618622
/*
@@ -1426,6 +1430,158 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
14261430
return (Datum)0;
14271431
}
14281432

1433+
/* ----------------------------------------------------------------
1434+
*ExecEvalArray - ARRAY[] expressions
1435+
* ----------------------------------------------------------------
1436+
*/
1437+
staticDatum
1438+
ExecEvalArray(ArrayExprState*astate,ExprContext*econtext,
1439+
bool*isNull)
1440+
{
1441+
ArrayExpr*arrayExpr= (ArrayExpr*)astate->xprstate.expr;
1442+
ArrayType*result;
1443+
List*element;
1444+
Oidelement_type=arrayExpr->element_typeid;
1445+
intndims=arrayExpr->ndims;
1446+
intdims[MAXDIM];
1447+
intlbs[MAXDIM];
1448+
1449+
if (ndims==1)
1450+
{
1451+
intnelems;
1452+
Datum*dvalues;
1453+
inti=0;
1454+
1455+
nelems=length(astate->elements);
1456+
1457+
/* Shouldn't happen here, but if length is 0, return NULL */
1458+
if (nelems==0)
1459+
{
1460+
*isNull= true;
1461+
return (Datum)0;
1462+
}
1463+
1464+
dvalues= (Datum*)palloc(nelems*sizeof(Datum));
1465+
1466+
/* loop through and build array of datums */
1467+
foreach(element,astate->elements)
1468+
{
1469+
ExprState*e= (ExprState*)lfirst(element);
1470+
booleisnull;
1471+
1472+
dvalues[i++]=ExecEvalExpr(e,econtext,&eisnull,NULL);
1473+
if (eisnull)
1474+
elog(ERROR,"Arrays cannot have NULL elements");
1475+
}
1476+
1477+
/* setup for 1-D array of the given length */
1478+
dims[0]=nelems;
1479+
lbs[0]=1;
1480+
1481+
result=construct_md_array(dvalues,ndims,dims,lbs,
1482+
element_type,
1483+
astate->elemlength,
1484+
astate->elembyval,
1485+
astate->elemalign);
1486+
}
1487+
else
1488+
{
1489+
char*dat=NULL;
1490+
Sizendatabytes=0;
1491+
intnbytes;
1492+
intouter_nelems=length(astate->elements);
1493+
intelem_ndims=0;
1494+
int*elem_dims=NULL;
1495+
int*elem_lbs=NULL;
1496+
boolfirstone= true;
1497+
inti;
1498+
1499+
if (ndims <=0||ndims>MAXDIM)
1500+
elog(ERROR,"Arrays cannot have more than %d dimensions",MAXDIM);
1501+
1502+
/* loop through and get data area from each element */
1503+
foreach(element,astate->elements)
1504+
{
1505+
ExprState*e= (ExprState*)lfirst(element);
1506+
booleisnull;
1507+
Datumarraydatum;
1508+
ArrayType*array;
1509+
intelem_ndatabytes;
1510+
1511+
arraydatum=ExecEvalExpr(e,econtext,&eisnull,NULL);
1512+
if (eisnull)
1513+
elog(ERROR,"Arrays cannot have NULL elements");
1514+
1515+
array=DatumGetArrayTypeP(arraydatum);
1516+
1517+
if (firstone)
1518+
{
1519+
/* Get sub-array details from first member */
1520+
elem_ndims=ARR_NDIM(array);
1521+
elem_dims= (int*)palloc(elem_ndims*sizeof(int));
1522+
memcpy(elem_dims,ARR_DIMS(array),elem_ndims*sizeof(int));
1523+
elem_lbs= (int*)palloc(elem_ndims*sizeof(int));
1524+
memcpy(elem_lbs,ARR_LBOUND(array),elem_ndims*sizeof(int));
1525+
firstone= false;
1526+
}
1527+
else
1528+
{
1529+
/* Check other sub-arrays are compatible */
1530+
if (elem_ndims!=ARR_NDIM(array))
1531+
elog(ERROR,"Multiple dimension arrays must have array "
1532+
"expressions with matching number of dimensions");
1533+
1534+
if (memcmp(elem_dims,ARR_DIMS(array),
1535+
elem_ndims*sizeof(int))!=0)
1536+
elog(ERROR,"Multiple dimension arrays must have array "
1537+
"expressions with matching dimensions");
1538+
1539+
if (memcmp(elem_lbs,ARR_LBOUND(array),
1540+
elem_ndims*sizeof(int))!=0)
1541+
elog(ERROR,"Multiple dimension arrays must have array "
1542+
"expressions with matching dimensions");
1543+
}
1544+
1545+
elem_ndatabytes=ARR_SIZE(array)-ARR_OVERHEAD(elem_ndims);
1546+
ndatabytes+=elem_ndatabytes;
1547+
if (dat==NULL)
1548+
dat= (char*)palloc(ndatabytes);
1549+
else
1550+
dat= (char*)repalloc(dat,ndatabytes);
1551+
1552+
memcpy(dat+ (ndatabytes-elem_ndatabytes),
1553+
ARR_DATA_PTR(array),
1554+
elem_ndatabytes);
1555+
}
1556+
1557+
/* setup for multi-D array */
1558+
dims[0]=outer_nelems;
1559+
lbs[0]=1;
1560+
for (i=1;i<ndims;i++)
1561+
{
1562+
dims[i]=elem_dims[i-1];
1563+
lbs[i]=elem_lbs[i-1];
1564+
}
1565+
1566+
nbytes=ndatabytes+ARR_OVERHEAD(ndims);
1567+
result= (ArrayType*)palloc(nbytes);
1568+
1569+
result->size=nbytes;
1570+
result->ndim=ndims;
1571+
result->flags=0;
1572+
result->elemtype=element_type;
1573+
memcpy(ARR_DIMS(result),dims,ndims*sizeof(int));
1574+
memcpy(ARR_LBOUND(result),lbs,ndims*sizeof(int));
1575+
if (ndatabytes>0)
1576+
memcpy(ARR_DATA_PTR(result),dat,ndatabytes);
1577+
1578+
if (dat!=NULL)
1579+
pfree(dat);
1580+
}
1581+
1582+
returnPointerGetDatum(result);
1583+
}
1584+
14291585
/* ----------------------------------------------------------------
14301586
*ExecEvalCoalesce
14311587
* ----------------------------------------------------------------
@@ -1908,6 +2064,11 @@ ExecEvalExpr(ExprState *expression,
19082064
isNull,
19092065
isDone);
19102066
break;
2067+
caseT_ArrayExpr:
2068+
retDatum=ExecEvalArray((ArrayExprState*)expression,
2069+
econtext,
2070+
isNull);
2071+
break;
19112072
caseT_CoalesceExpr:
19122073
retDatum=ExecEvalCoalesce((CoalesceExprState*)expression,
19132074
econtext,
@@ -2060,6 +2221,12 @@ ExecInitExpr(Expr *node, PlanState *parent)
20602221
astate->refexpr=ExecInitExpr(aref->refexpr,parent);
20612222
astate->refassgnexpr=ExecInitExpr(aref->refassgnexpr,
20622223
parent);
2224+
/* do one-time catalog lookups for type info */
2225+
astate->refattrlength=get_typlen(aref->refarraytype);
2226+
get_typlenbyvalalign(aref->refelemtype,
2227+
&astate->refelemlength,
2228+
&astate->refelembyval,
2229+
&astate->refelemalign);
20632230
state= (ExprState*)astate;
20642231
}
20652232
break;
@@ -2174,6 +2341,30 @@ ExecInitExpr(Expr *node, PlanState *parent)
21742341
state= (ExprState*)cstate;
21752342
}
21762343
break;
2344+
caseT_ArrayExpr:
2345+
{
2346+
ArrayExpr*arrayexpr= (ArrayExpr*)node;
2347+
ArrayExprState*astate=makeNode(ArrayExprState);
2348+
List*outlist=NIL;
2349+
List*inlist;
2350+
2351+
foreach(inlist,arrayexpr->elements)
2352+
{
2353+
Expr*e= (Expr*)lfirst(inlist);
2354+
ExprState*estate;
2355+
2356+
estate=ExecInitExpr(e,parent);
2357+
outlist=lappend(outlist,estate);
2358+
}
2359+
astate->elements=outlist;
2360+
/* do one-time catalog lookup for type info */
2361+
get_typlenbyvalalign(arrayexpr->element_typeid,
2362+
&astate->elemlength,
2363+
&astate->elembyval,
2364+
&astate->elemalign);
2365+
state= (ExprState*)astate;
2366+
}
2367+
break;
21772368
caseT_CoalesceExpr:
21782369
{
21792370
CoalesceExpr*coalesceexpr= (CoalesceExpr*)node;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp