BosCollege-SimpleDB-FLOAT数据类型支持

2018-11-13  本文已影响0人  ArthurN

Author: Sixing Yan

在SimpleDB-2.10中,数据库系统仅支持Int型和String型数据,即创建的schema仅支持 intvarchar 类型的数据。在SimpleDB-3.0中,我们增加了对FLOAT型数据的支持。

1. Constant

在SimpleDB中,存储的数据都是Constant型的数据,即都实现了Constant 这个接口。而Int和String数据则被实现为 IntConstant 类和 StringConstant 类。观察Constant接口以及IntConstant类的代码,我们可以实现float型数据类,即FloatConstant 类。

package simpledb.query;
/**
 * The class that wraps Java floats as database constants.
 * @author Sixing Yan
 */
public class FloatConstant implements Constant {
   private float val;
   public FloatConstant(float n) {val = n;}
   public Object asJavaVal() {return val;}
   public boolean equals(Object obj) {
      FloatConstant ic = (FloatConstant) obj;
      return ic != null && val.equals(ic.val);}
   public int compareTo(Constant c) {
      FloatConstant ic = (FloatConstant) c;
      return val.compareTo(ic.val);}
   public int hashCode() {return val.hashCode();}
   public String toString() {return val.toString();}
}

增加后float类的SimpleDB实现后,我们还要相应地让SimpleDB的Schema功能、Parse功能和Lexer功能支持float类。其中Schema功能与表的结构相关,Parse功能与SQL执行命令相关, Lexer功能与SQL语法解析相关。

2. Schema

对于Schema功能(类),增加AddFloatField方法。 这里我们设计语句只支持 float 而不支持 float(b) 这样的语法,因为 float(b) 的参数 b 指代二进制进度,而不是一般意义上的小数点精度,这样的含义容易让一般用户迷惑。所以这里只简单的实现 float

FLOAT(b) specifies a floating-point number with binary precision b. The precision b can range from 1 to 126. To convert from binary to decimal precision, multiply b by 0.30103. ---Oracle Online Help

public class Schema {
    ...
    /**
     * Adds an float field to the schema.
     * @param fldname the name of the field
     */
    public void addFloatField(String fldname) {addField(fldname, FLOAT, 0); }
    ...
}

3.Parse

对于Perse功能(类),增加对“float”关键字的判断。如果有,则对schema添加Float类型的数据。

public class Parser {
    ...
    public Constant constant() {
        if (lex.matchStringConstant())
            return new StringConstant(lex.eatStringConstant());
        else if (lex.matchFloatConstant())
            return new FloatConstant(lex.eatFloatConstant());
        else
            return new IntConstant(lex.eatIntConstant());
    }
    /**
     * Returns true if both of the term's expressions
     * evaluate to the same constant,
     * Only work with 'primary key'
     * @param fldname the scan
     * @return true if both expressions have the same value in the scan
    */
    private Schema fieldType(String fldname) {
        Schema schema = new Schema();
        if (lex.matchKeyword("int")) {
           ...
        } else if (lex.matchKeyword("varchar")) {
            ...
        } else {
            lex.eatKeyword("float");
            int strLen = lex.eatFloatConstant();
            schema.addFloatField(fldname, strLen);
        }
        return schema;}
    ...
}

4. Lexer

对于Lexer功能(类),增加对“float”型数据的检查和抽取。Lexer主要通过检测是否匹配,与抽取该位置的数值两部分组成,方法名为matchXXX() 和 eatXXX(),例如matchId和eatId等方法。其中matchFloatConstant只需判断当前数值是否为数字,而eatFloatConstant将输入的字符串转换成float型数据即可。

public class Lexer {
    ...
    /**
     * Returns true if the current token is a number.
     * @return true if the current token is a number
     */
    public boolean matchFloatConstant() {
        return tok.ttype == StreamTokenizer.TT_NUMBER;
    }
    /**
     * Throws an exception if the current token is not a float.
     * Otherwise, returns that string and moves to the next token.
     * @return the string value of the current token
     */
    public float eatFloatConstant() {
        if (!matchFloatConstant()) throw new BadSyntaxException();
        float i = new Float(tok.nval);
        nextToken();
        return i;}
    ...
    private void initKeywords() { keywords = Arrays.asList(..., "float", ...);}
}
上一篇下一篇

猜你喜欢

热点阅读