Example #1
0
        internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Now": return("now()");

                case "UtcNow": return("utc_timestamp()");

                case "Today": return("curdate()");

                case "MinValue": return("cast('0001/1/1 0:00:00' as datetime)");

                case "MaxValue": return("cast('9999/12/31 23:59:59' as datetime)");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Date": return($"cast(date_format({left},'%Y-%m-%d') as datetime)");

            case "TimeOfDay": return($"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})");

            case "DayOfWeek": return($"(dayofweek({left})-1)");

            case "Day": return($"dayofmonth({left})");

            case "DayOfYear": return($"dayofyear({left})");

            case "Month": return($"month({left})");

            case "Year": return($"year({left})");

            case "Hour": return($"hour({left})");

            case "Minute": return($"minute({left})");

            case "Second": return($"second({left})");

            case "Millisecond": return($"floor(microsecond({left})/1000)");

            case "Ticks": return($"(timestampdiff(microsecond, '0001-1-1', {left})*10)");
            }
            return(null);
        }
Example #2
0
        internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Zero": return("0");

                case "MinValue": return("-922337203685477580");                        //微秒 Ticks / 10

                case "MaxValue": return("922337203685477580");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Days": return($"(({left}) div {(long)1000000 * 60 * 60 * 24})");

            case "Hours": return($"(({left}) div {(long)1000000 * 60 * 60} mod 24)");

            case "Milliseconds": return($"(({left}) div 1000 mod 1000)");

            case "Minutes": return($"(({left}) div {(long)1000000 * 60} mod 60)");

            case "Seconds": return($"(({left}) div 1000000 mod 60)");

            case "Ticks": return($"(({left}) * 10)");

            case "TotalDays": return($"(({left}) / {(long)1000000 * 60 * 60 * 24})");

            case "TotalHours": return($"(({left}) / {(long)1000000 * 60 * 60})");

            case "TotalMilliseconds": return($"(({left}) / 1000)");

            case "TotalMinutes": return($"(({left}) / {(long)1000000 * 60})");

            case "TotalSeconds": return($"(({left}) / 1000000)");
            }
            return(null);
        }
