private CohortQueryBuilderDependencySql GetCachFetchSqlIfPossible(CohortQueryBuilderResult parent, AggregateConfiguration aggregate, CohortQueryBuilderDependencySql sql, bool isPatientIndexTable) { if (parent.CacheManager == null) { return(null); } string parameterSql = QueryBuilder.GetParameterDeclarationSQL(sql.ParametersUsed.Clone().GetFinalResolvedParametersList()); string hitTestSql = parameterSql + sql.Sql; var existingTable = parent.CacheManager.GetLatestResultsTable(aggregate, isPatientIndexTable ?AggregateOperation.JoinableInceptionQuery:AggregateOperation.IndexedExtractionIdentifierList, hitTestSql); //if there is a cached entry matching the cacheless SQL then we can just do a select from it (in theory) if (existingTable != null) { string sqlCachFetch = CachedAggregateConfigurationResultsManager.CachingPrefix + aggregate.Name + @"*/" + Environment.NewLine + "select * from " + existingTable.GetFullyQualifiedName() + Environment.NewLine; //Cache fetch does not require any parameters return(new CohortQueryBuilderDependencySql(sqlCachFetch, new ParameterManager())); } return(null); }
public void Build(CohortQueryBuilderResult parent, ISqlParameter[] globals) { bool isSolitaryPatientIndexTable = CohortSet.IsJoinablePatientIndexTable(); //Includes the parameter declaration and no rename operations (i.e. couldn't be used for building the tree but can be used for cache hit testing). if (JoinedTo != null) { SqlJoinableCacheless = parent.Helper.GetSQLForAggregate(JoinedTo, new QueryBuilderArgs(new QueryBuilderCustomArgs(), //don't respect customizations in the inception bit! globals)); SqlJoinableCached = GetCachFetchSqlIfPossible(parent, JoinedTo, SqlJoinableCacheless, true); } if (isSolitaryPatientIndexTable) { //explicit execution of a patient index table on it's own //the full uncached SQL for the query SqlCacheless = parent.Helper.GetSQLForAggregate(CohortSet, new QueryBuilderArgs(parent.Customise, globals)); if (SqlJoinableCached != null) { throw new QueryBuildingException("Patient index tables can't use other patient index tables!"); } } else { //the full uncached SQL for the query SqlCacheless = parent.Helper.GetSQLForAggregate(CohortSet, new QueryBuilderArgs(PatientIndexTableIfAny, JoinedTo, SqlJoinableCacheless, parent.Customise, globals)); //if the joined to table is cached we can generate a partial too with full sql for the outer sql block and a cache fetch join if (SqlJoinableCached != null) { SqlPartiallyCached = parent.Helper.GetSQLForAggregate(CohortSet, new QueryBuilderArgs(PatientIndexTableIfAny, JoinedTo, SqlJoinableCached, parent.Customise, globals)); } } //We would prefer a cache hit on the exact uncached SQL SqlFullyCached = GetCachFetchSqlIfPossible(parent, CohortSet, SqlCacheless, isSolitaryPatientIndexTable); //but if that misses we would take a cache hit of an execution of the SqlPartiallyCached if (SqlFullyCached == null && SqlPartiallyCached != null) { SqlFullyCached = GetCachFetchSqlIfPossible(parent, CohortSet, SqlPartiallyCached, isSolitaryPatientIndexTable); } }
private void RecreateHelpers(QueryBuilderCustomArgs customizations) { helper = new CohortQueryBuilderHelper(); Results = new CohortQueryBuilderResult(CacheServer, _childProvider, helper, customizations); }