示例#1
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;
  }
示例#2
0
  private TupleSource registerQuery(
      final CommandContext context, final TempTableStore contextStore, final Query query) {
    final GroupSymbol group = query.getFrom().getGroups().get(0);
    if (!group.isTempGroupSymbol()) {
      return null;
    }
    final String tableName = group.getNonCorrelationName();
    if (group.isGlobalTable()) {
      TempMetadataID matTableId = (TempMetadataID) group.getMetadataID();
      final GlobalTableStore globalStore = getGlobalStore(context, matTableId);
      final MatTableInfo info = globalStore.getMatTableInfo(tableName);
      return new ProxyTupleSource() {
        Future<Void> moreWork = null;
        TupleSource loadingTupleSource;
        DQPWorkContext newWorkContext;

        @Override
        protected TupleSource createTupleSource()
            throws TeiidComponentException, TeiidProcessingException {
          if (loadingTupleSource != null) {
            load();
          } else {
            boolean load = false;
            if (!info.isUpToDate()) {
              boolean invalidate = true;
              VDBMetaData vdb = context.getVdb();
              if (vdb != null) {
                String val = vdb.getPropertyValue("lazy-invalidate"); // $NON-NLS-1$
                if (val != null) {
                  invalidate = !Boolean.valueOf(val);
                }
              }
              load =
                  globalStore.needsLoading(
                      tableName, globalStore.getAddress(), true, false, invalidate);
              if (load) {
                load =
                    globalStore.needsLoading(
                        tableName, globalStore.getAddress(), false, false, invalidate);
              }
              if (!load) {
                synchronized (info) {
                  if (!info.isUpToDate()) {
                    RequestWorkItem workItem = context.getWorkItem();
                    info.addWaiter(workItem);
                    if (moreWork != null) {
                      moreWork.cancel(false);
                    }
                    moreWork =
                        workItem.scheduleWork(10000); // fail-safe - attempt again in 10 seconds
                    throw BlockedException.block(
                        "Blocking on mat view load", tableName); // $NON-NLS-1$
                  }
                }
              } else {
                if (!info.isValid() || executor == null) {
                  // blocking load
                  // TODO: we should probably do all loads using a temp session
                  if (info.getVdbMetaData() != null
                      && context.getDQPWorkContext() != null
                      && !info.getVdbMetaData()
                          .getFullName()
                          .equals(context.getDQPWorkContext().getVDB().getFullName())) {
                    assert executor != null;
                    // load with by pretending we're in the imported vdb
                    newWorkContext = createWorkContext(context, info.getVdbMetaData());
                    CommandContext newContext = context.clone();
                    newContext.setNewVDBState(newWorkContext);
                    loadingTupleSource =
                        loadGlobalTable(
                            newContext, group, tableName, newContext.getGlobalTableStore());
                  } else {
                    loadingTupleSource = loadGlobalTable(context, group, tableName, globalStore);
                  }
                  load();
                } else {
                  loadViaRefresh(context, tableName, context.getDQPWorkContext().getVDB(), info);
                }
              }
            }
          }
          TempTable table = globalStore.getTempTable(tableName);
          context.accessedDataObject(group.getMetadataID());
          TupleSource result =
              table.createTupleSource(
                  query.getProjectedSymbols(), query.getCriteria(), query.getOrderBy());
          cancelMoreWork();
          return result;
        }

        private void load() throws TeiidComponentException, TeiidProcessingException {
          if (newWorkContext != null) {
            try {
              newWorkContext.runInContext(
                  new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                      loadingTupleSource.nextTuple();
                      return null;
                    }
                  });
            } catch (Throwable e) {
              rethrow(e);
            }
          } else {
            loadingTupleSource.nextTuple();
          }
        }

        private void cancelMoreWork() {
          if (moreWork != null) {
            moreWork.cancel(false);
            moreWork = null;
          }
        }

        @Override
        public void closeSource() {
          if (loadingTupleSource != null) {
            loadingTupleSource.closeSource();
          }
          super.closeSource();
          cancelMoreWork();
        }
      };
    }
    // it's not expected for a blocked exception to bubble up from here, so return a tuplesource to
    // perform getOrCreateTempTable
    return new ProxyTupleSource() {
      @Override
      protected TupleSource createTupleSource()
          throws TeiidComponentException, TeiidProcessingException {
        TempTableStore tts = contextStore;

        TempTable tt =
            tts.getOrCreateTempTable(tableName, query, bufferManager, true, false, context, group);
        if (context.getDataObjects() != null) {
          Object id = RelationalPlanner.getTrackableGroup(group, context.getMetadata());
          if (id != null) {
            context.accessedDataObject(id);
          }
        }
        return tt.createTupleSource(
            query.getProjectedSymbols(), query.getCriteria(), query.getOrderBy());
      }
    };
  }
示例#3
0
  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();
        }
      }
    };
  }