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 virtual DbEval ParseBase() { #if DEBUG //System.Diagnostics.Debugger.Launch(); #endif bool NOT = false; if (0 == string.Compare("NOT", PeekPart(), true)) { NextPart(); // Eat the "NOT". NOT = true; } string op; DbValue val1, val2; { { if ("(" == PeekPart()) { NextPart(); // Eat the "(". DbEval leval = ParseBase(); leval = ParsingCheckCondOp(leval); string srp = NextPart(); if (")" != srp) { throw new Exception("Expected ) not " + srp); } if (NOT) { leval = new DbEvalNot(leval); } return(ParsingCheckCondOp(leval)); } Types.ExpressionType letype; string lvalue = Types.ReadNextBasicExpression(this, out letype); val1 = ExpressionToDbValue(lvalue, letype); } op = NextPart(); if (">" == op) { if (PeekPart() == "=") { NextPart(); op = ">="; } } else if ("<" == op) { string np = PeekPart(); if (np == "=") { NextPart(); op = "<="; } else if (np == ">") { NextPart(); op = "<>"; } } else if (0 == string.Compare("IS", op, true)) { string isx = NextPart(); if (0 == string.Compare("NULL", isx, true)) { // IS NULL...? DbValue val = new FuncEvalValue(this, "ISNULL", val1); DbEval isresult = new DbEvalIntBoolValue(this, val); if (NOT) { isresult = new DbEvalNot(isresult); } return(ParsingCheckCondOp(isresult)); } else if (0 == string.Compare("NOT", isx, true)) { isx = NextPart(); if (0 == string.Compare("NULL", isx, true)) { // IS NOT NULL...? DbValue val = new FuncEvalValue(this, "ISNOTNULL", val1); DbEval isresult = new DbEvalIntBoolValue(this, val); if (NOT) { isresult = new DbEvalNot(isresult); } return(ParsingCheckCondOp(isresult)); } else { throw new Exception("Expected NULL after IS NOT, not " + isx); } } else { throw new Exception("Expected NULL or NOT NULL after IS, not " + isx); } } { if ("(" == PeekPart()) { NextPart(); // Eat the "(". DbEval reval = ParseBase(); reval = ParsingCheckCondOp(reval); string srp = NextPart(); if (")" != srp) { throw new Exception("Expected ) not " + srp); } if (NOT) { reval = new DbEvalNot(reval); } return(ParsingCheckCondOp(reval)); } Types.ExpressionType retype; string rvalue = Types.ReadNextBasicExpression(this, out retype); val2 = ExpressionToDbValue(rvalue, retype); } } DbEval result; if ("=" == op) { result = new CompareEval(this, val1, val2); } else if (">" == op) { result = new GreaterThanEval(this, val1, val2); } else if (">=" == op) { result = new GreaterThanOrEqualEval(this, val1, val2); } else if ("<" == op) { result = new LessThanEval(this, val1, val2); } else if ("<=" == op) { result = new LessThanOrEqualEval(this, val1, val2); } else if ("<>" == op) { result = new CompareNotEqualEval(this, val1, val2); } else if (0 == string.Compare(op, "LIKE", true)) { DbValue val = new FuncEvalValue(this, "ISLIKE", val1, val2); result = new DbEvalIntBoolValue(this, val); } else { throw new Exception("Unknown operation: " + op); } if (NOT) { result = new DbEvalNot(result); } return(ParsingCheckCondOp(result)); }