/* SubscriptingRefState.workspace for array subscripting execution */ typedefstruct ArraySubWorkspace
{ /* Values determined during expression compilation */
Oid refelemtype; /* OID of the array element type */
int16 refattrlength; /* typlen of array type */
int16 refelemlength; /* typlen of the array element type */ bool refelembyval; /* is the element type pass-by-value? */ char refelemalign; /* typalign of the element type */
/* *Subscriptvaluesconvertedtointegers.Notethatthesearraysmustbe *oflengthMAXDIMevenwhendealingwithfewersubscripts,because *array_get/set_slicemayscribbleontheextraentries.
*/ int upperindex[MAXDIM]; int lowerindex[MAXDIM];
} ArraySubWorkspace;
/* *FinishparseanalysisofaSubscriptingRefexpressionforanarray. * *Transformthesubscriptexpressions,coercethemtointegers, *anddeterminetheresulttypeoftheSubscriptingRefnode.
*/ staticvoid
array_subscript_transform(SubscriptingRef *sbsref,
List *indirection,
ParseState *pstate, bool isSlice, bool isAssignment)
{
List *upperIndexpr = NIL;
List *lowerIndexpr = NIL;
ListCell *idx;
if (isSlice)
{ if (ai->lidx)
{
subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind); /* If it's not int4 already, try to coerce */
subexpr = coerce_to_target_type(pstate,
subexpr, exprType(subexpr),
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
-1); if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->lidx))));
} elseif (!ai->is_slice)
{ /* Make a constant 1 */
subexpr = (Node *) makeConst(INT4OID,
-1,
InvalidOid, sizeof(int32),
Int32GetDatum(1), false, true); /* pass by value */
} else
{ /* Slice with omitted lower bound, put NULL into the list */
subexpr = NULL;
}
lowerIndexpr = lappend(lowerIndexpr, subexpr);
} else
Assert(ai->lidx == NULL && !ai->is_slice);
if (ai->uidx)
{
subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind); /* If it's not int4 already, try to coerce */
subexpr = coerce_to_target_type(pstate,
subexpr, exprType(subexpr),
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
-1); if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->uidx))));
} else
{ /* Slice with omitted upper bound, put NULL into the list */
Assert(isSlice && ai->is_slice);
subexpr = NULL;
}
upperIndexpr = lappend(upperIndexpr, subexpr);
}
/* ... and store the transformed lists into the SubscriptRef node */
sbsref->refupperindexpr = upperIndexpr;
sbsref->reflowerindexpr = lowerIndexpr;
/* Verify subscript list lengths are within implementation limit */ if (list_length(upperIndexpr) > MAXDIM)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
list_length(upperIndexpr), MAXDIM))); /* We need not check lowerIndexpr separately */
/* Process upper subscripts */ for (int i = 0; i < sbsrefstate->numupper; i++)
{ if (sbsrefstate->upperprovided[i])
{ /* If any index expr yields NULL, result is NULL or error */ if (sbsrefstate->upperindexnull[i])
{ if (sbsrefstate->isassignment)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("array subscript in assignment must not be null")));
*op->resnull = true; returnfalse;
}
workspace->upperindex[i] = DatumGetInt32(sbsrefstate->upperindex[i]);
}
}
/* Likewise for lower subscripts */ for (int i = 0; i < sbsrefstate->numlower; i++)
{ if (sbsrefstate->lowerprovided[i])
{ /* If any index expr yields NULL, result is NULL or error */ if (sbsrefstate->lowerindexnull[i])
{ if (sbsrefstate->isassignment)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("array subscript in assignment must not be null")));
*op->resnull = true; returnfalse;
}
workspace->lowerindex[i] = DatumGetInt32(sbsrefstate->lowerindex[i]);
}
}
/* Should not get here if source array (or any subscript) is null */
Assert(!(*op->resnull));
*op->resvalue = array_get_slice(*op->resvalue,
sbsrefstate->numupper,
workspace->upperindex,
workspace->lowerindex,
sbsrefstate->upperprovided,
sbsrefstate->lowerprovided,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
workspace->refelemalign); /* The slice is never NULL, so no need to change *op->resnull */
}
*op->resvalue = array_set_element(arraySource,
sbsrefstate->numupper,
workspace->upperindex,
sbsrefstate->replacevalue,
sbsrefstate->replacenull,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
workspace->refelemalign); /* The result is never NULL, so no need to change *op->resnull */
}
*op->resvalue = array_set_slice(arraySource,
sbsrefstate->numupper,
workspace->upperindex,
workspace->lowerindex,
sbsrefstate->upperprovided,
sbsrefstate->lowerprovided,
sbsrefstate->replacevalue,
sbsrefstate->replacenull,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
workspace->refelemalign); /* The result is never NULL, so no need to change *op->resnull */
}
if (*op->resnull)
{ /* whole array is null, so any element is too */
sbsrefstate->prevvalue = (Datum) 0;
sbsrefstate->prevnull = true;
} else
sbsrefstate->prevvalue = array_get_element(*op->resvalue,
sbsrefstate->numupper,
workspace->upperindex,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
workspace->refelemalign,
&sbsrefstate->prevnull);
}
/* *Enforcetheimplementationlimitonnumberofarraysubscripts.This *checkisn'tentirelyredundantwithcheckingatparsetime;conceivably *theexpressionwasstoredbyabackendwithadifferentMAXDIMvalue.
*/ if (sbsrefstate->numupper > MAXDIM)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
sbsrefstate->numupper, MAXDIM)));
/* Should be impossible if parser is sane, but check anyway: */ if (sbsrefstate->numlower != 0 &&
sbsrefstate->numupper != sbsrefstate->numlower)
elog(ERROR, "upper and lower index lists are not same length");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.