Exemple #1
0
        /// <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()
            };
        }
        public PqlCompilerState(
            IExpressionEvaluatorRuntime parentRuntime,
            ParsedRequest parsedRequest,
            DataRequestParams requestParams,
            DataContainerDescriptor containerDescriptor,
            Type contextType,
            Type returnType)
            : base(parentRuntime, contextType, returnType, null)
        {
            if (parsedRequest == null)
            {
                throw new ArgumentNullException("parsedRequest");
            }

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

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

            ParsedRequest = parsedRequest;
            RequestParameters = requestParams;
            ContainerDescriptor = containerDescriptor;
            FieldRefs = new Dictionary<int, Tuple<ParameterExpression, Expression>>();
            ParamRefs = new Dictionary<int, Tuple<ParameterExpression, Expression>>();
        }
Exemple #3
0
        public void Complete(bool waitForProducerThread)
        {
            var completion = Completion;

            if (completion != null)
            {
                Completion = null;
                completion.Discard();
            }

            Thread.MemoryBarrier();

            DriverOutputBuffer = null;
            ResponseHeaders    = null;

            ParsedRequest.Clear();

            var cancellation = m_cancellationTokenSource;
            var engine       = m_engine;
            var message      = m_requestMessage;
            var authContext  = m_authContext;

            if (cancellation != null)
            {
                cancellation.Cancel();
            }

            if (engine != null)
            {
                if (m_tracer.IsDebugEnabled)
                {
                    if (message != null && authContext != null)
                    {
                        var age = (DateTime.Now - message.CreatedOn).TotalMilliseconds;
                        m_tracer.Debug(
                            string.Format(
                                "Releasing request context for auth context id {0}, total time spent: {1} ms", authContext.ContextId, age));
                    }
                    else
                    {
                        m_tracer.Debug("Releasing request context");
                    }
                }

                engine.EndExecution(this, waitForProducerThread);
            }

            if (message != null)
            {
                message.Close();
            }

            Cleanup();
        }
        public RequestExecutionContextCacheInfo(long hashCode)
        {
            if (hashCode == 0)
            {
                throw new ArgumentOutOfRangeException("hashCode", hashCode, "hashCode must be non-zero");
            }

            HashCode = hashCode;
            ParsedRequest = new ParsedRequest(true);
            RequestParams = new DataRequestParams();
            RequestBulk = new DataRequestBulk();
        }
Exemple #5
0
        public RequestExecutionContextCacheInfo(long hashCode)
        {
            if (hashCode == 0)
            {
                throw new ArgumentOutOfRangeException("hashCode", hashCode, "hashCode must be non-zero");
            }

            HashCode      = hashCode;
            ParsedRequest = new ParsedRequest(true);
            RequestParams = new DataRequestParams();
            RequestBulk   = new DataRequestBulk();
        }
        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);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Writes cacheable portion of request parsing and compilation information into the request context.
        /// </summary>
        public void WriteParsingResults(ParsedRequest parsedRequest)
        {
            ParsedRequest.BaseDataset.WriteTo(ref parsedRequest.BaseDataset);
            ParsedRequest.Select.WriteTo(ref parsedRequest.Select);
            ParsedRequest.Modify.WriteTo(ref parsedRequest.Modify);

            parsedRequest.OrdinalOfPrimaryKey = ParsedRequest.OrdinalOfPrimaryKey;
            parsedRequest.TargetEntity        = ParsedRequest.TargetEntity;
            parsedRequest.TargetEntityPkField = ParsedRequest.TargetEntityPkField;
            parsedRequest.StatementType       = ParsedRequest.StatementType;

            parsedRequest.SpecialCommand.IsSpecialCommand = ParsedRequest.SpecialCommand.IsSpecialCommand;
            parsedRequest.SpecialCommand.CommandType      = ParsedRequest.SpecialCommand.CommandType;
        }
