public string GetQuerySourceFromExpression(string name, Type type, Expression fromExpression)
{
var me = fromExpression as MemberExpression;
if (me != null)
{
var src = BuildMemberPath(me, true);
if (src != null)
return @"(SELECT sq AS ""{1}"" FROM unnest({0}) sq) AS ""{1}""".With(src, name);
}
var sqe = fromExpression as SubQueryExpression;
if (sqe != null)
{
if (sqe.QueryModel.CanUseMain())
return GetQuerySourceFromExpression(name, type, sqe.QueryModel.MainFromClause.FromExpression);
//TODO hack za replaceanje generiranog id-a
var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(sqe.QueryModel, this);
var grouping = sqe.QueryModel.ResultOperators.FirstOrDefault(it => it is GroupResultOperator) as GroupResultOperator;
if (grouping == null && subquery.Selects.Count == 1)
{
if (sqe.QueryModel.ResultOperators.Any(it => it is UnionResultOperator || it is ConcatResultOperator))
{
var ind = subquery.Selects[0].Sql.IndexOf(" AS ");
if (ind > 0)
{
var asName = subquery.Selects[0].Sql.Substring(ind + 4).Trim().Replace("\"", "");
if (asName != name)
subquery.Selects[0].Sql = subquery.Selects[0].Sql.Substring(0, ind + 4) + "\"" + name + "\"";
}
else
{
subquery.Selects[0].Sql = subquery.Selects[0].Sql + " AS \"" + name + "\"";
}
return "(" + subquery.BuildSqlString(true) + ") \"" + name + "\"";
}
return "(" + subquery.BuildSqlString(true).Replace("\"" + sqe.QueryModel.MainFromClause.ItemName + "\"", "\"" + name + "\"") + ") \"" + name + "\"";
}
return "(" + subquery.BuildSqlString(true) + ") \"" + name + "\"";
}
var ce = fromExpression as ConstantExpression;
if (ce != null)
{
var queryable = ce.Value as IQueryable;
if (queryable != null)
return GetQueryableExpression(name, queryable);
if (ce.Type.IsArray || ce.Value is Array)
return FormatStringArray(ce.Value, name, ce.Type);
else if (ce.Value is IEnumerable)
return FormatStringEnumerable(ce.Value, name, ce.Type);
return "(SELECT {0} AS \"{1}\") AS \"{1}\"".With(ce.Value, name);
}
var nae = fromExpression as NewArrayExpression;
if (nae != null)
{
if (nae.Expressions.Count == 0)
//TODO support for zero
throw new NotSupportedException("Expecting NewArray expressions. None found");
var inner = string.Join(" UNION ALL ", nae.Expressions.Select(it => "SELECT {0} AS \"{1}\"".With(GetSqlExpression(it), name)));
return "(" + inner + ") AS \"{0}\" ".With(name);
}
if (fromExpression is QuerySourceReferenceExpression && fromExpression.Type.IsGrouping())
{
var qse = fromExpression as QuerySourceReferenceExpression;
return
"(SELECT (\"{0}\".\"Values\")[i].* FROM generate_series(1, array_upper(\"{0}\".\"Values\", 1)) i) AS \"{1}\"".With(
qse.ReferencedQuerySource.ItemName,
name);
}
var pe = fromExpression as ParameterExpression;
if (pe != null)
return "UNNEST({0}\"{1}\") AS \"{2}\"".With(Context.Name, pe.Name, name);
return FromSqlSource(name, type);
}