📄 expressionvalue.java
字号:
/* =============================================================
* SmallSQL : a free Java DBMS library for the Java(tm) platform
* =============================================================
*
* (C) Copyright 2004-2006, by Volker Berlin.
*
* Project Info: http://www.smallsql.de/
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ---------------
* ExpressionValue.java
* ---------------
* Author: Volker Berlin
*
*/
package smallsql.database;
import java.math.BigDecimal;
import java.sql.*;
public class ExpressionValue extends Expression {
private Object value;
private int dataType;
private int length;
/**
* Constructor is used from PreparedStatement parameters ( '?' in sql expression )
*/
ExpressionValue(){
super(VALUE);
clear();
}
/**
* Constructor is used from Constructor GroupResult
*/
ExpressionValue(int type){
super(type);
switch(type){
case GROUP_BY:
case SUM:
case FIRST:
case LAST:
clear();
break;
case MIN:
case MAX:
// set value to null
break;
case COUNT:
value = new MutableInteger(0);
dataType = SQLTokenizer.INT;
break;
default: throw new Error();
}
}
/**
* Constructor for static Expression i.e. 0x23, 67, 23.8, 'qwert'
*/
ExpressionValue(Object value, int dataType ){
super(VALUE);
this.value = value;
this.dataType = dataType;
}
/**
* Is used in GroupResult.
*/
public boolean equals(Object expr){
if(!super.equals(expr)) return false;
if(!(expr instanceof ExpressionValue)) return false;
Object v = ((ExpressionValue)expr).value;
if(v == value) return true;
if(value == null) return false;
return value.equals(v);
}
/*==============================================================================
methods for Grouping
==============================================================================*/
/**
* Accumulate the value of the expression to this aggregate function value.
*/
void accumulate(Expression expr) throws Exception{
int type = getType();
if(type != GROUP_BY) expr = expr.getParams()[0];
switch(type){
case GROUP_BY:
case FIRST:
if(isEmpty()) set( expr.getObject(), expr.getDataType() );
break;
case LAST:
set( expr.getObject(), expr.getDataType() );
break;
case COUNT:
if(!expr.isNull()) ((MutableInteger)value).value++;
break;
case SUM:
if(isEmpty()){
initValue( expr );
}else
switch(dataType){
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
((MutableInteger)value).value += expr.getInt();
break;
case SQLTokenizer.BIGINT:
((MutableLong)value).value += expr.getLong();
break;
case SQLTokenizer.REAL:
((MutableFloat)value).value += expr.getFloat();
break;
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
((MutableDouble)value).value += expr.getDouble();
break;
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
MutableNumeric newValue = expr.getNumeric();
if(newValue != null)
((MutableNumeric)value).add( newValue );
break;
case SQLTokenizer.MONEY:
((Money)value).value += expr.getMoney();
break;
default: throw Utils.createSQLException("Unsupported data type "+SQLTokenizer.getKeyWord(dataType) +" for SUM function.");
}
break;
case MAX:
if(value == null){
if(expr.isNull())
dataType = expr.getDataType();
else
initValue( expr );
}else if(!expr.isNull()){
switch(dataType){
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
((MutableInteger)value).value = Math.max( ((MutableInteger)value).value, expr.getInt());
break;
case SQLTokenizer.BIGINT:
((MutableLong)value).value = Math.max( ((MutableLong)value).value, expr.getLong());
break;
case SQLTokenizer.REAL:
((MutableFloat)value).value = Math.max( ((MutableFloat)value).value, expr.getFloat());
break;
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
((MutableDouble)value).value = Math.max( ((MutableDouble)value).value, expr.getDouble());
break;
case SQLTokenizer.CHAR:
case SQLTokenizer.VARCHAR:
case SQLTokenizer.LONGVARCHAR:
String str = expr.getString();
if(String.CASE_INSENSITIVE_ORDER.compare( (String)value, str ) < 0) //cast needed for Compiler 1.5
value = str;
break;
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
MutableNumeric newValue = expr.getNumeric();
if(((MutableNumeric)value).compareTo( newValue ) < 0)
value = newValue;
break;
case SQLTokenizer.MONEY:
((Money)value).value = Math.max( ((Money)value).value, expr.getMoney());
break;
case SQLTokenizer.TIMESTAMP:
case SQLTokenizer.SMALLDATETIME:
case SQLTokenizer.DATE:
case SQLTokenizer.TIME:
((DateTime)value).time = Math.max( ((DateTime)value).time, expr.getLong());
break;
default: throw new Error(""+dataType);
}
}
break;
case MIN:
if(value == null){
if(expr.isNull())
dataType = expr.getDataType();
else
initValue( expr );
}else if(!expr.isNull()){
switch(dataType){
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
((MutableInteger)value).value = Math.min( ((MutableInteger)value).value, expr.getInt());
break;
case SQLTokenizer.BIGINT:
((MutableLong)value).value = Math.min( ((MutableLong)value).value, expr.getLong());
break;
case SQLTokenizer.REAL:
((MutableFloat)value).value = Math.min( ((MutableFloat)value).value, expr.getFloat());
break;
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
((MutableDouble)value).value = Math.min( ((MutableDouble)value).value, expr.getDouble());
break;
case SQLTokenizer.CHAR:
case SQLTokenizer.VARCHAR:
case SQLTokenizer.LONGVARCHAR:
String str = expr.getString();
if(String.CASE_INSENSITIVE_ORDER.compare( (String)value, str ) > 0) //cast needed for Compiler 1.5
value = str;
break;
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
MutableNumeric newValue = expr.getNumeric();
if(((MutableNumeric)value).compareTo( newValue ) > 0)
value = newValue;
break;
case SQLTokenizer.MONEY:
((Money)value).value = Math.min( ((Money)value).value, expr.getMoney());
break;
case SQLTokenizer.TIMESTAMP:
case SQLTokenizer.SMALLDATETIME:
case SQLTokenizer.DATE:
case SQLTokenizer.TIME:
((DateTime)value).time = Math.min( ((DateTime)value).time, expr.getLong());
break;
default: throw new Error(""+dataType);
}
}
break;
default: throw new Error();
}
}
/**
* Init a summary field with a Mutable
* @param expr the expression that produce the values which should be summary
* @throws Exception
*/
private void initValue(Expression expr) throws Exception{
dataType = expr.getDataType();
switch(dataType){
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
value = new MutableInteger(expr.getInt());
break;
case SQLTokenizer.BIGINT:
value = new MutableLong(expr.getLong());
break;
case SQLTokenizer.REAL:
value = new MutableFloat(expr.getFloat());
break;
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
value = new MutableDouble(expr.getDouble());
break;
case SQLTokenizer.SMALLMONEY:
case SQLTokenizer.MONEY:
value = Money.createFromUnscaledValue(expr.getMoney());
break;
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
value = new MutableNumeric(expr.getNumeric());
break;
case SQLTokenizer.TIMESTAMP:
case SQLTokenizer.SMALLDATETIME:
case SQLTokenizer.DATE:
case SQLTokenizer.TIME:
value = new DateTime(expr.getLong(), dataType);
break;
default:
// is used for MAX and MIN
value = expr.getObject();
}
}
/*==============================================================================
methods for PreparedStatement parameters
==============================================================================*/
private static final Object EMPTY = new Object();
final boolean isEmpty(){
return value == EMPTY;
}
final void clear(){
value = EMPTY;
}
final void set( Object value, int _dataType, int length ) throws SQLException{
set( value, _dataType );
this.length = length;
}
/**
*
* @param newValue The new Value.
* @param newDataType The data type of the new Value (One of the SQLTokenizer const).
* If the type is -1 then the data type is verify with many instanceof expressions.
* @throws SQLException If the newValue is not a instance of a know class.
*/
final void set( Object newValue, int newDataType ) throws SQLException{
this.value = newValue;
this.dataType = newDataType;
if(dataType < 0){
if(newValue == null)
this.dataType = SQLTokenizer.NULL;
else
if(newValue instanceof String)
this.dataType = SQLTokenizer.VARCHAR;
else
if(newValue instanceof Byte)
this.dataType = SQLTokenizer.TINYINT;
else
if(newValue instanceof Short)
this.dataType = SQLTokenizer.SMALLINT;
else
if(newValue instanceof Integer)
this.dataType = SQLTokenizer.INT;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -