Пример #1
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());
      }
    };
  }