private void ParseRequest(DataRequest request, DataRequestBulk requestBulk, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            if (parsedRequest.SpecialCommand.IsSpecialCommand)
            {
                if (parsedRequest.SpecialCommand.CommandType != ParsedRequest.SpecialCommandData.SpecialCommandType.Defragment)
                {
                    throw new CompilationException(
                        "Invalid special command type: " + parsedRequest.SpecialCommand.CommandType + ". Command text was: " + request.CommandText);
                }

                return;
            }

            // by now, we have all information about the request at hand, including parameter values data.
            // parser will write results into cacheInfo object
            m_parser.Parse(request, requestBulk, parsedRequest, cancellation);

            if (parsedRequest.StatementType == StatementType.Delete || parsedRequest.StatementType == StatementType.Insert)
            {
                // for insert and delete, we need all columns' data ready for modification before we start
                m_storageDriver.PrepareAllColumnsAndWait(parsedRequest.TargetEntity.DocumentType);
            }
            else
            {
                // for other statement types, we only need fields that we order by, filter on, fetch or update,
                // and we need them in that particular order.

                // schedule loading of sort order fields
                foreach (var field in parsedRequest.BaseDataset.OrderClauseFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.Item1);
                }

                // schedule loading of where clause fields
                foreach (var field in parsedRequest.BaseDataset.WhereClauseFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }

                // schedule loading of fetched fields
                foreach (var field in parsedRequest.Select.SelectFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }

                // schedule loading of inserted/updated fields
                foreach (var field in parsedRequest.Modify.ModifiedFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }
            }
        }
        /// <summary>
        /// Computes an Int64 hash value for a request for use with dictionary of prepared requests.
        /// </summary>
        public static long GetRequestHash(DataRequest request, DataRequestBulk requestBulk, DataRequestParams requestParams)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.HaveRequestBulk && requestBulk == null)
            {
                throw new ArgumentNullException("requestBulk");
            }

            if (request.HaveParameters && requestParams == null)
            {
                throw new ArgumentNullException("requestParams");
            }

            long hash;
            int modulo;
            InitHash(out hash, out modulo);

            if (request.HaveRequestBulk)
            {
                AppendToHash(ref hash, modulo, (requestBulk.EntityName ?? string.Empty).GetHashCode());
                AppendToHash(ref hash, modulo, (int)requestBulk.DbStatementType);

                foreach (var f in requestBulk.FieldNames)
                {
                    AppendToHash(ref hash, modulo, f.GetHashCode());
                }
            }
            else
            {
                AppendToHash(ref hash, modulo, (request.CommandText ?? string.Empty).GetHashCode());

                if (request.HaveParameters)
                {
                    foreach (var dataType in requestParams.DataTypes)
                    {
                        AppendToHash(ref hash, modulo, (int)dataType);
                    }

                    foreach (var bitVectorData in requestParams.IsCollectionFlags)
                    {
                        AppendToHash(ref hash, modulo, bitVectorData);
                    }
                }
            }

            return hash;
        }
        /// <summary>
        /// Reads portion of request headers appropriate for caching into the cache buffer.
        /// </summary>
        public void ReadRequestHeaders(DataRequest request, DataRequestParams requestParams, DataRequestBulk requestBulk, ParsedRequest parsedRequest)
        {
            if (request == null)
            {
                throw new ArgumentNullException("requestParams");
            }

            CommandText = request.CommandText;

            RequestParams.Clear();
            RequestBulk.Clear();

            if (request.HaveParameters)
            {
                RequestParams.DataTypes = requestParams.DataTypes;
                RequestParams.IsCollectionFlags = requestParams.IsCollectionFlags;
                RequestParams.Names = requestParams.Names;

                // some values are written into parsed request during request read process
                // have to replicate them in the cached version, because they are required for subsequent compilation
                ParsedRequest.Params.Names = parsedRequest.Params.Names;
                ParsedRequest.Params.DataTypes = parsedRequest.Params.DataTypes;
                ParsedRequest.Params.OrdinalToLocalOrdinal = parsedRequest.Params.OrdinalToLocalOrdinal;
            }

            if (request.HaveRequestBulk)
            {
                RequestBulk.DbStatementType = requestBulk.DbStatementType;
                RequestBulk.EntityName = requestBulk.EntityName;
                RequestBulk.FieldNames = requestBulk.FieldNames;

                // some values are written into parsed request during request read process
                // have to replicate them in the cached version, because they are required for subsequent compilation
                ParsedRequest.IsBulk = parsedRequest.IsBulk;
            }

            if (StringComparer.OrdinalIgnoreCase.Equals(CommandText, "defragment"))
            {
                ParsedRequest.SpecialCommand.IsSpecialCommand = true;
                ParsedRequest.SpecialCommand.CommandType = ParsedRequest.SpecialCommandData.SpecialCommandType.Defragment;
            }

            HaveRequestHeaders = true;
        }
        private PqlMessage SendCommand(IDataService channel, DataRequest dataRequest, DataRequestParams dataRequestParams, DataRequestBulk dataRequestBulk)
        {
            var authContext = m_connection.ClientSecurityContext;

            if (authContext == null)
            {
                throw new InvalidOperationException("Authentication context is not set on the thread");
            }

            if (string.IsNullOrWhiteSpace(authContext.TenantId))
            {
                throw new InvalidOperationException("Current authentication context does not have value for TenantId");
            }

            Message responseMessage;
            using (var holder = PqlDataConnection.CommandStreams.Take(m_connection.CancellationTokenSource.Token))
            {
                holder.Item.Attach(dataRequest, dataRequestParams, dataRequestBulk);

                var requestMessage = new PqlMessage(
                    holder.Item, new IDisposable[] {holder},
                    AuthContextSerializer.GetString(authContext),
                    m_connection.ConnectionProps.ScopeId,
                    m_connection.ConnectionProps.ProtocolVersion);

                responseMessage = channel.Process(requestMessage);
            }

            var pqlMessage = responseMessage as PqlMessage;

            if (pqlMessage != null)
            {
                return pqlMessage;
            }

            throw new DataException(string.Format(
                "Message must be of type {0}. Actual type that came from WCF transport was {1}",
                typeof(PqlMessage).AssemblyQualifiedName,
                responseMessage.GetType().AssemblyQualifiedName));
        }
