- 修复 pgsql WithTempQuery + ToList 对于 bool 类型处理导致的性能问题;#2093

This commit is contained in:
28810
2025-08-14 12:28:46 +08:00
parent ab5a6a3533
commit 62bd9afcdf
7 changed files with 375 additions and 18 deletions

View File

@@ -344,6 +344,17 @@ namespace FreeSql.Internal
case ExpressionType.Equal:
case ExpressionType.Not:
initExpArg = Expression.Condition(initExpArg, Expression.Constant(true, typeof(bool)), Expression.Constant(false, typeof(bool)));
switch (_ado.DataType)
{
case DataType.PostgreSQL: //#2093
case DataType.OdbcPostgreSQL:
case DataType.CustomPostgreSQL:
case DataType.KingbaseES:
case DataType.ShenTong:
case DataType.Xugu:
initExpArg = Expression.Convert(initExpArg, typeof(bool));
break;
}
break;
}
var child = new ReadAnonymousTypeInfo
@@ -456,6 +467,17 @@ namespace FreeSql.Internal
case ExpressionType.Equal:
case ExpressionType.Not:
initExpArg = Expression.Condition(initExpArg, Expression.Constant(true, typeof(bool)), Expression.Constant(false, typeof(bool)));
switch (_ado.DataType)
{
case DataType.PostgreSQL: //#2093
case DataType.OdbcPostgreSQL:
case DataType.CustomPostgreSQL:
case DataType.KingbaseES:
case DataType.ShenTong:
case DataType.Xugu:
initExpArg = Expression.Convert(initExpArg, typeof(bool));
break;
}
break;
}
var child = new ReadAnonymousTypeInfo
@@ -507,6 +529,17 @@ namespace FreeSql.Internal
case ExpressionType.Equal:
case ExpressionType.Not:
initExpArg = Expression.Condition(initExpArg, Expression.Constant(true, typeof(bool)), Expression.Constant(false, typeof(bool)));
switch (_ado.DataType)
{
case DataType.PostgreSQL: //#2093
case DataType.OdbcPostgreSQL:
case DataType.CustomPostgreSQL:
case DataType.KingbaseES:
case DataType.ShenTong:
case DataType.Xugu:
initExpArg = Expression.Convert(initExpArg, typeof(bool));
break;
}
break;
}
var csname = newExp.Members != null ? newExp.Members[a].Name : (initExpArg as MemberExpression)?.Member.Name;

View File

@@ -32,7 +32,25 @@ namespace FreeSql.Custom.PostgreSQL
{
switch (exp.Type.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))";
case "System.Boolean":
var boolstr = getExp(operandExp);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp";
@@ -60,7 +78,25 @@ namespace FreeSql.Custom.PostgreSQL
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.Boolean":
var boolstr = getExp(callExp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp";
@@ -587,7 +623,25 @@ namespace FreeSql.Custom.PostgreSQL
{
switch (exp.Method.Name)
{
case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))";
case "ToBoolean":
var boolstr = getExp(exp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "ToByte": return $"({getExp(exp.Arguments[0])})::int2";
case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)";
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp";

View File

@@ -33,7 +33,25 @@ namespace FreeSql.KingbaseES
{
switch (exp.Type.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))";
case "System.Boolean":
var boolstr = getExp(operandExp);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp";
@@ -61,7 +79,25 @@ namespace FreeSql.KingbaseES
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.Boolean":
var boolstr = getExp(callExp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp";
@@ -620,7 +656,25 @@ namespace FreeSql.KingbaseES
{
switch (exp.Method.Name)
{
case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))";
case "ToBoolean":
var boolstr = getExp(exp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "ToByte": return $"({getExp(exp.Arguments[0])})::int2";
case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)";
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp";

View File

@@ -32,7 +32,25 @@ namespace FreeSql.Odbc.PostgreSQL
{
switch (exp.Type.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))";
case "System.Boolean":
var boolstr = getExp(operandExp);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp";
@@ -60,7 +78,25 @@ namespace FreeSql.Odbc.PostgreSQL
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.Boolean":
var boolstr = getExp(callExp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp";
@@ -587,7 +623,25 @@ namespace FreeSql.Odbc.PostgreSQL
{
switch (exp.Method.Name)
{
case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))";
case "ToBoolean":
var boolstr = getExp(exp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "ToByte": return $"({getExp(exp.Arguments[0])})::int2";
case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)";
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp";

View File

@@ -33,7 +33,25 @@ namespace FreeSql.PostgreSQL
{
switch (exp.Type.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))";
case "System.Boolean":
var boolstr = getExp(operandExp);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp";
@@ -61,7 +79,25 @@ namespace FreeSql.PostgreSQL
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.Boolean":
var boolstr = getExp(callExp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp";
@@ -618,7 +654,25 @@ namespace FreeSql.PostgreSQL
{
switch (exp.Method.Name)
{
case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))";
case "ToBoolean":
var boolstr = getExp(exp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "ToByte": return $"({getExp(exp.Arguments[0])})::int2";
case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)";
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp";

View File

@@ -32,7 +32,25 @@ namespace FreeSql.ShenTong
{
switch (exp.Type.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(({getExp(operandExp)})::text not in ('0','false','f','no'))";
case "System.Boolean":
var boolstr = getExp(operandExp);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp";
@@ -60,7 +78,25 @@ namespace FreeSql.ShenTong
case "TryParse":
switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::text not in ('0','false','f','no'))";
case "System.Boolean":
var boolstr = getExp(callExp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::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 ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp";
@@ -554,7 +590,25 @@ namespace FreeSql.ShenTong
{
switch (exp.Method.Name)
{
case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::text not in ('0','false','f','no'))";
case "ToBoolean":
var boolstr = getExp(exp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "ToByte": return $"({getExp(exp.Arguments[0])})::int2";
case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)";
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp";

View File

@@ -33,7 +33,25 @@ namespace FreeSql.Xugu
{
switch (exp.Type.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))";
case "System.Boolean":
var boolstr = getExp(operandExp);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)";
case "System.Char": return $"substring(cast({getExp(operandExp)} as varchar),1,1)";
case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as datetime)";
@@ -64,7 +82,25 @@ namespace FreeSql.Xugu
case "TryParse":
switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))";
case "System.Boolean":
var boolstr = getExp(callExp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)";
case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as varchar),1,1)";
case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as datetime)";
@@ -555,7 +591,25 @@ namespace FreeSql.Xugu
{
switch (exp.Method.Name)
{
case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))";
case "ToBoolean":
var boolstr = getExp(exp.Arguments[0]);
switch (boolstr)
{
case "0":
case "'0'":
case "false":
case "'f'":
case "'no'":
return "'f'::bool";
case "1":
case "'1'":
case "true":
case "'t'":
case "'yes'":
return "'t'::bool";
default:
return $"(({boolstr})::varchar not in ('0','false','f','no'))";
}
case "ToByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as varchar),1,1)";
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)";