001package gudusoft.gsqlparser.nodes; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.stmt.TCreateTableSqlStatement; 005 006/** 007 * Use a constraint to define an integrity constraint, a rule that restricts the values in a database. 008 * <p>Oracle Database lets you create six types of constraints and lets you declare them in two ways. 009 * <ul> 010 * <li>A NOT NULL constraint prohibits a database value from being null.</li> 011 * <li>A unique constraint prohibits multiple rows from having the same value in the same column or combination of columns but allows some values to be null. 012 * call method {@link #getColumnList()} to result columns of this unique key. 013 * </li> 014 * <li>A primary key constraint combines a NOT NULL constraint and a unique 015 * constraint in a single declaration. It prohibits multiple rows from having the same 016 * value in the same column or combination of columns and prohibits values from being null. 017 * call method {@link #getColumnList()} to result columns of this primary key. 018 * </li> 019 * <li>A foreign key constraint requires values in one table to match values in another table. 020 * call method {@link #getColumnList()} to result columns of this foreign key. 021 * </li> 022 * <li>A check constraint requires a value in the database to comply with a specified condition. 023 * call method {@link #getCheckCondition()} to return this condition. 024 * </li> 025 * <li>A REF column by definition references an object in another object type or in a relational table. 026 * A REF constraint lets you further describe the relationship between the REF column and the object it references. 027 </li> 028 * <li>default constraint is valid in sql server.</li> 029 * </ul> 030 * 031 * @see EConstraintType#notnull 032 * @see EConstraintType#unique 033 * @see EConstraintType#primary_key 034 * @see EConstraintType#foreign_key 035 * @see EConstraintType#check 036 * @see EConstraintType#reference 037 * @see EConstraintType#default_value 038 */ 039 040public class TConstraint extends TParseTreeNode { 041 042 private TColumnGeneratedClause columnGeneratedClause; 043 044 public void setColumnGeneratedClause(TColumnGeneratedClause columnGeneratedClause) { 045 this.columnGeneratedClause = columnGeneratedClause; 046 } 047 048 public TColumnGeneratedClause getColumnGeneratedClause() { 049 return columnGeneratedClause; 050 } 051 052 public void setOnFilegroup(TDummy onFilegroup) { 053 this.onFilegroup = onFilegroup; 054 } 055 056 public TDummy getOnFilegroup() { 057 return onFilegroup; 058 } 059 060 private TDummy onFilegroup = null; 061 062 private TDummy withIndexoption = null; 063 064 public void setWithIndexoption(TDummy withIndexoption) { 065 this.withIndexoption = withIndexoption; 066 } 067 068 public TDummy getWithIndexoption() { 069 return withIndexoption; 070 } 071 072 private TObjectName indexName; 073 074 /** 075 * SQL Server, index name of table index when {@link #getConstraint_type} is {@link EConstraintType#table_index} 076 * or index name of column index when {@link #getConstraint_type} is {@link EConstraintType#column_index} 077 * 078 * @return index name 079 */ 080 public TObjectName getIndexName() { 081 return indexName; 082 } 083 084 private EConstraintType constraint_type; 085 private TObjectName constraintName = null; 086 private TPTNodeList <TKeyAction> keyActions; 087 088 private TObjectName commentObject; 089 090 public void setCommentObject(TObjectName commentObject) { 091 this.commentObject = commentObject; 092 } 093 094 private TObjectName forObjectName; 095 096 public void setForObjectName(TObjectName forObjectName) { 097 this.forObjectName = forObjectName; 098 } 099 100 public TObjectName getForObjectName() { 101 return forObjectName; 102 } 103 104 public TObjectName getCommentObject() { 105 106 return commentObject; 107 } 108 109 public void setKeyActions(TPTNodeList<TKeyAction> keyActions) { 110 this.keyActions = keyActions; 111 } 112 113 public TPTNodeList<TKeyAction> getKeyActions() { 114 115 return keyActions; 116 } 117 118 public void setConstraintLevel(int constraintLevel) { 119 this.constraintLevel = constraintLevel; 120 } 121 122 /** 123 * 124 * @return is this a columnn level constraint or table level constraint 125 * TBaseType.constraint_level_table or TBaseType.constraint_level_column. 126 127 */ 128 public int getConstraintLevel() { 129 return constraintLevel; 130 } 131 132 private int constraintLevel = TBaseType.constraint_level_table; 133 134 private TExpression defaultExpression = null; 135 136 public void setDefaultExpression(TExpression defaultExpression) { 137 this.defaultExpression = defaultExpression; 138 } 139 140 /** 141 * 142 * @return default expression of sql server. 143 */ 144 public TExpression getDefaultExpression() { 145 146 return defaultExpression; 147 } 148 149 public void setConstraintName(TObjectName constraintName) { 150 this.constraintName = constraintName; 151 } 152 153 /** 154 * 155 * @return name for the constraint, it's optional. 156 */ 157 public TObjectName getConstraintName() { 158 159 return constraintName; 160 } 161 162 public void setConstraint_type(EConstraintType constraint_type) { 163 this.constraint_type = constraint_type; 164 } 165 166 /** 167 * 168 * @return type of constraints. 169 * @see EConstraintType#notnull 170 * @see EConstraintType#unique 171 * @see EConstraintType#primary_key 172 * @see EConstraintType#foreign_key 173 * @see EConstraintType#check 174 * @see EConstraintType#reference 175 * @see EConstraintType#default_value 176 */ 177 public EConstraintType getConstraint_type() { 178 179 return constraint_type; 180 } 181 182 public void setClustered(boolean clustered) { 183 this.clustered = clustered; 184 } 185 186 public void setClusteredToken(TSourceToken clusteredToken) 187 { 188 if (clusteredToken == null) return; 189 if (clusteredToken.toString().equalsIgnoreCase("clustered")){ 190 clustered = true; 191 }else if (clusteredToken.toString().equalsIgnoreCase("nonclustered")){ 192 nonClustered = true; 193 } 194 } 195 196 public boolean isClustered() { 197 198 return clustered; 199 } 200 201 private boolean clustered = false; 202 private boolean nonClustered = false; 203 204 public boolean isNonClustered() { 205 return nonClustered; 206 } 207 208 public void setNonClustered(boolean nonClustered) { 209 210 this.nonClustered = nonClustered; 211 } 212 213 private TPTNodeList<TColumnWithSortOrder> columnList = null; 214 private TExpression checkCondition = null; 215 private TPTNodeList <TAutomaticProperty> automaticProperties = null; 216 217 public void setAutomaticProperties(TPTNodeList<TAutomaticProperty> automaticProperties) { 218 this.automaticProperties = automaticProperties; 219 } 220 221 /** 222 * 223 * @return Automatic Initialization and Updating for TIMESTAMP in MySQL 224 */ 225 public TPTNodeList<TAutomaticProperty> getAutomaticProperties() { 226 227 return automaticProperties; 228 } 229 230 /** 231 * 232 * @return used in check constraint, requires a value in the database to comply with this specified condition. 233 */ 234 public TExpression getCheckCondition() { 235 return checkCondition; 236 } 237 238 /** 239 * 240 * @return column name list used when constraint type is unique, primary key or foreign key. 241 */ 242 public TPTNodeList<TColumnWithSortOrder> getColumnList() { 243 return columnList; 244 } 245 246 public void setColumnList(TPTNodeList<TColumnWithSortOrder> columnList) { 247 this.columnList = columnList; 248 } 249 250 private TPTNodeList <TIndexColName> indexCols; 251 252 /** 253 * @deprecated since 1.8.7.2, use {@link #getColumnList()} instead. 254 * @return 255 */ 256 public TPTNodeList<TIndexColName> getIndexCols() { 257 return indexCols; 258 } 259 260 261 public void init(Object arg1){ 262 if (arg1 instanceof TExpression){ 263 this.checkCondition = (TExpression)arg1; 264 }else if (arg1 instanceof TPTNodeList){ 265 this.columnList = (TPTNodeList<TColumnWithSortOrder>)arg1; 266 }else if (arg1 instanceof TObjectNameList){ 267 // column in TObjectNameList not changed to TPTNodeList<TColumnWithSortOrder> in .y file 268 // so we convert it here 269 this.columnList = new TPTNodeList<TColumnWithSortOrder>(); 270 TObjectNameList onl = (TObjectNameList)arg1; 271 for(int i=0;i<onl.size();i++){ 272 this.columnList.addElement(new TColumnWithSortOrder(onl.getObjectName(i))); 273 } 274// indexCols = (TPTNodeList)arg1; 275 } 276 } 277 278 private TObjectName indexColumnName = null; 279 280 281 /** 282 * Snowflake index table constraint: CREATE TABLE t1 (c1 INT, c2 INT, CONSTRAINT c1_idx INDEX (c1)); 283 * @return 284 */ 285 public TObjectName getIndexColumnName() { 286 return indexColumnName; 287 } 288 289 public void init(Object arg1, Object arg2,Object arg3){ 290 init(arg1,arg2); 291 switch (constraint_type){ 292 case table_index: 293 indexColumnName = (TObjectName)arg3; 294 indexColumnName.setDbObjectType(EDbObjectType.column); 295 break; 296 default: 297 break; 298 } 299 } 300 301 public void init(Object arg1, Object arg2){ 302 constraint_type = (EConstraintType)arg1; 303 switch (constraint_type){ 304 case table_index: 305 indexName = (TObjectName)arg2; 306 indexName.setDbObjectType(EDbObjectType.index); 307 break; 308 case cluster: 309 break; 310 case default_value: 311 this.defaultExpression = (TExpression) arg2; 312 break; 313 default: 314 break; 315 } 316 } 317 318 private TObjectName referencedObject = null; 319 320 public void setReferencedColumnList(TObjectNameList referencedColumnList) { 321 this.referencedColumnList = referencedColumnList; 322 } 323 324 /** 325 * 326 * @return column name list of referenced object in reference clause when constraint type is REF constraint. 327 */ 328 public TObjectNameList getReferencedColumnList() { 329 330 return referencedColumnList; 331 } 332 333 private TObjectNameList referencedColumnList = null; 334 335 336 public void setReferencedObject(TObjectName referencedObject) { 337 this.referencedObject = referencedObject; 338 } 339 340 /** 341 * 342 * @return referenced object in reference clause when constraint type is REF constraint. 343 */ 344 public TObjectName getReferencedObject() { 345 346 return referencedObject; 347 } 348 349 private TExpression seed; 350 351 public void setIncrement(TExpression increment) { 352 this.increment = increment; 353 } 354 355 public void setSeed(TExpression seed) { 356 this.seed = seed; 357 } 358 359 /** 360 * Used internal 361 * @return 362 */ 363 public TExpression getIncrement() { 364 365 return increment; 366 } 367 368 /** 369 * Used internal 370 * @return 371 */ 372 public TExpression getSeed() { 373 return seed; 374 } 375 376 private TExpression increment; 377 378 public void accept(TParseTreeVisitor v){ 379 v.preVisit(this); 380 v.postVisit(this); 381 } 382 383 public void acceptChildren(TParseTreeVisitor v){ 384 v.preVisit(this); 385 v.postVisit(this); 386 } 387 388 public void doParse(TCustomSqlStatement psql, ESqlClause plocation){ 389 switch (getConstraint_type()){ 390 case primary_key: 391 case unique: 392 if (getColumnList() != null){ 393 for(int i=0;i<getColumnList().size();i++){ 394 getColumnList().getElement(i).setOwnerConstraint(this); 395 if (psql instanceof TCreateTableSqlStatement){ 396 getColumnList().getElement(i).setOwnerTable(psql.tables.getTable(0)); 397 psql.tables.getTable(0).getLinkedColumns().addObjectName(getColumnList().getElement(i).getColumnName()); 398 getColumnList().getElement(i).getColumnName().setSourceTable(psql.tables.getTable(0)); 399 } 400 psql.getIndexColumns().addElement(getColumnList().getElement(i)); 401 } 402 } 403 break; 404 case foreign_key: 405 case reference:{ 406 if (getColumnList() != null){ 407 for(int i=0;i<getColumnList().size();i++){ 408 getColumnList().getElement(i).setOwnerConstraint(this); 409 if (psql instanceof TCreateTableSqlStatement){ 410 getColumnList().getElement(i).setOwnerTable(psql.tables.getTable(0)); 411 } 412 psql.getIndexColumns().addElement(getColumnList().getElement(i)); 413 } 414 } 415 416 TTable lcTable = null; 417 if (referencedObject != null){ 418 referencedObject.setObjectType(TObjectName.ttobjTable); 419 420 lcTable = new TTable(referencedObject); 421 lcTable.setPropertyFromObjectName(referencedObject,ETableEffectType.tetConstraintReference); 422// lcTable.setStartToken(referencedObject.getStartToken()); 423// lcTable.setEndToken(referencedObject.getEndToken()); 424// lcTable.setGsqlparser(referencedObject.getGsqlparser()); 425// lcTable.setEffectType(ETableEffectType.tetConstraintReference); 426// lcTable.setTableType(ETableSource.objectname); 427 psql.addToTables(lcTable); 428 } 429 if (referencedColumnList!=null){ 430 for(int i=0;i<referencedColumnList.size();i++){ 431 referencedColumnList.getObjectName(i).setLocation(ESqlClause.constraintRef); 432 lcTable.getLinkedColumns().addObjectName(referencedColumnList.getObjectName(i)); 433 } 434 } 435 }; 436 break; 437 case check: 438 if ((checkCondition != null) &&(checkCondition.getBetweenOperand() == null)){ 439 // missing between operand in sql like this in teradata: 440 // CREATE TABLE tab1 (Id CHAR(9) ,SalaryFactor DOUBLE PRECISION BETWEEN .1 AND 1E1 ); 441 442 // System.out.println(checkCondition.toString()); 443 } 444 break; 445 default:; 446 } 447 } 448 449 public void setCheckCondition(TExpression checkCondition) { 450 this.checkCondition = checkCondition; 451 } 452 453 public void setIndexCols(TPTNodeList<TIndexColName> indexCols) { 454 this.indexCols = indexCols; 455 } 456}