private object VisitExpr([NotNull] SqlParser.ExprContext context, bool considerColumnAlias) { if (context.K_IN() != null && (context.in_list_expr() != null || context.factored_select_stmt() != null)) { var result = new OperationExpression() { OperationType = OperationType.Binary, Operator = context.K_NOT() != null ? "NOT IN" : "IN", SubExpressions = new List <IExpression>() }; result.SubExpressions.Add((IExpression)VisitExpr(context.expr(0))); if (context.factored_select_stmt() != null) { var statement = (SelectStatement)VisitFactored_select_stmt(context.factored_select_stmt()); result.SubExpressions.Add(new SubQueryExpression() { Statement = statement }); } else { var listExpression = new ListExpression() { SubExpressions = new List <IExpression>() }; result.SubExpressions.Add(listExpression); foreach (var item in context.in_list_expr().expr()) { listExpression.SubExpressions.Add((IExpression)VisitExpr(item)); } } return(result); } if (context.K_EXISTS() != null && context.factored_select_stmt() != null) { var statement = (SelectStatement)VisitFactored_select_stmt(context.factored_select_stmt()); var result = new OperationExpression() { OperationType = OperationType.Unary, Operator = context.K_NOT() != null ? "NOT EXISTS" : "EXISTS", SubExpressions = new List <IExpression>() { new SubQueryExpression() { Statement = statement, } } }; return(result); } if (context.column_name() != null) { var table = context.table_name() == null ? "" : context.table_name().GetText(); var column = context.column_name().GetText(); var tableMap = queryTableStack.Peek(); var columMap = queryColumnStack.Peek(); if (considerColumnAlias && TryGetColumnExpressionByAlias(columMap, column, out var columnExpression)) { return(columnExpression); } GetTableNameAlias(tableMap, table, out var tableName, out var tableAlias); return(new ColumnExpression() { ColumnName = EscapeTableOrColumnName(column), TableName = tableName, TableAlias = tableAlias }); } if (context.function() != null) { var func = new FunctionExpression { FunctionName = context.function().function_name().GetText() }; if (!GCSqlVisitorCheck.FunctionsDict.TryGetValue(func.FunctionName, out var parametersInfo)) { throw new SQLParseException($"Not supported function '{func.FunctionName}'"); } // parameter count check var parameterCount = context.function().args_list()?.expr()?.Length ?? 0; if (parameterCount < parametersInfo.Min || parameterCount > parametersInfo.Max) { if (parametersInfo.Min == parametersInfo.Max) { throw new SQLParseException($"Not '{func.FunctionName}' function accpet {parametersInfo.Max} parameter(s)"); } else { throw new SQLParseException($"Not '{func.FunctionName}' function accpet {parametersInfo.Min} to {parametersInfo.Max} parameter(s)"); } } func.SubExpressions = new List <IExpression>(); if (context.function().args_list() != null) { if (context.function().args_list().GetText() == "*") { func.SubExpressions.Add(new KeywordExpression() { Keyword = context.function().args_list().GetText() }); } else { var exprList = context.function().args_list().expr(); if (exprList != null && exprList.Length != 0) { for (int i = 0; i < exprList.Length; i++) { var item = exprList[i]; IExpression argumentExpression = null; var descriptor = parametersInfo.Descriptors != null && i < parametersInfo.Descriptors.Length ? parametersInfo.Descriptors[i] : null; if (descriptor != null) { switch (descriptor.DescriptorType) { case ParameterDescriptorType.Enum: var parameterText = item?.GetText(); if (!descriptor.CheckParameter(parameterText)) { throw new SQLParseException($"'{parameterText}' is not a recognized datepart option."); } argumentExpression = new LiteralValueExpression() { Value = parameterText, ValueType = LiteralValueType.String, }; break; default: // do not need special handling. break; } } argumentExpression = argumentExpression ?? (IExpression)VisitExpr(item); func.SubExpressions.Add(argumentExpression); } } } } return(func); } if (context.unary_operator() != null) { var result = new OperationExpression() { OperationType = OperationType.Unary }; result.Operator = context.unary_operator().GetText().ToUpper(); result.SubExpressions = new List <IExpression> { (IExpression)VisitExpr((SqlParser.ExprContext)context.unary_operator().Parent.GetChild(1)) }; // special handling for the not exists, in order to reduce the layer of the expression if (result.SubExpressions.Count == 1 && (result.SubExpressions[0] as OperationExpression)?.Operator == "EXISTS") { ((OperationExpression)result.SubExpressions[0]).Operator = "NOT EXISTS"; return(result.SubExpressions[0]); } return(result); } if (context.BIND_PARAMETER() != null) { return(new ParamExpression() { ParamName = context.GetText() }); } if (context.ChildCount == 1) { if (context.literal_value() != null) { var value = context.literal_value(); var text = value.GetText(); if (!string.IsNullOrEmpty(text) && text.StartsWith("'") && text.EndsWith("'")) { text = text.Substring(1, text.Length - 2); } var result = new LiteralValueExpression() { Value = text }; if (value.NUMERIC_LITERAL() != null) { result.ValueType = LiteralValueType.Number; } else if (value.STRING_LITERAL() != null) { result.ValueType = LiteralValueType.String; } else if (value.NUMERIC_BOOLEAN() != null) { result.ValueType = LiteralValueType.Boolean; } else if (value.BLOB_LITERAL() != null) { result.ValueType = LiteralValueType.Blob; } else if (value.K_NULL() != null) { result.ValueType = LiteralValueType.Null; } return(result); } } else if (context.ChildCount == 2) { if (context.K_ISNULL() != null) { var result = new OperationExpression() { OperationType = OperationType.Binary, Operator = "IS" }; result.SubExpressions = new List <IExpression> { (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(0)), new LiteralValueExpression() { ValueType = LiteralValueType.Null, Value = "NULL" } }; return(result); } } else if (context.ChildCount == 3) { if (context.GetChild(0).GetText() == "(" && context.GetChild(2).GetText() == ")") { return(VisitExpr((SqlParser.ExprContext)context.GetChild(1))); } var result = new OperationExpression() { OperationType = OperationType.Binary }; var op = context.GetChild(1).GetText().ToUpper(); switch (op) { case "AND": case "OR": case "*": case "/": case "+": case "-": case "=": case "!=": case "<>": case ">": case "<": case ">=": case "<=": case "<<": case ">>": case "&": case "|": case "%": case "LIKE": { result.Operator = op; result.SubExpressions = new List <IExpression> { (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(0)), (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(2)) }; } break; case "IS": { result.SubExpressions = new List <IExpression>() { (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(0)) }; if (context.GetChild(2) is SqlParser.ExprContext exprContext) { if (exprContext.ChildCount == 2 && exprContext.unary_operator() != null && exprContext.unary_operator().K_NOT() != null && exprContext.GetChild(1).GetText().ToUpper() == "NULL") { result.Operator = "IS NOT"; result.SubExpressions.Add(new LiteralValueExpression() { Value = "NULL", ValueType = LiteralValueType.Null }); } else { result.Operator = op; result.SubExpressions.Add((IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(2))); } } else { result.Operator = op; result.SubExpressions.Add((IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(2))); } } break; } return(result); } else if (context.ChildCount == 4) { if (context.expr().Length == 2 && context.GetChild(1).GetText().ToUpper() == "NOT" && context.GetChild(2).GetText().ToUpper() == "LIKE") { var result = new OperationExpression() { OperationType = OperationType.Binary, Operator = "NOT LIKE", SubExpressions = new List <IExpression>() { (IExpression)VisitExpr(context.expr(0)), (IExpression)VisitExpr(context.expr(1)) } }; return(result); } } else if (context.ChildCount == 5 && context.expr().Length == 3 && context.GetChild(1).GetText().ToUpper() == "BETWEEN" && context.GetChild(3).GetText().ToUpper() == "AND") { return(new BetweenExpression() { SubExpressions = new List <IExpression>() { (IExpression)VisitExpr(context.expr(0)), (IExpression)VisitExpr(context.expr(1)), (IExpression)VisitExpr(context.expr(2)) } }); } return(null); }
/// <summary> /// Visit a parse tree produced by <see cref="SqlParser.expr"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitExpr([NotNull] SqlParser.ExprContext context) { return(VisitChildren(context)); }
public override object VisitExpr([NotNull] SqlParser.ExprContext context) { return(VisitExpr(context, true)); }