Exemple #8
0
        public void Cleanup()
        {
            m_authContext           = null;
            m_lastError             = null;
            m_requestMessage        = null;
            m_engine                = null;
            ResponseHeaders         = null;
            RecordsAffected         = 0;
            TotalRowsProduced       = 0;
            DriverOutputBuffer      = null;
            InputDataEnumerator     = null;
            ClauseEvaluationContext = null;
            OutputDataBuffer        = null;
            Completion              = null;
            ContainerDescriptor     = null;

            CacheInfo = null;
            Request.Clear();
            RequestBulk.Clear();
            RequestParameters.Clear();
            ParsedRequest.Clear();

            var cancellation = Interlocked.CompareExchange(ref m_cancellationTokenSource, null, m_cancellationTokenSource);

            if (cancellation != null)
            {
                cancellation.Cancel();
            }

            var ring = Interlocked.CompareExchange(ref m_buffersRing, null, m_buffersRing);

            if (ring != null)
            {
                ring.Dispose();
            }

            var items = m_buffersRingItems; // do not replace with null

            if (items != null)
            {
                foreach (var item in items)
                {
                    item.Cleanup();
                }
            }
        }
        /// <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 static Expression GetOrAddFieldRefToCompilationContext(ParsedRequest parsedRequest, PqlCompilerState compilerState, FieldMetadata field)
        {
            Tuple<ParameterExpression, Expression> refTuple;
            if (compilerState.FieldRefs.TryGetValue(field.FieldId, out refTuple))
            {
                return refTuple.Item1;
            }

            var ordinal = GetFieldOrdinalInDriverFetchFields(parsedRequest, field);
            var rowData = Expression.Field(compilerState.Context, "InputRow");

            var fieldAccessor = DriverRowData.CreateReadAccessor(rowData, field.DbType, ordinal);
            var fieldRef = Expression.Variable(fieldAccessor.Type);

            compilerState.FieldRefs.Add(
                field.FieldId, new Tuple<ParameterExpression, Expression>(fieldRef, fieldAccessor));
            return fieldRef;
        }
        private static Expression GetOrAddParameterRefToCompilationContext(ParsedRequest parsedRequest, PqlCompilerState compilerState, int parameterOrdinal)
        {
            Tuple<ParameterExpression, Expression> refTuple;
            if (compilerState.ParamRefs.TryGetValue(parameterOrdinal, out refTuple))
            {
                return refTuple.Item1;
            }

            ParameterExpression paramRef;
            Expression paramExtractor;
            var localOrdinal = parsedRequest.Params.OrdinalToLocalOrdinal[parameterOrdinal];
            var dbType = parsedRequest.Params.DataTypes[parameterOrdinal];

            if (BitVector.Get(compilerState.RequestParameters.IsCollectionFlags, parameterOrdinal))
            {
                var rowData = Expression.Field(compilerState.Context, "InputParametersCollections");
                var hashsetType = typeof (HashSet<>).MakeGenericType(DriverRowData.DeriveSystemType(dbType));
                paramExtractor = Expression.Convert(Expression.ArrayIndex(rowData, Expression.Constant(localOrdinal, typeof(int))), hashsetType);
                paramRef = Expression.Variable(paramExtractor.Type);
            }
            else
            {
                var rowData = Expression.Field(compilerState.Context, "InputParametersRow");
                paramExtractor = DriverRowData.CreateReadAccessor(rowData, dbType, localOrdinal);
                paramRef = Expression.Variable(paramExtractor.Type);
            }

            compilerState.ParamRefs.Add(
                parameterOrdinal, new Tuple<ParameterExpression, Expression>(paramRef, paramExtractor));
            return paramRef;
        }
        /// <summary>
        /// Writes cacheable portion of request parsing and compilation information into the request context.
        /// </summary>
        public void WriteParsingResults(ParsedRequest parsedRequest)
        {
            ParsedRequest.BaseDataset.WriteTo(ref parsedRequest.BaseDataset);
            ParsedRequest.Select.WriteTo(ref parsedRequest.Select);
            ParsedRequest.Modify.WriteTo(ref parsedRequest.Modify);

            parsedRequest.OrdinalOfPrimaryKey = ParsedRequest.OrdinalOfPrimaryKey;
            parsedRequest.TargetEntity = ParsedRequest.TargetEntity;
            parsedRequest.TargetEntityPkField = ParsedRequest.TargetEntityPkField;
            parsedRequest.StatementType = ParsedRequest.StatementType;

            parsedRequest.SpecialCommand.IsSpecialCommand = ParsedRequest.SpecialCommand.IsSpecialCommand;
            parsedRequest.SpecialCommand.CommandType = ParsedRequest.SpecialCommand.CommandType;
        }
        private static void InitDriverFetchFields(ParsedRequest parsedRequest)
        {
            if (parsedRequest.IsBulk)
            {
                foreach (var field in parsedRequest.BulkInput.BulkInputFields)
                {
                    parsedRequest.BaseDataset.BaseFields.Add(field);
                }

                parsedRequest.BaseDataset.BaseFieldsMainCount = parsedRequest.BaseDataset.BaseFields.Count;
            }
            else
            {
                foreach (var field in parsedRequest.BaseDataset.WhereClauseFields)
                {
                    parsedRequest.BaseDataset.BaseFields.Add(field);
                }

                foreach (var field in parsedRequest.Select.SelectFields)
                {
                    if (!parsedRequest.BaseDataset.BaseFields.Contains(field))
                    {
                        parsedRequest.BaseDataset.BaseFields.Add(field);
                    }
                }

                parsedRequest.BaseDataset.BaseFieldsMainCount = parsedRequest.BaseDataset.WhereClauseFields.Count;
            }
        }
 private static int GetFieldOrdinalInDriverFetchFields(ParsedRequest parsedRequest, FieldMetadata field)
 {
     // get ordinal of this field in the dataset returned by storage driver
     var ordinal = parsedRequest.BaseDataset.BaseFields.IndexOf(field);
     if (ordinal < 0)
     {
         throw new Exception(
             string.Format(
                 "Internal error: driver fetch fields does have have field {0}, id {1} of entity {2}"
                 , field.Name, field.FieldId, parsedRequest.TargetEntity.Name));
     }
     return ordinal;
 }
        private static Func<DriverRowData, int> CompileInt32ParamExtractorForPaging(ParsedRequest parsedRequest, ParseTreeNode parseTreeNode, int defaultValue)
        {
            var paramName = parseTreeNode.RequireChild("id_simple", 0).Token.ValueString;
            if (string.IsNullOrEmpty(paramName) || paramName[0] != '@')
            {
                throw new CompilationException("Values for paging clause must be Int32 constants or Int32 parameters", parseTreeNode);
            }

            var names = parsedRequest.Params.Names;
            if (names != null)
            {
                for (var paramOrdinal = 0; paramOrdinal < names.Length; paramOrdinal++)
                {
                    if (StringComparer.OrdinalIgnoreCase.Equals(names[paramOrdinal], paramName))
                    {
                        if (parsedRequest.Params.DataTypes[paramOrdinal] != DbType.Int32)
                        {
                            throw new CompilationException(string.Format(
                                "Parameter {0} must be of type Int32 for use in paging options. Actual type: {1}",
                                paramName, parsedRequest.Params.DataTypes[paramOrdinal])
                            , parseTreeNode);
                        }

                        var localOrdinal = parsedRequest.Params.OrdinalToLocalOrdinal[paramOrdinal];
                        return data => BitVector.Get(data.NotNulls, localOrdinal) ? data.GetInt32(localOrdinal) : defaultValue;
                    }
                }
            }

            throw new CompilationException("Unknown parameter: " + paramName, parseTreeNode);
        }
