Package org.apache.derby.iapi.sql.dictionary

Examples of org.apache.derby.iapi.sql.dictionary.IndexRowGenerator


      cd = td.getConglomerateDescriptor(constants.indexCIDS[index]);
      int[] baseColumnPositions = constants.irgs[index].baseColumnPositions();
      boolean[] isAscending = constants.irgs[index].isAscending();
      int numColumnOrderings;
            SortObserver sortObserver;
            final IndexRowGenerator indDes = cd.getIndexDescriptor();

            if (indDes.isUnique() || indDes.isUniqueDeferrable())
      {
                numColumnOrderings =
                        indDes.isUnique() ? baseColumnPositions.length :
                        baseColumnPositions.length + 1;

        String indexOrConstraintName = cd.getConglomerateName();
                boolean deferred = false;
                boolean uniqueDeferrable = false;
View Full Code Here


  {
    TableDescriptor       td;
    UUID             toid;
    ColumnDescriptor      columnDescriptor;
    int[]            baseColumnPositions;
    IndexRowGenerator      indexRowGenerator = null;
    ExecRow[]          baseRows;
    ExecIndexRow[]        indexRows;
    ExecRow[]          compactBaseRows;
    GroupFetchScanController    scan;
    RowLocationRetRowSource      rowSource;
    long            sortId;
    int              maxBaseColumnPosition = -1;

    LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
    DataDictionary dd = lcc.getDataDictionary();
    DependencyManager dm = dd.getDependencyManager();
    TransactionController tc = lcc.getTransactionExecute();

    /*
    ** Inform the data dictionary that we are about to write to it.
    ** There are several calls to data dictionary "get" methods here
    ** that might be done in "read" mode in the data dictionary, but
    ** it seemed safer to do this whole operation in "write" mode.
    **
    ** We tell the data dictionary we're done writing at the end of
    ** the transaction.
    */
    dd.startWriting(lcc);

    /*
    ** If the schema descriptor is null, then
    ** we must have just read ourselves in. 
    ** So we will get the corresponding schema
    ** descriptor from the data dictionary.
    */
    SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, tc, true) ;


    /* Get the table descriptor. */
    /* See if we can get the TableDescriptor
     * from the Activation.  (Will be there
     * for backing indexes.)
     */
    td = activation.getDDLTableDescriptor();

    if (td == null)
    {
      /* tableId will be non-null if adding an index to
       * an existing table (as opposed to creating a
       * table with a constraint with a backing index).
       */
      if (tableId != null)
      {
        td = dd.getTableDescriptor(tableId);
      }
      else
      {
        td = dd.getTableDescriptor(tableName, sd, tc);
      }
    }

    if (td == null)
    {
      throw StandardException.newException(SQLState.LANG_CREATE_INDEX_NO_TABLE,
            indexName, tableName);
    }

    if (td.getTableType() == TableDescriptor.SYSTEM_TABLE_TYPE)
    {
      throw StandardException.newException(SQLState.LANG_CREATE_SYSTEM_INDEX_ATTEMPTED,
            indexName, tableName);
    }

    /* Get a shared table lock on the table. We need to lock table before
     * invalidate dependents, otherwise, we may interfere with the
     * compilation/re-compilation of DML/DDL.  See beetle 4325 and $WS/
     * docs/language/SolutionsToConcurrencyIssues.txt (point f).
     */
    lockTableForDDL(tc, td.getHeapConglomerateId(), false);

    // invalidate any prepared statements that
    // depended on this table (including this one)
    if (! forCreateTable)
    {
      dm.invalidateFor(td, DependencyManager.CREATE_INDEX, lcc);
    }

    // Translate the base column names to column positions
    baseColumnPositions = new int[columnNames.length];
    for (int i = 0; i < columnNames.length; i++)
    {
      // Look up the column in the data dictionary
      columnDescriptor = td.getColumnDescriptor(columnNames[i]);
      if (columnDescriptor == null)
      {
        throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,
                              columnNames[i],
                              tableName);
      }

      TypeId typeId = columnDescriptor.getType().getTypeId();

      // Don't allow a column to be created on a non-orderable type
      ClassFactory cf = lcc.getLanguageConnectionFactory().getClassFactory();
      boolean isIndexable = typeId.orderable(cf);

      if (isIndexable && typeId.userType()) {
        String userClass = typeId.getCorrespondingJavaTypeName();

        // Don't allow indexes to be created on classes that
        // are loaded from the database. This is because recovery
        // won't be able to see the class and it will need it to
        // run the compare method.
        try {
          if (cf.isApplicationClass(cf.loadApplicationClass(userClass)))
            isIndexable = false;
        } catch (ClassNotFoundException cnfe) {
          // shouldn't happen as we just check the class is orderable
          isIndexable = false;
        }
      }

      if (!isIndexable) {
        throw StandardException.newException(SQLState.LANG_COLUMN_NOT_ORDERABLE_DURING_EXECUTION,
          typeId.getSQLTypeName());
      }

      // Remember the position in the base table of each column
      baseColumnPositions[i] = columnDescriptor.getPosition();

      if (maxBaseColumnPosition < baseColumnPositions[i])
        maxBaseColumnPosition = baseColumnPositions[i];
    }

    /* The code below tries to determine if the index that we're about
     * to create can "share" a conglomerate with an existing index.
     * If so, we will use a single physical conglomerate--namely, the
     * one that already exists--to support both indexes. I.e. we will
     * *not* create a new conglomerate as part of this constant action.
         *
         * Deferrable constraints are backed by indexes that are *not* shared
         * since they use physically non-unique indexes and as such are
         * different from indexes used to represent non-deferrable
         * constraints.
     */

    // check if we have similar indices already for this table
    ConglomerateDescriptor[] congDescs = td.getConglomerateDescriptors();
    boolean shareExisting = false;
    for (int i = 0; i < congDescs.length; i++)
    {
      ConglomerateDescriptor cd = congDescs[i];
      if ( ! cd.isIndex())
        continue;

      if (droppedConglomNum == cd.getConglomerateNumber())
      {
        /* We can't share with any conglomerate descriptor
         * whose conglomerate number matches the dropped
         * conglomerate number, because that descriptor's
         * backing conglomerate was dropped, as well.  If
         * we're going to share, we have to share with a
         * descriptor whose backing physical conglomerate
         * is still around.
         */
        continue;
      }

      IndexRowGenerator irg = cd.getIndexDescriptor();
      int[] bcps = irg.baseColumnPositions();
      boolean[] ia = irg.isAscending();
      int j = 0;

      /* The conditions which allow an index to share an existing
       * conglomerate are as follows:
       *
       * 1. the set of columns (both key and include columns) and their
       *  order in the index is the same as that of an existing index AND
       *
       * 2. the ordering attributes are the same AND
       *
       * 3. one of the following is true:
       *    a) the existing index is unique, OR
       *    b) the existing index is non-unique with uniqueWhenNotNulls
       *       set to TRUE and the index being created is non-unique, OR
       *    c) both the existing index and the one being created are
       *       non-unique and have uniqueWithDuplicateNulls set to FALSE.
             *
             * 4. hasDeferrableChecking is FALSE.
             */
            boolean possibleShare =
                    (irg.isUnique() || !unique) &&
                    (bcps.length == baseColumnPositions.length) &&
                    !hasDeferrableChecking;

      //check if existing index is non unique and uniqueWithDuplicateNulls
      //is set to true (backing index for unique constraint)
      if (possibleShare && !irg.isUnique ())
      {
        /* If the existing index has uniqueWithDuplicateNulls set to
         * TRUE it can be shared by other non-unique indexes; otherwise
         * the existing non-unique index has uniqueWithDuplicateNulls
         * set to FALSE, which means the new non-unique conglomerate
         * can only share if it has uniqueWithDuplicateNulls set to
         * FALSE, as well.
         */
        possibleShare = (irg.isUniqueWithDuplicateNulls() ||
                ! uniqueWithDuplicateNulls);
      }

      if (possibleShare && indexType.equals(irg.indexType()))
      {
        for (; j < bcps.length; j++)
        {
          if ((bcps[j] != baseColumnPositions[j]) || (ia[j] != isAscending[j]))
            break;
        }
      }

      if (j == baseColumnPositions.length// share
      {
        /*
         * Don't allow users to create a duplicate index. Allow if being done internally
         * for a constraint
         */
        if (!isConstraint)
        {
          activation.addWarning(
              StandardException.newWarning(
                SQLState.LANG_INDEX_DUPLICATE,
                cd.getConglomerateName()));

          return;
        }

        /* Sharing indexes share the physical conglomerate
         * underneath, so pull the conglomerate number from
         * the existing conglomerate descriptor.
         */
        conglomId = cd.getConglomerateNumber();

        /* We create a new IndexRowGenerator because certain
         * attributes--esp. uniqueness--may be different between
         * the index we're creating and the conglomerate that
         * already exists.  I.e. even though we're sharing a
         * conglomerate, the new index is not necessarily
         * identical to the existing conglomerate. We have to
         * keep track of that info so that if we later drop
         * the shared physical conglomerate, we can figure out
         * what this index (the one we're creating now) is
         * really supposed to look like.
         */
        indexRowGenerator =
          new IndexRowGenerator(
            indexType, unique, uniqueWithDuplicateNulls,
                        false, // uniqueDeferrable
                        false, // deferrable indexes are not shared
            baseColumnPositions,
            isAscending,
            baseColumnPositions.length);

        //DERBY-655 and DERBY-1343 
        // Sharing indexes will have unique logical conglomerate UUIDs.
        conglomerateUUID = dd.getUUIDFactory().createUUID();
        shareExisting = true;
        break;
      }
    }

    /* If we have a droppedConglomNum then the index we're about to
     * "create" already exists--i.e. it has an index descriptor and
     * the corresponding information is already in the system catalogs.
     * The only thing we're missing, then, is the physical conglomerate
     * to back the index (because the old conglomerate was dropped).
     */
    boolean alreadyHaveConglomDescriptor = (droppedConglomNum > -1L);

    /* If this index already has an essentially same one, we share the
     * conglomerate with the old one, and just simply add a descriptor
     * entry into SYSCONGLOMERATES--unless we already have a descriptor,
     * in which case we don't even need to do that.
     */
    DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
    if (shareExisting && !alreadyHaveConglomDescriptor)
    {
      ConglomerateDescriptor cgd =
        ddg.newConglomerateDescriptor(conglomId, indexName, true,
                      indexRowGenerator, isConstraint,
                      conglomerateUUID, td.getUUID(), sd.getUUID() );
      dd.addDescriptor(cgd, sd, DataDictionary.SYSCONGLOMERATES_CATALOG_NUM, false, tc);
      // add newly added conglomerate to the list of conglomerate
      // descriptors in the td.
      ConglomerateDescriptorList cdl =
        td.getConglomerateDescriptorList();
      cdl.add(cgd);

      // can't just return yet, need to get member "indexTemplateRow"
      // because create constraint may use it
    }

    // Describe the properties of the index to the store using Properties
    // RESOLVE: The following properties assume a BTREE index.
    Properties  indexProperties;
   
    if (properties != null)
    {
      indexProperties = properties;
    }
    else
    {
      indexProperties = new Properties();
    }

    // Tell it the conglomerate id of the base table
    indexProperties.put("baseConglomerateId",
              Long.toString(td.getHeapConglomerateId()));
       
        if (uniqueWithDuplicateNulls && !hasDeferrableChecking)
        {
            if (dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null))
            {
        indexProperties.put(
                    "uniqueWithDuplicateNulls", Boolean.toString(true));
      }
      else
            {
        // for lower version of DD there is no unique with nulls
                // index creating a unique index instead.
        if (uniqueWithDuplicateNulls)
                {
          unique = true;
        }
      }
    }

    // All indexes are unique because they contain the RowLocation.
    // The number of uniqueness columns must include the RowLocation
    // if the user did not specify a unique index.
    indexProperties.put("nUniqueColumns",
          Integer.toString(unique ? baseColumnPositions.length :
                        baseColumnPositions.length + 1)
              );
    // By convention, the row location column is the last column
    indexProperties.put("rowLocationColumn",
              Integer.toString(baseColumnPositions.length));

    // For now, all columns are key fields, including the RowLocation
    indexProperties.put("nKeyFields",
              Integer.toString(baseColumnPositions.length + 1));

    // For now, assume that all index columns are ordered columns
    if (! shareExisting)
    {
            if (dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null))
            {
                indexRowGenerator = new IndexRowGenerator(
                        indexType,
                        unique,
                        uniqueWithDuplicateNulls,
                        uniqueDeferrable,
                        (hasDeferrableChecking &&
                         constraintType != DataDictionary.FOREIGNKEY_CONSTRAINT),
                        baseColumnPositions,
                        isAscending,
                        baseColumnPositions.length);
      }
      else
            {
        indexRowGenerator = new IndexRowGenerator(
                                            indexType,
                                            unique,
                                            false,
                                            false,
                                            false,
View Full Code Here

    String    keyString = "";
    String[]  columnNames = cd.getColumnNames();

    if (cd.isIndex() && columnNames != null )
    {
      IndexRowGenerator irg = cd.getIndexDescriptor();

      int[] keyColumns = irg.baseColumnPositions();

      keyString = ", key columns = {" + columnNames[keyColumns[0] - 1];
      for (int index = 1; index < keyColumns.length; index++)
      {
        keyString = keyString + ", " + columnNames[keyColumns[index] - 1];
View Full Code Here

      ordering  = new ColumnOrdering[numIndexes][];
      collation = new int[numIndexes][];

      for (int index = 0; index < numIndexes; index++)
      {
                IndexRowGenerator curIndex = compressIRGs[index];
        // create a single index row template for each index
                indexRows[index] = curIndex.getIndexRowTemplate();
                curIndex.getIndexRow(emptyHeapRow,
                        rl,
                        indexRows[index],
                        (FormatableBitSet) null);
        /* For non-unique indexes, we order by all columns + the RID.
         * For unique indexes, we just order by the columns.
         * No need to try to enforce uniqueness here as
         * index should be valid.
         */
                int[] baseColumnPositions = curIndex.baseColumnPositions();

                boolean[] isAscending = curIndex.isAscending();

        int numColumnOrderings;
        numColumnOrderings = baseColumnPositions.length + 1;
        ordering[index]    = new ColumnOrdering[numColumnOrderings];
                collation[index]   = curIndex.getColumnCollationIds(
                                                td.getColumnDescriptorList());

        for (int ii =0; ii < numColumnOrderings - 1; ii++)
        {
          ordering[index][ii] =
View Full Code Here

          distinctConglomNums[distinctCount++] = cd.getConglomerateNumber();
                    conglomerates.add( cd );
        }
      }

      IndexRowGenerator ixd = cd.getIndexDescriptor();
      int[] cols = ixd.baseColumnPositions();

      if (colBitSet != null)
      {
        for (int i = 0; i < cols.length; i++)
        {
View Full Code Here

    DataValueDescriptor    col;
    String          tabID =null;
    Long          conglomNumber = null;
    String          conglomName = null;
    Boolean          supportsIndex = null;
    IndexRowGenerator    indexRowGenerator = null;
    Boolean          supportsConstraint = null;
    String          conglomUUIDString = null;
    String          schemaID = null;
    ConglomerateDescriptor  conglomerate = (ConglomerateDescriptor)td;

    /* Insert info into sysconglomerates */

    if (td != null)
    {
      /* Sometimes the SchemaDescriptor is non-null and sometimes it
       * is null.  (We can't just rely on getting the schema id from
       * the ConglomerateDescriptor because it can be null when
       * we are creating a new conglomerate.
       */
      if (parent != null)
      {
        SchemaDescriptor sd = (SchemaDescriptor)parent;
        schemaID = sd.getUUID().toString()
      }
      else
      {
        schemaID = conglomerate.getSchemaID().toString()
      }
      tabID = conglomerate.getTableID().toString();
      conglomNumber = new Long( conglomerate.getConglomerateNumber() );
      conglomName = conglomerate.getConglomerateName();
      conglomUUIDString = conglomerate.getUUID().toString();

      supportsIndex = new Boolean( conglomerate.isIndex() );
      indexRowGenerator = conglomerate.getIndexDescriptor();
      supportsConstraint = new Boolean( conglomerate.isConstraint() );
    }

    /* RESOLVE - It would be nice to require less knowledge about sysconglomerates
     * and have this be more table driven.
     */

    /* Build the row to insert */
    row = getExecutionFactory().getValueRow(SYSCONGLOMERATES_COLUMN_COUNT);

    /* 1st column is SCHEMAID (UUID - char(36)) */
    row.setColumn(1, new SQLChar(schemaID));

    /* 2nd column is TABLEID (UUID - char(36)) */
    row.setColumn(2, new SQLChar(tabID));

    /* 3rd column is CONGLOMERATENUMBER (long) */
    row.setColumn(3, new SQLLongint(conglomNumber));

    /* 4th column is CONGLOMERATENAME (varchar(128))
    ** If null, use the tableid so we always
    ** have a unique column
    */
    row.setColumn(4, (conglomName == null) ?
                new SQLVarchar(tabID): new SQLVarchar(conglomName));

    /* 5th  column is ISINDEX (boolean) */
    row.setColumn(5, new SQLBoolean(supportsIndex));

    /* 6th column is DESCRIPTOR
    *  (user type org.apache.derby.catalog.IndexDescriptor)
    */
    row.setColumn(6,
      new UserType(
            (indexRowGenerator == null ?
              (IndexDescriptor) null :
              indexRowGenerator.getIndexDescriptor()
            )
          )
        );

    /* 7th column is ISCONSTRAINT (boolean) */
 
View Full Code Here

    DataDescriptorGenerator  ddg = dd.getDataDescriptorGenerator();
    long conglomerateNumber;
    String  name;
    boolean isConstraint;
    boolean isIndex;
    IndexRowGenerator  indexRowGenerator;
    DataValueDescriptor col;
    ConglomerateDescriptor conglomerateDesc;
    String    conglomUUIDString;
    UUID    conglomUUID;
    String    schemaUUIDString;
    UUID    schemaUUID;
    String    tableUUIDString;
    UUID    tableUUID;

    /* 1st column is SCHEMAID (UUID - char(36)) */
    col = row.getColumn(1);
    schemaUUIDString = col.getString();
    schemaUUID = getUUIDFactory().recreateUUID(schemaUUIDString);

    /* 2nd column is TABLEID (UUID - char(36)) */
    col = row.getColumn(2);
    tableUUIDString = col.getString();
    tableUUID = getUUIDFactory().recreateUUID(tableUUIDString);


    /* 3nd column is CONGLOMERATENUMBER (long) */
    col = row.getColumn(3);
    conglomerateNumber = col.getLong();

    /* 4rd column is CONGLOMERATENAME (varchar(128)) */
    col = row.getColumn(4);
    name = col.getString();

    /* 5th column is ISINDEX (boolean) */
    col = row.getColumn(5);
    isIndex = col.getBoolean();

    /* 6th column is DESCRIPTOR */
    col = row.getColumn(6);
    indexRowGenerator = new IndexRowGenerator(
      (IndexDescriptor) col.getObject());

    /* 7th column is ISCONSTRAINT (boolean) */
    col = row.getColumn(7);
    isConstraint = col.getBoolean();
View Full Code Here

                    if ( optimizerTracingIsOn() ) { getOptimizerTracer().traceScanningHeapWithUniqueKey(); }
        }
      }
      else
      {
        IndexRowGenerator irg =
              currentConglomerateDescriptor.getIndexDescriptor();

        int[] baseColumnPositions = irg.baseColumnPositions();
        boolean[] isAscending = irg.isAscending();

        for (int i = 0; i < baseColumnPositions.length; i++)
        {
          /*
          ** Don't add the column to the ordering if it's already
View Full Code Here

   */
    @Override
  public boolean isCoveringIndex(ConglomerateDescriptor cd) throws StandardException
  {
    boolean coveringIndex = true;
    IndexRowGenerator  irg;
    int[]        baseCols;
    int          colPos;

    /* You can only be a covering index if you're an index */
    if ( ! cd.isIndex())
      return false;

    irg = cd.getIndexDescriptor();
    baseCols = irg.baseColumnPositions();

    /* First we check to see if this is a covering index */
        for (ResultColumn rc : getResultColumns())
    {
      /* Ignore unreferenced columns */
 
View Full Code Here

                    // multi-probe by primary key not chosen on tables with
                    // >256 rows), even though we do not keep the
                    // statistics for single-column unique indexes, we
                    // should improve the selectivity of such an index
                    // when the index is being considered by the optimizer.
                    IndexRowGenerator irg = cd.getIndexDescriptor();
                    if (irg.isUnique()
                            && irg.numberOfOrderedColumns() == 1
                            && startStopPredCount == 1) {
                        statStartStopSelectivity = (1/(double)baseRowCount());
                    }
                }
            }
View Full Code Here

TOP

Related Classes of org.apache.derby.iapi.sql.dictionary.IndexRowGenerator

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.