/// <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>>(); }
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(); }
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> /// 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; }
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; }
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); }
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; } } } }
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); }
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); }