package org.basex.query.expr; import static org.basex.query.QueryText.*; import java.io.IOException; import org.basex.io.serial.Serializer; import org.basex.query.QueryContext; import org.basex.query.QueryException; import org.basex.query.item.AtomType; import org.basex.query.item.Item; import org.basex.query.item.SeqType; import org.basex.query.item.SeqType.Occ; import org.basex.util.InputInfo; import org.basex.util.Token; /** * Cast expression. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class Cast extends Single { /** * Function constructor. * @param ii input info * @param e expression * @param t data type */ public Cast(final InputInfo ii, final Expr e, final SeqType t) { super(ii, e); type = t; } @Override public Expr comp(final QueryContext ctx) throws QueryException { checkUp(expr, ctx); super.comp(ctx); Expr e = this; final SeqType t = expr.type(); if(expr.isValue()) { // pre-evaluate value e = preEval(ctx); } else if(type.type == AtomType.BLN || type.type == AtomType.FLT || type.type == AtomType.DBL || type.type == AtomType.QNM || type.type == AtomType.URI) { // skip cast if specified and return types are equal if(t.eq(type) || t.type == type.type && t.one() && type.zeroOrOne()) e = expr; if(e != this) optPre(e, ctx); } // adopt occurrence of argument if(e == this && t.one()) type = SeqType.get(type.type, Occ.O); return e; } @Override public Item item(final QueryContext ctx, final InputInfo ii) throws QueryException { return type.cast(expr.item(ctx, ii), this, true, ctx, ii); } @Override public void plan(final Serializer ser) throws IOException { ser.openElement(this, TYP, Token.token(type.toString())); expr.plan(ser); ser.closeElement(); } @Override public String toString() { return expr + " " + CAST + ' ' + AS + ' ' + type; } }