コード例 #1
0
        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);
        }
コード例 #2
0
 /// <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));
 }
コード例 #3
0
 public override object VisitExpr([NotNull] SqlParser.ExprContext context)
 {
     return(VisitExpr(context, true));
 }