001 002package gudusoft.gsqlparser.dlineage.dataflow.model; 003 004import java.util.LinkedHashSet; 005import java.util.Set; 006 007import gudusoft.gsqlparser.EDbVendor; 008import gudusoft.gsqlparser.EExpressionType; 009import gudusoft.gsqlparser.ESetOperatorType; 010import gudusoft.gsqlparser.TSourceToken; 011import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 012import gudusoft.gsqlparser.dlineage.util.Pair3; 013import gudusoft.gsqlparser.nodes.TObjectName; 014import gudusoft.gsqlparser.nodes.TResultColumn; 015import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType; 016import gudusoft.gsqlparser.sqlenv.TSQLEnv; 017import gudusoft.gsqlparser.stmt.TSelectSqlStatement; 018import gudusoft.gsqlparser.util.SQLUtil; 019 020public class SelectSetResultColumn extends ResultColumn { 021 022 private LinkedHashSet<String> aliasSet = new LinkedHashSet<String>(); 023 024 public SelectSetResultColumn(ResultSet resultSet, 025 TResultColumn resultColumnObject, int index) { 026 super(resultSet, resultColumnObject); 027 aliasSet.clear(); 028 if (isNotSameAlias(resultSet, index)) { 029 this.name = aliasSet.iterator().next(); 030 } else { 031 if (resultColumnObject.getAliasClause() != null) { 032 this.name = resultColumnObject.getAliasClause().toString(); 033 } else if (resultColumnObject.getColumnNameOnly() != null 034 && !"".equals(resultColumnObject.getColumnNameOnly())) { 035 this.name = resultColumnObject.getColumnNameOnly(); 036 } else if (resultColumnObject.getExpr().getExpressionType() == EExpressionType.simple_constant_t) { 037 this.name = resultColumnObject.getExpr().toString(); 038 } 039 else { 040 this.name = quote(resultColumnObject.toString()); 041 } 042 } 043 044 this.fullName = this.name; 045 } 046 047 private boolean isNotSameAlias(ResultSet resultSet, int index) { 048 if (resultSet instanceof SelectSetResultSet) { 049 SelectSetResultSet selectSetResultSet = (SelectSetResultSet) resultSet; 050 if (selectSetResultSet 051 .getSetOperatorType() == ESetOperatorType.none) { 052 return false; 053 } 054 TSelectSqlStatement select = selectSetResultSet.getSelectObject(); 055 return isNotSameAlias(select, index); 056 } else if (resultSet instanceof SelectResultSet) { 057 SelectResultSet selectResultSet = (SelectResultSet) resultSet; 058 if (selectResultSet.getSelectStmt() 059 .getSetOperatorType() == ESetOperatorType.none) { 060 return false; 061 } 062 TSelectSqlStatement select = selectResultSet.getSelectStmt(); 063 return isNotSameAlias(select, index); 064 } 065 return false; 066 } 067 068 private boolean isNotSameAlias(TSelectSqlStatement select, int index) { 069 collectSelectAlias(select, index, aliasSet); 070 aliasSet.remove("*"); 071 return aliasSet.size() > 1; 072 } 073 074 private void collectSelectAlias(TSelectSqlStatement select, int index, 075 Set<String> aliasSet) { 076 // Iterative traversal using explicit stack to avoid StackOverflow 077 java.util.Deque<TSelectSqlStatement> stack = new java.util.ArrayDeque<>(); 078 stack.push(select); 079 080 while (!stack.isEmpty()) { 081 TSelectSqlStatement current = stack.pop(); 082 if (current.getSetOperatorType() == ESetOperatorType.none) { 083 if (current.getResultColumnList() == null) { 084 continue; 085 } 086 TResultColumn column = current.getResultColumnList() 087 .getResultColumn(index); 088 089 String alias = null; 090 if (column == null) { 091 continue; 092 } 093 if (column.getAliasClause() != null) { 094 alias = column.getAliasClause().toString(); 095 } else if (column.getColumnNameOnly() != null && !"".equals(column.getColumnNameOnly())) { 096 alias = column.getColumnNameOnly(); 097 } else if (column.getExpr().getExpressionType() == EExpressionType.simple_constant_t) { 098 alias = column.getExpr().toString(); 099 } else { 100 alias = quote(column.toString()); 101 } 102 aliasSet.add(alias); 103 } else { 104 // Push right first so left is processed first 105 if (current.getRightStmt() != null) stack.push(current.getRightStmt()); 106 if (current.getLeftStmt() != null) stack.push(current.getLeftStmt()); 107 } 108 } 109 } 110 111 private String quote(String column) { 112 EDbVendor vendor = ModelBindingManager.getGlobalVendor(); 113 if (!DlineageUtil.isQuote(column)){ 114 return SQLUtil.quoteDottedName(vendor, ESQLDataObjectType.dotColumn, column); 115 } 116 else return column; 117 } 118 119 public SelectSetResultColumn(ResultSet resultSet, 120 ResultColumn resultColumn) { 121 if (resultColumn == null || resultSet == null) 122 throw new IllegalArgumentException( 123 "ResultColumn arguments can't be null."); 124 125 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 126 127 this.resultSet = resultSet; 128 resultSet.addColumn(this); 129 this.setStruct(resultColumn.isStruct()); 130 131 if(resultColumn.getRefColumnName()!=null) { 132 TResultColumn resultColumnObject = (TResultColumn) resultColumn 133 .getColumnObject(); 134 TSourceToken startToken = resultColumnObject.getStartToken(); 135 TSourceToken endToken = resultColumnObject.getEndToken(); 136 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 137 startToken.columnNo, ModelBindingManager.getGlobalHash()); 138 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 139 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 140 this.columnObject = resultColumnObject; 141 this.refColumnName = resultColumn.getRefColumnName(); 142 this.name = resultColumn.getName(); 143 } 144 else if (resultColumn.getColumnObject() instanceof TResultColumn) { 145 TResultColumn resultColumnObject = (TResultColumn) resultColumn 146 .getColumnObject(); 147 if (resultColumnObject.getAliasClause() != null) { 148 this.alias = resultColumnObject.getAliasClause().toString(); 149 TSourceToken startToken = resultColumnObject.getAliasClause() 150 .getStartToken(); 151 TSourceToken endToken = resultColumnObject.getAliasClause() 152 .getEndToken(); 153 this.aliasStartPosition = new Pair3<Long, Long, String>( 154 startToken.lineNo, startToken.columnNo, ModelBindingManager.getGlobalHash()); 155 this.aliasEndPosition = new Pair3<Long, Long, String>(endToken.lineNo, 156 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 157 158 this.name = this.alias; 159 } else if (resultColumnObject.getExpr() 160 .getExpressionType() == EExpressionType.simple_object_name_t) { 161 this.name = resultColumnObject.getColumnNameOnly(); 162 } else if (resultColumnObject.getFieldAttr() != null) { 163 this.name = resultColumnObject.getColumnNameOnly(); 164 } else { 165 if (resultColumnObject.getExpr() 166 .getExpressionType() == EExpressionType.simple_constant_t) { 167 this.name = resultColumnObject.toString(); 168 } else if (resultColumnObject.getExpr() 169 .getExpressionType() == EExpressionType.function_t) { 170 this.name = resultColumnObject.getCompactString(); 171 } else if (resultColumnObject.getColumnNameOnly() != null 172 && !"".equals( 173 resultColumnObject.getColumnNameOnly())) { 174 this.name = resultColumnObject.getColumnNameOnly(); 175 } else { 176 this.name = resultColumnObject.toString(); 177 } 178 } 179 180 if (resultColumnObject.getExpr() 181 .getExpressionType() == EExpressionType.function_t) { 182 this.fullName = resultColumnObject.getExpr() 183 .getFunctionCall() 184 .getFunctionName() 185 .toString(); 186 } else { 187 this.fullName = resultColumnObject.toString(); 188 } 189 190 TSourceToken startToken = resultColumnObject.getStartToken(); 191 TSourceToken endToken = resultColumnObject.getEndToken(); 192 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 193 startToken.columnNo, ModelBindingManager.getGlobalHash()); 194 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 195 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 196 this.columnObject = resultColumnObject; 197 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 198 TObjectName resultColumnObject = (TObjectName) resultColumn 199 .getColumnObject(); 200 201 if (resultColumnObject.getColumnNameOnly() != null 202 && !"".equals(resultColumnObject.getColumnNameOnly())) { 203 this.name = resultColumnObject.getColumnNameOnly(); 204 } else { 205 this.name = resultColumnObject.toString(); 206 } 207 208 this.fullName = this.name; 209 210 TSourceToken startToken = resultColumnObject.getStartToken(); 211 TSourceToken endToken = resultColumnObject.getEndToken(); 212 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 213 startToken.columnNo, ModelBindingManager.getGlobalHash()); 214 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 215 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 216 this.columnObject = resultColumnObject; 217 } else { 218 this.name = resultColumn.getName(); 219 this.fullName = this.name; 220 221 TSourceToken startToken = resultColumn.getColumnObject() 222 .getStartToken(); 223 TSourceToken endToken = resultColumn.getColumnObject() 224 .getEndToken(); 225 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 226 startToken.columnNo, ModelBindingManager.getGlobalHash()); 227 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 228 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 229 this.columnObject = resultColumn.getColumnObject(); 230 } 231 } 232 233 public Set<String> getAliasSet() { 234 return aliasSet; 235 } 236}