001 002package gudusoft.gsqlparser.dlineage.dataflow.model; 003 004import java.util.*; 005import java.util.concurrent.atomic.AtomicInteger; 006 007import gudusoft.gsqlparser.EExpressionType; 008import gudusoft.gsqlparser.TSourceToken; 009import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 010import gudusoft.gsqlparser.dlineage.util.Pair; 011import gudusoft.gsqlparser.dlineage.util.Pair3; 012import gudusoft.gsqlparser.nodes.TExpression; 013import gudusoft.gsqlparser.nodes.TObjectName; 014import gudusoft.gsqlparser.nodes.TParseTreeNode; 015import gudusoft.gsqlparser.nodes.TResultColumn; 016import gudusoft.gsqlparser.nodes.TResultColumnList; 017import gudusoft.gsqlparser.util.SQLUtil; 018 019public class ResultColumn extends Column{ 020 021 protected ResultSet resultSet; 022 023 protected long id; 024 025 protected String alias; 026 protected Pair3<Long, Long, String> aliasStartPosition; 027 protected Pair3<Long, Long, String> aliasEndPosition; 028 029 protected String fullName; 030 protected String name; 031 032 protected Pair3<Long, Long, String> startPosition; 033 protected Pair3<Long, Long, String> endPosition; 034 035 protected TParseTreeNode columnObject; 036 037 protected String refColumnName; 038 039 protected Map<String, Set<TObjectName>> starLinkColumns = new LinkedHashMap<String, Set<TObjectName>>(); 040 041 private boolean showStar = true; 042 043 protected boolean isFunction = false; 044 045 private boolean isPseduo = false; 046 047 private boolean isStruct = false; 048 049 private List<Transform> transforms; 050 051 public ResultColumn() { 052 053 } 054 055 public ResultColumn(ResultSet resultSet, TParseTreeNode columnObject) { 056 if (columnObject == null || resultSet == null) 057 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 058 059 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 060 061 this.resultSet = resultSet; 062 resultSet.addColumn(this); 063 064 this.columnObject = columnObject; 065 066 TSourceToken startToken = columnObject.getStartToken(); 067 TSourceToken endToken = columnObject.getEndToken(); 068 069 if (columnObject instanceof TObjectName) { 070 if (((TObjectName) columnObject).getColumnNameOnly() != null 071 && !"".equals(((TObjectName) columnObject).getColumnNameOnly())) { 072 this.name = ((TObjectName) columnObject).getColumnNameOnly(); 073 } else { 074 this.name = ((TObjectName) columnObject).toString(); 075 } 076 } else 077 this.name = columnObject.toString(); 078 079 this.fullName = columnObject.toString(); 080 081 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 082 ModelBindingManager.getGlobalHash()); 083 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), 084 ModelBindingManager.getGlobalHash()); 085 } 086 087 public ResultColumn(ResultSet resultSet, TResultColumn resultColumnObject) { 088 if (resultColumnObject == null || resultSet == null) 089 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 090 091 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 092 093 this.resultSet = resultSet; 094 resultSet.addColumn(this); 095 096 this.columnObject = resultColumnObject; 097 098 if (resultColumnObject.getAliasClause() != null) { 099 this.alias = resultColumnObject.getAliasClause().toString(); 100 TSourceToken startToken = resultColumnObject.getAliasClause().getStartToken(); 101 TSourceToken endToken = resultColumnObject.getAliasClause().getEndToken(); 102 this.aliasStartPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 103 ModelBindingManager.getGlobalHash()); 104 this.aliasEndPosition = new Pair3<Long, Long, String>(endToken.lineNo, 105 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 106 107 if(resultSet.getAliasMap().containsKey(this.alias.toLowerCase())){ 108 int index = resultSet.getAliasMap().get(this.alias.toLowerCase()).incrementAndGet(); 109 this.name = SQLUtil.trimSingleQuote(this.alias) + "(" + index + ")"; 110 } 111 else { 112 resultSet.getAliasMap().put(this.alias.toLowerCase(), new AtomicInteger(0)); 113 this.name = SQLUtil.trimSingleQuote(this.alias); 114 } 115 } else if (resultColumnObject.getExpr() != null) { 116 this.name = getColumnName(resultColumnObject.getExpr()); 117 } 118 119 if(this.name == null){ 120 if (resultColumnObject.getColumnNameOnly() != null 121 && !"".equals(resultColumnObject.getColumnNameOnly())) { 122 if (resultColumnObject.getExpr().getObjectOperand() != null 123 && resultColumnObject.getExpr().getObjectOperand().getPropertyToken() != null) { 124 this.name = resultColumnObject.getExpr().getObjectOperand().getPropertyToken().getAstext(); 125 } else { 126 this.name = resultColumnObject.getColumnNameOnly(); 127 } 128 } else { 129 this.name = resultColumnObject.toString(); 130 } 131 } 132 133 if (resultColumnObject.getExpr().getExpressionType() == EExpressionType.function_t) { 134 this.fullName = resultColumnObject.getExpr().getFunctionCall().toString(); 135 } else if (resultColumnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) { 136 this.fullName = resultColumnObject.getExpr().getLeftOperand().toString(); 137 } else { 138 this.fullName = resultColumnObject.toString(); 139 } 140 141 TSourceToken startToken = resultColumnObject.getStartToken(); 142 TSourceToken endToken = resultColumnObject.getEndToken(); 143 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 144 ModelBindingManager.getGlobalHash()); 145 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), 146 ModelBindingManager.getGlobalHash()); 147 } 148 149 public ResultColumn(ResultSet resultSet, TResultColumn resultColumnObject, String refColumnName) { 150 if (resultColumnObject == null || resultSet == null) 151 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 152 153 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 154 155 this.resultSet = resultSet; 156 resultSet.addColumn(this); 157 158 this.columnObject = resultColumnObject; 159 this.refColumnName = refColumnName; 160 161 this.name = refColumnName; 162 163 TSourceToken startToken = resultColumnObject.getStartToken(); 164 TSourceToken endToken = resultColumnObject.getEndToken(); 165 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 166 ModelBindingManager.getGlobalHash()); 167 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), 168 ModelBindingManager.getGlobalHash()); 169 } 170 171 protected String getColumnName(TExpression expr) { 172 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 173 return expr.toString(); 174 } else if (expr.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 175 this.alias = expr.getLeftOperand().toString(); 176 TSourceToken startToken = expr.getLeftOperand().getStartToken(); 177 TSourceToken endToken = expr.getLeftOperand().getEndToken(); 178 this.aliasStartPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 179 ModelBindingManager.getGlobalHash()); 180 this.aliasEndPosition = new Pair3<Long, Long, String>(endToken.lineNo, 181 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 182 183 return this.alias; 184 } else if (expr.getExpressionType() == EExpressionType.function_t) { 185 return expr.getFunctionCall().toString(); 186 } else if (expr.getExpressionType() == EExpressionType.typecast_t) { 187 return expr.getLeftOperand().toString(); 188 } else if (expr.getExpressionType() == EExpressionType.parenthesis_t) { 189 return getColumnName(expr.getLeftOperand()); 190 } else if (expr.getExpressionType() == EExpressionType.simple_object_name_t) { 191 TObjectName columnName = expr.getObjectOperand(); 192 if (columnName.getPropertyToken() != null) { 193 return columnName.getPropertyToken().getAstext(); 194 } else { 195 if (SQLUtil.isEmpty(columnName.getColumnNameOnly())) { 196 return columnName.toString(); 197 } else { 198 return columnName.getColumnNameOnly(); 199 } 200 } 201 } else if (expr.getExpressionType() == EExpressionType.subquery_t) { 202 TResultColumnList resultset = expr.getSubQuery().getResultColumnList(); 203 if (resultset != null && resultset.size() == 1) { 204 TResultColumn resultColumn = resultset.getResultColumn(0); 205 if (!SQLUtil.isEmpty(resultColumn.getColumnAlias())) { 206 return resultColumn.getColumnAlias(); 207 } else if (resultColumn.getExpr() != null) { 208 return getColumnName(resultColumn.getExpr()); 209 } else if (resultColumn.getColumnNameOnly() != null 210 && !"".equals(resultColumn.getColumnNameOnly())) { 211 if (resultColumn.getExpr().getObjectOperand() != null 212 && resultColumn.getExpr().getObjectOperand().getPropertyToken() != null) { 213 this.name = resultColumn.getExpr().getObjectOperand().getPropertyToken().getAstext(); 214 } else { 215 this.name = resultColumn.getColumnNameOnly(); 216 } 217 } else { 218 this.name = resultColumn.toString(); 219 } 220 } 221 } 222 return null; 223 } 224 225 public ResultColumn(SelectResultSet resultSet, Pair<TResultColumn, TObjectName> starColumnPair) { 226 if (starColumnPair == null || resultSet == null) 227 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 228 229 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 230 231 this.resultSet = resultSet; 232 resultSet.addColumn(this); 233 234 this.columnObject = starColumnPair.first; 235 236 TSourceToken startToken = columnObject.getStartToken(); 237 TSourceToken endToken = columnObject.getEndToken(); 238 239 this.name = ((TObjectName) columnObject).getColumnNameOnly(); 240 if(name == null){ 241 name = ((TObjectName) columnObject).toString(); 242 } 243 this.fullName = columnObject.toString(); 244 245 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 246 ModelBindingManager.getGlobalHash()); 247 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), 248 ModelBindingManager.getGlobalHash()); 249 } 250 251 // private int getIndexOf(TResultColumnList resultColumnList, 252 // TResultColumn resultColumnObject) { 253 // for (int i = 0; i < resultColumnList.size(); i++) { 254 // if (resultColumnList.getResultColumn(i) == resultColumnObject) 255 // return i; 256 // } 257 // return -1; 258 // } 259 260 public ResultSet getResultSet() { 261 return resultSet; 262 } 263 264 public long getId() { 265 return id; 266 } 267 268 public String getAlias() { 269 return alias; 270 } 271 272 public Pair3<Long, Long, String> getAliasStartPosition() { 273 return aliasStartPosition; 274 } 275 276 public Pair3<Long, Long, String> getAliasEndPosition() { 277 return aliasEndPosition; 278 } 279 280 public String getFullName() { 281 return fullName; 282 } 283 284 public Pair3<Long, Long, String> getStartPosition() { 285 return startPosition; 286 } 287 288 public Pair3<Long, Long, String> getEndPosition() { 289 return endPosition; 290 } 291 292 public TParseTreeNode getColumnObject() { 293 return columnObject; 294 } 295 296 public String getName() { 297 return name; 298 } 299 300 public boolean bindStarLinkColumn(TObjectName objectName) { 301 if (objectName == null) { 302 return false; 303 } 304 305 String columnName = DlineageUtil.getColumnName(objectName); 306 307 if ("*".equals(columnName)) { 308 return false; 309 } 310 311 boolean flag = false; 312 if (!starLinkColumns.containsKey(columnName)) { 313 starLinkColumns.put(columnName, new LinkedHashSet<TObjectName>()); 314 flag = true; 315 } 316 317 starLinkColumns.get(columnName).add(objectName); 318 319 if (this.getStarSourceColumns() != null) { 320 for (Column column : this.getStarSourceColumns()) { 321 boolean find = false; 322 if (column instanceof ResultColumn) { 323 ResultSet resultset = ((ResultColumn) column).getResultSet(); 324 for (ResultColumn resultColumn : resultset.getColumns()) { 325 if (DlineageUtil.compareColumnIdentifier(getColumnName(resultColumn.name), 326 getColumnName(objectName.toString()))) { 327 find = true; 328 break; 329 } 330 } 331 } 332 if (!find) { 333 column.bindStarLinkColumn(objectName); 334 } 335 } 336 } 337 338 return flag; 339 } 340 341 private String getColumnName(String column) { 342 if (column == null) { 343 return null; 344 } 345 String name = column.substring(column.lastIndexOf(".") + 1); 346 if (name == null || "".equals(name.trim())) { 347 return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim()); 348 } else 349 return DlineageUtil.getIdentifierNormalColumnName(name.trim()); 350 } 351 352 353 public int indexOfStarLinkColumn(TObjectName objectName) { 354 if (objectName == null) { 355 return -1; 356 } 357 358 String columnName = DlineageUtil.getColumnName(objectName); 359 360 if ("*".equals(columnName)) { 361 return -1; 362 } 363 364 int index = -1; 365 for (String item : starLinkColumns.keySet()) { 366 index++; 367 if (item.equals(columnName)) { 368 return index; 369 } 370 } 371 return index; 372 } 373 374 public void unbindStarLinkColumn(TObjectName objectName) { 375 if (objectName == null) { 376 return; 377 } 378 379 String columnName = DlineageUtil.getColumnName(objectName); 380 starLinkColumns.remove(columnName); 381 } 382 383 public void bindStarLinkColumn(TObjectName objectName, int index) { 384 if (objectName == null) { 385 return; 386 } 387 388 String columnName = DlineageUtil.getColumnName(objectName); 389 390 if ("*".equals(columnName)) { 391 return; 392 } 393 if (!starLinkColumns.containsKey(columnName)) { 394 Map<String, Set<TObjectName>> copyStarLinkColumns = new LinkedHashMap<String, Set<TObjectName>>(); 395 int i = 0; 396 for(String item: starLinkColumns.keySet()){ 397 if(index == i){ 398 copyStarLinkColumns.put(columnName, new LinkedHashSet<TObjectName>()); 399 } 400 copyStarLinkColumns.put(item, starLinkColumns.get(item)); 401 i++; 402 } 403 starLinkColumns = copyStarLinkColumns; 404 } 405 406 if (starLinkColumns.get(columnName) != null) { 407 starLinkColumns.get(columnName).add(objectName); 408 } 409 else { 410 starLinkColumns.put(columnName, new LinkedHashSet<TObjectName>()); 411 starLinkColumns.get(columnName).add(objectName); 412 } 413 } 414 415 public boolean hasStarLinkColumn(){ 416 return starLinkColumns!=null && !starLinkColumns.isEmpty(); 417 } 418 419 public Map<String, Set<TObjectName>> getStarLinkColumns() { 420 return starLinkColumns; 421 } 422 423 public List<TObjectName> getStarLinkColumnList() { 424 List<TObjectName> columns = new ArrayList<TObjectName>(); 425 if (starLinkColumns != null) { 426 for (Set<TObjectName> columnSet : starLinkColumns.values()) { 427 columns.addAll(columnSet); 428 } 429 } 430 return columns; 431 } 432 433 public List<String> getStarLinkColumnNames() { 434 List<String> columns = new ArrayList<String>(); 435 if (starLinkColumns != null) { 436 columns.addAll(starLinkColumns.keySet()); 437 } 438 return columns; 439 } 440 441 public TObjectName getStarLinkColumnName(int index) { 442 List<String> columns = new ArrayList<String>(); 443 if (starLinkColumns != null) { 444 columns.addAll(starLinkColumns.keySet()); 445 } 446 return starLinkColumns.get(getStarLinkColumnNames().get(index)).iterator().next(); 447 } 448 449 public boolean isShowStar() { 450 return showStar; 451 } 452 453 public void setShowStar(boolean showStar) { 454 this.showStar = showStar; 455 } 456 457 public boolean isFunction() { 458 return isFunction; 459 } 460 461 public void setFunction(boolean isFunction) { 462 this.isFunction = isFunction; 463 } 464 465 public boolean isPseduo() { 466 return isPseduo; 467 } 468 469 public void setPseduo(boolean isPseduo) { 470 this.isPseduo = isPseduo; 471 } 472 473 public String getRefColumnName() { 474 return refColumnName; 475 } 476 477 @Override 478 public String toString() { 479 return this.name; 480 } 481 482 public boolean isStruct() { 483 return isStruct; 484 } 485 486 public void setStruct(boolean isStruct) { 487 this.isStruct = isStruct; 488 } 489 490 public List<Transform> getTransforms() { 491 return transforms; 492 } 493 494 public void setTransform(Transform transform) { 495 if(transform==null) { 496 return; 497 } 498 if(transforms == null) { 499 transforms = new ArrayList<Transform>(); 500 } 501 if(!transforms.contains(transform)) { 502 transforms.add(transform); 503 } 504 } 505}