<commit_before>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

using JetBrains.Annotations;

namespace LinqToDB.Linq.Builder
{
	using Common;
	using DataProvider;
	using Extensions;
	using Mapping;
	using SqlQuery;
	using LinqToDB.Expressions;

	partial class ExpressionBuilder
	{
		#region Sequence

		static readonly object _sync = new object();

		static List<ISequenceBuilder> _sequenceBuilders = new List<ISequenceBuilder>
		{
			new TableBuilder               (),
			new SelectBuilder              (),
			new SelectManyBuilder          (),
			new WhereBuilder               (),
			new OrderByBuilder             (),
			new GroupByBuilder             (),
			new JoinBuilder                (),
			new AllJoinsBuilder            (),
			new AllJoinsLinqBuilder        (),
			new TakeSkipBuilder            (),
			new DefaultIfEmptyBuilder      (),
			new DistinctBuilder            (),
			new FirstSingleBuilder         (),
			new AggregationBuilder         (),
			new MethodChainBuilder         (),
			new ScalarSelectBuilder        (),
			new CountBuilder               (),
			new PassThroughBuilder         (),
			new TableAttributeBuilder      (),
			new InsertBuilder              (),
			new InsertBuilder.Into         (),
			new InsertBuilder.Value        (),
			new InsertOrUpdateBuilder      (),
			new UpdateBuilder              (),
			new UpdateBuilder.Set          (),
			new DeleteBuilder              (),
			new ContainsBuilder            (),
			new AllAnyBuilder              (),
			new ConcatUnionBuilder         (),
			new IntersectBuilder           (),
			new CastBuilder                (),
			new OfTypeBuilder              (),
			new AsUpdatableBuilder         (),
			new LoadWithBuilder            (),
			new DropBuilder                (),
			new TruncateBuilder            (),
			new ChangeTypeExpressionBuilder(),
			new WithTableExpressionBuilder (),
			new MergeBuilder                             (),
			new MergeBuilder.InsertWhenNotMatched        (),
			new MergeBuilder.UpdateWhenMatched           (),
			new MergeBuilder.UpdateWhenMatchedThenDelete (),
			new MergeBuilder.UpdateWhenNotMatchedBySource(),
			new MergeBuilder.DeleteWhenMatched           (),
			new MergeBuilder.DeleteWhenNotMatchedBySource(),
			new MergeBuilder.On                          (),
			new MergeBuilder.Merge                       (),
			new MergeBuilder.MergeInto                   (),
			new MergeBuilder.Using                       (),
			new MergeBuilder.UsingTarget                 (),
			new ContextParser              (),
			new ArrayBuilder               ()
		};

		public static void AddBuilder(ISequenceBuilder builder)
		{
			_sequenceBuilders.Add(builder);
		}

		#endregion

		#region Init

		readonly Query                             _query;
		readonly List<ISequenceBuilder>            _builders = _sequenceBuilders;
		private  bool                              _reorder;
		readonly Dictionary<Expression,Expression> _expressionAccessors;
		private  HashSet<Expression>               _subQueryExpressions;

		public readonly List<ParameterAccessor>    CurrentSqlParameters = new List<ParameterAccessor>();

		public readonly List<ParameterExpression>  BlockVariables       = new List<ParameterExpression>();
		public readonly List<Expression>           BlockExpressions     = new List<Expression>();
		public          bool                       IsBlockDisable;
		public          int                        VarIndex;

		readonly HashSet<Expression> _visitedExpressions;

		public ExpressionBuilder(
			Query                 query,
			IDataContext          dataContext,
			Expression            expression,
			ParameterExpression[] compiledParameters)
		{
			_query               = query;

			_expressionAccessors = expression.GetExpressionAccessors(ExpressionParam);

			CompiledParameters   = compiledParameters;
			DataContext          = dataContext;
			OriginalExpression   = expression;

			_visitedExpressions  = new HashSet<Expression>();
			Expression           = ConvertExpressionTree(expression);
			_visitedExpressions  = null;

			if (Configuration.AvoidSpecificDataProviderAPI)
			{
				DataReaderLocal = DataReaderParam;
			}
			else
			{
				DataReaderLocal = BuildVariable(Expression.Convert(DataReaderParam, dataContext.DataReaderType), "ldr");
			}
		}

