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