public static DbValue MUL(DbFunctionTools tools, DbFunctionArguments args) { string FunctionName = "MUL"; args.EnsureCount(FunctionName, 2); DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); if (Types.IsNullValue(arg0)) { return(tools.AllocValue(arg0, arg0type)); // Give a null, take a null. } DbType arg1type; ByteSlice arg1 = args[1].Eval(out arg1type); if (Types.IsNullValue(arg1)) { return(tools.AllocValue(arg1, arg1type)); // Give a null, take a null. } switch (arg0type.ID) { case DbTypeID.INT: { int x = tools.GetInt(arg0); switch (arg1type.ID) { case DbTypeID.INT: { int y = tools.GetInt(arg1); return(tools.AllocValue(x * y)); } break; case DbTypeID.LONG: { long y = tools.GetLong(arg1); return(tools.AllocValue(x * y)); } break; case DbTypeID.DOUBLE: { double y = tools.GetDouble(arg1); return(tools.AllocValue(x * y)); } break; default: args.Expected(FunctionName, 1, "input INT, LONG or DOUBLE, got " + arg1type.Name.ToUpper()); return(null); // Doesn't reach here. } } break; case DbTypeID.LONG: { long x = tools.GetLong(arg0); switch (arg1type.ID) { case DbTypeID.INT: { int y = tools.GetInt(arg1); return(tools.AllocValue(x * y)); } break; case DbTypeID.LONG: { long y = tools.GetLong(arg1); return(tools.AllocValue(x * y)); } break; case DbTypeID.DOUBLE: { double y = tools.GetDouble(arg1); return(tools.AllocValue(x * y)); } break; default: args.Expected(FunctionName, 1, "input INT, LONG or DOUBLE, got " + arg1type.Name.ToUpper()); return(null); // Doesn't reach here. } } break; case DbTypeID.DOUBLE: { double x = tools.GetDouble(arg0); switch (arg1type.ID) { case DbTypeID.INT: { int y = tools.GetInt(arg1); return(tools.AllocValue(x * y)); } break; case DbTypeID.LONG: { long y = tools.GetLong(arg1); return(tools.AllocValue(x * y)); } break; case DbTypeID.DOUBLE: { double y = tools.GetDouble(arg1); return(tools.AllocValue(x * y)); } break; default: args.Expected(FunctionName, 1, "input INT, LONG or DOUBLE, got " + arg1type.Name.ToUpper()); return(null); // Doesn't reach here. } } break; default: args.Expected(FunctionName, 0, "input INT, LONG or DOUBLE, got " + arg0type.Name.ToUpper()); return(null); // Doesn't reach here. } }
DbValue ExpressionToDbValue(string value, Types.ExpressionType etype) { switch(etype) { case Types.ExpressionType.FUNCTION: { int ilp = value.IndexOf('('); #if DEBUG if (-1 == ilp) { throw new Exception("DEBUG: ExpressionToDbValue: function expects ("); } if (!value.EndsWith(")")) { throw new Exception("DEBUG: ExpressionToDbValue: function expects )"); } #endif string fname = value.Substring(0, ilp); string sargs = value.Substring(ilp + 1, value.Length - ilp - 1 - 1); List<DbValue> args = new List<DbValue>(); StringPartReader argsparser = new StringPartReader(sargs); if (argsparser.PeekPart().Length != 0) { for (; ; ) { if (0 == string.Compare("AS", argsparser.PeekPart(), true)) { argsparser.NextPart(); // Eat "AS". { StringBuilder sbas = new StringBuilder(); int asparens = 0; for (; ; ) { string s = argsparser.PeekPart(); if (0 == s.Length || "," == s) { break; } else if ("(" == s) { asparens++; sbas.Append(argsparser.NextPart()); } else if (")" == s) { if (0 == asparens) { break; } asparens--; sbas.Append(argsparser.NextPart()); } else { sbas.Append(argsparser.NextPart()); } } if (0 == sbas.Length) { throw new Exception("Expected type after AS"); } args.Add(ExpressionToDbValue("'AS " + sbas.Replace("'", "''") + "'", Types.ExpressionType.AS)); } } else { string argvalue; Types.ExpressionType argetype; argvalue = Types.ReadNextBasicExpression(argsparser, out argetype); args.Add(ExpressionToDbValue(argvalue, argetype)); } { string s = argsparser.PeekPart(); if (s != ",") { if (0 == string.Compare("AS", s, true)) { continue; } if (s.Length != 0) { throw new Exception("Unexpected in function arguments: " + argsparser.RemainingString); } break; } } argsparser.NextPart(); // Eat the ','. } } return new FuncEvalValue(this, fname, args); } break; case Types.ExpressionType.NAME: { int FieldIndex = _IndexOfRowColType_ensure(value); return new ColValue(this, ColumnTypes[FieldIndex]); } break; case Types.ExpressionType.NUMBER: case Types.ExpressionType.STRING: case Types.ExpressionType.AS: case Types.ExpressionType.NULL: { DbTypeID id; ByteSlice bs = Types.LiteralToValue(value, out id); return new ImmediateValue(this, bs, DbType.Prepare(bs.Length, id)); } break; default: throw new Exception("Unexpected value: " + value); } }
public static DbValue IIF(DbFunctionTools tools, DbFunctionArguments args) { string FunctionName = "IIF"; args.EnsureCount(FunctionName, 3); DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); DbType arg1type; ByteSlice arg1 = args[1].Eval(out arg1type); DbType arg2type; ByteSlice arg2 = args[2].Eval(out arg2type); bool truecond; if (Types.IsNullValue(arg0)) { truecond = false; } else if (DbTypeID.INT == arg0type.ID) { truecond = 0 != tools.GetInt(arg0); } else if (DbTypeID.LONG == arg0type.ID) { truecond = 0 != tools.GetLong(arg0); } else if (DbTypeID.DOUBLE == arg0type.ID) { truecond = 0 != tools.GetDouble(arg0); } else { bool allzero = true; for (int i = 1; i < arg0.Length; i++) { if (arg0[i] != 0) { allzero = false; break; } } truecond = !allzero; } byte[] resultbuf = new byte[arg1.Length > arg2.Length ? arg1.Length : arg2.Length]; DbType resulttype; if (truecond) { resulttype = DbType.Prepare(resultbuf.Length, arg1type.ID); for (int i = 0; i < arg1.Length; i++) { resultbuf[i] = arg1[i]; } } else { resulttype = DbType.Prepare(resultbuf.Length, arg2type.ID); for (int i = 0; i < arg2.Length; i++) { resultbuf[i] = arg2[i]; } } return(tools.AllocValue(ByteSlice.Prepare(resultbuf), resulttype)); }