Exemple #16
0
        /// <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 void ParseInsertStatement(ParsedRequest parsedRequest, ParseTreeNode insertStmt)
        {
            // get FROM entity name
            var insertEntityClause = insertStmt.RequireChild("Id", 2);
            parsedRequest.TargetEntity = GetTargetEntity(insertEntityClause);

            // preprocess identifiers
            m_preprocessor.ProcessIdentifierAliases(insertStmt, parsedRequest.TargetEntity);

            var insertFieldsListClause = insertStmt.RequireChild("idList", 3, 0);
            var valueListClause = insertStmt.RequireChild("insertTuplesList", 4, 1);

            if (valueListClause.ChildNodes.Count != 1)
            {
                throw new CompilationException("Multi-tuple explicit list of values for INSERT is not yet supported");
            }

            valueListClause = valueListClause.ChildNodes[0];

            if (insertFieldsListClause.ChildNodes.Count != valueListClause.ChildNodes.Count)
            {
                throw new CompilationException("Number of fields in INSERT clause must match number of expressions in VALUES clause", insertStmt);
            }

            parsedRequest.TargetEntityPkField = m_containerDescriptor.RequireField(parsedRequest.TargetEntity.DocumentType, parsedRequest.TargetEntity.PrimaryKeyFieldName);
            for (var ordinal = 0; ordinal < insertFieldsListClause.ChildNodes.Count; ordinal++)
            {
                var insertFieldNode = insertFieldsListClause.ChildNodes[ordinal];
                var field = TryGetFieldByIdentifierNode(insertFieldNode, m_containerDescriptor, parsedRequest.TargetEntity.DocumentType);
                if (field == null)
                {
                    throw new CompilationException("Attempting to INSERT into an unknown field", insertFieldNode);
                }

                if (ReferenceEquals(field, parsedRequest.TargetEntityPkField))
                {
                    parsedRequest.OrdinalOfPrimaryKey = ordinal;
                }

                if (parsedRequest.Modify.ModifiedFields.Contains(field))
                {
                    throw new CompilationException("A field can be assigned by INSERT only once: " + field.Name, insertFieldNode);
                }

                var expressionClause = valueListClause.ChildNodes[ordinal];

                // update clauses list will hold value expressions
                parsedRequest.Modify.ModifiedFields.Add(field);
                parsedRequest.Modify.InsertUpdateSetClauses.Add(expressionClause);
            }

            if (parsedRequest.OrdinalOfPrimaryKey < 0)
            {
                throw new CompilationException("Value for primary key field must be specified: " + parsedRequest.TargetEntityPkField.Name);
            }
        }
        private void ParseDeleteStatement(ParsedRequest parsedRequest, ParseTreeNode deleteStmt)
        {
            // get FROM entity name
            var deleteFromClause = deleteStmt.RequireChild("Id", 2);
            parsedRequest.TargetEntity = GetTargetEntity(deleteFromClause);

            // preprocess identifiers
            m_preprocessor.ProcessIdentifierAliases(deleteStmt, parsedRequest.TargetEntity);

            var ctx = GetTreeIteratorContext(parsedRequest, m_containerDescriptor);
            ctx.Functor = FieldExtractor;

            // get field names for where clause
            var whereClause = deleteStmt.TryGetChild("whereClauseOpt", 3);
            ParseWhereClause(whereClause, ctx);

            // get field names for order clause
            ctx.ParsedRequest.BaseDataset.OrderClause = deleteStmt.TryGetChild("orderList", 4, 2);
            ParseOrderClause(ctx);
        }
        private void ParseBulkRequest(DataRequestBulk requestBulk, ParsedRequest parsedRequest)
        {
            switch (requestBulk.DbStatementType)
            {
                case StatementType.Insert:
                case StatementType.Update:
                    parsedRequest.StatementType = requestBulk.DbStatementType;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("requestBulk", requestBulk.DbStatementType, "Invalid bulk statement type");
            }

            parsedRequest.TargetEntity = m_containerDescriptor.RequireDocumentType(
                m_containerDescriptor.RequireDocumentTypeName(requestBulk.EntityName));

            if (string.IsNullOrEmpty(parsedRequest.TargetEntity.PrimaryKeyFieldName))
            {
                throw new Exception("Target entity does not have a primary key, cannot perform bulk operations on it");
            }

            parsedRequest.TargetEntityPkField = m_containerDescriptor.RequireField(
                parsedRequest.TargetEntity.DocumentType, parsedRequest.TargetEntity.PrimaryKeyFieldName);

            // we always expect value of primary key into driver row data for bulk requests at first position
            parsedRequest.OrdinalOfPrimaryKey = 0;

            if (0 != StringComparer.OrdinalIgnoreCase.Compare(requestBulk.FieldNames[0], parsedRequest.TargetEntityPkField.Name))
            {
                throw new Exception("First field in bulk request input schema on this entity must be the primary key field");
            }

            for (var ordinal = 0; ordinal < requestBulk.FieldNames.Length; ordinal++)
            {
                var fieldName = requestBulk.FieldNames[ordinal];
                var field = m_containerDescriptor.RequireField(parsedRequest.TargetEntity.DocumentType, fieldName);

                if (ordinal != 0 && ReferenceEquals(parsedRequest.TargetEntityPkField, field))
                {
                    throw new Exception("Primary key field may only be used in first position");
                }

                if (parsedRequest.Modify.ModifiedFields.Contains(field))
                {
                    throw new CompilationException("A field can be assigned only once: " + field.Name, null);
                }

                parsedRequest.BulkInput.BulkInputFields.Add(field);
                parsedRequest.Modify.ModifiedFields.Add(field);
                parsedRequest.Modify.InsertUpdateSetClauses.Add(null);
            }
        }
 private static void WriteParsedRequestToCache(RequestExecutionContextCacheInfo cacheInfo, ParsedRequest parsedRequest)
 {
 }
        private static void ReadPagingOptions(ParseTreeNode selectStmt, ParsedRequest parsedRequest)
        {
            var clause = selectStmt.RequireChild("pageOffset", 10);
            if (clause != null && clause.ChildNodes.Count > 0)
            {
                var param = clause.TryGetChild("Id", 1);
                if (param != null)
                {
                    parsedRequest.BaseDataset.Paging.Offset = CompileInt32ParamExtractorForPaging(parsedRequest, param, 0);
                }
                else
                {
                    var number = clause.RequireChild("number", 1);
                    int value;
                    if (!int.TryParse(number.Token.ValueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)
                        || value < 0)
                    {
                        throw new CompilationException("Invalid value for page offset", number);
                    }
                    parsedRequest.BaseDataset.Paging.Offset = x => value;
                }
            }

            clause = selectStmt.RequireChild("pageSize", 9);
            if (clause != null && clause.ChildNodes.Count > 0)
            {
                var param = clause.TryGetChild("Id", 1);
                if (param != null)
                {
                    parsedRequest.BaseDataset.Paging.PageSize = CompileInt32ParamExtractorForPaging(parsedRequest, param, Int32.MaxValue);
                }
                else
                {
                    var number = clause.RequireChild("number", 1);
                    int value;
                    if (!int.TryParse(number.Token.ValueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)
                        || value < -1)
                    {
                        throw new CompilationException("Invalid value for page size", number);
                    }

                    if (value != -1)
                    {
                        parsedRequest.BaseDataset.Paging.PageSize = x => value;
                    }
                }
            }
        }
