public Schema(CreateTableCommand command) throws DatabaseException {

		// create the attributes based on AttributeDescriptors
		List<CreateTableCommand.AttributeDescriptor> attrDescriptors = command.getAttributeDescriptors();
		attributes = new Attribute[attrDescriptors.size()];
		for (int i=0; i<attrDescriptors.size(); ++i) {
			attributes[i] = new Attribute(i, attrDescriptors.get(i));
		}
		
		// generate map based on attributes
		updateAttributesMap();
		
		// generate primaryKeyPositions based on primaryKeyAttrNames
		List<String> primaryKeyAttrNames = command.getPrimaryKeyAttrNames();
		primaryKeyPositions = new int[primaryKeyAttrNames.size()];
		for (int i=0; i<primaryKeyPositions.length; ++i) {
			String primaryKeyAttrName = primaryKeyAttrNames.get(i);
			Integer position = attributesMap.get(primaryKeyAttrName);
			if (position == null) {
				throw new DatabaseException("Primary key attribute '"+
						primaryKeyAttrName+"' does not exist.");
			}
			for (int j=0; j<i; j++) {
				if (primaryKeyPositions[j] == position) {
					throw new DatabaseException("'"+primaryKeyAttrName+
							"' appears multiple times in primary key.");
				}
			}
			primaryKeyPositions[i] = position;
		}
		
		// generate foreign keys based on foreignKeyDescriptors
		List<CreateTableCommand.ForeignKeyDescriptor> foreignKeyDescriptors = 
				command.getForeignKeyDescriptors();
		foreignKeys = new ForeignKey[foreignKeyDescriptors.size()];
		for (int i=0; i<foreignKeys.length; ++i) {
			foreignKeys[i] = new ForeignKey(foreignKeyDescriptors.get(i));
		}
		
		// there is no subschema initially (all attributes visible)
		visiblePositions = new TreeSet<Integer>();
		for (int i=0; i<attributes.length; ++i)
			visiblePositions.add(i);
	}