Exemple #1
0
  /**
   * The constructor is protected, to ensure that instances can only be created using the
   * compileQuery() methods of StaticQueryContext
   *
   * @param exp an expression to be wrapped as an XQueryExpression
   * @param exec the executable
   * @param mainModule the static context of the main module
   * @param config the configuration
   * @throws XPathException if an error occurs
   */
  protected XQueryExpression(
      Expression exp, Executable exec, QueryModule mainModule, Configuration config)
      throws XPathException {
    stackFrameMap = config.makeSlotManager();
    executable = exec;
    exp.setContainer(this);
    try {
      ExpressionVisitor visitor = ExpressionVisitor.make(mainModule);
      visitor.setExecutable(exec);
      exp = visitor.simplify(exp);
      exp.checkForUpdatingSubexpressions();
      exp = visitor.typeCheck(exp, mainModule.getUserQueryContext().getRequiredContextItemType());
      //            ExpressionPresenter presenter = new ExpressionPresenter(config,
      //                    ExpressionPresenter.defaultDestination(config, new
      // FileOutputStream("c:/projects/montreal/before50.xml")));
      //            exp.explain(presenter);
      //            presenter.close();
      exp = exp.optimize(visitor, Type.ITEM_TYPE);
    } catch (XPathException err) {
      // err.printStackTrace();
      mainModule.reportFatalError(err);
      throw err;
    }
    ExpressionTool.allocateSlots(exp, 0, stackFrameMap);

    expression = exp;
    executable.setConfiguration(config);
    executable.setDefaultCollationName(mainModule.getDefaultCollationName());
    executable.setCollationTable(mainModule.getUserQueryContext().getAllCollations());
    staticContext = mainModule;
    isUpdating = exp.isUpdatingExpression();
  }
 @Override
 public Expression optimize(Session session) {
   left = left.optimize(session);
   boolean constant = left.isConstant();
   if (constant && left == ValueExpression.getNull()) {
     return left;
   }
   boolean allValuesConstant = true;
   boolean allValuesNull = true;
   int size = valueList.size();
   for (int i = 0; i < size; i++) {
     Expression e = valueList.get(i);
     e = e.optimize(session);
     if (e.isConstant() && e.getValue(session) != ValueNull.INSTANCE) {
       allValuesNull = false;
     }
     if (allValuesConstant && !e.isConstant()) {
       allValuesConstant = false;
     }
     if (left instanceof ExpressionColumn && e instanceof Parameter) {
       ((Parameter) e).setColumn(((ExpressionColumn) left).getColumn());
     }
     valueList.set(i, e);
   }
   if (constant && allValuesConstant) {
     return ValueExpression.get(getValue(session));
   }
   if (size == 1) {
     Expression right = valueList.get(0);
     Expression expr = new Comparison(session, Comparison.EQUAL, left, right);
     expr = expr.optimize(session);
     return expr;
   }
   if (allValuesConstant && !allValuesNull) {
     int leftType = left.getType();
     if (leftType == Value.UNKNOWN) {
       return this;
     }
     Expression expr = new ConditionInConstantSet(session, left, valueList);
     expr = expr.optimize(session);
     return expr;
   }
   return this;
 }
 @Override
 public Expression optimize(Session session) {
   userConnection = session.createConnection(false);
   int len = args.length;
   argTypes = new int[len];
   for (int i = 0; i < len; i++) {
     Expression expr = args[i];
     args[i] = expr.optimize(session);
     int type = expr.getType();
     argTypes[i] = type;
   }
   try {
     Aggregate aggregate = getInstance();
     dataType = aggregate.getInternalType(argTypes);
   } catch (SQLException e) {
     throw DbException.convert(e);
   }
   return this;
 }
 @Override
 public Expression optimize(Session session) {
   if (on != null) {
     on = on.optimize(session);
     dataType = on.getType();
     scale = on.getScale();
     precision = on.getPrecision();
     displaySize = on.getDisplaySize();
   }
   if (groupConcatOrderList != null) {
     for (SelectOrderBy o : groupConcatOrderList) {
       o.expression = o.expression.optimize(session);
     }
     groupConcatSort = initOrder(session);
   }
   if (groupConcatSeparator != null) {
     groupConcatSeparator = groupConcatSeparator.optimize(session);
   }
   switch (type) {
     case GROUP_CONCAT:
       dataType = Value.STRING;
       scale = 0;
       precision = displaySize = Integer.MAX_VALUE;
       break;
     case COUNT_ALL:
     case COUNT:
       dataType = Value.LONG;
       scale = 0;
       precision = ValueLong.PRECISION;
       displaySize = ValueLong.DISPLAY_SIZE;
       break;
     case SELECTIVITY:
       dataType = Value.INT;
       scale = 0;
       precision = ValueInt.PRECISION;
       displaySize = ValueInt.DISPLAY_SIZE;
       break;
     case HISTOGRAM:
       dataType = Value.ARRAY;
       scale = 0;
       precision = displaySize = Integer.MAX_VALUE;
       break;
     case SUM:
       if (dataType == Value.BOOLEAN) {
         // example: sum(id > 3) (count the rows)
         dataType = Value.LONG;
       } else if (!DataType.supportsAdd(dataType)) {
         throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL());
       } else {
         dataType = DataType.getAddProofType(dataType);
       }
       break;
     case AVG:
       if (!DataType.supportsAdd(dataType)) {
         throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL());
       }
       break;
     case MIN:
     case MAX:
       break;
     case STDDEV_POP:
     case STDDEV_SAMP:
     case VAR_POP:
     case VAR_SAMP:
       dataType = Value.DOUBLE;
       precision = ValueDouble.PRECISION;
       displaySize = ValueDouble.DISPLAY_SIZE;
       scale = 0;
       break;
     case BOOL_AND:
     case BOOL_OR:
       dataType = Value.BOOLEAN;
       precision = ValueBoolean.PRECISION;
       displaySize = ValueBoolean.DISPLAY_SIZE;
       scale = 0;
       break;
     default:
       DbException.throwInternalError("type=" + type);
   }
   return this;
 }
  @Override
  public Statement semantic(Scope sc, SemanticContext context) {
    SwitchStatement sw = sc.sw;
    this.sw = sw;

    exp = exp.semantic(sc, context);
    if (sw != null) {
      int i;

      exp = exp.implicitCastTo(sc, sw.condition.type, context);
      exp = exp.optimize(WANTvalue | WANTinterpret, context);

      boolean gotoL1 = false;

      if (context.isD2()) {
        /* This is where variables are allowed as case expressions.
         */
        if (exp.op == TOKvar) {
          VarExp ve = (VarExp) exp;
          VarDeclaration v = ve.var.isVarDeclaration();
          Type t = exp.type.toBasetype(context);
          if (v != null && (t.isintegral() || t.ty == Tclass)) {
              /* Flag that we need to do special code generation
               * for this, i.e. generate a sequence of if-then-else
               */
            sw.hasVars = 1;
            // goto L1;
            gotoL1 = true;
          }
        }
      }

      if (!gotoL1) {
        if (exp.op != TOKstring && exp.op != TOKint64) {
          if (context.acceptsErrors()) {
            context.acceptProblem(
                Problem.newSemanticTypeError(
                    IProblem.CaseMustBeAnIntegralOrStringConstant,
                    sourceExp,
                    exp.toChars(context)));
          }
          exp = new IntegerExp(0);
        }
      }

      // L1:
      for (i = 0; i < sw.cases.size(); i++) {
        CaseStatement cs = (CaseStatement) sw.cases.get(i);

        if (cs.exp.equals(exp, context)) {
          if (context.acceptsErrors()) {
            context.acceptProblem(
                Problem.newSemanticTypeErrorLoc(
                    IProblem.DuplicateCaseInSwitchStatement, this, exp.toChars(context)));
          }
          break;
        }
      }

      sw.cases.add(this);

      // Resolve any goto case's with no exp to this case statement
      if (sw.gotoCases != null) {
        for (i = 0; i < sw.gotoCases.size(); i++) {
          GotoCaseStatement gcs = (GotoCaseStatement) sw.gotoCases.get(i);

          if (gcs.exp == null) {
            gcs.cs = this;
            sw.gotoCases.remove(i); // remove from array
          }
        }
      }

      if (context.isD2()) {
        if (sc.sw.tf != sc.tf) {
          if (context.acceptsErrors()) {
            context.acceptProblem(
                Problem.newSemanticTypeErrorLoc(
                    IProblem.SwitchAndCaseAreInDifferentFinallyBlocks, this));
          }
        }
      }
    } else {
      if (context.acceptsErrors()) {
        context.acceptProblem(Problem.newSemanticTypeError(IProblem.CaseIsNotInSwitch, this));
      }
    }
    statement = statement.semantic(sc, context);
    return this;
  }