Beispiel #1
0
  private TupleSource loadGlobalTable(
      final CommandContext context,
      final GroupSymbol group,
      final String tableName,
      final GlobalTableStore globalStore)
      throws TeiidComponentException, TeiidProcessingException {
    LogManager.logInfo(
        LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30013, tableName));
    final QueryMetadataInterface metadata = context.getMetadata();
    final List<ElementSymbol> allColumns = ResolverUtil.resolveElementsInGroup(group, metadata);
    final TempTable table = globalStore.createMatTable(tableName, group);
    table.setUpdatable(false);
    return new ProxyTupleSource() {
      TupleSource insertTupleSource;
      boolean success;
      QueryProcessor qp;
      boolean closed;
      boolean errored;

      @Override
      protected TupleSource createTupleSource()
          throws TeiidComponentException, TeiidProcessingException {
        int rowCount = -1;
        try {
          if (insertTupleSource == null) {
            String fullName = metadata.getFullName(group.getMetadataID());
            String transformation = metadata.getVirtualPlan(group.getMetadataID()).getQuery();
            qp =
                context
                    .getQueryProcessorFactory()
                    .createQueryProcessor(transformation, fullName, context);
            insertTupleSource = new BatchCollector.BatchProducerTupleSource(qp);
          }
          table.insert(insertTupleSource, allColumns, false, null);
          table.getTree().compact();
          rowCount = table.getRowCount();
          Determinism determinism = qp.getContext().getDeterminismLevel();
          context.setDeterminismLevel(determinism);
          // TODO: could pre-process indexes to remove overlap
          for (Object index : metadata.getIndexesInGroup(group.getMetadataID())) {
            List<ElementSymbol> columns =
                GlobalTableStoreImpl.resolveIndex(metadata, allColumns, index);
            table.addIndex(columns, false);
          }
          for (Object key : metadata.getUniqueKeysInGroup(group.getMetadataID())) {
            List<ElementSymbol> columns =
                GlobalTableStoreImpl.resolveIndex(metadata, allColumns, key);
            table.addIndex(columns, true);
          }
          CacheHint hint = table.getCacheHint();
          if (hint != null && table.getPkLength() > 0) {
            table.setUpdatable(hint.isUpdatable(false));
          }
          if (determinism.compareTo(Determinism.VDB_DETERMINISTIC) < 0
              && (hint == null
                  || hint.getScope() == null
                  || Scope.VDB.compareTo(hint.getScope()) <= 0)) {
            LogManager.logInfo(
                LogConstants.CTX_DQP,
                QueryPlugin.Util.gs(
                    QueryPlugin.Event.TEIID31143, determinism, tableName)); // $NON-NLS-1$
          }
          globalStore.loaded(tableName, table);
          success = true;
          LogManager.logInfo(
              LogConstants.CTX_MATVIEWS,
              QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30014, tableName, rowCount));
          return CollectionTupleSource.createUpdateCountTupleSource(rowCount);
        } catch (BlockedException e) {
          throw e;
        } catch (Exception e) {
          errored = true;
          LogManager.logError(
              LogConstants.CTX_MATVIEWS,
              e,
              QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30015, tableName));
          closeSource();
          rethrow(e);
          throw new AssertionError();
        }
      }

      @Override
      public void closeSource() {
        if (closed) {
          return;
        }
        if (!errored) {
          LogManager.logInfo(
              LogConstants.CTX_MATVIEWS,
              QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31153, tableName));
        }
        closed = true;
        if (!success) {
          globalStore.failedLoad(tableName);
          table.remove();
        }
        if (qp != null) {
          qp.closeProcessing();
        }
        super.closeSource();
      }
    };
  }
Beispiel #2
0
  TupleSource registerRequest(final CommandContext context, String modelName, final Command command)
      throws TeiidComponentException, TeiidProcessingException {
    final TempTableStore contextStore = context.getTempTableStore();
    if (command instanceof Query) {
      Query query = (Query) command;
      if (modelName != null && !modelName.equals(TempMetadataAdapter.TEMP_MODEL.getID())) {
        return null;
      }
      return registerQuery(context, contextStore, query);
    }
    if (command instanceof ProcedureContainer) {
      if (command instanceof StoredProcedure) {
        StoredProcedure proc = (StoredProcedure) command;
        if (CoreConstants.SYSTEM_ADMIN_MODEL.equals(modelName)) {
          TupleSource result = handleSystemProcedures(context, proc);
          if (result != null) {
            return result;
          }
        } else if (proc.getGroup().isGlobalTable()) {
          return handleCachedProcedure(context, proc);
        }
        return null; // it's not a stored procedure we want to handle
      }

      final GroupSymbol group = ((ProcedureContainer) command).getGroup();
      if (!modelName.equals(TempMetadataAdapter.TEMP_MODEL.getID()) || !group.isTempGroupSymbol()) {
        return null;
      }
      return new ProxyTupleSource() {

        @Override
        protected TupleSource createTupleSource()
            throws TeiidComponentException, TeiidProcessingException {
          final String groupKey = group.getNonCorrelationName();
          final TempTable table =
              contextStore.getOrCreateTempTable(
                  groupKey, command, bufferManager, true, true, context, group);
          if (command instanceof Insert) {
            Insert insert = (Insert) command;
            TupleSource ts = insert.getTupleSource();
            if (ts == null) {
              Evaluator eval =
                  new Evaluator(Collections.emptyMap(), TempTableDataManager.this, context);
              List<Object> values = new ArrayList<Object>(insert.getValues().size());
              for (Expression expr : (List<Expression>) insert.getValues()) {
                values.add(eval.evaluate(expr, null));
              }
              ts = new CollectionTupleSource(Arrays.asList(values).iterator());
            }
            return table.insert(ts, insert.getVariables(), true, context);
          }
          if (command instanceof Update) {
            final Update update = (Update) command;
            final Criteria crit = update.getCriteria();
            return table.update(crit, update.getChangeList());
          }
          if (command instanceof Delete) {
            final Delete delete = (Delete) command;
            final Criteria crit = delete.getCriteria();
            if (crit == null) {
              // TODO: we'll add a real truncate later
              int rows = table.truncate(false);
              return CollectionTupleSource.createUpdateCountTupleSource(rows);
            }
            return table.delete(crit);
          }
          throw new AssertionError("unknown command " + command); // $NON-NLS-1$
        }
      };
    }
    if (command instanceof Create) {
      Create create = (Create) command;
      String tempTableName = create.getTable().getName();
      if (contextStore.hasTempTable(tempTableName)) {
        throw new QueryProcessingException(
            QueryPlugin.Event.TEIID30229,
            QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30229, tempTableName));
      }
      if (create.getTableMetadata() != null) {
        contextStore.addForeignTempTable(tempTableName, create);
      } else {
        contextStore.addTempTable(tempTableName, create, bufferManager, true, context);
      }
      return CollectionTupleSource.createUpdateCountTupleSource(0);
    }
    if (command instanceof Drop) {
      String tempTableName = ((Drop) command).getTable().getName();
      contextStore.removeTempTableByName(tempTableName, context);
      return CollectionTupleSource.createUpdateCountTupleSource(0);
    }
    if (command instanceof AlterTempTable) {
      AlterTempTable att = (AlterTempTable) command;
      TempTable tt = contextStore.getTempTable(att.getTempTable());
      Assertion.isNotNull(tt, "Table doesn't exist"); // $NON-NLS-1$
      tt.setUpdatable(false);
      if (att.getIndexColumns() != null && tt.getRowCount() > 2 * tt.getTree().getPageSize(true)) {
        for (List<ElementSymbol> cols : att.getIndexColumns()) {
          tt.addIndex(cols, false);
        }
      }
      return CollectionTupleSource.createUpdateCountTupleSource(0);
    }
    return null;
  }
