All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.phoenix.expression.function.RandomFunction Maven / Gradle / Ivy

There is a newer version: 4.15.0-HBase-1.5
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.phoenix.expression.function;

import java.io.DataInput;
import java.io.IOException;
import java.util.List;
import java.util.Random;

import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.parse.FunctionParseNode.Argument;
import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PDouble;
import org.apache.phoenix.schema.types.PLong;

/**
 * Random function that produces a unique value upon each invocation unless a seed is provided.
 * If a seed is provided the returned value is identical across each invocation for a single row, but different across multiple rows.
 * The seed must be a constant.
 * 

* Example: *

 * 0: jdbc:phoenix:localhost> select rand(), rand(), rand(1), rand(2), rand(1) from t;
 * +----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
 * |           RAND()           |           RAND()           |          RAND(1)           |          RAND(2)           |          RAND(1)      |
 * +----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
 * | 0.18927325291276054        | 0.19335253869230284        | 0.7308781907032909         | 0.7311469360199058         | 0.7308781907032909    |
 * | 0.08156917775368278        | 0.10178318739559034        | 0.41008081149220166        | 0.9014476240300544         | 0.41008081149220166   |
 * +----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
 * 2 rows selected (0.096 seconds)
 * 0: jdbc:phoenix:localhost> select rand(), rand(), rand(1), rand(2), rand(1) from t;
 * +----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
 * |           RAND()           |           RAND()           |          RAND(1)           |          RAND(2)           |          RAND(1)      |
 * +----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
 * | 0.6452639556507597         | 0.8167638693890659         | 0.7308781907032909         | 0.7311469360199058         | 0.7308781907032909    |
 * | 0.8084646053276106         | 0.6969504742211767         | 0.41008081149220166        | 0.9014476240300544         | 0.41008081149220166   |
 * +----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
 * 2 rows selected (0.098 seconds)
 * 
*/ @BuiltInFunction(name = RandomFunction.NAME, args = {@Argument(allowedTypes={PLong.class},defaultValue="null",isConstant=true)}) public class RandomFunction extends ScalarFunction { public static final String NAME = "RAND"; private Random random; private boolean hasSeed; private Double current; public RandomFunction() { } public RandomFunction(List children) { super(children); init(); } private void init() { Number seed = (Number)((LiteralExpression)children.get(0)).getValue(); random = seed == null ? new Random() : new Random(seed.longValue()); hasSeed = seed != null; current = null; } @Override public void readFields(DataInput input) throws IOException { super.readFields(input); init(); } @Override public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { if (current == null) { current = random.nextDouble(); } ptr.set(PDouble.INSTANCE.toBytes(current)); return true; } // produce a new random value for each row @Override public void reset() { super.reset(); current = null; } @Override public PDataType getDataType() { return PDouble.INSTANCE; } @Override public String getName() { return NAME; } @Override public Determinism getDeterminism() { return hasSeed ? Determinism.PER_ROW : Determinism.PER_INVOCATION; } @Override public boolean isStateless() { return true; } // take the random object onto account @Override public int hashCode() { int hashCode = super.hashCode(); return hasSeed ? hashCode : (hashCode + random.hashCode()); } // take the random object onto account, as otherwise we'll potentially collapse two // RAND() calls into a single one. @Override public boolean equals(Object obj) { return super.equals(obj) && (hasSeed || random.equals(((RandomFunction)obj).random)); } // make sure we do not show the default 'null' parameter @Override public final String toString() { StringBuilder buf = new StringBuilder(getName() + "("); if (!hasSeed) return buf.append(")").toString(); for (int i = 0; i < children.size() - 1; i++) { buf.append(children.get(i) + ", "); } buf.append(children.get(children.size()-1) + ")"); return buf.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy