/*
* Copyright (c) 2006-2013 Massachusetts General Hospital
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the i2b2 Software License v1.0
* which accompanies this distribution.
*
* Contributors:
* Christopher Herrick
*/
package edu.harvard.i2b2.crc.dao.setfinder.querybuilder.temporal;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.harvard.i2b2.common.exception.I2B2DAOException;
import edu.harvard.i2b2.common.exception.I2B2Exception;
import edu.harvard.i2b2.crc.dao.DAOFactoryHelper;
import edu.harvard.i2b2.crc.dao.setfinder.querybuilder.QueryTimingHandler;
import edu.harvard.i2b2.crc.dao.setfinder.querybuilder.temporal.TemporalQueryOptions.QueryConstraintStrategy;
import edu.harvard.i2b2.crc.dao.setfinder.querybuilder.temporal.TemporalQueryOptions.TemporalConstraintStrategy;
import edu.harvard.i2b2.crc.datavo.db.DataSourceLookup;
import edu.harvard.i2b2.crc.datavo.i2b2message.SecurityType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryDefinitionType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryJoinColumnType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryJoinType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryOperatorType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.QuerySpanConstraintType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryAggregateOperatorType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.PanelType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryConstraintType;
public class TemporalSubQuery implements Comparable{
protected final Log log = LogFactory.getLog(getClass());
public enum TemporalQuerySpanUnits{
YEAR,
MONTH,
DAY,
HOUR,
SECOND,
MINUTE
};
public enum TemporalQueryReturnColumns {
PATIENT,
ENCOUNTER,
INSTANCE,
START_DATE,
END_DATE,
FIRST_START_DATE,
LAST_START_DATE,
FIRST_END_DATE,
LAST_END_DATE,
ENCOUNTER_START_DATE,
ENCOUNTER_END_DATE,
FIRST_ENCOUNTER_START_DATE,
LAST_ENCOUNTER_START_DATE,
FIRST_ENCOUNTER_END_DATE,
LAST_ENCOUNTER_END_DATE
};
private List<TemporalPanel> panelList = null;
private TemporalQuery parent;
private int invertedPanelCount = 0;
private int startPanelIndex = 0;
private int endPanelIndex = -1;
private EnumSet<TemporalQueryReturnColumns> rtnColumns = EnumSet.of(TemporalQueryReturnColumns.PATIENT);
private QueryDefinitionType subQuery = null;
private String subQueryId = null;
private HashMap<String, List<QueryConstraintType>> constraints = null;
private boolean aggregateApplied = false;
private List<String> preProcessingSql = null;
private List<String> postProcessingSql = null;
public TemporalSubQuery(TemporalQuery parent, List<PanelType> groupPanels) throws I2B2Exception{
this.parent = parent;
this.subQuery = new QueryDefinitionType();
this.subQuery.setQueryId(parent.generateUniqueId());
this.subQuery.getPanel().addAll(groupPanels);
this.preProcessingSql = new ArrayList<String>();
this.postProcessingSql = new ArrayList<String>();
parsePanels(groupPanels);
}
public TemporalSubQuery(TemporalQuery parent, QueryDefinitionType event) throws I2B2Exception{
this.parent = parent;
this.subQuery = event;
if (event.getQueryId()==null||event.getQueryId().trim().length()==0)
event.setQueryId(parent.generateUniqueId());
this.preProcessingSql = new ArrayList<String>();
this.postProcessingSql = new ArrayList<String>();
parsePanels(event.getPanel());
}
public TemporalSubQuery(TemporalQuery parent, QueryDefinitionType event, HashMap<String, List<QueryConstraintType>> constraintList) throws I2B2Exception{
this.parent = parent;
this.subQuery = event;
if (event.getQueryId()==null||event.getQueryId().trim().length()==0)
event.setQueryId(parent.generateUniqueId());
if (constraintList!=null)
this.constraints = constraintList;
this.preProcessingSql = new ArrayList<String>();
this.postProcessingSql = new ArrayList<String>();
parsePanels(event.getPanel());
}
public TemporalSubQuery(TemporalQuery parent, QueryDefinitionType event, HashMap<String, List<QueryConstraintType>> constraintList, EnumSet<TemporalQueryReturnColumns> returnColumns) throws I2B2Exception{
this.parent = parent;
this.subQuery = event;
if (event.getQueryId()==null||event.getQueryId().trim().length()==0)
event.setQueryId(parent.generateUniqueId());
if (constraintList!=null)
this.constraints = constraintList;
if (returnColumns!=null)
this.rtnColumns = returnColumns;
this.preProcessingSql = new ArrayList<String>();
this.postProcessingSql = new ArrayList<String>();
parsePanels(event.getPanel());
}
private void parsePanels(List<PanelType> grpList) throws I2B2Exception{
TreeSet<TemporalPanel> panelSet = new TreeSet<TemporalPanel>();
for (PanelType panelType : grpList) {
TemporalPanel panelItem = new TemporalPanel(this, panelType);
if (panelItem.isPanelInverted())
invertedPanelCount++;
panelSet.add(panelItem);
}
panelList = new ArrayList<TemporalPanel>();
panelList.addAll(panelSet);
}
public String buildSql() throws I2B2DAOException{
StringBuffer subQuerySqlBuffer = new StringBuffer();
int currentPanelIndex = 0;
for (TemporalPanel panel : panelList){
String panelSql = panel.buildSql(currentPanelIndex);
subQuerySqlBuffer.append(panelSql);
if (!panel.isPanelInverted()){
endPanelIndex = currentPanelIndex;
currentPanelIndex++;
}
subQuerySqlBuffer.append(getSqlDelimiter());
}
if (parent.getSubQueryCount()>1){
int level = 0;
if (this.isFirstSubQuery())
level = 1;
subQuerySqlBuffer.append(buildMoveToMasterSql(level));
subQuerySqlBuffer.append(getSqlDelimiter());
if (parent.getServerType().equals(DAOFactoryHelper.ORACLE))
parent.addPostProcessingSql(getDeleteTempMasterSql(this.getSubQueryId(), 0));
subQuerySqlBuffer.append(getDeleteTempTableSql());
subQuerySqlBuffer.append(getSqlDelimiter());
}
if (!this.isFirstSubQuery()){
subQuerySqlBuffer.append(buildMasterTableTimingConstraintUpdate(1));
subQuerySqlBuffer.append(getSqlDelimiter());
}
StringBuffer sqlBuffer = new StringBuffer();
if (this.preProcessingSql!=null&&this.preProcessingSql.size()>0){
for(String sql : this.preProcessingSql){
sqlBuffer.append(sql);
sqlBuffer.append(getSqlDelimiter());
}
}
sqlBuffer.append(subQuerySqlBuffer.toString());
if (this.postProcessingSql!=null&&this.postProcessingSql.size()>0){
for(String sql : this.postProcessingSql){
sqlBuffer.append(sql);
sqlBuffer.append(getSqlDelimiter());
}
}
return sqlBuffer.toString();
}
public boolean isFirstSubQuery(){
return parent.isFirstSubQuery(this);
}
public boolean isLastSubQuery(){
return parent.isLastSubQuery(this);
}
protected TemporalQueryReturnColumns getStartDateReturnType(){
//currently, we only support one start and end date type per query. if both instance and encounter start dates
//are specified in a query, we'll use the instance date
if (rtnColumns.contains(TemporalQueryReturnColumns.START_DATE)
|| (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_START_DATE) && rtnColumns
.contains(TemporalQueryReturnColumns.LAST_START_DATE))
|| (rtnColumns
.contains(TemporalQueryReturnColumns.END_DATE) && (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_START_DATE) || rtnColumns
.contains(TemporalQueryReturnColumns.LAST_START_DATE)))) {
return TemporalQueryReturnColumns.START_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_START_DATE)) {
return TemporalQueryReturnColumns.FIRST_START_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.LAST_START_DATE)) {
return TemporalQueryReturnColumns.LAST_START_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.ENCOUNTER_START_DATE)
|| (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_START_DATE) && rtnColumns
.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_START_DATE))
|| (rtnColumns
.contains(TemporalQueryReturnColumns.ENCOUNTER_END_DATE) && (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_START_DATE) || rtnColumns
.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_START_DATE)))) {
return TemporalQueryReturnColumns.ENCOUNTER_START_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_START_DATE)) {
return TemporalQueryReturnColumns.FIRST_ENCOUNTER_START_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_START_DATE)) {
return TemporalQueryReturnColumns.LAST_ENCOUNTER_START_DATE;
}
return null;
}
protected TemporalQueryReturnColumns getEndDateReturnType(){
if (rtnColumns.contains(TemporalQueryReturnColumns.END_DATE)
|| (rtnColumns.contains(TemporalQueryReturnColumns.FIRST_END_DATE) && rtnColumns
.contains(TemporalQueryReturnColumns.LAST_END_DATE))
|| (rtnColumns
.contains(TemporalQueryReturnColumns.START_DATE) && (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_END_DATE) || rtnColumns
.contains(TemporalQueryReturnColumns.LAST_END_DATE)))) {
return TemporalQueryReturnColumns.END_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_END_DATE)) {
return TemporalQueryReturnColumns.FIRST_END_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.LAST_END_DATE)) {
return TemporalQueryReturnColumns.LAST_END_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.ENCOUNTER_END_DATE)
|| (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_END_DATE) && rtnColumns
.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_END_DATE))
|| (rtnColumns
.contains(TemporalQueryReturnColumns.ENCOUNTER_START_DATE) && (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_END_DATE) || rtnColumns
.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_END_DATE)))) {
return TemporalQueryReturnColumns.ENCOUNTER_END_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_END_DATE)) {
return TemporalQueryReturnColumns.FIRST_ENCOUNTER_END_DATE;
} else if (rtnColumns
.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_END_DATE)) {
return TemporalQueryReturnColumns.LAST_ENCOUNTER_END_DATE;
}
return null;
}
protected String buildMasterTableTimingConstraintUpdate(int level){
String timingConstraintSql = buildTimingConstraintSql(level);
StringBuilder updateSql = new StringBuilder();
if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER)){
if (useSqlServerTempTables()){
updateSql.append("update #m" + getSubQueryId() + " ");
updateSql.append("set level_no = " + String.valueOf(level) + " ");
updateSql.append("from #m" + getSubQueryId() + " t ");
updateSql.append(timingConstraintSql + " ");
updateSql.append("and t.level_no = " + String.valueOf(level - 1) + " ");
}
else {
updateSql.append("update " + parent.getMasterTempTableName() + " ");
updateSql.append("set level_no = " + String.valueOf(level) + " ");
updateSql.append("from " + parent.getMasterTempTableName() + " t ");
updateSql.append(timingConstraintSql + " ");
updateSql.append("and t.level_no = " + String.valueOf(level - 1) + " ");
updateSql.append("and t.master_id = '" + this.getSubQueryId() + "'");
}
}
else {
updateSql.append("update " + parent.getMasterTempTableName() + " t ");
updateSql.append("set level_no = " + String.valueOf(level) + " ");
updateSql.append(timingConstraintSql + " ");
updateSql.append("and t.level_no = " + String.valueOf(level - 1) + " ");
updateSql.append("and t.master_id = '" + this.getSubQueryId() + "'");
}
return updateSql.toString();
}
protected String buildTimingConstraintUpdate(int panelCount){
String timingConstraintSql = buildTimingConstraintSql(panelCount);
StringBuilder updateSql = new StringBuilder();
if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER)){
updateSql.append("update " + parent.getTempTableName() + " ");
updateSql.append("set panel_count = " + String.valueOf(panelCount) + " ");
updateSql.append("from " + parent.getTempTableName() + " t ");
}
else {
updateSql.append("update " + parent.getTempTableName() + " t ");
updateSql.append("set panel_count = " + String.valueOf(panelCount) + " ");
}
updateSql.append(timingConstraintSql + " ");
updateSql.append("and t.panel_count = " + String.valueOf(panelCount - 1));
return updateSql.toString();
}
private String addTimingConstraintSql(String panelSql){
String timingConstraint = buildTimingConstraintSql();
int lastIndex = panelSql.lastIndexOf(this.getSqlDelimiter());
if (lastIndex==-1){
panelSql += timingConstraint;
}
else if (parent.getQueryOptions().getQueryConstraintLogic()==QueryConstraintStrategy.TEMP_TABLES &&
parent.getServerType().equals(DAOFactoryHelper.SQLSERVER)){
panelSql = addToRegExExpression(panelSql, "insert into " + parent.getTempTableName() + "(.*?)(?:(" + getSqlDelimiter().replace("*", "\\*") + "|$))", timingConstraint);
}
else {
panelSql = panelSql.replace(getSqlDelimiter(), timingConstraint + getSqlDelimiter()) + timingConstraint;
}
return panelSql;
}
private String addToRegExExpression(String sqlString, String regEx, String newSql){
StringBuilder sql = new StringBuilder();
Pattern p = Pattern.compile(regEx, Pattern.DOTALL|Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(sqlString);
int lastIndex = 0;
while (m.find()){
int endIndex = m.end();
String text = sqlString.substring(lastIndex, endIndex - getSqlDelimiter().length());
sql.append(text);
sql.append(newSql);
sql.append(getSqlDelimiter());
lastIndex = endIndex;
}
sql.append(sqlString.substring(lastIndex));
return sql.toString();
}
protected String buildTimingConstraintSql(){
return buildTimingConstraintSql(-1);
}
protected String buildTimingConstraintSql(int panelCount){
StringBuffer timingSqlBuf = new StringBuffer("");
boolean firstConstraint = true;
boolean encounterConstraint = false;
if (parent.getQueryTiming()!=null&&
(parent.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAME)||
parent.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEVISIT)))
encounterConstraint = true;
String lastSubQueryId = parent.getLastProcessedSubQueryId();
if (lastSubQueryId!=null&&lastSubQueryId.trim().length()>0){
if (useSqlServerTempTables()){
timingSqlBuf.append(" where exists (select 1 from " +
"#m" + lastSubQueryId + " m " +
"where m.patient_num = t.patient_num " +
(encounterConstraint?"and m.encounter_num = t.encounter_num ":"") +
"and m.level_no = 1 " +
//"group by m.patient_num" +
") \n");
}
else {
timingSqlBuf.append(" where exists (select 1 from " + parent.getMasterTempTableName() + " m " +
"where m.master_id = '" + lastSubQueryId + "' " +
"and m.patient_num = t.patient_num " +
(encounterConstraint?"and m.encounter_num = t.encounter_num ":"") +
"and m.level_no = 1 " +
//"group by m.patient_num " +
") \n");
}
firstConstraint = false;
}
if (constraints!=null){
for (List<QueryConstraintType> constraintLists: constraints.values()){
for (QueryConstraintType constraint: constraintLists){
QueryJoinType masterTableQuery = constraint.getFirstQuery();
QueryJoinType tempTableQuery = constraint.getSecondQuery();
//first, get the right column comparison
String firstColumn = getColumnNameFromType(constraint.getFirstQuery().getJoinColumn());
String secondColumn = getColumnNameFromType(constraint.getSecondQuery().getJoinColumn());
String firstPrefix = "m";
String secondPrefix = "t";
boolean switchedPrefix = false;
String otherQueryId = constraint.getFirstQuery().getQueryId();
if (constraint.getFirstQuery().getQueryId().equals(getQueryId())){
firstPrefix = secondPrefix;
secondPrefix = "m";
otherQueryId = constraint.getSecondQuery().getQueryId();
masterTableQuery = tempTableQuery;
tempTableQuery = constraint.getFirstQuery();
switchedPrefix = true;
}
String dateConstraintSql = buildDateSqlForMaster(masterTableQuery, encounterConstraint);
if (dateConstraintSql!=null&&dateConstraintSql.trim().length()>0){
if (firstConstraint){
timingSqlBuf.append(" where ");
firstConstraint = false;
}
else
timingSqlBuf.append(" and ");
timingSqlBuf.append(" exists (" +
"select 1 " +
"from (" + dateConstraintSql + ") m ");
String newPrefix = "t";
String columnName = getColumnNameFromType(tempTableQuery.getJoinColumn());
if (tempTableQuery.getAggregateOperator().equals(QueryAggregateOperatorType.FIRST)){
timingSqlBuf.append(", (select m.patient_num " +
(encounterConstraint?", m.encounter_num ":"") +
", min(m." + columnName + ") " + columnName + " ");
if (useSqlServerTempTables()){
timingSqlBuf.append("from #m" + this.buildSubQueryId(tempTableQuery.getQueryId()) + " m ");
}
else {
timingSqlBuf.append("from " + parent.getMasterTempTableName() + " m " +
"where m.master_id = '" + this.buildSubQueryId(tempTableQuery.getQueryId()) + "' ");
}
timingSqlBuf.append("group by m.patient_num" +
(encounterConstraint?", m.encounter_num ":"") +
") t2 " +
"where m.patient_num = t2.patient_num " +
(encounterConstraint?"and m.encounter_num = t2.encounter_num ":"") +
"and t.patient_num = t2.patient_num " +
(encounterConstraint?"and t.encounter_num = t2.encounter_num ":"") +
"and ");
newPrefix = "t2";
}
else if (tempTableQuery.getAggregateOperator().equals(QueryAggregateOperatorType.LAST)){
timingSqlBuf.append(", (select m.patient_num, max(m." + columnName + ") " + columnName + " ");
if (useSqlServerTempTables()){
timingSqlBuf.append("from #m" + this.buildSubQueryId(tempTableQuery.getQueryId()) + " m ");
}
else {
timingSqlBuf.append("from " + parent.getMasterTempTableName() + " m " +
"where m.master_id = '" + this.buildSubQueryId(tempTableQuery.getQueryId()) + "' ");
}
timingSqlBuf.append("group by m.patient_num) t2 " +
"where m.patient_num = t2.patient_num " +
(encounterConstraint?"and m.encounter_num = t2.encounter_num ":"") +
"and t.patient_num = t2.patient_num " +
(encounterConstraint?"and t.encounter_num = t2.encounter_num ":"") +
"and ");
newPrefix = "t2";
}
else {
timingSqlBuf.append("where ");
}
if (firstPrefix.equals("t"))
firstPrefix = newPrefix;
else
secondPrefix = newPrefix;
timingSqlBuf.append("m.patient_num = t.patient_num " +
(encounterConstraint?"and m.encounter_num = t.encounter_num ":""));
timingSqlBuf.append("and " + firstPrefix + "." + firstColumn + " ");
QueryOperatorType dateOperator = constraint.getOperator();
if (dateOperator.equals(QueryOperatorType.EQUAL))
timingSqlBuf.append("= ");
else if (dateOperator.equals(QueryOperatorType.GREATER))
timingSqlBuf.append("> ");
else if (dateOperator.equals(QueryOperatorType.GREATEREQUAL))
timingSqlBuf.append(">= ");
else if (dateOperator.equals(QueryOperatorType.LESS))
timingSqlBuf.append("< ");
else if (dateOperator.equals(QueryOperatorType.LESSEQUAL))
timingSqlBuf.append("<= ");
timingSqlBuf.append(secondPrefix + "." + secondColumn + " ");
if (constraint.getSpan()!=null&&constraint.getSpan().size()>0){
for (QuerySpanConstraintType spanConstraint : constraint.getSpan())
{
String spanFirstPrefix = firstPrefix;
String spanFirstColumn = firstColumn;
String spanSecondPrefix = secondPrefix;
String spanSecondColumn = secondColumn;
String spanOperator = "=";
QueryOperatorType spanOpType = spanConstraint.getOperator();
if (spanConstraint.getOperator()!=null){
if (spanOpType.equals(QueryOperatorType.EQUAL))
spanOperator = "= ";
else if (spanOpType.equals(QueryOperatorType.GREATER))
spanOperator = "> ";
else if (spanOpType.equals(QueryOperatorType.GREATEREQUAL))
spanOperator = ">= ";
else if (spanOpType.equals(QueryOperatorType.LESS))
spanOperator = "< ";
else if (spanOpType.equals(QueryOperatorType.LESSEQUAL))
spanOperator = "<= ";
}
String units = spanConstraint.getUnits();
String sqlUnits = "";
int span = spanConstraint.getSpanValue();
if (units!=null){
if (dateOperator.equals(QueryOperatorType.GREATER)||dateOperator.equals(QueryOperatorType.GREATEREQUAL)){
String spanPrefix = spanFirstPrefix;
String spanColumn = spanFirstColumn;
spanFirstPrefix = spanSecondPrefix;
spanFirstColumn = spanSecondColumn;
spanSecondPrefix = spanPrefix;
spanSecondColumn = spanColumn;
}
if (TemporalQuerySpanUnits.valueOf(units)==TemporalQuerySpanUnits.YEAR){
if (parent.getServerType().equals(DAOFactoryHelper.ORACLE))
sqlUnits = "ADD_MONTHS(" + spanFirstPrefix + "." + spanFirstColumn + ", (12 * " + span + "))";
else if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
sqlUnits = "DATEADD(YEAR, (" + span + "), " + spanFirstPrefix + "." + spanFirstColumn + ")";
else if (parent.getServerType().equals(DAOFactoryHelper.POSTGRESQL))
sqlUnits = " " + spanFirstPrefix + "." + spanFirstColumn + " + cast('" + span + " years' as interval) ";
}
else if (TemporalQuerySpanUnits.valueOf(units)==TemporalQuerySpanUnits.MONTH){
if (parent.getServerType().equals(DAOFactoryHelper.ORACLE))
sqlUnits = "ADD_MONTHS(" + spanFirstPrefix + "." + spanFirstColumn + ", (" + span + "))";
else if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
sqlUnits = "DATEADD(MONTH, (" + span + "), " + spanFirstPrefix + "." + spanFirstColumn + ")";
else if (parent.getServerType().equals(DAOFactoryHelper.POSTGRESQL))
sqlUnits = " " + spanFirstPrefix + "." + spanFirstColumn + " + cast('" + span + " months' as interval) ";
}
else if (TemporalQuerySpanUnits.valueOf(units)==TemporalQuerySpanUnits.DAY){
if (parent.getServerType().equals(DAOFactoryHelper.ORACLE))
sqlUnits = "(" + spanFirstPrefix + "." + spanFirstColumn + " + (" + span + "))";
else if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
sqlUnits = "DATEADD(DAY, (" + span + "), " + spanFirstPrefix + "." + spanFirstColumn + ")";
else if (parent.getServerType().equals(DAOFactoryHelper.POSTGRESQL))
sqlUnits = " " + spanFirstPrefix + "." + spanFirstColumn + " + cast('" + span + " days' as interval) ";
}
else if (TemporalQuerySpanUnits.valueOf(units)==TemporalQuerySpanUnits.HOUR){
if (parent.getServerType().equals(DAOFactoryHelper.ORACLE))
sqlUnits = "(" + spanFirstPrefix + "." + spanFirstColumn + " + (1/24 * " + span + "))";
else if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
sqlUnits = "DATEADD(HOUR, (" + span + "), " + spanFirstPrefix + "." + spanFirstColumn + ")";
else if (parent.getServerType().equals(DAOFactoryHelper.POSTGRESQL))
sqlUnits = " " + spanFirstPrefix + "." + spanFirstColumn + " + cast('" + span + " hours' as interval) ";
}
else if (TemporalQuerySpanUnits.valueOf(units)==TemporalQuerySpanUnits.MINUTE){
if (parent.getServerType().equals(DAOFactoryHelper.ORACLE))
sqlUnits = "(" + spanFirstPrefix + "." + spanFirstColumn + " + (1/1440 * " + span + "))";
else if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
sqlUnits = "DATEADD(MINUTE, (" + span + "), " + spanFirstPrefix + "." + spanFirstColumn + ")";
else if (parent.getServerType().equals(DAOFactoryHelper.POSTGRESQL))
sqlUnits = " " + spanFirstPrefix + "." + spanFirstColumn + " + cast('" + span + " minutes' as interval) ";
}
else if (TemporalQuerySpanUnits.valueOf(units)==TemporalQuerySpanUnits.SECOND){
if (parent.getServerType().equals(DAOFactoryHelper.ORACLE))
sqlUnits = "(" + spanFirstPrefix + "." + spanFirstColumn + " + (1/86400 * " + span + "))";
else if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
sqlUnits = "DATEADD(SECOND, (" + span + "), " + spanFirstPrefix + "." + spanFirstColumn + ")";
else if (parent.getServerType().equals(DAOFactoryHelper.POSTGRESQL))
sqlUnits = " " + spanFirstPrefix + "." + spanFirstColumn + " + cast('" + span + " seconds' as interval) ";
}
}
if (sqlUnits.trim().length()>0)
timingSqlBuf.append("and " + spanSecondPrefix + "." + spanSecondColumn + " " + spanOperator + " " + sqlUnits);
}
}
}
timingSqlBuf.append(")");
}
}
}
return timingSqlBuf.toString();
}
private String getTempQueryConstraint(QueryJoinType tempJoin, int panelCount){
boolean useTempTables = false;
if (parent.getServerType().equalsIgnoreCase(
DAOFactoryHelper.SQLSERVER)&&
parent.getQueryOptions().getQueryConstraintLogic()==QueryConstraintStrategy.TEMP_TABLES){
useTempTables = true;
}
StringBuilder tempClause = new StringBuilder();
if (tempJoin!=null){
String columnName = "";
String columnAlias = "";
String temporalTableAlias = "f";
String temporalJoinTable = "observation_fact";
if (tempJoin.getJoinColumn().equals(QueryJoinColumnType.STARTDATE)){
columnName = "start_date";
columnAlias = "temporal_start_date";
temporalTableAlias = "f";
temporalJoinTable = "observation_fact";
}
else if (tempJoin.getJoinColumn().equals(QueryJoinColumnType.ENDDATE)){
columnName = "end_date";
columnAlias = "temporal_end_date";
temporalTableAlias = "f";
temporalJoinTable = "observation_fact";
}
else if (tempJoin.getJoinColumn().equals(QueryJoinColumnType.ENCOUNTER_STARTDATE)){
columnName = "start_date";
columnAlias = "temporal_start_date";
temporalTableAlias = "v";
temporalJoinTable = "visit_dimension";
}
else if (tempJoin.getJoinColumn().equals(QueryJoinColumnType.ENCOUNTER_ENDDATE)){
columnName = "end_date";
columnAlias = "temporal_end_date";
temporalTableAlias = "v";
temporalJoinTable = "visit_dimension";
}
if (columnName.trim().length()>0){
if (tempJoin.getAggregateOperator().equals(QueryAggregateOperatorType.FIRST)){
tempClause.append("select " + temporalTableAlias + ".patient_num, " +
"min(" + temporalTableAlias + "." + columnName + ") " + columnAlias + " " +
"from " + parent.getDatabaseSchema() + temporalJoinTable + " " + temporalTableAlias + " ");
}
else if (tempJoin.getAggregateOperator().equals(QueryAggregateOperatorType.LAST)){
tempClause.append("select " + temporalTableAlias + ".patient_num, max(" + temporalTableAlias + "." + columnName + ") " + columnAlias + " " +
"from " + parent.getDatabaseSchema() + temporalJoinTable + " " + temporalTableAlias + " ");
}
else{
tempClause.append("select " + temporalTableAlias + ".patient_num, " + temporalTableAlias + ".encounter_num, " + temporalTableAlias + "." + columnName + " " + columnAlias + " " +
"from " + parent.getDatabaseSchema() + temporalJoinTable + " " + temporalTableAlias + " ");
}
String tableAlias = "cnst";
if (parent.getQueryOptions().getTemporalConstraintStrategy()==TemporalConstraintStrategy.TEMP_TABLE_UPDATE){
tempClause.append(", " + getTempTableName() + " cnst ");
}
else if (useTempTables){
tempClause.append(", #t cnst ");
}
else {
tempClause.append(", t cnst ");
}
tempClause.append("where " + tableAlias + ".patient_num = " + temporalTableAlias + ".patient_num ");
if (this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.ANY)){
tempClause.append("and " + tableAlias + ".encounter_num = " + temporalTableAlias + ".encounter_num ");
}
if (parent.getQueryOptions().getTemporalConstraintStrategy()==TemporalConstraintStrategy.TEMP_TABLE_UPDATE){
tempClause.append("and " + tableAlias + ".panel_count = " + String.valueOf(panelCount) + " ");
}
if ((tempJoin.getAggregateOperator().equals(QueryAggregateOperatorType.FIRST))||
(tempJoin.getAggregateOperator().equals(QueryAggregateOperatorType.LAST)))
tempClause.append("group by " + temporalTableAlias + ".patient_num ");
else
tempClause.append("group by " + temporalTableAlias + ".patient_num, " + temporalTableAlias + ".encounter_num, v." + columnName + " ");
}
}
return tempClause.toString();
}
private String buildDateSqlForMaster(QueryJoinType masterJoin, boolean includeEncounter){
String columnName = getColumnNameFromType(masterJoin.getJoinColumn());
String encounterColumn = (includeEncounter?", m.encounter_num ":"");
String selectStatement = "select m.patient_num " + encounterColumn + ", m." + columnName + " ";
String fromStatement = "from " + parent.getMasterTempTableName() + " m ";
String whereStatement = "where m.master_id = '" + this.buildSubQueryId(masterJoin.getQueryId()) + "' ";
String groupByStatement = "group by m.patient_num " + encounterColumn + " ";
if (useSqlServerTempTables()){
fromStatement = "from #m" + this.buildSubQueryId(masterJoin.getQueryId()) + " m ";
whereStatement = "";
}
if (!masterJoin.getJoinColumn().equals(QueryJoinColumnType.INSTANCE)){
if (masterJoin.getAggregateOperator().equals(QueryAggregateOperatorType.FIRST)){
selectStatement = "select m.patient_num " + encounterColumn + ", min(m." + columnName + ") " + columnName + " ";
}
else if (masterJoin.getAggregateOperator().equals(QueryAggregateOperatorType.LAST)){
selectStatement = "select m.patient_num " + encounterColumn + ", max(m." + columnName + ") " + columnName + " ";
}
else {
selectStatement = "select m.patient_num " + encounterColumn + ", m." + columnName + " ";
if (whereStatement.trim().length()>0)
whereStatement += "and m.level_no = 1 ";
else
whereStatement = "where m.level_no = 1 ";
groupByStatement = "";
}
}
else {
selectStatement = "select " + columnName + ", temporal_start_date, temporal_end_date ";
groupByStatement = "";
}
return selectStatement + " " +
fromStatement + " " +
whereStatement + " " +
groupByStatement;
}
/*private String getConstrainedDateSqlFromMaster(QueryJoinType masterJoin){
String columnName = getColumnNameFromType(masterJoin.getJoinColumn());
if (!masterJoin.getJoinColumn().equals(QueryJoinColumnType.INSTANCE)){
if (masterJoin.getAggregateOperator().equals(QueryAggregateOperatorType.FIRST))
return "select m.patient_num, min(m." + columnName + ") " + columnName + " " +
"from " + parent.getMasterTempTableName() + " m " +
"where m.master_id = '" + this.buildSubQueryId(masterJoin.getQueryId()) + "' " +
"group by m.patient_num";
else if (masterJoin.getAggregateOperator().equals(QueryAggregateOperatorType.LAST))
return "select m.patient_num, max(m." + columnName + ") " + columnName + " " +
"from " + parent.getMasterTempTableName() + " m " +
"where m.master_id = '" + this.buildSubQueryId(masterJoin.getQueryId()) + "' " +
"group by m.patient_num";
else
return "select m.patient_num, m." + columnName + " " +
"from " + parent.getMasterTempTableName() + " m " +
"where m.master_id = '" + this.buildSubQueryId(masterJoin.getQueryId()) + "' " +
"and m.level_no = 1 ";
}
else
return "select " + columnName + ", temporal_start_date, temporal_end_date " +
"from " + parent.getMasterTempTableName() + " m " +
"where m.master_id = '" + this.buildSubQueryId(masterJoin.getQueryId()) + "' ";
}*/
protected String getColumnNameFromType(QueryJoinColumnType columnType){
if (columnType!=null){
if (columnType.equals(QueryJoinColumnType.ENCOUNTER))
return "encounter_num";
else if (columnType.equals(QueryJoinColumnType.STARTDATE))
return "temporal_start_date";
else if (columnType.equals(QueryJoinColumnType.ENDDATE))
return "temporal_end_date";
else if (columnType.equals(QueryJoinColumnType.ENCOUNTER_STARTDATE))
return "temporal_start_date";
else if (columnType.equals(QueryJoinColumnType.ENCOUNTER_ENDDATE))
return "temporal_end_date";
else if (columnType.equals(QueryJoinColumnType.INSTANCE))
return "provider_id, start_date, concept_cd, instance_num, encounter_num, patient_num";
}
return "patient_num";
}
protected String buildMoveToMasterSql(int level) {
String tempTableName = parent.getTempTableName();
String masterTableName = parent.getMasterTempTableName();
StringBuilder masterSql = new StringBuilder();
StringBuilder insertClause = new StringBuilder();
if (!useSqlServerTempTables()){
insertClause.append(" insert into " + masterTableName);
insertClause.append("(master_id, patient_num, level_no");
if (rtnColumns.contains(TemporalQueryReturnColumns.ENCOUNTER)){
insertClause.append(", encounter_num");
}
if (rtnColumns.contains(TemporalQueryReturnColumns.INSTANCE)){
if (!rtnColumns.contains(TemporalQueryReturnColumns.ENCOUNTER)){
insertClause.append(", encounter_num");
}
insertClause.append(", provider_id, start_date, concept_cd, instance_num");
}
if (returnInstanceStartDate()||returnEncounterStartDate()){
insertClause.append(", temporal_start_date");
}
if (returnInstanceEndDate()||returnEncounterEndDate()){
insertClause.append(", temporal_end_date");
}
insertClause.append(") ");
}
else {
masterSql.append(parent.buildTempTableCheckDrop("#m" + getSubQueryId()));
masterSql.append(parent.getSqlDelimiter());
}
String schema = getDatabaseSchema();
if (schema==null)
schema = "";
else if (!schema.endsWith("."))
schema += ".";
String primaryTableAlias = "t.";
StringBuilder fromClause = new StringBuilder("from " + tempTableName + " t ");
StringBuilder whereClause = new StringBuilder(" where t.panel_count = " + this.getEndPanelIndex() + " ");
if ((((rtnColumns.contains(TemporalQueryReturnColumns.INSTANCE)||
returnInstanceStartDate()))&&
(!this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEINSTANCENUM)))||
(returnInstanceEndDate())){
primaryTableAlias = "f.";
fromClause.append(", " + schema + "observation_fact f ");
whereClause.append("and f.patient_num = t.patient_num ");
if (this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAME)||
this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEVISIT)){
whereClause.append("and f.encounter_num = t.encounter_num ");
}
else if (this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEINSTANCENUM)){
whereClause.append("and f.encounter_num = t.encounter_num ");
whereClause.append("and f.provider_id = t.provider_id ");
whereClause.append("and f.start_date = t.start_date ");
whereClause.append("and f.instance_num = t.instance_num ");
whereClause.append("and f.concept_cd = t.concept_cd ");
}
if (returnEncounterEndDate()||returnEncounterStartDate()){
fromClause.append(", " + schema + "visit_dimension v ");
whereClause.append("and f.patient_num = v.patient_num ");
whereClause.append("and f.encounter_num = v.encounter_num ");
}
}
else if ((rtnColumns.contains(TemporalQueryReturnColumns.ENCOUNTER)&&
!this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAME)&&
!this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEVISIT)&&
!this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEINSTANCENUM))||
returnEncounterStartDate()||
returnEncounterEndDate()){
primaryTableAlias = "v.";
fromClause.append(", " + schema + "visit_dimension v ");
whereClause.append("and v.patient_num = t.patient_num ");
if (!this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.ANY)){
whereClause.append("and v.encounter_num = t.encounter_num ");
}
}
boolean aggregate = false;
StringBuilder selectClause = new StringBuilder();
if (useSqlServerTempTables()){
selectClause.append("select t.patient_num, " + String.valueOf(level) + " level_no ");
}
else {
selectClause.append("select '" + getSubQueryId() + "', t.patient_num, " + String.valueOf(level) + " ");
}
StringBuilder groupByClause = new StringBuilder("group by t.patient_num ");
if (rtnColumns.contains(TemporalQueryReturnColumns.INSTANCE)){
selectClause.append(", " + primaryTableAlias + "encounter_num, " +
primaryTableAlias + "provider_id, " +
primaryTableAlias + "start_date, " +
primaryTableAlias + "concept_cd, " +
primaryTableAlias + "instance_num");
groupByClause.append(", " + primaryTableAlias + "encounter_num, " +
primaryTableAlias + "provider_id, " +
primaryTableAlias + "start_date, " +
primaryTableAlias + "concept_cd, " +
primaryTableAlias + "instance_num");
}
else if (rtnColumns.contains(TemporalQueryReturnColumns.ENCOUNTER)){
selectClause.append(", " + primaryTableAlias + "encounter_num");
groupByClause.append(", " + primaryTableAlias + "encounter_num");
}
TemporalQueryReturnColumns startDateRtn = getStartDateReturnType();
if (startDateRtn!=null){
if (startDateRtn==TemporalQueryReturnColumns.FIRST_START_DATE){
selectClause.append(", min(" + primaryTableAlias + "start_date) temporal_start_date ");
aggregate = true;
}
else if (startDateRtn==TemporalQueryReturnColumns.LAST_START_DATE){
selectClause.append(", max(" + primaryTableAlias + "start_date) temporal_start_date ");
aggregate = true;
}
else if (startDateRtn==TemporalQueryReturnColumns.START_DATE){
selectClause.append(", " + primaryTableAlias + "start_date temporal_start_date ");
groupByClause.append(", " + primaryTableAlias + "start_date");
}
else if (startDateRtn==TemporalQueryReturnColumns.FIRST_ENCOUNTER_START_DATE){
selectClause.append(", min(" + primaryTableAlias + "start_date) temporal_start_date ");
aggregate = true;
}
else if (startDateRtn==TemporalQueryReturnColumns.LAST_ENCOUNTER_START_DATE){
selectClause.append(", max(" + primaryTableAlias + "start_date) temporal_start_date ");
aggregate = true;
}
else if (startDateRtn==TemporalQueryReturnColumns.ENCOUNTER_START_DATE){
selectClause.append(", " + primaryTableAlias + "start_date temporal_start_date ");
groupByClause.append(", " + primaryTableAlias + "start_date");
}
}
TemporalQueryReturnColumns endDateRtn = getEndDateReturnType();
if (endDateRtn!=null){
if (endDateRtn==TemporalQueryReturnColumns.FIRST_END_DATE){
selectClause.append(", min(" + primaryTableAlias + "end_date) temporal_end_date ");
aggregate = true;
}
else if (endDateRtn==TemporalQueryReturnColumns.LAST_END_DATE){
selectClause.append(", max(" + primaryTableAlias + "end_date) temporal_end_date ");
aggregate = true;
}
else if (endDateRtn==TemporalQueryReturnColumns.END_DATE){
selectClause.append(", " + primaryTableAlias + "end_date temporal_end_date ");
groupByClause.append(", " + primaryTableAlias + "end_date");
}
else if (endDateRtn==TemporalQueryReturnColumns.FIRST_ENCOUNTER_END_DATE){
selectClause.append(", min(" + primaryTableAlias + "end_date) temporal_end_date ");
aggregate = true;
}
else if (endDateRtn==TemporalQueryReturnColumns.LAST_ENCOUNTER_END_DATE){
selectClause.append(", max(" + primaryTableAlias + "end_date) temporal_end_date ");
aggregate = true;
}
else if (endDateRtn==TemporalQueryReturnColumns.ENCOUNTER_END_DATE){
selectClause.append(", " + primaryTableAlias + "end_date temporal_end_date ");
groupByClause.append(", " + primaryTableAlias + "end_date");
}
}
String intoClause = "";
if (useSqlServerTempTables()){
intoClause = " into #m" + getSubQueryId() + " ";
}
String indexClause = "";
if (useSqlServerTempTables()){
indexClause = "CREATE NONCLUSTERED INDEX m" + getSubQueryId() + "_idx on #m" + getSubQueryId() + " (patient_num, temporal_start_date, level_no)";
}
masterSql.append(insertClause.toString());
masterSql.append(selectClause.toString());
masterSql.append(intoClause);
masterSql.append(fromClause.toString());
masterSql.append(whereClause.toString());
if (aggregate)
masterSql.append(groupByClause.toString());
if (indexClause.trim().length()>0){
masterSql.append(getSqlDelimiter());
masterSql.append(indexClause);
}
return masterSql.toString();
}
private boolean useSqlServerTempTables(){
return parent.useSqlServerTempTables();
}
protected String getDeleteTempTableSql() {
String tempTableName = parent.getTempTableName();
if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
return "truncate table "+ tempTableName;
else
return "delete "+
(parent.getServerType().equalsIgnoreCase(DAOFactoryHelper.POSTGRESQL)? " from " : "") + tempTableName;
}
protected String getDeleteDxTempTableSql() {
String tempTableName = parent.getDxTempTableName();
if (parent.getServerType().equals(DAOFactoryHelper.SQLSERVER))
return "truncate table "+ tempTableName;
else
return "delete "+
(parent.getServerType().equalsIgnoreCase(DAOFactoryHelper.POSTGRESQL)? " from " : "") + tempTableName;
}
protected String getDeleteTempMasterSql(String masterId, int level) {
String masterTableName = parent.getMasterTempTableName();
if (useSqlServerTempTables()){
return "if (object_id(#m" + masterId + ") is not null) drop table #m" + masterId + "\n" +
" else delete " + masterTableName + " " +
"where master_id = '" + masterId + "' " +
"and level_no >= " + String.valueOf(level);
}
else
return "delete " +
(parent.getServerType().equalsIgnoreCase(DAOFactoryHelper.POSTGRESQL)? " from " : "") +
masterTableName + " " +
"where master_id = '" + masterId + "' " +
"and level_no >= " + String.valueOf(level);
}
public List<TemporalPanel> getPanelList() {
return panelList;
}
public int getPanelCount(){
return this.panelList.size();
}
public boolean allAreInverted(){
return this.invertedPanelCount == this.panelList.size();
}
public int getInvertedPanelCount(){
return this.invertedPanelCount;
}
public int getNonInvertedPanelCount(){
return this.panelList.size() - this.invertedPanelCount;
}
protected SecurityType getSecurityType() {
return parent.getSecurityType();
}
protected SecurityType getRequestorSecurityType() {
return parent.getRequestorSecurityType();
}
protected String getProjectId() {
return parent.getProjectId();
}
protected DataSourceLookup getDataSourceLookup(){
return parent.getDataSourceLookup();
}
protected String getDatabaseSchema(){
return parent.getDatabaseSchema();
}
protected String getParentQueryTiming(){
return parent.getQueryTiming();
}
protected String getQueryTiming(){
String timing = subQuery.getQueryTiming();
if (timing==null||timing.trim().length()==0)
timing = parent.getQueryTiming();
if (timing==null||timing.trim().length()==0)
timing = QueryTimingHandler.ANY;
return timing;
}
protected String getServerType(){
return parent.getServerType();
}
protected Map getProjectParameterMap(){
return parent.getProjectParameterMap();
}
protected QueryTimingHandler getTimingHandler(){
return parent.getTimingHandler();
}
protected int getPanelIndex(TemporalPanel panel){
if (panel==null||panelList==null)
return -1;
else
return this.panelList.indexOf(panel);
}
protected String getTempTableName(){
return parent.getTempTableName();
}
protected boolean allowLargeTextValueConstrainFlag(){
return parent.allowLargeTextValueConstrainFlag();
}
protected boolean hasInvertedPanel(){
return invertedPanelCount>0;
}
private String buildSubQueryId(String eventId){
if (eventId==null)
return null;
else{
int index = parent.getSubQueryIndex(eventId);
return parent.getQueryId() + "_S" + String.valueOf(index);
}
}
protected String getSubQueryId(){
if (this.subQueryId==null)
subQueryId = buildSubQueryId(getQueryId());
return subQueryId;
}
protected String getQueryId(){
if (subQuery==null)
return null;
else
return subQuery.getQueryId();
}
protected String buildTempTableCheckDrop(String tempTableName) {
return parent.buildTempTableCheckDrop(tempTableName);
}
protected boolean returnEncounterNum(){
if (this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEVISIT)||
this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAME))
return true;
else
return false;
}
protected boolean returnInstanceNum(){
if (this.getQueryTiming().equalsIgnoreCase(QueryTimingHandler.SAMEINSTANCENUM))
return true;
else
return false;
}
protected boolean returnEncounterStartDate(){
if (rtnColumns.contains(TemporalQueryReturnColumns.ENCOUNTER_START_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_START_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_START_DATE))
return true;
else
return false;
}
protected boolean returnEncounterEndDate(){
if (rtnColumns.contains(TemporalQueryReturnColumns.ENCOUNTER_END_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.FIRST_ENCOUNTER_END_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.LAST_ENCOUNTER_END_DATE))
return true;
else
return false;
}
protected boolean returnInstanceStartDate(){
if (rtnColumns.contains(TemporalQueryReturnColumns.START_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.FIRST_START_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.LAST_START_DATE))
return true;
else
return false;
}
protected boolean returnInstanceEndDate(){
if (rtnColumns.contains(TemporalQueryReturnColumns.END_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.FIRST_END_DATE) ||
rtnColumns.contains(TemporalQueryReturnColumns.LAST_END_DATE))
return true;
else
return false;
}
protected int getProcessingLevel(){
return parent.getProcessingLevel();
}
public String getSqlDelimiter() {
return parent.getSqlDelimiter();
}
protected int getEndPanelIndex() {
if (endPanelIndex==-1){
int nonInvertedPanels = getPanelCount() - getInvertedPanelCount();
if (!this.isFirstSubQuery()&&(parent.getQueryOptions().getTemporalConstraintStrategy()==TemporalConstraintStrategy.TEMP_TABLE_UPDATE))
nonInvertedPanels++;
endPanelIndex = this.startPanelIndex + (nonInvertedPanels>0?nonInvertedPanels-1:0);
}
return endPanelIndex;
}
private List<QueryConstraintType> getConstraintsForSubQuery(TemporalSubQuery subQuery){
if (subQuery!=null){
String eventId = subQuery.getQueryId();
if (this.constraints!=null){
return constraints.get(eventId);
}
}
return null;
}
protected TemporalQueryOptions getQueryOptions() {
return parent.getQueryOptions();
}
public void addIgnoredMessage(String errorMessage) {
parent.addIgnoredMessage(errorMessage);
}
protected void addPreProcessingSql(String sql){
if (sql!=null&&sql.trim().length()>0)
this.preProcessingSql.add(sql);
}
protected void addPostProcessingSql(String sql){
if (sql!=null&&sql.trim().length()>0)
this.postProcessingSql.add(sql);
}
protected QueryDefinitionType searchForQueryInRequestDefinition(String subQueryId){
return parent.searchForSubQuery(subQueryId);
}
public boolean occursTogether(TemporalSubQuery subQuery){
String eventId = subQuery.getQueryId();
List<QueryConstraintType> constraintList = getConstraintsForSubQuery(subQuery);
if (constraintList!=null){
for(QueryConstraintType constraint : constraintList){
if (((constraint.getFirstQuery().getQueryId()!=null&constraint.getFirstQuery().getQueryId().equalsIgnoreCase(eventId))||
(constraint.getSecondQuery().getQueryId()!=null&constraint.getSecondQuery().getQueryId().equalsIgnoreCase(eventId)))&&
(constraint.getOperator().equals(QueryOperatorType.EQUAL)||constraint.getOperator().equals(QueryOperatorType.GREATEREQUAL)||constraint.getOperator().equals(QueryOperatorType.LESSEQUAL))){
return true;
}
}
}
return false;
}
public boolean occursAfter(TemporalSubQuery subQuery){
String eventId = subQuery.getQueryId();
List<QueryConstraintType> constraintList = getConstraintsForSubQuery(subQuery);
if (constraintList!=null){
for(QueryConstraintType constraint : constraintList){
if ((constraint.getSecondQuery().getQueryId()!=null&&constraint.getSecondQuery().getQueryId().equalsIgnoreCase(eventId))&&
(constraint.getOperator().equals(QueryOperatorType.GREATER)||constraint.getOperator().equals(QueryOperatorType.GREATEREQUAL))){
return true;
}
else if ((constraint.getFirstQuery().getQueryId()!=null&&constraint.getFirstQuery().getQueryId().equalsIgnoreCase(eventId))&&
(constraint.getOperator().equals(QueryOperatorType.LESS)||constraint.getOperator().equals(QueryOperatorType.LESSEQUAL))){
return true;
}
}
}
return false;
}
public boolean occursBefore(TemporalSubQuery subQuery){
String eventId = subQuery.getQueryId();
List<QueryConstraintType> constraintList = getConstraintsForSubQuery(subQuery);
if (constraintList!=null){
for(QueryConstraintType constraint : constraintList){
if ((constraint.getSecondQuery().getQueryId()!=null&&constraint.getSecondQuery().getQueryId().equalsIgnoreCase(eventId))&&
(constraint.getOperator().equals(QueryOperatorType.LESS)||constraint.getOperator().equals(QueryOperatorType.LESSEQUAL))){
return true;
}
else if ((constraint.getFirstQuery().getQueryId()!=null&&constraint.getFirstQuery().getQueryId().equalsIgnoreCase(eventId))&&
(constraint.getOperator().equals(QueryOperatorType.GREATER)||constraint.getOperator().equals(QueryOperatorType.GREATEREQUAL))){
return true;
}
}
}
return false;
}
@Override
public int compareTo(Object element) {
if (element.getClass().equals((TemporalSubQuery.class))) {
TemporalSubQuery tp2 = (TemporalSubQuery) element;
boolean before = occursBefore(tp2);
boolean after = occursAfter(tp2);
if (before&&!after)
return -1;
else if (after&&!before)
return 1;
else {
return this.panelList.get(0).compareTo(tp2.panelList.get(0));
}
} else {
return this.toString().compareTo(element.toString());
}
}
}