1 65 66 67 package org.hsqldb; 68 69 import org.hsqldb.HsqlNameManager.HsqlName; 70 import org.hsqldb.index.RowIterator; 71 import org.hsqldb.lib.ArrayUtil; 72 import org.hsqldb.lib.Iterator; 73 74 78 86 class Constraint { 87 88 97 static final int CASCADE = 0, 98 SET_NULL = 2, 99 NO_ACTION = 3, 100 SET_DEFAULT = 4, 101 INIT_DEFERRED = 5, 102 INIT_IMMEDIATE = 6, 103 NOT_DEFERRABLE = 7; 104 static final int FOREIGN_KEY = 0, 105 MAIN = 1, 106 UNIQUE = 2, 107 CHECK = 3, 108 PRIMARY_KEY = 4; 109 ConstraintCore core; 110 HsqlName constName; 111 int constType; 112 113 116 Constraint(HsqlName name, Table t, Index index, int type) { 117 118 core = new ConstraintCore(); 119 constName = name; 120 constType = type; 121 core.mainTable = t; 122 core.mainIndex = index; 123 126 core.mainColArray = ArrayUtil.arraySlice(index.getColumns(), 0, 127 index.getVisibleColumns()); 128 core.colLen = core.mainColArray.length; 129 } 130 131 134 Constraint(HsqlName name, Constraint fkconstraint) { 135 136 constName = name; 137 constType = MAIN; 138 core = fkconstraint.core; 139 } 140 141 156 Constraint(HsqlName pkname, HsqlName name, Table mainTable, 157 Table refTable, int[] mainCols, int[] refCols, 158 Index mainIndex, Index refIndex, int deleteAction, 159 int updateAction) throws HsqlException { 160 161 core = new ConstraintCore(); 162 core.pkName = pkname; 163 core.fkName = name; 164 constName = name; 165 constType = FOREIGN_KEY; 166 core.mainTable = mainTable; 167 core.refTable = refTable; 168 172 core.mainColArray = mainCols; 173 core.colLen = core.mainColArray.length; 174 core.refColArray = refCols; 175 core.mainIndex = mainIndex; 176 core.refIndex = refIndex; 177 core.deleteAction = deleteAction; 178 core.updateAction = updateAction; 179 } 180 181 184 Constraint(HsqlName name, int[] mainCols, Table refTable, int[] refCols, 185 int type, int deleteAction, int updateAction) { 186 187 core = new ConstraintCore(); 188 constName = name; 189 constType = type; 190 core.mainColArray = mainCols; 191 core.refTable = refTable; 192 core.refColArray = refCols; 193 core.deleteAction = deleteAction; 194 core.updateAction = updateAction; 195 } 196 197 private Constraint() {} 198 199 202 HsqlName getName() { 203 return constName; 204 } 205 206 209 private void setName(String name, boolean isquoted) throws HsqlException { 210 constName.rename(name, isquoted); 211 } 212 213 220 String getPkName() { 221 return core.pkName == null ? null 222 : core.pkName.name; 223 } 224 225 232 String getFkName() { 233 return core.fkName == null ? null 234 : core.fkName.name; 235 } 236 237 240 int getType() { 241 return constType; 242 } 243 244 247 Table getMain() { 248 return core.mainTable; 249 } 250 251 254 Index getMainIndex() { 255 return core.mainIndex; 256 } 257 258 261 Table getRef() { 262 return core.refTable; 263 } 264 265 268 Index getRefIndex() { 269 return core.refIndex; 270 } 271 272 275 int getDeleteAction() { 276 return core.deleteAction; 277 } 278 279 282 int getUpdateAction() { 283 return core.updateAction; 284 } 285 286 289 int[] getMainColumns() { 290 return core.mainColArray; 291 } 292 293 296 int[] getRefColumns() { 297 return core.refColArray; 298 } 299 300 304 boolean isIndexFK(Index index) { 305 306 if (constType == FOREIGN_KEY || constType == MAIN) { 307 if (core.mainIndex == index || core.refIndex == index) { 308 return true; 309 } 310 } 311 312 return false; 313 } 314 315 319 boolean isIndexUnique(Index index) { 320 return (constType == UNIQUE && core.mainIndex == index); 321 } 322 323 326 boolean hasColumn(Table table, String colname) { 327 328 if (constType != CHECK) { 329 return false; 330 } 331 332 Expression.Collector coll = new Expression.Collector(); 333 334 coll.addAll(core.check, Expression.COLUMN); 335 336 Iterator it = coll.iterator(); 337 338 for (; it.hasNext(); ) { 339 Expression e = (Expression) it.next(); 340 341 if (e.getColumnName().equals(colname) 342 && table.tableName.name.equals(e.getTableName())) { 343 return true; 344 } 345 } 346 347 return false; 348 } 349 350 boolean hasColumn(int colIndex) { 351 352 if (constType == MAIN) { 353 return ArrayUtil.find(core.mainColArray, colIndex) != -1; 354 } else if (constType == FOREIGN_KEY) { 355 return ArrayUtil.find(core.refColArray, colIndex) != -1; 356 } 357 358 return false; 359 } 360 361 363 367 boolean isEquivalent(int[] col, int type) { 368 369 if (type != constType || constType != UNIQUE 370 || core.colLen != col.length) { 371 return false; 372 } 373 374 return ArrayUtil.haveEqualSets(core.mainColArray, col, core.colLen); 375 } 376 377 381 boolean isEquivalent(Table tablemain, int[] colmain, Table tableref, 382 int[] colref) { 383 384 if (constType != Constraint.MAIN 385 && constType != Constraint.FOREIGN_KEY) { 386 return false; 387 } 388 389 if (tablemain != core.mainTable || tableref != core.refTable) { 390 return false; 391 } 392 393 return ArrayUtil.areEqualSets(core.mainColArray, colmain) 394 && ArrayUtil.areEqualSets(core.refColArray, colref); 395 } 396 397 407 void replaceTable(Table oldt, Table newt, int colindex, 408 int adjust) throws HsqlException { 409 410 if (oldt == core.mainTable) { 411 core.mainTable = newt; 412 413 if (core.mainIndex != null) { 415 core.mainIndex = 416 core.mainTable.getIndex(core.mainIndex.getName().name); 417 core.mainColArray = 418 ArrayUtil.toAdjustedColumnArray(core.mainColArray, 419 colindex, adjust); 420 } 421 } 422 423 if (oldt == core.refTable) { 424 core.refTable = newt; 425 426 if (core.refIndex != null) { 427 core.refIndex = 428 core.refTable.getIndex(core.refIndex.getName().name); 429 430 if (core.refIndex != core.mainIndex) { 431 core.refColArray = 432 ArrayUtil.toAdjustedColumnArray(core.refColArray, 433 colindex, adjust); 434 } 435 } 436 } 437 } 438 439 443 void checkInsert(Session session, Object [] row) throws HsqlException { 444 445 if (constType == Constraint.MAIN || constType == Constraint.UNIQUE 446 || constType == Constraint.PRIMARY_KEY) { 447 448 return; 451 } 452 453 if (constType == Constraint.CHECK) { 454 checkCheckConstraint(session, row); 455 456 return; 457 } 458 459 if (Index.isNull(row, core.refColArray)) { 460 return; 461 } 462 463 boolean exists = core.mainIndex.exists(session, row, 465 core.refColArray); 466 467 if (!exists) { 468 469 if (core.mainTable == core.refTable) { 471 boolean match = true; 472 473 for (int i = 0; i < core.colLen; i++) { 474 if (!row[core.refColArray[i]].equals( 475 row[core.mainColArray[i]])) { 476 match = false; 477 478 break; 479 } 480 } 481 482 if (match) { 483 return; 484 } 485 } 486 487 throw Trace.error(Trace.INTEGRITY_CONSTRAINT_VIOLATION_NOPARENT, 488 Trace.Constraint_violation, new Object [] { 489 core.fkName.name, core.mainTable.getName().name 490 }); 491 } 492 } 493 494 497 void checkCheckConstraint(Session session, 498 Object [] row) throws HsqlException { 499 500 core.checkFilter.currentData = row; 501 502 boolean nomatch = Boolean.FALSE.equals(core.check.test(session)); 503 504 core.checkFilter.currentData = null; 505 506 if (nomatch) { 507 throw Trace.error(Trace.CHECK_CONSTRAINT_VIOLATION, 508 Trace.Constraint_violation, new Object [] { 509 constName.name, core.mainTable.tableName.name 510 }); 511 } 512 } 513 514 516 531 RowIterator findFkRef(Session session, Object [] row, 532 boolean delete) throws HsqlException { 533 534 if (row == null || Index.isNull(row, core.mainColArray)) { 535 return core.refIndex.emptyIterator(); 536 } 537 538 return delete 539 ? core.refIndex.findFirstRowForDelete(session, row, 540 core.mainColArray) 541 : core.refIndex.findFirstRow(session, row, core.mainColArray); 542 } 543 544 551 boolean hasMainRef(Session session, Object [] row) throws HsqlException { 552 553 if (Index.isNull(row, core.refColArray)) { 554 return false; 555 } 556 557 boolean exists = core.mainIndex.exists(session, row, 558 core.refColArray); 559 560 if (!exists) { 563 throw Trace.error(Trace.INTEGRITY_CONSTRAINT_VIOLATION_NOPARENT, 564 Trace.Constraint_violation, new Object [] { 565 core.fkName.name, core.refTable.getName().name 566 }); 567 } 568 569 return exists; 570 } 571 572 578 private static boolean hasReferencedRow(Session session, 579 Object [] rowdata, int[] rowColArray, 580 Index mainIndex) throws HsqlException { 581 582 if (Index.isNull(rowdata, rowColArray)) { 583 return true; 584 } 585 586 return mainIndex.exists(session, rowdata, rowColArray); 588 } 589 590 595 static void checkReferencedRows(Session session, Table table, 596 int[] rowColArray, 597 Index mainIndex) throws HsqlException { 598 599 RowIterator it = table.getPrimaryIndex().firstRow(session); 600 601 while (true) { 602 Row row = it.next(); 603 604 if (row == null) { 605 break; 606 } 607 608 Object [] rowdata = row.getData(); 609 610 if (!Constraint.hasReferencedRow(session, rowdata, rowColArray, 611 mainIndex)) { 612 String colvalues = ""; 613 614 for (int i = 0; i < rowColArray.length; i++) { 615 Object o = rowdata[rowColArray[i]]; 616 617 colvalues += o; 618 colvalues += ","; 619 } 620 621 throw Trace.error( 622 Trace.INTEGRITY_CONSTRAINT_VIOLATION_NOPARENT, 623 Trace.Constraint_violation, new Object [] { 624 colvalues, table.getName().name 625 }); 626 } 627 } 628 } 629 } 630 | Popular Tags |