Example #3
0
        internal override string ExpressionLambdaToSqlOther(Expression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            Func <Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.NodeType)
            {
            case ExpressionType.Convert:
                var operandExp = (exp as UnaryExpression)?.Operand;
                var gentype    = exp.Type.NullableTypeOrThis();
                if (gentype != exp.Type.NullableTypeOrThis())
                {
                    switch (exp.Type.NullableTypeOrThis().ToString())
                    {
                    case "System.Boolean": return($"({getExp(operandExp)} not in ('0','false'))");

                    case "System.Byte": return($"cast({getExp(operandExp)} as unsigned)");

                    case "System.Char": return($"substr(cast({getExp(operandExp)} as char), 1, 1)");

                    case "System.DateTime": return($"cast({getExp(operandExp)} as datetime)");

                    case "System.Decimal": return($"cast({getExp(operandExp)} as decimal(36,18))");

                    case "System.Double": return($"cast({getExp(operandExp)} as decimal(32,16))");

                    case "System.Int16":
                    case "System.Int32":
                    case "System.Int64":
                    case "System.SByte": return($"cast({getExp(operandExp)} as signed)");

                    case "System.Single": return($"cast({getExp(operandExp)} as decimal(14,7))");

                    case "System.String": return($"cast({getExp(operandExp)} as char)");

                    case "System.UInt16":
                    case "System.UInt32":
                    case "System.UInt64": return($"cast({getExp(operandExp)} as unsigned)");

                    case "System.Guid": return($"substr(cast({getExp(operandExp)} as char), 1, 36)");
                    }
                }
                break;

            case ExpressionType.Call:
                var callExp = exp as MethodCallExpression;

                switch (callExp.Method.Name)
                {
                case "Parse":
                case "TryParse":
                    switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString())
                    {
                    case "System.Boolean": return($"({getExp(callExp.Arguments[0])} not in ('0','false'))");

                    case "System.Byte": return($"cast({getExp(callExp.Arguments[0])} as unsigned)");

                    case "System.Char": return($"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)");

                    case "System.DateTime": return($"cast({getExp(callExp.Arguments[0])} as datetime)");

                    case "System.Decimal": return($"cast({getExp(callExp.Arguments[0])} as decimal(36,18))");

                    case "System.Double": return($"cast({getExp(callExp.Arguments[0])} as decimal(32,16))");

                    case "System.Int16":
                    case "System.Int32":
                    case "System.Int64":
                    case "System.SByte": return($"cast({getExp(callExp.Arguments[0])} as signed)");

                    case "System.Single": return($"cast({getExp(callExp.Arguments[0])} as decimal(14,7))");

                    case "System.UInt16":
                    case "System.UInt32":
                    case "System.UInt64": return($"cast({getExp(callExp.Arguments[0])} as unsigned)");

                    case "System.Guid": return($"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)");
                    }
                    break;

                case "NewGuid":
                    break;

                case "Next":
                    if (callExp.Object?.Type == typeof(Random))
                    {
                        return("cast(rand()*1000000000 as signed)");
                    }
                    break;

                case "NextDouble":
                    if (callExp.Object?.Type == typeof(Random))
                    {
                        return("rand()");
                    }
                    break;

                case "Random":
                    if (callExp.Method.DeclaringType.IsNumberType())
                    {
                        return("rand()");
                    }
                    break;

                case "ToString":
                    if (callExp.Object != null)
                    {
                        return($"cast({getExp(callExp.Object)} as char)");
                    }
                    break;
                }

                var objExp  = callExp.Object;
                var objType = objExp?.Type;
                if (objType?.FullName == "System.Byte[]")
                {
                    return(null);
                }

                var argIndex = 0;
                if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable))
                {
                    objExp  = callExp.Arguments.FirstOrDefault();
                    objType = objExp?.Type;
                    argIndex++;
                }
                if (objType == null)
                {
                    objType = callExp.Method.DeclaringType;
                }
                if (objType != null)
                {
                    var left = objExp == null ? null : getExp(objExp);
                    if (objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
                    {
                        switch (callExp.Method.Name)
                        {
                        case "Contains":
                            //判断 in
                            return($"({getExp(callExp.Arguments[argIndex])}) in {left}");
                        }
                    }
                }
                break;

            case ExpressionType.NewArrayInit:
                var arrExp = exp as NewArrayExpression;
                var arrSb  = new StringBuilder();
                arrSb.Append("(");
                for (var a = 0; a < arrExp.Expressions.Count; a++)
                {
                    if (a > 0)
                    {
                        arrSb.Append(",");
                    }
                    arrSb.Append(getExp(arrExp.Expressions[a]));
                }
                if (arrSb.Length == 1)
                {
                    arrSb.Append("NULL");
                }
                return(arrSb.Append(")").ToString());

            case ExpressionType.ListInit:
                var listExp = exp as ListInitExpression;
                var listSb  = new StringBuilder();
                listSb.Append("(");
                for (var a = 0; a < listExp.Initializers.Count; a++)
                {
                    if (listExp.Initializers[a].Arguments.Any() == false)
                    {
                        continue;
                    }
                    if (a > 0)
                    {
                        listSb.Append(",");
                    }
                    listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault()));
                }
                if (listSb.Length == 1)
                {
                    listSb.Append("NULL");
                }
                return(listSb.Append(")").ToString());

            case ExpressionType.New:
                var newExp = exp as NewExpression;
                if (typeof(IList).IsAssignableFrom(newExp.Type))
                {
                    if (newExp.Arguments.Count == 0)
                    {
                        return("(NULL)");
                    }
                    if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false)
                    {
                        return("(NULL)");
                    }
                    return(getExp(newExp.Arguments[0]));
                }
                return(null);
            }
            return(null);
        }
Example #4
0
        internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Empty": return("''");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Length": return($"char_length({left})");
            }
            return(null);
        }
Example #5
0
        internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Now": return("datetime(current_timestamp,'localtime')");

                case "UtcNow": return("current_timestamp");

                case "Today": return("date(current_timestamp,'localtime')");

                case "MinValue": return("datetime('0001-01-01 00:00:00.000')");

                case "MaxValue": return("datetime('9999-12-31 23:59:59.999')");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Date": return($"date({left})");

            case "TimeOfDay": return($"strftime('%s',{left})");

            case "DayOfWeek": return($"strftime('%w',{left})");

            case "Day": return($"strftime('%d',{left})");

            case "DayOfYear": return($"strftime('%j',{left})");

            case "Month": return($"strftime('%m',{left})");

            case "Year": return($"strftime('%Y',{left})");

            case "Hour": return($"strftime('%H',{left})");

            case "Minute": return($"strftime('%M',{left})");

            case "Second": return($"strftime('%S',{left})");

            case "Millisecond": return($"(strftime('%f',{left})-strftime('%S',{left}))");

            case "Ticks": return($"(strftime('%s',{left})*10000000+621355968000000000)");
            }
            return(null);
        }
