1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.services.loader.ClassInspector; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 import org.apache.derby.iapi.services.io.StoredFormatIds; 28 import org.apache.derby.iapi.reference.Limits; 29 import org.apache.derby.iapi.error.StandardException; 30 31 import org.apache.derby.iapi.sql.compile.CompilerContext; 32 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 33 34 import org.apache.derby.iapi.sql.dictionary.AliasDescriptor; 35 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 36 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 37 38 import org.apache.derby.iapi.types.DataTypeDescriptor; 39 import org.apache.derby.iapi.types.DataValueDescriptor; 40 import org.apache.derby.iapi.types.TypeId; 41 42 import org.apache.derby.iapi.sql.depend.DependencyManager; 43 import org.apache.derby.iapi.sql.depend.ProviderList; 44 import org.apache.derby.iapi.sql.depend.ProviderInfo; 45 46 import org.apache.derby.iapi.reference.SQLState; 47 48 import org.apache.derby.impl.sql.execute.ColumnInfo; 49 50 import org.apache.derby.catalog.AliasInfo; 51 import org.apache.derby.catalog.DefaultInfo; 52 import org.apache.derby.catalog.UUID; 53 54 import org.apache.derby.catalog.types.DefaultInfoImpl; 55 56 import java.util.Vector ; 57 import java.sql.Types ; 58 59 66 67 public class ColumnDefinitionNode extends TableElementNode 68 { 69 boolean isAutoincrement; 70 DataTypeDescriptor dataTypeServices; 71 DataValueDescriptor defaultValue; 72 DefaultInfoImpl defaultInfo; 73 DefaultNode defaultNode; 74 long autoincrementIncrement; 75 long autoincrementStart; 76 long autoinc_create_or_modify_Start_Increment; 84 boolean autoincrementVerify; 85 86 public static final int CREATE_AUTOINCREMENT = 0; 90 public static final int MODIFY_AUTOINCREMENT_RESTART_VALUE = 1; 93 public static final int MODIFY_AUTOINCREMENT_INC_VALUE = 2; 96 97 107 108 public void init( 109 Object name, 110 Object defaultNode, 111 Object dataTypeServices, 112 Object autoIncrementInfo) 113 throws StandardException 114 { 115 super.init(name); 116 this.dataTypeServices = (DataTypeDescriptor) dataTypeServices; 117 if (defaultNode instanceof UntypedNullConstantNode) 118 { 119 120 if (dataTypeServices != null) 121 { 122 defaultValue = 123 ((UntypedNullConstantNode) defaultNode). 124 convertDefaultNode(this.dataTypeServices); 125 } 126 } 127 else 128 { 129 if (SanityManager.DEBUG) 130 { 131 if (defaultNode != null && 132 ! (defaultNode instanceof DefaultNode)) 133 { 134 SanityManager.THROWASSERT( 135 "defaultNode expected to be instanceof DefaultNode, not " + 136 defaultNode.getClass().getName()); 137 } 138 } 139 this.defaultNode = (DefaultNode) defaultNode; 140 if (autoIncrementInfo != null) 141 { 142 long[] aii = (long[]) autoIncrementInfo; 143 autoincrementStart = aii[QueryTreeNode.AUTOINCREMENT_START_INDEX]; 144 autoincrementIncrement = aii[QueryTreeNode.AUTOINCREMENT_INC_INDEX]; 145 autoinc_create_or_modify_Start_Increment = aii[QueryTreeNode.AUTOINCREMENT_CREATE_MODIFY]; 151 152 156 autoincrementVerify = (aii[QueryTreeNode.AUTOINCREMENT_IS_AUTOINCREMENT_INDEX] > 0) ? false : true; 157 isAutoincrement = true; 158 if (dataTypeServices != null) 164 (this.dataTypeServices).setNullability(false); 165 } 166 } 167 } 168 169 175 176 public String toString() 177 { 178 if (SanityManager.DEBUG) 179 { 180 return "dataTypeServices: " + dataTypeServices.toString() + "\n" + 181 "defaultValue: " + defaultValue + "\n" + 182 super.toString(); 183 } 184 else 185 { 186 return ""; 187 } 188 } 189 190 195 public String getColumnName() 196 { 197 return this.name; 198 } 199 200 205 public DataTypeDescriptor getDataTypeServices() 206 { 207 return this.dataTypeServices; 208 } 209 210 216 217 public DataValueDescriptor getDefaultValue() 218 { 219 return this.defaultValue; 220 } 221 222 228 229 public DefaultInfo getDefaultInfo() 230 { 231 return defaultInfo; 232 } 233 234 239 public DefaultNode getDefaultNode() 240 { 241 return defaultNode; 242 } 243 244 249 public boolean isAutoincrementColumn() 250 { 251 if (SanityManager.DEBUG) 252 { 253 if (isAutoincrement && autoincrementIncrement == 0 && 257 (autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.CREATE_AUTOINCREMENT || 258 autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE)) 259 { 260 SanityManager.THROWASSERT( 261 "autoincrementIncrement expected to be non-zero"); 262 } 263 if ((! isAutoincrement) && 264 (autoincrementStart != 0 || autoincrementIncrement != 0)) 265 { 266 SanityManager.THROWASSERT( 267 "both autoincrementStart and autoincrementIncrement expected to be 0"); 268 } 269 } 270 return isAutoincrement; 271 } 272 273 278 long getAutoincrementStart() 279 { 280 if (SanityManager.DEBUG) 281 { 282 SanityManager.ASSERT(isAutoincrement, 283 "isAutoincrement expected to be true"); 284 } 285 return autoincrementStart; 286 } 287 288 293 long getAutoincrementIncrement() 294 { 295 if (SanityManager.DEBUG) 296 { 297 SanityManager.ASSERT(isAutoincrement, 298 "isAutoincrement expected to be true"); 299 } 300 return autoincrementIncrement; 301 } 302 303 313 long getAutoinc_create_or_modify_Start_Increment() 314 { 315 if (SanityManager.DEBUG) 316 { 317 SanityManager.ASSERT(isAutoincrement, 318 "isAutoincrement expected to be true"); 319 } 320 return autoinc_create_or_modify_Start_Increment; 321 } 322 323 330 331 public void checkUserType(TableDescriptor td) 332 throws StandardException 333 { 334 String columnTypeName; 335 336 337 if (!dataTypeServices.getTypeId().userType()) 338 return; 339 340 ClassInspector classInspector = getClassFactory().getClassInspector(); 341 342 columnTypeName = 343 dataTypeServices.getTypeId().getCorrespondingJavaTypeName(); 344 345 346 347 348 351 352 boolean foundMatch = false; 353 Throwable reason = null; 354 try { 355 foundMatch = classInspector.accessible(columnTypeName); 356 } catch (ClassNotFoundException cnfe) { 357 reason = cnfe; 358 } 359 360 if (!foundMatch) 361 { 362 throw StandardException.newException(SQLState.LANG_TYPE_DOESNT_EXIST, reason, columnTypeName, 363 name); 364 } 365 366 if (! classInspector.assignableTo(columnTypeName, 367 "java.io.Serializable") && 368 ! classInspector.assignableTo(columnTypeName,"java.sql.SQLData")) 370 { 371 getCompilerContext().addWarning( 372 StandardException.newWarning(SQLState.LANG_TYPE_NOT_SERIALIZABLE, columnTypeName, 373 name)); 374 } 375 } 376 377 382 UUID getOldDefaultUUID() 383 { 384 return null; 385 } 386 387 392 int getAction() 393 { 394 return ColumnInfo.CREATE; 395 } 396 397 405 void bindAndValidateDefault(DataDictionary dd, TableDescriptor td) 406 throws StandardException 407 { 408 409 if (td != null && !dataTypeServices.isNullable() && defaultNode == null) 410 { 411 if (!isAutoincrement) 412 throw StandardException.newException(SQLState.LANG_DB2_NOT_NULL_COLUMN_INVALID_DEFAULT, getColumnName()); 413 } 414 415 if (defaultNode == null) 417 { 418 return; 419 } 420 421 if (defaultValue != null) 423 { 424 return; 425 } 426 427 validateDefault(dd, td); 429 } 430 431 432 447 public void validateAutoincrement(DataDictionary dd, TableDescriptor td, int tableType) 448 throws StandardException 449 { 450 if (isAutoincrement == false) 451 return; 452 453 if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) 454 throw StandardException.newException(SQLState.LANG_NOT_ALLOWED_FOR_DECLARED_GLOBAL_TEMP_TABLE); 455 456 if (autoincrementIncrement == 0 && 460 (autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.CREATE_AUTOINCREMENT || 461 autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE)) 462 throw StandardException.newException(SQLState.LANG_AI_INVALID_INCREMENT, getColumnName()); 463 int jdbctype = dataTypeServices.getTypeId().getJDBCTypeId(); 464 switch (jdbctype) 465 { 466 case Types.TINYINT: 467 autoincrementCheckRange((long)Byte.MIN_VALUE, 468 (long)Byte.MAX_VALUE, 469 TypeId.TINYINT_NAME); 470 break; 471 case Types.SMALLINT: 472 autoincrementCheckRange((long)Short.MIN_VALUE, 473 (long)Short.MAX_VALUE, 474 TypeId.SMALLINT_NAME); 475 break; 476 case Types.INTEGER: 477 autoincrementCheckRange((long)Integer.MIN_VALUE, 478 (long)Integer.MAX_VALUE, 479 TypeId.INTEGER_NAME); 480 break; 481 case Types.BIGINT: 482 autoincrementCheckRange(Long.MIN_VALUE, Long.MAX_VALUE, 483 TypeId.LONGINT_NAME); 484 break; 485 default: 486 throw StandardException.newException(SQLState.LANG_AI_INVALID_TYPE, 487 getColumnName()); 488 } 489 } 490 491 496 private void autoincrementCheckRange(long minValue, long maxValue, 497 String typeName) 498 throws StandardException 499 { 500 if ((minValue > autoincrementIncrement) || 501 (maxValue < autoincrementIncrement)) 502 { 503 throw StandardException.newException( 504 SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, typeName); 505 } 506 if ((minValue > autoincrementStart) || 507 (maxValue < autoincrementStart)) 508 { 509 throw StandardException.newException( 510 SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, typeName); 511 } 512 } 513 520 void validateDefault(DataDictionary dd, TableDescriptor td) 521 throws StandardException 522 { 523 if (defaultNode == null) 524 return; 525 526 if (isAutoincrement){ 528 defaultInfo = createDefaultInfoOfAutoInc(); 529 return; 530 } 531 532 533 535 CompilerContext cc = getCompilerContext(); 536 537 ValueNode defaultTree = defaultNode.getDefaultTree(); 538 539 543 final int previousReliability = cc.getReliability(); 544 try 545 { 546 552 ProviderList apl = null; 553 ProviderList prevAPL = null; 554 555 if (SanityManager.DEBUG) { 556 apl = new ProviderList(); 557 prevAPL = cc.getCurrentAuxiliaryProviderList(); 558 cc.setCurrentAuxiliaryProviderList(apl); 559 } 560 561 cc.setReliability( CompilerContext.DEFAULT_RESTRICTION ); 563 defaultTree = defaultTree.bindExpression( 564 (FromList) getNodeFactory().getNode( 565 C_NodeTypes.FROM_LIST, 566 getNodeFactory().doJoinOrderOptimization(), 567 getContextManager()), 568 (SubqueryList) null, 569 (Vector ) null); 570 571 TypeId columnTypeId = (TypeId) dataTypeServices.getTypeId(); 572 TypeId defaultTypeId = defaultTree.getTypeId(); 573 574 if (!defaultTypeIsValid(columnTypeId, dataTypeServices, 577 defaultTypeId, defaultTree, defaultNode.getDefaultText())) 578 { 579 throw StandardException.newException( 580 SQLState.LANG_DB2_INVALID_DEFAULT_VALUE, 581 this.name); 582 } 583 584 if (! getTypeCompiler(columnTypeId). 586 storable(defaultTypeId, getClassFactory())) 587 { 588 throw StandardException.newException(SQLState.LANG_NOT_STORABLE, 589 columnTypeId.getSQLTypeName(), 590 defaultTypeId.getSQLTypeName() ); 591 } 592 593 defaultInfo = new DefaultInfoImpl(false, 596 defaultNode.getDefaultText(), 597 defaultValue); 598 599 if (SanityManager.DEBUG) 600 { 601 602 if (apl.size() > 0) 603 { 604 605 SanityManager.THROWASSERT("DEFAULT clause has unexpected dependencies"); 606 } 607 cc.setCurrentAuxiliaryProviderList(prevAPL); 609 } 610 611 } 612 finally 613 { 614 cc.setReliability(previousReliability); 615 } 616 } 617 618 619 private static DefaultInfoImpl createDefaultInfoOfAutoInc(){ 620 return new DefaultInfoImpl(true, 621 null, 622 null); 623 } 624 625 626 640 641 public boolean defaultTypeIsValid(TypeId columnType, 642 DataTypeDescriptor columnDesc, TypeId defaultType, 643 ValueNode defaultNode, String defaultText) 644 throws StandardException 645 { 646 647 if (defaultText.length() > Limits.DB2_CHAR_MAXWIDTH) 648 return false; 650 651 664 665 int colType = columnType.getTypeFormatId(); 666 int defType = (defaultType == null ? -1 : defaultType.getTypeFormatId()); 667 668 if (!defaultNode.isConstantExpression()) { 669 678 boolean charCol = ((colType == StoredFormatIds.CHAR_TYPE_ID) || 679 (colType == StoredFormatIds.VARCHAR_TYPE_ID) || 680 (colType == StoredFormatIds.LONGVARCHAR_TYPE_ID)); 681 682 if (defaultNode instanceof SpecialFunctionNode) { 683 684 switch (defaultNode.getNodeType()) 685 { 686 case C_NodeTypes.USER_NODE: 687 case C_NodeTypes.CURRENT_USER_NODE: 688 case C_NodeTypes.SESSION_USER_NODE: 689 case C_NodeTypes.SYSTEM_USER_NODE: 690 return (charCol && (columnDesc.getMaximumWidth() >= 693 Limits.DB2_MIN_COL_LENGTH_FOR_CURRENT_USER)); 694 695 case C_NodeTypes.CURRENT_SCHEMA_NODE: 696 return (charCol && (columnDesc.getMaximumWidth() >= 698 Limits.DB2_MIN_COL_LENGTH_FOR_CURRENT_SCHEMA)); 699 default: 700 return false; 702 } 703 } 704 705 } 706 707 switch (colType) { 708 709 case StoredFormatIds.INT_TYPE_ID: 710 return (defType == StoredFormatIds.INT_TYPE_ID); 718 719 case StoredFormatIds.LONGINT_TYPE_ID: 720 return ((defType == StoredFormatIds.INT_TYPE_ID) 725 || (defType == StoredFormatIds.LONGINT_TYPE_ID)); 726 727 case StoredFormatIds.DECIMAL_TYPE_ID: 728 if (defType == StoredFormatIds.DECIMAL_TYPE_ID) { 729 DataTypeDescriptor defDesc = defaultNode.getTypeServices(); 733 int len = defaultText.length(); 734 int precision = defDesc.getPrecision(); 735 int scale = defDesc.getScale(); 736 for (int i = 1; i <= scale; scale--, precision--) { 737 if (defaultText.charAt(len - i) != '0') 738 break; 739 } 740 return ((scale <= columnDesc.getScale()) && 741 ((precision - scale) <= 742 (columnDesc.getPrecision() - columnDesc.getScale()))); 743 } 744 else if ((defType == StoredFormatIds.LONGINT_TYPE_ID) || 745 (defType == StoredFormatIds.INT_TYPE_ID)) { 746 return true; 752 } 753 else 754 return false; 756 757 case StoredFormatIds.CHAR_TYPE_ID: 758 case StoredFormatIds.VARCHAR_TYPE_ID: 759 case StoredFormatIds.LONGVARCHAR_TYPE_ID: 760 return (defType == StoredFormatIds.CHAR_TYPE_ID); 767 768 case StoredFormatIds.BIT_TYPE_ID: 769 case StoredFormatIds.VARBIT_TYPE_ID: 770 case StoredFormatIds.LONGVARBIT_TYPE_ID: 771 return (defType == StoredFormatIds.BIT_TYPE_ID); 773 774 case StoredFormatIds.USERDEFINED_TYPE_ID_V3: 775 return (defType == colType); 777 778 case StoredFormatIds.BLOB_TYPE_ID: 779 case StoredFormatIds.CLOB_TYPE_ID: 780 case StoredFormatIds.SMALLINT_TYPE_ID: 781 case StoredFormatIds.REAL_TYPE_ID: 782 case StoredFormatIds.DOUBLE_TYPE_ID: 783 case StoredFormatIds.DATE_TYPE_ID: 784 case StoredFormatIds.TIME_TYPE_ID: 785 case StoredFormatIds.TIMESTAMP_TYPE_ID: 786 return true; 791 792 default: 793 return false; 799 800 } 801 802 } 803 804 } 805 | Popular Tags |