private static void GenerateResultDefinition(
			XmlElement            rootNode,
			TemplateNodeQueryInfo templateNodeQueryInfo,
			ErrorInfo             errorInfo,
			InstanceInfo          instance,
			long                  rowCount,
			Int64                 recordSets
		)
		{
			string     errorCode   = string.Empty;
			string     errorNumber = "0";
			XmlElement node        = rootNode.OwnerDocument.CreateElement(QueryResultNodeName);

			node.SetAttribute("instance",   instance.Name);
			node.SetAttribute("name",       templateNodeQueryInfo.QueryName);
			node.SetAttribute("RecordSets", recordSets.ToString());
			node.SetAttribute("RowCount",   rowCount.ToString());

			if (errorInfo != null)
			{
				XmlElement errorNode = rootNode.OwnerDocument.CreateElement("SqlErrorMessage");

				errorNode.InnerText = errorInfo.Message;
				node.AppendChild(errorNode);
				errorCode = errorInfo.Code;
				errorNumber = errorInfo.Number;
			}

			node.SetAttribute("SqlErrorCode",   errorCode);
			node.SetAttribute("SqlErrorNumber", errorNumber);
			node.SetAttribute("hierarchy",      templateNodeQueryInfo.ResultHierarchy);

			rootNode.AppendChild(node);
		}
		public void SaveMeta(
			Int64?           groupGueryId,
			ErrorInfo        error,
			IList<DataTable> tables
		)
		{
			Int64 rowCount       = 0L;
			Int64 recordSetCount = 0L;
			string errorNumber   = null;
			string errorCode     = null;
			string errorMessage  = null;
			ITableRow row        = new TableRow(this.MetaResultTable.TableDefinition);

			row.Values.Add(QueryDirectory.DirectoryTableName.AsFk(),        null);
			row.Values.Add(QueryGroupDirectory.DirectoryTableName.AsFk(),   groupGueryId);
			row.Values.Add(MetaResultTable.RequestIdFieldName,              this.MetaResultTable.GetMaxRequestId() + 1);
			row.Values.Add(MetaResultTable.SessionIdFieldName,              1);
			row.Values.Add(TableDefinition.DateCreated,                     DateTime.Now);

			if (error == null)
			{
				rowCount = tables != null
					? tables.Select(x => x.Rows).Sum(x => x.Count)
					: 0L;

				recordSetCount = tables != null
					? tables.Count
					: 0L;
			}
			else
			{
				errorNumber  = error.Number;
				errorCode    = error.Code;
				errorMessage = error.Message;
			}

			row.Values.Add(MetaResultTable.RowCountFieldName,       rowCount);
			row.Values.Add(MetaResultTable.RecordSetCountFieldName, recordSetCount);
			row.Values.Add(MetaResultTable.ErrorIdFieldName,        errorNumber);
			row.Values.Add(MetaResultTable.ErrorCodeFieldName,      errorCode);
			row.Values.Add(MetaResultTable.ErrorMessageFieldName,   errorMessage);

			this.MetaResultTable.ReplaceRows(new[] { row });
		}
		/// <summary>
		/// Constructor with exception thrown
		/// </summary>
		/// <param name="errorInfo">Error info</param>
		public QueryResultInfo(ErrorInfo errorInfo) : this()
		{
			this._errorInfo = errorInfo;
		}
		public QueryInstanceResultInfo GetConnectionSelectResults(
			InstanceInfo          selectConnectionInstance,
			QueryInfo             queryInfo,
			QueryItemInfo         queryItem,
			TemplateNodeQueryInfo query
		)
		{
			QueryDatabaseResultInfo dbResultInfo;

			try
			{
				DataTable[] tables = ExecuteSql(
					selectConnectionInstance,
					queryItem,
					query.TemplateNode.GetDefaultDatabase(),
					queryInfo.Parameters,
					query.ParameterValues
				);

				if (tables != null && tables.Length < 0)
				{
					throw new InvalidTemplateException(query + " returned no recordsets.");
				}

				dbResultInfo = new QueryDatabaseResultInfo(tables, queryItem);
			}
			catch (Exception exc)
			{
				ErrorInfo error = new ErrorInfo(exc);

				dbResultInfo = new QueryDatabaseResultInfo(error, queryItem);
			}

			QueryInstanceResultInfo instanceResultInfo = new QueryInstanceResultInfo(selectConnectionInstance);

			instanceResultInfo.AddDatabaseResult(dbResultInfo);

			return instanceResultInfo;
		}
		/// <summary>
		/// Default constructor
		/// </summary>
		public QueryResultInfo()
		{
			this._instancesResult = new ConcurrentDictionary<InstanceInfo, QueryInstanceResultInfo>();
			this._errorInfo       = null;
		}
		/// <summary>
		/// Constructor with exception thrown
		/// </summary>
		/// <param name="errorInfo">Error info</param>
		/// <param name="instance">Server instance</param>
		public QueryInstanceResultInfo(ErrorInfo errorInfo, InstanceInfo instance) : this()
		{
			this._instance  = instance;
			this._errorInfo = errorInfo;
		}
		public QueryInstanceResultInfo()
		{
			this._instance        = null;
			this._databasesResult = new ConcurrentDictionary<string, QueryDatabaseResultInfo>();
			this._errorInfo       = null;
		}
		/// <summary>
		/// Constructor for thrown exception
		/// </summary>
		/// <param name="errorInfo">Error info</param>
		/// <param name="queryItem">Query item</param>
		/// <param name="databaseId">Database name (null for instance scope)</param>
		public QueryDatabaseResultInfo(ErrorInfo errorInfo, QueryItemInfo queryItem, string database = "", string databaseId = "")
		{
			this.QueryItem   = queryItem;
			this._errorInfo  = errorInfo;
			this._database   = database;
			this._databaseId = databaseId;
		}
		public DataTable[] GetGroupSelectResultsFromServer(
			SqlProcessor          sqlProcessor,
			InstanceInfo          serverInstance,
			QueryInfo             queryInfo,
			TemplateNodeQueryInfo query
		)
		{
			DataTable[] tables = null;
			ErrorInfo   error  = null;

			Debug.Assert(IsInstance);
			Debug.Assert(GroupQueries.Contains(query));

			var db = this._model.GetVaultProcessor(ConnectionGroup).CurrentStorage;

			InstanceTemplate settings = GetUserSettings();

			//looking for user settings for parameter values
			query.ReadParametersFrom(settings);

			try
			{
				tables = sqlProcessor.ExecuteSql(
					serverInstance,
					queryInfo,
					GetDefaultDatabase(),
					queryInfo.Parameters,
					query.ParameterValues,
					fromGroupSelect: true
				);
			}
			catch (Exception ex)
			{
				error  = new ErrorInfo(ex);
				tables = null;
			}

			Int64? queryId = db.QueryGroupDirectory.GetQueryId(
				query.TemplateNode,
				query,
				serverInstance,
				DateTime.Now,
				false
			);

			db.SaveMeta(queryId, error, tables);

			if (tables != null && tables.Length < 0)
			{
				throw new InvalidTemplateException(query + " returned no recordsets.");
			}

			return tables;
		}