Example #6
0
        internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            Func <Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            if (exp.Object == null)
            {
                switch (exp.Method.Name)
                {
                case "IsNullOrEmpty":
                    var arg1 = getExp(exp.Arguments[0]);
                    return($"({arg1} is null or {arg1} = '')");
                }
            }
            else
            {
                var left = getExp(exp.Object);
                switch (exp.Method.Name)
                {
                case "StartsWith":
                case "EndsWith":
                case "Contains":
                    var args0Value = getExp(exp.Arguments[0]);
                    if (args0Value == "NULL")
                    {
                        return($"({left}) IS NULL");
                    }
                    if (exp.Method.Name == "StartsWith")
                    {
                        return($"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"({args0Value})||'%'")}");
                    }
                    if (exp.Method.Name == "EndsWith")
                    {
                        return($"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"'%'||({args0Value})")}");
                    }
                    if (args0Value.StartsWith("'") && args0Value.EndsWith("'"))
                    {
                        return($"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}");
                    }
                    return($"({left}) LIKE '%'||({args0Value})||'%'");
Example #7
0
        internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Now": return("current_timestamp");

                case "UtcNow": return("(current_timestamp at time zone 'UTC')");

                case "Today": return("current_date");

                case "MinValue": return("'0001/1/1 0:00:00'::timestamp");

                case "MaxValue": return("'9999/12/31 23:59:59'::timestamp");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Date": return($"({left})::date");

            case "TimeOfDay": return($"(extract(epoch from ({left})::time)*1000000)");

            case "DayOfWeek": return($"extract(dow from ({left})::timestamp)");

            case "Day": return($"extract(day from ({left})::timestamp)");

            case "DayOfYear": return($"extract(doy from ({left})::timestamp)");

            case "Month": return($"extract(month from ({left})::timestamp)");

            case "Year": return($"extract(year from ({left})::timestamp)");

            case "Hour": return($"extract(hour from ({left})::timestamp)");

            case "Minute": return($"extract(minute from ({left})::timestamp)");

            case "Second": return($"extract(second from ({left})::timestamp)");

            case "Millisecond": return($"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)");

            case "Ticks": return($"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)");
            }
            return(null);
        }
