/* * Copyright 2014-2015 the original author or authors * * Licensed 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 com.wplatform.ddal.dbobject.table; import java.util.ArrayList; import com.wplatform.ddal.command.expression.Expression; import com.wplatform.ddal.dbobject.index.Index; import com.wplatform.ddal.dbobject.index.IndexMate; import com.wplatform.ddal.dbobject.index.IndexType; import com.wplatform.ddal.dbobject.schema.Schema; import com.wplatform.ddal.engine.Session; import com.wplatform.ddal.message.DbException; import com.wplatform.ddal.value.Value; /** * The table SYSTEM_RANGE is a virtual table that generates incrementing numbers * with a given start end end point. */ public class RangeTable extends Table { /** * The name of the range table. */ public static final String NAME = "SYSTEM_RANGE"; private Expression min, max; private boolean optimized; /** * Create a new range with the given start and end expressions. * * @param schema the schema (always the main schema) * @param min the start expression * @param max the end expression * @param noColumns whether this table has no columns */ public RangeTable(Schema schema, Expression min, Expression max, boolean noColumns) { super(schema, 0, NAME); Column[] cols = noColumns ? new Column[0] : new Column[]{new Column( "X", Value.LONG)}; this.min = min; this.max = max; setColumns(cols); } @Override public String getSQL() { return NAME + "(" + min.getSQL() + ", " + max.getSQL() + ")"; } @Override public void checkRename() { throw DbException.getUnsupportedException("SYSTEM_RANGE"); } @Override public boolean canGetRowCount() { return true; } @Override public long getRowCount(Session session) { return Math.max(0, getMax(session) - getMin(session) + 1); } @Override public String getTableType() { throw DbException.throwInternalError(); } @Override public Index getScanIndex(Session session) { return new IndexMate(this, 0, null, IndexColumn.wrap(columns), IndexType.createScan()); } /** * Calculate and get the start value of this range. * * @param session the session * @return the start value */ public long getMin(Session session) { optimize(session); return min.getValue(session).getLong(); } /** * Calculate and get the end value of this range. * * @param session the session * @return the end value */ public long getMax(Session session) { optimize(session); return max.getValue(session).getLong(); } private void optimize(Session s) { if (!optimized) { min = min.optimize(s); max = max.optimize(s); optimized = true; } } @Override public ArrayList<Index> getIndexes() { return null; } @Override public Index getUniqueIndex() { return null; } @Override public long getRowCountApproximation() { return 100; } @Override public boolean isDeterministic() { return true; } }