Exemple #22
0
        public void AttachDriverOutputBufferAndInputParameters(DriverRowData driverOutputBuffer, ParsedRequest parsedRequest)
        {
            if (driverOutputBuffer == null)
            {
                throw new ArgumentNullException("driverOutputBuffer");
            }

            if (DriverOutputBuffer != null)
            {
                throw new InvalidOperationException("Cannot reassign driver output buffer");
            }

            DriverOutputBuffer = driverOutputBuffer;
            ClauseEvaluationContext.InputRow                   = driverOutputBuffer;
            ClauseEvaluationContext.InputParametersRow         = parsedRequest.Params.InputValues;
            ClauseEvaluationContext.InputParametersCollections = parsedRequest.Params.InputCollections;
        }
        private void ParseUpdateStatement(ParsedRequest parsedRequest, ParseTreeNode updateStmt)
        {
            // get FROM entity name
            var updateEntityClause = updateStmt.RequireChild("Id", 1);
            parsedRequest.TargetEntity = GetTargetEntity(updateEntityClause);

            // preprocess identifiers
            m_preprocessor.ProcessIdentifierAliases(updateStmt, parsedRequest.TargetEntity);

            var ctx = GetTreeIteratorContext(parsedRequest, m_containerDescriptor);
            ctx.Functor = FieldExtractor;

            var assignListClause = updateStmt.RequireChild("assignList", 3);
            foreach (var assignClause in assignListClause.ChildNodes)
            {
                var field = TryGetFieldByIdentifierNode(assignClause.RequireChild("Id", 0), m_containerDescriptor, parsedRequest.TargetEntity.DocumentType);
                if (field == null)
                {
                    throw new CompilationException("Attempting to SET an unknown field", assignClause);
                }

                if (parsedRequest.Modify.ModifiedFields.Contains(field))
                {
                    throw new CompilationException("A field can be assigned by UPDATE only once: " + field.Name, null);
                }

                var expressionClause = assignClause.RequireChild(null, 2);
                parsedRequest.Modify.ModifiedFields.Add(field);
                parsedRequest.Modify.InsertUpdateSetClauses.Add(expressionClause);

                // iterator callback will place all referenced column IDs into "select" list
                // later on, "select" list is used along with "where" list to create driver fetch list
                ctx.Argument = 1;
                IterateTree(expressionClause, 0, ctx);
            }

            // get field names for where clause
            var whereClause = updateStmt.TryGetChild("whereClauseOpt", 4);
            ParseWhereClause(whereClause, ctx);

            // get field names for order clause
            ctx.ParsedRequest.BaseDataset.OrderClause = updateStmt.TryGetChild("orderList", 5, 2);
            ParseOrderClause(ctx);
        }
        public void AttachDriverOutputBufferAndInputParameters(DriverRowData driverOutputBuffer, ParsedRequest parsedRequest)
        {
            if (driverOutputBuffer == null)
            {
                throw new ArgumentNullException("driverOutputBuffer");
            }

            if (DriverOutputBuffer != null)
            {
                throw new InvalidOperationException("Cannot reassign driver output buffer");
            }

            DriverOutputBuffer = driverOutputBuffer;
            ClauseEvaluationContext.InputRow = driverOutputBuffer;
            ClauseEvaluationContext.InputParametersRow = parsedRequest.Params.InputValues;
            ClauseEvaluationContext.InputParametersCollections = parsedRequest.Params.InputCollections;
        }
        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);
            }
        }
 private static TreeIteratorContext GetTreeIteratorContext(ParsedRequest parsedRequest, DataContainerDescriptor containerDescriptor)
 {
     var result = new TreeIteratorContext();
     result.ContainerDescriptor = containerDescriptor;
     result.ParsedRequest = parsedRequest;
     return result;
 }
        private void ParseSelectStatement(ParsedRequest parsedRequest, ParseTreeNode selectStmt)
        {
            // get FROM entity name
            var fromClause = selectStmt.RequireChild("fromClauseOpt", 4);
            var fromEntityNode = fromClause.RequireChild("Id", 1, 0);
            parsedRequest.TargetEntity = GetTargetEntity(fromEntityNode);

            var ctx = GetTreeIteratorContext(parsedRequest, m_containerDescriptor);
            ctx.Functor = FieldExtractor;

            // get field names for select clause
            var selectColumnItemList = selectStmt.TryGetChild(null, 2, 0);
            if (selectColumnItemList == null)
            {
                throw new CompilationException("Could not find select clause", selectStmt);
            }

            if (0 == StringComparer.Ordinal.Compare("columnItemList", selectColumnItemList.Term.Name))
            {
                // iterator callback will place all referenced column IDs into "select" list
                // later on, "select" list is used along with "where" list to create driver fetch list
                ctx.Argument = 1;

                foreach (var columnItem in selectColumnItemList.ChildNodes)
                {
                    // column or column with alias
                    columnItem.RequireChildren(1, 2);

                    var columnSource = columnItem.RequireChild("columnSource", 0);

                    // store a reference to every column item and its alias,
                    // since we may need to compile it into an expression or do something else later
                    parsedRequest.Select.SelectClauses.Add(columnItem);

                    // preprocess identifiers
                    m_preprocessor.ProcessIdentifierAliases(columnSource, parsedRequest.TargetEntity);

                    // extract field names from a regular select clause (but do not look into "as" alias)
                    IterateTree(columnSource, 0, ctx);
                }
            }
            else if (selectColumnItemList.ChildNodes.Count == 0 && selectColumnItemList.Token != null && "*".Equals(selectColumnItemList.Token.Text))
            {
                // they ask for all fields (wildcard)
                // let's extract only unpacked blobs
                var docTypeDescriptor = parsedRequest.TargetEntity;
                foreach (var field in m_containerDescriptor.EnumerateFields().Where(x => x.OwnerDocumentType == docTypeDescriptor.DocumentType))
                {
                    ctx.ParsedRequest.Select.SelectFields.Add(field);
                    ctx.ParsedRequest.Select.SelectClauses.Add(m_simpleFieldAccessorNodes[field.FieldId]);
                }
            }
            else
            {
                throw new CompilationException("Must have list of columns or an asterisk in select clause", selectColumnItemList);
            }

            // get field names for where clause
            var whereClause = selectStmt.TryGetChild("whereClauseOpt", 5);
            ParseWhereClause(whereClause, ctx);

            // get field names for order clause
            ctx.ParsedRequest.BaseDataset.OrderClause = selectStmt.TryGetChild("orderList", 8, 2);
            ParseOrderClause(ctx);

            ReadPagingOptions(selectStmt, ctx.ParsedRequest);
        }
        /// <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()
                };
        }