Example #8
0
        internal override string ExpressionLambdaToSqlOther(Expression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            Func <Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.NodeType)
            {
            case ExpressionType.Convert:
                var operandExp = (exp as UnaryExpression)?.Operand;
                var gentype    = exp.Type.NullableTypeOrThis();
                if (gentype != exp.Type.NullableTypeOrThis())
                {
                    switch (exp.Type.NullableTypeOrThis().ToString())
                    {
                    case "System.Boolean": return($"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))");

                    case "System.Byte": return($"({getExp(operandExp)})::int2");

                    case "System.Char": return($"substr(({getExp(operandExp)})::char, 1, 1)");

                    case "System.DateTime": return($"({getExp(operandExp)})::timestamp");

                    case "System.Decimal": return($"({getExp(operandExp)})::numeric");

                    case "System.Double": return($"({getExp(operandExp)})::float8");

                    case "System.Int16": return($"({getExp(operandExp)})::int2");

                    case "System.Int32": return($"({getExp(operandExp)})::int4");

                    case "System.Int64": return($"({getExp(operandExp)})::int8");

                    case "System.SByte": return($"({getExp(operandExp)})::int2");

                    case "System.Single": return($"({getExp(operandExp)})::float4");

                    case "System.String": return($"({getExp(operandExp)})::varchar");

                    case "System.UInt16": return($"({getExp(operandExp)})::int2");

                    case "System.UInt32": return($"({getExp(operandExp)})::int4");

                    case "System.UInt64": return($"({getExp(operandExp)})::int8");

                    case "System.Guid": return($"({getExp(operandExp)})::uuid");
                    }
                }
                break;

            case ExpressionType.ArrayLength:
                var arrOperExp = getExp((exp as UnaryExpression).Operand);
                if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")"))
                {
                    return($"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)");
                }
                return($"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end");

            case ExpressionType.Call:
                var callExp = exp as MethodCallExpression;

                switch (callExp.Method.Name)
                {
                case "Parse":
                case "TryParse":
                    switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString())
                    {
                    case "System.Boolean": return($"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))");

                    case "System.Byte": return($"({getExp(callExp.Arguments[0])})::int2");

                    case "System.Char": return($"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)");

                    case "System.DateTime": return($"({getExp(callExp.Arguments[0])})::timestamp");

                    case "System.Decimal": return($"({getExp(callExp.Arguments[0])})::numeric");

                    case "System.Double": return($"({getExp(callExp.Arguments[0])})::float8");

                    case "System.Int16": return($"({getExp(callExp.Arguments[0])})::int2");

                    case "System.Int32": return($"({getExp(callExp.Arguments[0])})::int4");

                    case "System.Int64": return($"({getExp(callExp.Arguments[0])})::int8");

                    case "System.SByte": return($"({getExp(callExp.Arguments[0])})::int2");

                    case "System.Single": return($"({getExp(callExp.Arguments[0])})::float4");

                    case "System.UInt16": return($"({getExp(callExp.Arguments[0])})::int2");

                    case "System.UInt32": return($"({getExp(callExp.Arguments[0])})::int4");

                    case "System.UInt64": return($"({getExp(callExp.Arguments[0])})::int8");

                    case "System.Guid": return($"({getExp(callExp.Arguments[0])})::uuid");
                    }
                    break;

                case "NewGuid":
                    break;

                case "Next":
                    if (callExp.Object?.Type == typeof(Random))
                    {
                        return("(random()*1000000000)::int4");
                    }
                    break;

                case "NextDouble":
                    if (callExp.Object?.Type == typeof(Random))
                    {
                        return("random()");
                    }
                    break;

                case "Random":
                    if (callExp.Method.DeclaringType.IsNumberType())
                    {
                        return("random()");
                    }
                    break;

                case "ToString":
                    if (callExp.Object != null)
                    {
                        return($"({getExp(callExp.Object)})::varchar");
                    }
                    break;
                }

                var objExp  = callExp.Object;
                var objType = objExp?.Type;
                if (objType?.FullName == "System.Byte[]")
                {
                    return(null);
                }

                var argIndex = 0;
                if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable))
                {
                    objExp  = callExp.Arguments.FirstOrDefault();
                    objType = objExp?.Type;
                    argIndex++;
                }
                if (objType == null)
                {
                    objType = callExp.Method.DeclaringType;
                }
                if (objType != null)
                {
                    var left = objExp == null ? null : getExp(objExp);
                    switch (objType.FullName)
                    {
                    case "Newtonsoft.Json.Linq.JToken":
                    case "Newtonsoft.Json.Linq.JObject":
                    case "Newtonsoft.Json.Linq.JArray":
                        switch (callExp.Method.Name)
                        {
                        case "Any": return($"(jsonb_array_length(coalesce({left},'[]')) > 0)");

                        case "Contains":
                            var json = getExp(callExp.Arguments[argIndex]);
                            if (json.StartsWith("'") && json.EndsWith("'"))
                            {
                                return($"(coalesce({left},'{{}}') @> {_common.FormatSql("{0}", JToken.Parse(json.Trim('\'')))})");
                            }
                            return($"(coalesce({left},'{{}}') @> ({json})::jsonb)");

                        case "ContainsKey": return($"(coalesce({left},'{{}}') ? {getExp(callExp.Arguments[argIndex])})");

                        case "Concat":
                            var right2 = getExp(callExp.Arguments[argIndex]);
                            return($"(coalesce({left},'{{}}') || {right2})");

                        case "LongCount":
                        case "Count": return($"jsonb_array_length(coalesce({left},'[]'))");

                        case "Parse":
                            var json2 = getExp(callExp.Arguments[argIndex]);
                            if (json2.StartsWith("'") && json2.EndsWith("'"))
                            {
                                return(_common.FormatSql("{0}", JToken.Parse(json2.Trim('\''))));
                            }
                            return($"({json2})::jsonb");
                        }
                        break;
                    }
                    if (objType.FullName == typeof(Dictionary <string, string>).FullName)
                    {
                        switch (callExp.Method.Name)
                        {
                        case "Contains":
                            var right = getExp(callExp.Arguments[argIndex]);
                            return($"({left} @> ({right}))");

                        case "ContainsKey": return($"({left} ? {getExp(callExp.Arguments[argIndex])})");

                        case "Concat": return($"({left} || {getExp(callExp.Arguments[argIndex])})");

                        case "GetLength":
                        case "GetLongLength":
                        case "Count": return($"case when {left} is null then 0 else array_length(akeys({left}),1) end");

                        case "Keys": return($"akeys({left})");

                        case "Values": return($"avals({left})");
                        }
                    }
                    if (objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
                    {
                        switch (callExp.Method.Name)
                        {
                        case "Any":
                            if (left.StartsWith("(") || left.EndsWith(")"))
                            {
                                left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
                            }
                            return($"(case when {left} is null then 0 else array_length({left},1) end > 0)");

                        case "Contains":
                            //判断 in 或 array @> array
                            var right1 = getExp(callExp.Arguments[argIndex]);
                            if (left.StartsWith("array[") || left.EndsWith("]"))
                            {
                                return($"{right1} in ({left.Substring(6, left.Length - 7)})");
                            }
                            if (left.StartsWith("(") || left.EndsWith(")"))
                            {
                                return($"{right1} in {left}");
                            }
                            if (right1.StartsWith("(") || right1.EndsWith(")"))
                            {
                                right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]";
                            }
                            return($"({left} @> array[{right1}])");

                        case "Concat":
                            if (left.StartsWith("(") || left.EndsWith(")"))
                            {
                                left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
                            }
                            var right2 = getExp(callExp.Arguments[argIndex]);
                            if (right2.StartsWith("(") || right2.EndsWith(")"))
                            {
                                right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
                            }
                            return($"({left} || {right2})");

                        case "GetLength":
                        case "GetLongLength":
                        case "Length":
                        case "Count":
                            if (left.StartsWith("(") || left.EndsWith(")"))
                            {
                                left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
                            }
                            return($"case when {left} is null then 0 else array_length({left},1) end");
                        }
                    }
                }
                break;

            case ExpressionType.MemberAccess:
                var memExp       = exp as MemberExpression;
                var memParentExp = memExp.Expression?.Type;
                if (memParentExp?.FullName == "System.Byte[]")
                {
                    return(null);
                }
                if (memParentExp != null)
                {
                    if (memParentExp.IsArray == true)
                    {
                        var left = getExp(memExp.Expression);
                        if (left.StartsWith("(") || left.EndsWith(")"))
                        {
                            left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
                        }
                        switch (memExp.Member.Name)
                        {
                        case "Length":
                        case "Count": return($"case when {left} is null then 0 else array_length({left},1) end");
                        }
                    }
                    switch (memParentExp.FullName)
                    {
                    case "Newtonsoft.Json.Linq.JToken":
                    case "Newtonsoft.Json.Linq.JObject":
                    case "Newtonsoft.Json.Linq.JArray":
                        var left = getExp(memExp.Expression);
                        switch (memExp.Member.Name)
                        {
                        case "Count": return($"jsonb_array_length(coalesce({left},'[]'))");
                        }
                        break;
                    }
                    if (memParentExp.FullName == typeof(Dictionary <string, string>).FullName)
                    {
                        var left = getExp(memExp.Expression);
                        switch (memExp.Member.Name)
                        {
                        case "Count": return($"case when {left} is null then 0 else array_length(akeys({left}),1) end");

                        case "Keys": return($"akeys({left})");

                        case "Values": return($"avals({left})");
                        }
                    }
                }
                break;

            case ExpressionType.NewArrayInit:
                var arrExp = exp as NewArrayExpression;
                var arrSb  = new StringBuilder();
                arrSb.Append("array[");
                for (var a = 0; a < arrExp.Expressions.Count; a++)
                {
                    if (a > 0)
                    {
                        arrSb.Append(",");
                    }
                    arrSb.Append(getExp(arrExp.Expressions[a]));
                }
                if (arrSb.Length == 1)
                {
                    arrSb.Append("NULL");
                }
                return(arrSb.Append("]").ToString());

            case ExpressionType.ListInit:
                var listExp = exp as ListInitExpression;
                var listSb  = new StringBuilder();
                listSb.Append("(");
                for (var a = 0; a < listExp.Initializers.Count; a++)
                {
                    if (listExp.Initializers[a].Arguments.Any() == false)
                    {
                        continue;
                    }
                    if (a > 0)
                    {
                        listSb.Append(",");
                    }
                    listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault()));
                }
                if (listSb.Length == 1)
                {
                    listSb.Append("NULL");
                }
                return(listSb.Append(")").ToString());

            case ExpressionType.New:
                var newExp = exp as NewExpression;
                if (typeof(IList).IsAssignableFrom(newExp.Type))
                {
                    if (newExp.Arguments.Count == 0)
                    {
                        return("(NULL)");
                    }
                    if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false)
                    {
                        return("(NULL)");
                    }
                    return(getExp(newExp.Arguments[0]));
                }
                return(null);
            }
            return(null);
        }