Example #5
0
        private void ParsePqlStatementRequest(DataRequest request, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            ParseTree parseTree;
            using (var poolAccessor = m_parsers.Take(cancellation))
            {
                try
                {
                    parseTree = poolAccessor.Item.Parse(request.CommandText);
                }
                finally
                {
                    // get rid of temp utility objects right now, to help them be reclaimed with Gen0
                    poolAccessor.Item.Reset();
                }
            }

            if (parseTree.Status != ParseTreeStatus.Parsed)
            {
                throw new CompilationException(BuildParserErrorMessage(parseTree));
            }

            // root is a batch of Pql statements
            var root = parseTree.Root;

            if (root.ChildNodes == null || root.ChildNodes.Count != 1)
            {
                throw new CompilationException("Pql batch must contain exactly one statement", root);
            }

            var statementRoot = root.ChildNodes[0];

            // run first round of syntactical analysis on the tree
            if ("selectStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Select;
                ParseSelectStatement(parsedRequest, statementRoot);
            }
            else if ("updateStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Update;
                ParseUpdateStatement(parsedRequest, statementRoot);
            }
            else if ("insertStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Insert;
                ParseInsertStatement(parsedRequest, statementRoot);
            }
            else if ("deleteStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Delete;
                ParseDeleteStatement(parsedRequest, statementRoot);
            }
            else
            {
                throw new CompilationException("Invalid statement: " + statementRoot.Term.Name, statementRoot);
            }
        }
Example #6
0
        /// <summary>
        /// Parses specified expression text, with a cancellation option. 
        /// May incur some waiting in highly concurrent environment, because the number of pooled parsers is limited.
        /// </summary>
        public void Parse(DataRequest request, DataRequestBulk requestBulk, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (parsedRequest == null)
            {
                throw new ArgumentNullException("parsedRequest");
            }

            if (cancellation == null)
            {
                throw new ArgumentNullException("cancellation");
            }

            if (request.HaveRequestBulk && requestBulk == null)
            {
                throw new ArgumentNullException("requestBulk");
            }

            if (request.HaveRequestBulk)
            {
                ParseBulkRequest(requestBulk, parsedRequest);
            }
            else
            {
                ParsePqlStatementRequest(request, parsedRequest, cancellation);
            }

            InitDriverFetchFields(parsedRequest);
        }
        /// <summary>
        /// Ctr.
        /// </summary>
        /// <param name="process">Parent process, receives crash notifications</param>
        /// <param name="tracer">Tracer object</param>
        public RequestExecutionContext(IPqlEngineHostProcess process, ITracer tracer)
        {
            if (process == null)
            {
                throw new ArgumentNullException("process");
            }

            if (tracer == null)
            {
                throw new ArgumentNullException("tracer");
            }

            m_tracer = tracer;

            m_process = process;

            ParsedRequest = new ParsedRequest(false);
            Request = new DataRequest();
            RequestBulk = new DataRequestBulk();
            RequestParameters = new DataRequestParams();

            m_buffersRingItems = new []
                {
                    new RequestExecutionBuffer(),
                    new RequestExecutionBuffer(),
                    new RequestExecutionBuffer()
                };
        }