Beispiel #1
0
ASTNode *DbXmlStaticTyper::optimizeDbXmlPredicate(DbXmlPredicate *item)
{
	item->setExpression(optimize(item->getExpression()));

	AutoContextItemTypeReset contextTypeReset(context_);
	VariableTypeStore* varStore = context_ ? context_->getVariableTypeStore() : 0;

	if(context_) {
		StaticAnalysis &varSrc = item->getVarSRC();

		varSrc.getStaticType() = item->getExpression()->getStaticAnalysis().getStaticType();
		varSrc.setProperties(StaticAnalysis::DOCORDER | StaticAnalysis::GROUPED |
			StaticAnalysis::PEER | StaticAnalysis::SUBTREE | StaticAnalysis::SAMEDOC |
			StaticAnalysis::ONENODE | StaticAnalysis::SELF);

		if(item->getName() == 0) {
			context_->setContextItemType(varSrc.getStaticType());
		} else {
			varStore->addLogicalBlockScope();
			varStore->declareVar(item->getURI(), item->getName(), varSrc);
		}
	}

	item->setPredicate(optimize(const_cast<ASTNode *>(item->getPredicate())));

	if(context_ && item->getName() != 0) {
		varStore->removeScope();
	}

	return item;
}
Beispiel #2
0
void XQGlobalVariable::staticTyping(StaticContext* context, StaticTyper *styper)
{
  VariableTypeStore* varStore = context->getVariableTypeStore();

  if(m_Value != NULL) {
    XQUserFunction::staticTypeFunctionCalls(m_Value, context, styper);

    m_Value = m_Value->staticTyping(context, styper);
    _src.copy(m_Value->getStaticAnalysis());

    if(m_Value->getStaticAnalysis().isUpdating()) {
      XQThrow(StaticErrorException,X("XQGlobalVariable::staticTyping"),
              X("It is a static error for the initializing expression of a global variable "
                "to be an updating expression [err:XUST0001]"));
    }
  }

  if(m_Value == 0 || !required_) {
    if(m_Type != 0) {
      bool isPrimitive;
      m_Type->getStaticType(_src.getStaticType(), context, isPrimitive, m_Type);
    }
    else {
      _src.getStaticType() = StaticType(StaticType::ITEM_TYPE, 0, StaticType::UNLIMITED);
    }
  }

  varStore->declareGlobalVar(m_szURI, m_szLocalName, _src);
}
Beispiel #3
0
void XQQuery::staticTyping(StaticTyper *styper)
{
  StaticContext *context = m_context;

  StaticTyper defaultTyper;
  if(styper == 0) styper = &defaultTyper;

  VariableTypeStore* varStore = context->getVariableTypeStore();

  // Static type the imported modules (again)
  ImportedModules::const_iterator modIt;
  for(modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) {
    (*modIt)->staticTyping(styper);
  }  

  // Define types for the imported variables
  for(modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) {
    for(GlobalVariables::const_iterator varIt = (*modIt)->m_userDefVars.begin();
        varIt != (*modIt)->m_userDefVars.end(); ++varIt) {
      varStore->declareGlobalVar((*varIt)->getVariableURI(), (*varIt)->getVariableLocalName(),
                                 (*varIt)->getStaticAnalysis());
    }
  }

  // Run staticTyping on the global variables
  if(!m_userDefVars.empty()) {
    // declare all the global variables with a special StaticAnalysis, in order to recognize 'variable is defined
    // later' errors instead of more generic 'variable not found'. In order to catch references to not yet defined
    // variables (but when no recursion happens) we also create a scope where we undefine the rest of the variables (once
    // we enter in a function call, the scope will disappear and the forward references to the global variables will
    // appear).
    StaticAnalysis forwardRef(context->getMemoryManager());
    forwardRef.setProperties(StaticAnalysis::FORWARDREF);

    StaticAnalysis undefinedVar(context->getMemoryManager());
    undefinedVar.setProperties(StaticAnalysis::UNDEFINEDVAR);

    GlobalVariables::iterator itVar, itVar2;
    for(itVar = m_userDefVars.begin(); itVar != m_userDefVars.end(); ++itVar) {
      varStore->declareGlobalVar((*itVar)->getVariableURI(), (*itVar)->getVariableLocalName(),
                                 forwardRef);
    }

    for(itVar = m_userDefVars.begin(); itVar != m_userDefVars.end(); ++itVar) {
      varStore->addLogicalBlockScope();
      for(itVar2 = itVar; itVar2 != m_userDefVars.end(); ++itVar2) {
        varStore->declareVar((*itVar2)->getVariableURI(), (*itVar2)->getVariableLocalName(),
                             undefinedVar);
      }
      (*itVar)->staticTyping(context, styper);
      varStore->removeScope();
    }
  }

  // Run staticTyping on the user defined functions,
  // which calculates a better type for them
  UserFunctions::iterator i, j;
  for(i = m_userDefFns.begin(); i != m_userDefFns.end(); ++i) {
    for(j = m_userDefFns.begin(); j != m_userDefFns.end(); ++j) {
      (*j)->resetStaticTypingOnce();
    }

    (*i)->staticTypingOnce(context, styper);
  }

  // Run staticTyping on the query body
  if(m_query) m_query = m_query->staticTyping(context, styper);
}
Beispiel #4
0
void XQUserFunction::staticTyping(StaticContext *context, StaticTyper *styper)
{
  // Nothing more to do for external functions
  if(body_ == NULL) return;

  if(signature_->updating == FunctionSignature::OP_TRUE && signature_->returnType != NULL) {
    XQThrow(StaticErrorException, X("XQUserFunction::staticTyping"),
            X("It is a static error for an updating function to declare a return type [err:XUST0028]"));
  }

  // Find user defined functions and templates that are referenced in our body,
  // and try to call staticTyping() on them before us.
  if(context) staticTypeFunctionCalls(body_, context, styper);

  bool ciTypeSet = false;
  StaticType ciType = StaticType();
  if(pattern_ != NULL) {
    VectorOfASTNodes::iterator patIt = pattern_->begin();
    for(; patIt != pattern_->end(); ++patIt) {
      (*patIt) = (*patIt)->staticTyping(context, styper);
      if(!ciTypeSet) {
        ciTypeSet = true;
        ciType = (*patIt)->getStaticAnalysis().getStaticType();
      }
      else ciType |= (*patIt)->getStaticAnalysis().getStaticType();
    }
    if(ciTypeSet) {
      ciType.setCardinality(1, 1);
    }
  }
  if(isTemplate_ && name_ != 0) {
    // Named template
    ciTypeSet = true;
    ciType = StaticType::ITEM_TYPE;
  }

  // define the new variables in a new scope and assign them the proper values
  if(context) {
    VariableTypeStore *varStore = context->getVariableTypeStore();

    if(isGlobal_) varStore->addLocalScope();
    else varStore->addLogicalBlockScope();

    // Declare the parameters
    if(signature_->argSpecs) {
      ArgumentSpecs::iterator it;
      for(it = signature_->argSpecs->begin(); it != signature_->argSpecs->end (); ++it) {
        varStore->declareVar((*it)->getURI(), (*it)->getName(), (*it)->getStaticAnalysis());
      }
    }
  }

  {
    // Declare the context item
    AutoContextItemTypeReset contextTypeReset(context, ciType);
    body_ = body_->staticTyping(context, styper);
  }

  if(context)
    context->getVariableTypeStore()->removeScope();

  if(signature_->updating == FunctionSignature::OP_TRUE) {
    if(!body_->getStaticAnalysis().isUpdating() && !body_->getStaticAnalysis().isPossiblyUpdating())
      XQThrow(StaticErrorException, X("XQUserFunction::staticTyping"),
              X("It is a static error for the body expression of a user defined updating function "
                "not to be an updating expression [err:XUST0002]"));
  }
  else {
    if(body_->getStaticAnalysis().isUpdating()) {
      if(isTemplate_) {
        XQThrow(StaticErrorException, X("XQUserFunction::staticTyping"),
                X("It is a static error for the body expression of a template "
                  "to be an updating expression [err:XUST0001]"));
      } else {
        XQThrow(StaticErrorException, X("XQUserFunction::staticTyping"),
                X("It is a static error for the body expression of a user defined function "
                  "to be an updating expression [err:XUST0001]"));
      }
    }
  }

  // Remove the parameter variables from the stored StaticAnalysis
  src_.clear();
  src_.copy(body_->getStaticAnalysis());
  if(signature_->argSpecs) {
    for(ArgumentSpecs::iterator it = signature_->argSpecs->begin(); it != signature_->argSpecs->end (); ++it) {
      if(!src_.removeVariable((*it)->getURI(), (*it)->getName())) {
        // The parameter isn't used, so set it to null, so that we don't bother to evaluate it
        (*it)->setNotUsed();
      }
    }
  }

  // Run staticTyping on the template instances
  if(templateInstance_ != 0 && context) {
    StaticAnalysis templateVarSrc(context->getMemoryManager());
    templateVarSrc.getStaticType() = StaticType::ITEM_TYPE;

    VariableTypeStore *varStore = context->getVariableTypeStore();
    varStore->addLogicalBlockScope();

    if(signature_->argSpecs != 0) {
      ArgumentSpecs::const_iterator argIt;
      for(argIt = signature_->argSpecs->begin(); argIt != signature_->argSpecs->end(); ++argIt) {
        varStore->declareVar((*argIt)->getURI(), (*argIt)->getName(), templateVarSrc);
      }
    }

    // Turn off warnings here, since they are largely irrelevent to the user
    AutoMessageListenerReset reset(context);

    templateInstance_ = templateInstance_->staticTyping(context, styper);

    varStore->removeScope();
  }
}
Beispiel #5
0
void XQQuery::staticTyping(StaticTyper *styper)
{
  StaticTyper defaultTyper;
  if(styper == 0) styper = &defaultTyper;

  // Static type the imported modules (again)
  ImportedModules::const_iterator modIt;
  if(m_moduleCacheOwned) {
    for(modIt = m_moduleCache->ordered_.begin(); modIt != m_moduleCache->ordered_.end(); ++modIt) {
      (*modIt)->staticTyping(styper);
    }
  }

  // Define types for the imported variables
  VariableTypeStore* varStore = m_context->getVariableTypeStore();
  GlobalVariables::const_iterator varIt;
  for(modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) {
    XQQuery *module = *modIt;
    for(; module; module = module->getNext()) {
      for(varIt = module->m_userDefVars.begin(); varIt != module->m_userDefVars.end(); ++varIt) {
        varStore->declareGlobalVar((*varIt)->getVariableURI(), (*varIt)->getVariableLocalName(),
                                   (*varIt)->getStaticAnalysis(), *varIt);
      }
    }
  }

  // Set up a default type for the global variables
  for(varIt = m_userDefVars.begin(); varIt != m_userDefVars.end(); ++varIt) {
    (*varIt)->resetStaticTypingOnce();
    varStore->declareGlobalVar((*varIt)->getVariableURI(), (*varIt)->getVariableLocalName(),
                               (*varIt)->getStaticAnalysis(), *varIt);
  }

  UserFunctions::const_iterator i, j;
  {
    GlobalVariables globalsOrder(XQillaAllocator<XQGlobalVariable*>(m_context->getMemoryManager()));
    AutoReset<GlobalVariables*> autoReset(styper->getGlobalsOrder());
    styper->getGlobalsOrder() = &globalsOrder;

    // Run staticTyping on the global variables
    for(varIt = m_userDefVars.begin(); varIt != m_userDefVars.end(); ++varIt) {
      for(j = m_userDefFns.begin(); j != m_userDefFns.end(); ++j) {
        (*j)->resetStaticTypingOnce();
      }

      (*varIt)->staticTypingOnce(m_context, styper);
    }

    // XQuery 1.1 reorders the global variables to enable forward references
    if(m_version3)
      m_userDefVars = globalsOrder;
  }

  // Run staticTyping on the user defined functions,
  // which calculates a better type for them
  for(i = m_userDefFns.begin(); i != m_userDefFns.end(); ++i) {
    for(j = m_userDefFns.begin(); j != m_userDefFns.end(); ++j) {
      (*j)->resetStaticTypingOnce();
    }

    (*i)->staticTypingOnce(m_context, styper);
  }

  // Run staticTyping on the query body
  if(m_query) m_query = m_query->staticTyping(m_context, styper);
}