Example #9
0
        internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Now": return("getdate()");

                case "UtcNow": return("getutcdate()");

                case "Today": return("convert(char(10),getdate(),120)");

                case "MinValue": return("'1753/1/1 0:00:00'");

                case "MaxValue": return("'9999/12/31 23:59:59'");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Date": return($"convert(char(10),{left},120)");

            case "TimeOfDay": return($"datediff(second, convert(char(10),{left},120), {left})");

            case "DayOfWeek": return($"(datepart(weekday, {left})-1)");

            case "Day": return($"datepart(day, {left})");

            case "DayOfYear": return($"datepart(dayofyear, {left})");

            case "Month": return($"datepart(month, {left})");

            case "Year": return($"datepart(year, {left})");

            case "Hour": return($"datepart(hour, {left})");

            case "Minute": return($"datepart(minute, {left})");

            case "Second": return($"datepart(second, {left})");

            case "Millisecond": return($"(datepart(millisecond, {left})/1000)");

            case "Ticks": return($"(cast(datediff(second, '1970-1-1', {left}) as bigint)*10000000+621355968000000000)");
            }
            return(null);
        }
Example #10
0
        internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Zero": return("numtodsinterval(0,'second')");

                case "MinValue": return("numtodsinterval(-233720368.5477580,'second')");

                case "MaxValue": return("numtodsinterval(233720368.5477580,'second')");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Days": return($"extract(day from {left})");

            case "Hours": return($"extract(hour from {left})");

            case "Milliseconds": return($"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)");

            case "Minutes": return($"extract(minute from {left})");

            case "Seconds": return($"floor(extract(second from {left}))");

            case "Ticks": return($"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000");

            case "TotalDays": return($"extract(day from {left})");

            case "TotalHours": return($"(extract(day from {left})*24+extract(hour from {left}))");

            case "TotalMilliseconds": return($"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*1000");

            case "TotalMinutes": return($"(extract(day from {left})*1440+extract(hour from {left})*60+extract(minute from {left}))");

            case "TotalSeconds": return($"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))");
            }
            return(null);
        }
Example #11
0
        internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List <SelectTableInfo> _tables, List <SelectColumnInfo> _selectColumnMap, Func <Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Now": return("systimestamp");

                case "UtcNow": return("sys_extract_utc(systimestamp)");

                case "Today": return("trunc(systimestamp)");

                case "MinValue": return("to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')");

                case "MaxValue": return("to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);

            switch (exp.Member.Name)
            {
            case "Date": return($"trunc({left})");

            case "TimeOfDay": return($"({left}-trunc({left}))");

            case "DayOfWeek": return($"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end");

            case "Day": return($"cast(to_char({left},'DD') as number)");

            case "DayOfYear": return($"cast(to_char({left},'DDD') as number)");

            case "Month": return($"cast(to_char({left},'MM') as number)");

            case "Year": return($"cast(to_char({left},'YYYY') as number)");

            case "Hour": return($"cast(to_char({left},'HH24') as number)");

            case "Minute": return($"cast(to_char({left},'MI') as number)");

            case "Second": return($"cast(to_char({left},'SS') as number)");

            case "Millisecond": return($"cast(to_char({left},'FF3') as number)");

            case "Ticks": return($"cast(to_char({left},'FF7') as number)");
            }
            return(null);
        }