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