Beispiel #3
0
  private TupleSource handleSystemProcedures(final CommandContext context, StoredProcedure proc)
      throws TeiidComponentException, QueryMetadataException, QueryProcessingException,
          QueryResolverException, QueryValidatorException, TeiidProcessingException,
          ExpressionEvaluationException {
    final QueryMetadataInterface metadata = context.getMetadata();
    if (StringUtil.endsWithIgnoreCase(proc.getProcedureCallableName(), REFRESHMATVIEW)) {
      Object groupID =
          validateMatView(
              metadata, (String) ((Constant) proc.getParameter(2).getExpression()).getValue());
      TempMetadataID matTableId =
          context.getGlobalTableStore().getGlobalTempTableMetadataId(groupID);
      final GlobalTableStore globalStore = getGlobalStore(context, matTableId);
      String matViewName = metadata.getFullName(groupID);
      String matTableName = metadata.getFullName(matTableId);
      LogManager.logDetail(
          LogConstants.CTX_MATVIEWS, "processing refreshmatview for", matViewName); // $NON-NLS-1$
      boolean invalidate =
          Boolean.TRUE.equals(((Constant) proc.getParameter(3).getExpression()).getValue());
      boolean needsLoading =
          globalStore.needsLoading(matTableName, globalStore.getAddress(), true, true, invalidate);
      if (!needsLoading) {
        return CollectionTupleSource.createUpdateCountTupleSource(-1);
      }
      GroupSymbol matTable = new GroupSymbol(matTableName);
      matTable.setMetadataID(matTableId);
      return loadGlobalTable(context, matTable, matTableName, globalStore);
    } else if (StringUtil.endsWithIgnoreCase(proc.getProcedureCallableName(), REFRESHMATVIEWROW)) {
      final Object groupID =
          validateMatView(
              metadata, (String) ((Constant) proc.getParameter(2).getExpression()).getValue());
      TempMetadataID matTableId =
          context.getGlobalTableStore().getGlobalTempTableMetadataId(groupID);
      final GlobalTableStore globalStore = getGlobalStore(context, matTableId);
      Object pk = metadata.getPrimaryKey(groupID);
      String matViewName = metadata.getFullName(groupID);
      if (pk == null) {
        throw new QueryProcessingException(
            QueryPlugin.Event.TEIID30230,
            QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30230, matViewName));
      }
      List<?> ids = metadata.getElementIDsInKey(pk);
      Constant key = (Constant) proc.getParameter(3).getExpression();
      Object initialValue = key.getValue();
      SPParameter keyOther = proc.getParameter(4);
      Object[] otherCols = null;
      int length = 1;
      if (keyOther != null) {
        otherCols = ((ArrayImpl) ((Constant) keyOther.getExpression()).getValue()).getValues();
        if (otherCols != null) {
          length += otherCols.length;
        }
      }
      if (ids.size() != length) {
        throw new QueryProcessingException(
            QueryPlugin.Event.TEIID30231,
            QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30231, matViewName, ids.size(), length));
      }
      final String matTableName = RelationalPlanner.MAT_PREFIX + matViewName.toUpperCase();
      MatTableInfo info = globalStore.getMatTableInfo(matTableName);
      if (!info.isValid()) {
        return CollectionTupleSource.createUpdateCountTupleSource(-1);
      }
      TempTable tempTable = globalStore.getTempTable(matTableName);
      if (!tempTable.isUpdatable()) {
        throw new QueryProcessingException(
            QueryPlugin.Event.TEIID30232,
            QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30232, matViewName));
      }
      Iterator<?> iter = ids.iterator();
      final Object[] params = new Object[length];
      StringBuilder criteria = new StringBuilder();
      for (int i = 0; i < length; i++) {
        Object id = iter.next();
        String targetTypeName = metadata.getElementType(id);
        Object value = i == 0 ? initialValue : otherCols[i - 1];
        value =
            DataTypeManager.transformValue(value, DataTypeManager.getDataTypeClass(targetTypeName));
        params[i] = value;
        if (i != 0) {
          criteria.append(" AND "); // $NON-NLS-1$
        }
        criteria.append(metadata.getFullName(id)).append(" = ?"); // $NON-NLS-1$
      }
      LogManager.logInfo(
          LogConstants.CTX_MATVIEWS,
          QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30012, matViewName, Arrays.toString(params)));

      String queryString =
          Reserved.SELECT
              + " * "
              + Reserved.FROM
              + ' '
              + matViewName
              + ' '
              + Reserved.WHERE
              + ' '
              + //$NON-NLS-1$
              criteria.toString()
              + ' '
              + Reserved.OPTION
              + ' '
              + Reserved.NOCACHE;
      final QueryProcessor qp =
          context
              .getQueryProcessorFactory()
              .createQueryProcessor(queryString, matViewName.toUpperCase(), context, params);
      final TupleSource ts = new BatchCollector.BatchProducerTupleSource(qp);
      return new ProxyTupleSource() {

        @Override
        protected TupleSource createTupleSource()
            throws TeiidComponentException, TeiidProcessingException {
          List<?> tuple = ts.nextTuple();
          boolean delete = false;
          if (tuple == null) {
            delete = true;
            tuple = Arrays.asList(params);
          } else {
            tuple = new ArrayList<Object>(tuple); // ensure the list is serializable
          }
          List<?> result = globalStore.updateMatViewRow(matTableName, tuple, delete);
          if (eventDistributor != null) {
            eventDistributor.updateMatViewRow(
                context.getVdbName(),
                context.getVdbVersion(),
                metadata.getName(metadata.getModelID(groupID)),
                metadata.getName(groupID),
                tuple,
                delete);
          }
          return CollectionTupleSource.createUpdateCountTupleSource(result != null ? 1 : 0);
        }

        @Override
        public void closeSource() {
          super.closeSource();
          qp.closeProcessing();
        }
      };
    }
    return null;
  }
  private TupleSource updateMatviewRows(
      final CommandContext context,
      final QueryMetadataInterface metadata,
      final Object groupID,
      final GlobalTableStore globalStore,
      final String matViewName,
      List<?> ids,
      Object[][] params)
      throws QueryProcessingException, TeiidComponentException, QueryMetadataException,
          TransformationException {
    final String matTableName = RelationalPlanner.MAT_PREFIX + matViewName.toUpperCase();
    MatTableInfo info = globalStore.getMatTableInfo(matTableName);
    if (!info.isValid()) {
      return CollectionTupleSource.createUpdateCountTupleSource(-1);
    }
    TempTable tempTable = globalStore.getTempTable(matTableName);
    if (!tempTable.isUpdatable()) {
      throw new QueryProcessingException(
          QueryPlugin.Event.TEIID30232,
          QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30232, matViewName));
    }

    List<Object[]> converted = new ArrayList<Object[]>();
    for (Object[] param : params) {
      if (param == null || ids.size() != param.length) {
        throw new QueryProcessingException(
            QueryPlugin.Event.TEIID30231,
            QueryPlugin.Util.gs(
                QueryPlugin.Event.TEIID30231,
                matViewName,
                ids.size(),
                param == null ? 0 : param.length));
      }
      final Object[] vals = new Object[param.length];
      for (int i = 0; i < ids.size(); i++) {
        Object value = param[i];
        String targetTypeName = metadata.getElementType(ids.get(i));
        value =
            DataTypeManager.transformValue(value, DataTypeManager.getDataTypeClass(targetTypeName));
        vals[i] = value;
      }
      converted.add(vals);
    }
    final Iterator<Object[]> paramIter = converted.iterator();

    Iterator<?> iter = ids.iterator();
    StringBuilder criteria = new StringBuilder();
    for (int i = 0; i < ids.size(); i++) {
      Object id = iter.next();
      String targetTypeName = metadata.getElementType(id);
      if (i != 0) {
        criteria.append(" AND "); // $NON-NLS-1$
      }
      criteria.append(metadata.getFullName(id)).append(" = ?"); // $NON-NLS-1$
    }

    final String queryString =
        Reserved.SELECT
            + " * "
            + Reserved.FROM
            + ' '
            + matViewName
            + ' '
            + Reserved.WHERE
            + ' '
            + //$NON-NLS-1$
            criteria.toString()
            + ' '
            + Reserved.OPTION
            + ' '
            + Reserved.NOCACHE;

    return new ProxyTupleSource() {
      private QueryProcessor qp;
      private TupleSource ts;
      private Object[] params;
      private int count;

      @Override
      protected TupleSource createTupleSource()
          throws TeiidComponentException, TeiidProcessingException {
        while (true) {
          if (qp == null) {
            params = paramIter.next();
            LogManager.logInfo(
                LogConstants.CTX_MATVIEWS,
                QueryPlugin.Util.gs(
                    QueryPlugin.Event.TEIID30012, matViewName, Arrays.toString(params)));
            qp =
                context
                    .getQueryProcessorFactory()
                    .createQueryProcessor(queryString, matViewName.toUpperCase(), context, params);
            ts = new BatchCollector.BatchProducerTupleSource(qp);
          }

          List<?> tuple = ts.nextTuple();
          boolean delete = false;
          if (tuple == null) {
            delete = true;
            tuple = Arrays.asList(params);
          } else {
            tuple = new ArrayList<Object>(tuple); // ensure the list is serializable
          }
          List<?> result = globalStore.updateMatViewRow(matTableName, tuple, delete);

          if (result != null) {
            count++;
          }

          if (eventDistributor != null) {
            eventDistributor.updateMatViewRow(
                context.getVdbName(),
                context.getVdbVersion(),
                metadata.getName(metadata.getModelID(groupID)),
                metadata.getName(groupID),
                tuple,
                delete);
          }

          qp.closeProcessing();
          qp = null;
          ts = null;

          if (!paramIter.hasNext()) {
            break;
          }
        }

        return CollectionTupleSource.createUpdateCountTupleSource(count);
      }

      @Override
      public void closeSource() {
        super.closeSource();
        if (qp != null) {
          qp.closeProcessing();
        }
      }
    };
  }