		#endregion

		#region Public Members

		public readonly IDataContext          DataContext;
		public readonly Expression            OriginalExpression;
		public readonly Expression            Expression;
		public readonly ParameterExpression[] CompiledParameters;
		public readonly List<IBuildContext>   Contexts = new List<IBuildContext>();

		public static readonly ParameterExpression QueryRunnerParam = Expression.Parameter(typeof(IQueryRunner), "qr");
		public static readonly ParameterExpression DataContextParam = Expression.Parameter(typeof(IDataContext), "dctx");
		public static readonly ParameterExpression DataReaderParam  = Expression.Parameter(typeof(IDataReader),  "rd");
		public        readonly ParameterExpression DataReaderLocal;
		public static readonly ParameterExpression ParametersParam  = Expression.Parameter(typeof(object[]),     "ps");
		public static readonly ParameterExpression ExpressionParam  = Expression.Parameter(typeof(Expression),   "expr");

		public MappingSchema MappingSchema => DataContext.MappingSchema;

		#endregion

		#region Builder SQL

		internal Query<T> Build<T>()
		{
			var sequence = BuildSequence(new BuildInfo((IBuildContext)null, Expression, new SelectQuery()));

			if (_reorder)
				lock (_sync)
				{
					_reorder = false;
					_sequenceBuilders = _sequenceBuilders.OrderByDescending(_ => _.BuildCounter).ToList();
				}

			_query.Init(sequence, CurrentSqlParameters);

			var param = Expression.Parameter(typeof(Query<T>), "info");

			sequence.BuildQuery((Query<T>)_query, param);
<commit_msg>convert "select *" to "select <columns>"<commit_after>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

using JetBrains.Annotations;

namespace LinqToDB.Linq.Builder
{
	using Common;
	using DataProvider;
	using Extensions;
	using Mapping;
	using SqlQuery;
	using LinqToDB.Expressions;

	partial class ExpressionBuilder
	{
		#region Sequence

		static readonly object _sync = new object();

		static List<ISequenceBuilder> _sequenceBuilders = new List<ISequenceBuilder>
		{
			new TableBuilder               (),
			new SelectBuilder              (),
			new SelectManyBuilder          (),
			new WhereBuilder               (),
			new OrderByBuilder             (),
			new GroupByBuilder             (),
			new JoinBuilder                (),
			new AllJoinsBuilder            (),
			new AllJoinsLinqBuilder        (),
			new TakeSkipBuilder            (),
			new DefaultIfEmptyBuilder      (),
			new DistinctBuilder            (),
			new FirstSingleBuilder         (),
			new AggregationBuilder         (),
			new MethodChainBuilder         (),
			new ScalarSelectBuilder        (),
			new CountBuilder               (),
			new PassThroughBuilder         (),
			new TableAttributeBuilder      (),
			new InsertBuilder              (),
			new InsertBuilder.Into         (),
			new InsertBuilder.Value        (),
			new InsertOrUpdateBuilder      (),
			new UpdateBuilder              (),
			new UpdateBuilder.Set          (),
			new DeleteBuilder              (),
			new ContainsBuilder            (),
			new AllAnyBuilder              (),
			new ConcatUnionBuilder         (),
			new IntersectBuilder           (),
			new CastBuilder                (),
			new OfTypeBuilder              (),
			new AsUpdatableBuilder         (),
			new LoadWithBuilder            (),
			new DropBuilder                (),
			new TruncateBuilder            (),
			new ChangeTypeExpressionBuilder(),
			new WithTableExpressionBuilder (),
			new MergeBuilder                             (),
			new MergeBuilder.InsertWhenNotMatched        (),
			new MergeBuilder.UpdateWhenMatched           (),
			new MergeBuilder.UpdateWhenMatchedThenDelete (),
			new MergeBuilder.UpdateWhenNotMatchedBySource(),
			new MergeBuilder.DeleteWhenMatched           (),
			new MergeBuilder.DeleteWhenNotMatchedBySource(),
			new MergeBuilder.On                          (),
			new MergeBuilder.Merge                       (),
			new MergeBuilder.MergeInto                   (),
			new MergeBuilder.Using                       (),
			new MergeBuilder.UsingTarget                 (),
			new ContextParser              (),
			new ArrayBuilder               ()
		};

		public static void AddBuilder(ISequenceBuilder builder)
		{
			_sequenceBuilders.Add(builder);
		}

		#endregion

		#region Init

		readonly Query                             _query;
		readonly List<ISequenceBuilder>            _builders = _sequenceBuilders;
		private  bool                              _reorder;
		readonly Dictionary<Expression,Expression> _expressionAccessors;
		private  HashSet<Expression>               _subQueryExpressions;

		public readonly List<ParameterAccessor>    CurrentSqlParameters = new List<ParameterAccessor>();

		public readonly List<ParameterExpression>  BlockVariables       = new List<ParameterExpression>();
		public readonly List<Expression>           BlockExpressions     = new List<Expression>();
		public          bool                       IsBlockDisable;
		public          int                        VarIndex;

		readonly HashSet<Expression> _visitedExpressions;

		public ExpressionBuilder(
			Query                 query,
			IDataContext          dataContext,
			Expression            expression,
			ParameterExpression[] compiledParameters)
		{
			_query               = query;

			_expressionAccessors = expression.GetExpressionAccessors(ExpressionParam);

			CompiledParameters   = compiledParameters;
			DataContext          = dataContext;
			OriginalExpression   = expression;

			_visitedExpressions  = new HashSet<Expression>();
			Expression           = ConvertExpressionTree(expression);
			_visitedExpressions  = null;

			if (Configuration.AvoidSpecificDataProviderAPI)
			{
				DataReaderLocal = DataReaderParam;
			}
			else
			{
				DataReaderLocal = BuildVariable(Expression.Convert(DataReaderParam, dataContext.DataReaderType), "ldr");
			}
		}

		#endregion

		#region Public Members

		public readonly IDataContext          DataContext;
		public readonly Expression            OriginalExpression;
		public readonly Expression            Expression;
		public readonly ParameterExpression[] CompiledParameters;
		public readonly List<IBuildContext>   Contexts = new List<IBuildContext>();

		public static readonly ParameterExpression QueryRunnerParam = Expression.Parameter(typeof(IQueryRunner), "qr");
		public static readonly ParameterExpression DataContextParam = Expression.Parameter(typeof(IDataContext), "dctx");
		public static readonly ParameterExpression DataReaderParam  = Expression.Parameter(typeof(IDataReader),  "rd");
		public        readonly ParameterExpression DataReaderLocal;
		public static readonly ParameterExpression ParametersParam  = Expression.Parameter(typeof(object[]),     "ps");
		public static readonly ParameterExpression ExpressionParam  = Expression.Parameter(typeof(Expression),   "expr");

		public MappingSchema MappingSchema => DataContext.MappingSchema;

		#endregion

		#region Builder SQL

		internal Query<T> Build<T>()
		{
			var sequence = BuildSequence(new BuildInfo((IBuildContext)null, Expression, new SelectQuery()));
			//todo: call only for top-level select without columns
			sequence.ConvertToIndex(null, 0, ConvertFlags.All);

			if (_reorder)
				lock (_sync)
				{
					_reorder = false;
					_sequenceBuilders = _sequenceBuilders.OrderByDescending(_ => _.BuildCounter).ToList();
				}

			_query.Init(sequence, CurrentSqlParameters);

			var param = Expression.Parameter(typeof(Query<T>), "info");

			sequence.BuildQuery((Query<T>)_query, param);

{'fraction_non_alphanumeric': 0.07758478081058726, 'fraction_numerical': 8.271298593879239e-05, 'mean_word_length': 2.5107433217189317, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2760566', 'n_tokens_mistral': 3471, 'n_tokens_neox': 2861, 'n_words': 691}