/** * @brief Convert the current object to a PostbreSQL Datum * * If the current object is Null, we still return <tt>Datum(0)</tt>, i.e., we * return a valid Datum. It is the responsibilty of the caller to separately * call isNull(). * * @param inFCInfo The PostgreSQL FunctionCallInfo that was passed to the UDF. * This is necessary for verifying that the top-level AnyType has the * correct type. */ inline Datum AbstractionLayer::AnyType::getAsDatum(const FunctionCallInfo inFCInfo) { consistencyCheck(); Oid targetTypeID; TupleDesc tupleDesc; TypeFuncClass funcClass; bool exceptionOccurred = false; PG_TRY(); { // FIXME: get_call_result_type is tagged as expensive in funcapi.c // It seems not to be necessary to release the tupleDesc // E.g., in plython.c ReleaseTupleDesc() is not called funcClass = get_call_result_type(inFCInfo, &targetTypeID, &tupleDesc); } PG_CATCH(); { exceptionOccurred = true; } PG_END_TRY(); if (exceptionOccurred) throw std::invalid_argument("An exception occurred while " "gathering inormation about the PostgreSQL return type."); bool targetIsComposite = (funcClass == TYPEFUNC_COMPOSITE); if (targetIsComposite && !isComposite()) throw std::logic_error("Invalid type conversion requested. " "Simple type supplied but PostgreSQL expects composite type."); if (!targetIsComposite && isComposite()) throw std::logic_error("Invalid type conversion requested. " "Composite type supplied but PostgreSQL expects simple type."); // tupleDesc can be NULL if the return type is not composite return getAsDatum(targetTypeID, isComposite(), tupleDesc); }
/* * Generate the .pyi file. */ void generateTypeHints(sipSpec *pt, moduleDef *mod, const char *pyiFile) { FILE *fp; /* Generate the file. */ if ((fp = fopen(pyiFile, "w")) == NULL) fatal("Unable to create file \"%s\"\n", pyiFile); /* Write the header. */ fprintf(fp, "# The PEP 484 type hints stub file for the %s module.\n" "#\n" "# Generated by SIP %s\n" , mod->name , sipVersion); prCopying(fp, mod, "#"); fprintf(fp, "\n" "\n" ); if (isComposite(mod)) pyiCompositeModule(pt, mod, fp); else pyiModule(pt, mod, fp); fclose(fp); }
void SegmentedString::advanceAndUpdateLineNumberSlowCase() { if (m_currentString.length()) { if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExcludeLineNumbers()) { ++m_currentLine; // Plus 1 because numberOfCharactersConsumed value hasn't incremented yet; // it does with length() decrement below. m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1; } m_currentString.decrementLength(); if (!m_currentString.length()) advanceSubstring(); else m_currentString.incrementAndGetCurrentChar(); // Only need the ++ } else if (!isComposite()) { m_currentString.clear(); m_empty = true; m_fastPathFlags = NoFastPath; m_advanceFunc = &SegmentedString::advanceEmpty; m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar() : 0; }
void SegmentedString::advanceAndUpdateLineNumberSlowCase() { if (m_pushedChar1) { m_pushedChar1 = m_pushedChar2; m_pushedChar2 = 0; if (m_pushedChar1) { m_currentChar = m_pushedChar1; return; } updateAdvanceFunctionPointers(); } else if (m_currentString.m_length) { if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExcludeLineNumbers()) { ++m_currentLine; // Plus 1 because numberOfCharactersConsumed value hasn't incremented yet; it does with m_length decrement below. m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1; } if (--m_currentString.m_length == 0) advanceSubstring(); else m_currentString.incrementAndGetCurrentChar(); // Only need the ++ } else if (!isComposite()) { m_currentString.clear(); m_empty = true; m_fastPathFlags = NoFastPath; m_advanceFunc = &SegmentedString::advanceEmpty; m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0; }
void SegmentedString::setExcludeLineNumbers() { m_currentString.setExcludeLineNumbers(); if (isComposite()) { Deque<SegmentedSubstring>::iterator it = m_substrings.begin(); Deque<SegmentedSubstring>::iterator e = m_substrings.end(); for (; it != e; ++it) it->setExcludeLineNumbers(); } }
unsigned SegmentedString::length() const { unsigned length = m_currentString.length(); if (isComposite()) { Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); for (; it != e; ++it) length += it->length(); } return length; }
String SegmentedString::toString() const { StringBuilder result; m_currentString.appendTo(result); if (isComposite()) { Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); for (; it != e; ++it) it->appendTo(result); } return result.toString(); }
void SegmentedString::advanceSlowCase() { if (m_currentString.length()) { m_currentString.decrementLength(); if (!m_currentString.length()) advanceSubstring(); } else if (!isComposite()) { m_currentString.clear(); m_empty = true; m_fastPathFlags = NoFastPath; m_advanceFunc = &SegmentedString::advanceEmpty; m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar() : 0; }
/** * @brief Return the n-th element from a composite value * * To the user, AnyType is a fully recursive type: Each AnyType object can be a * composite object and be composed of a number of other AnyType objects. * On top of the C++ abstraction layer, function have a single-top level * AnyType object as parameter. */ inline AbstractionLayer::AnyType AbstractionLayer::AnyType::operator[](uint16_t inID) const { consistencyCheck(); if (isNull()) throw std::invalid_argument("Unexpected Null value in function " "argument."); if (!isComposite()) throw std::invalid_argument("Invalid type conversion requested. " "Expected composite type but got simple type."); if (mContent == ReturnComposite) return mChildren[inID]; Oid typeID = 0; bool isMutable = false; Datum datum = 0; bool isTuple = false; HeapTupleHeader pgTuple = NULL; try { if (mContent == FunctionComposite) { if (inID >= size_t(PG_NARGS())) throw std::out_of_range("Access behind end of argument list"); if (PG_ARGISNULL(inID)) return AnyType(); backendGetTypeIDForFunctionArg(inID, typeID, isMutable); datum = PG_GETARG_DATUM(inID); } else if (mContent == NativeComposite) backendGetTypeIDAndDatumForTupleElement(inID, typeID, datum); if (typeID == InvalidOid) throw std::invalid_argument("Backend returned invalid type ID."); backendGetIsCompositeTypeAndHeapTupleHeader(typeID, datum, isTuple, pgTuple); } catch (PGException &e) { throw std::invalid_argument("An exception occurred while " "gathering information about PostgreSQL function arguments."); } return isTuple ? AnyType(pgTuple, datum, typeID) : AnyType(datum, typeID, isMutable); }
void CCPACSMaterial::ReadCPACS(TixiDocumentHandle tixiHandle, const std::string &materialXPath) { Cleanup(); // check path if ( tixiCheckElement(tixiHandle, materialXPath.c_str()) != SUCCESS) { LOG(ERROR) << "Material definition" << materialXPath << " not found in CPACS file!" << std::endl; return; } // test whether composite or normal material std::string tempstring = materialXPath + "/materialUID"; char * matUID = NULL; if (tixiGetTextElement(tixiHandle, tempstring.c_str(), &matUID) == SUCCESS){ uid = matUID; is_composite = false; } else if (tixiGetTextElement(tixiHandle, std::string(materialXPath + "/compositeUID").c_str(), &matUID) == SUCCESS){ uid = matUID; is_composite = true; } else { throw CTiglError("Neither Material UID nor Composite UID specified in " + materialXPath, TIGL_ERROR); } // get thickness (not mandatory) tempstring = materialXPath + "/thickness"; if (tixiCheckElement(tixiHandle, tempstring.c_str())== SUCCESS) { if (tixiGetDoubleElement(tixiHandle, tempstring.c_str(), &thickness) != SUCCESS) { LOG(ERROR) << "Invalid material thickness in " << materialXPath; } } else if (tixiCheckElement(tixiHandle, std::string(materialXPath + "/thicknessScaling").c_str())== SUCCESS) { if (tixiGetDoubleElement(tixiHandle, std::string(materialXPath + "/thicknessScaling").c_str(), &thicknessScaling) != SUCCESS) { LOG(ERROR) << "Invalid composite thickness scaling in " << materialXPath; } } else { if (!isComposite()) { LOG(INFO) << "Thickness of Material " << materialXPath << " not set."; } else { LOG(INFO) << "Thickness scaling of Composite Material " << materialXPath << " not set."; } } isvalid = true; }
inline bool isPrime(long long unsigned int &number) { if(number < 4) return true; if(number % 2 == 0) return false; long long unsigned int base; for(int t = 0; t < TRIES; ++ t) { base = random(2, number - 2); if(isComposite(base, number)) return false; } return true; }
void SegmentedString::advanceSubstring() { if (isComposite()) { m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); m_currentString = m_substrings.takeFirst(); // If we've previously consumed some characters of the non-current // string, we now account for those characters as part of the current // string, not as part of "prior to current string." m_numberOfCharactersConsumedPriorToCurrentString -= m_currentString.numberOfCharactersConsumed(); updateAdvanceFunctionPointers(); } else { m_currentString.clear(); m_empty = true; m_fastPathFlags = NoFastPath; m_advanceFunc = &SegmentedString::advanceEmpty; m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } }
inline T AnyType::getAs() const { consistencyCheck(); if (isNull()) throw std::invalid_argument("Invalid type conversion. " "Null where not expected."); if (isComposite()) throw std::invalid_argument("Invalid type conversion. " "Composite type where not expected."); // Verify type OID if (TypeTraits<T>::oid != InvalidOid && mTypeID != TypeTraits<T>::oid) { std::stringstream errorMsg; errorMsg << "Invalid type conversion. Expected type ID " << TypeTraits<T>::oid; if (mSysInfo) errorMsg << " ('" << mSysInfo->typeInformation(TypeTraits<T>::oid)->getName() << "')"; errorMsg << " but got " << mTypeID; if (mSysInfo) errorMsg << " ('" << mSysInfo->typeInformation(mTypeID)->getName() << "')"; errorMsg << '.'; throw std::invalid_argument(errorMsg.str()); } // Verify type name if (TypeTraits<T>::typeName() && std::strncmp(mTypeName, TypeTraits<T>::typeName(), NAMEDATALEN)) { std::stringstream errorMsg; errorMsg << "Invalid type conversion. Expected type '" << TypeTraits<T>::typeName() << "' but backend type name is '" << mTypeName << "' (ID " << mTypeID << ")."; } bool needMutableClone = (TypeTraits<T>::isMutable && !mIsMutable); return TypeTraits<T>::toCXXType(mDatum, needMutableClone, mSysInfo); }
T AbstractionLayer::AnyType::getAs() const { consistencyCheck(); if (isNull()) throw std::invalid_argument("Invalid type conversion requested. Got " "Null from backend."); if (isComposite()) throw std::invalid_argument("Invalid type conversion requested. " "Expected simple or array type but got composite type from " "backend."); if (mTypeID != TypeTraits<T>::oid) throw std::invalid_argument( "Invalid type conversion requested. PostgreSQL type does not match " "C++ type."); bool needMutableClone = (TypeTraits<T>::isMutable && !mIsMutable); return TypeTraits<T>::toCXXType(mDatum, needMutableClone); }
void SegmentedString::advanceSlowCase() { if (m_pushedChar1) { m_pushedChar1 = m_pushedChar2; m_pushedChar2 = 0; if (m_pushedChar1) { m_currentChar = m_pushedChar1; return; } updateAdvanceFunctionPointers(); } else if (m_currentString.m_length) { if (--m_currentString.m_length == 0) advanceSubstring(); } else if (!isComposite()) { m_currentString.clear(); m_empty = true; m_fastPathFlags = NoFastPath; m_advanceFunc = &SegmentedString::advanceEmpty; m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0; }
/** * @brief A built-in module type is part of nmlib, and not created by the user. */ bool isBuiltin() const { return !isComposite(); //subject to change (some builtins may become composites in the future }
/** * @brief Return a PostgreSQL Datum representing the current object * * If the current object is Null, we still return <tt>Datum(0)</tt>, i.e., we * return a valid Datum. It is the responsibilty of the caller to separately * call isNull(). * * The only *conversion* taking place in this function is *combining* Datums * into a tuple. At this place, we do not have to worry any more about retaining * memory. * * @param inFnCallInfo The PostgreSQL FunctionCallInfo that was passed to the * UDF. For polymorphic functions or functions that return RECORD, the * function-call information (specifically, the expression parse tree) * is necessary to dynamically resolve type information. * @param inTargetTypeID PostgreSQL OID of the target type to convert to. If * omitted the target type is the return type of the function specified by * \c inFnCallInfo. * * @see getAsDatum(const FunctionCallInfo) */ inline Datum AnyType::getAsDatum(FunctionCallInfo inFnCallInfo, Oid inTargetTypeID) const { consistencyCheck(); // The default value to return in case of Null is 0. Note, however, that // 0 can also be a perfectly valid (non-null) Datum. It is the caller's // responsibility to call isNull() separately. if (isNull()) return 0; // Note: mSysInfo is NULL if this object was not an argument from the // backend. SystemInformation* sysInfo = SystemInformation::get(inFnCallInfo); FunctionInformation* funcInfo = sysInfo ->functionInformation(inFnCallInfo->flinfo->fn_oid); TupleDesc targetTupleDesc; if (inTargetTypeID == InvalidOid) { inTargetTypeID = funcInfo->getReturnType(inFnCallInfo); // If inTargetTypeID is \c RECORDOID, the tuple description needs to be // derived from the function call targetTupleDesc = funcInfo->getReturnTupleDesc(inFnCallInfo); } else { // If we are here, we should not see inTargetTypeID == RECORDOID because // that should only happen for the first non-recursive call of // getAsDatum where inTargetTypeID == InvalidOid by default. // If it would happen, then the following would return NULL and an // exception would be raised a few line below. So no need to add a check // here. targetTupleDesc = sysInfo->typeInformation(inTargetTypeID) ->getTupleDesc(); } bool targetIsComposite = targetTupleDesc != NULL; Datum returnValue = mDatum; if (targetIsComposite && !isComposite()) throw std::runtime_error("Invalid type conversion. " "Simple type supplied but backend expects composite type."); if (!targetIsComposite && isComposite()) throw std::runtime_error("Invalid type conversion. " "Composite type supplied but backend expects simple type."); if (targetIsComposite) { if (static_cast<size_t>(targetTupleDesc->natts) < mChildren.size()) throw std::runtime_error("Invalid type conversion. " "Internal composite type has more elements than backend " "composite type."); std::vector<Datum> values; std::vector<char> nulls; for (uint16_t pos = 0; pos < mChildren.size(); ++pos) { Oid targetTypeID = targetTupleDesc->attrs[pos]->atttypid; values.push_back(mChildren[pos].getAsDatum(inFnCallInfo, targetTypeID)); nulls.push_back(mChildren[pos].isNull()); } // All elements that have not been initialized will be set to Null for (uint16_t pos = mChildren.size(); pos < static_cast<size_t>(targetTupleDesc->natts); ++pos) { values.push_back(Datum(0)); nulls.push_back(true); } HeapTuple heapTuple = madlib_heap_form_tuple(targetTupleDesc, &values[0], reinterpret_cast<bool*>(&nulls[0])); // BACKEND: HeapTupleGetDatum is a macro that will not cause an // exception returnValue = HeapTupleGetDatum(heapTuple); } else { /* if (!targetIsComposite) */ if (mTypeID != InvalidOid && inTargetTypeID != mTypeID) { std::stringstream errorMsg; errorMsg << "Invalid type conversion. " "Backend expects type ID " << inTargetTypeID << " ('" << sysInfo->typeInformation(inTargetTypeID)->getName() << "') " "but supplied type ID is " << mTypeID << + " ('" << sysInfo->typeInformation(mTypeID)->getName() << "')."; throw std::invalid_argument(errorMsg.str()); } if (mTypeName && std::strncmp(mTypeName, sysInfo->typeInformation(inTargetTypeID)->getName(), NAMEDATALEN)) { std::stringstream errorMsg; errorMsg << "Invalid type conversion. Backend expects type '" << sysInfo->typeInformation(inTargetTypeID)->getName() << "' (ID " << inTargetTypeID << ") but internal type name is '" << mTypeName << "'."; throw std::invalid_argument(errorMsg.str()); } } return returnValue; }
/** * @brief Return the n-th element from a composite value * * To the user, AnyType is a fully recursive type: Each AnyType object can be a * composite object and be composed of a number of other AnyType objects. * Function written using the C++ abstraction layer have a single logical * argument of type AnyType. */ inline AnyType AnyType::operator[](uint16_t inID) const { consistencyCheck(); if (isNull()) { // Handle case mContent == NULL throw std::invalid_argument("Invalid type conversion. " "Null where not expected."); } if (!isComposite()) { // Handle case mContent == Scalar throw std::invalid_argument("Invalid type conversion. " "Composite type where not expected."); } if (mContent == ReturnComposite) return mChildren[inID]; // It holds now that mContent is either FunctionComposite or NativeComposite // In this case, it is guaranteed that fcinfo != NULL Oid typeID = 0; bool isMutable = false; Datum datum = 0; if (mContent == FunctionComposite) { // This AnyType object represents to composite value consisting of all // function arguments if (inID >= size_t(PG_NARGS())) throw std::out_of_range("Invalid type conversion. Access behind " "end of argument list."); if (PG_ARGISNULL(inID)) return AnyType(); typeID = mSysInfo->functionInformation(fcinfo->flinfo->fn_oid) ->getArgumentType(inID, fcinfo->flinfo); if (inID == 0) { // If we are called as an aggregate function, the first argument is // the transition state. In that case, we are free to modify the // data. In fact, for performance reasons, we *should* even do all // modifications in-place. In all other cases, directly modifying // memory is dangerous. // See warning at: // http://www.postgresql.org/docs/current/static/xfunc-c.html#XFUNC-C-BASETYPE // BACKEND: AggCheckCallContext currently will never raise an // exception isMutable = AggCheckCallContext(fcinfo, NULL); } datum = PG_GETARG_DATUM(inID); } else { /* if (mContent == NativeComposite) */ // This AnyType objects represents a tuple that was passed from the // backend TupleDesc tupdesc = mSysInfo ->typeInformation(HeapTupleHeaderGetTypeId(mTupleHeader)) ->getTupleDesc(HeapTupleHeaderGetTypMod(mTupleHeader)); if (inID >= tupdesc->natts) throw std::out_of_range("Invalid type conversion. Access behind " "end of composite object."); typeID = tupdesc->attrs[inID]->atttypid; bool isNull = false; datum = madlib_GetAttributeByNum(mTupleHeader, inID, &isNull); if (isNull) return AnyType(); } if (typeID == InvalidOid) throw std::invalid_argument("Backend returned invalid type ID."); return mSysInfo->typeInformation(typeID)->isCompositeType() ? AnyType(mSysInfo, madlib_DatumGetHeapTupleHeader(datum), datum, typeID) : AnyType(mSysInfo, datum, typeID, isMutable); }
void SegmentedString::advanceEmpty() { ASSERT(!m_currentString.m_length && !isComposite()); m_currentChar = 0; }
inline CubitBoolean CompositeTool:: isComposite( const BasicTopologyEntity* bte_ptr ) const { return bte_ptr ? isComposite(bte_ptr->get_geometry_entity_ptr()) : CUBIT_FALSE; }
/** * @brief Return a PostgreSQL Datum representing the current object * * The only *conversion* taking place in this function is *combining* Datums * into a tuple. At this place, we do not have to worry any more about retaining * memory. * * @param inTargetTypeID PostgreSQL OID of the target type to convert to * @param inTargetIsComposite Whether the target type is composite. * \c indeterminate if unknown. * @param inTargetTupleDesc If target type is known to be composite, then * (optionally) the PostgreSQL TupleDesc. NULL is always a valid argument. * * @see getAsDatum(const FunctionCallInfo) */ inline Datum AbstractionLayer::AnyType::getAsDatum(Oid inTargetTypeID, boost::tribool inTargetIsComposite, TupleDesc inTargetTupleDesc) const { consistencyCheck(); // The default value to return in case of Null is 0. Note, however, that // 0 can also be a perfectly valid (non-null) Datum. It is the caller's // responsibility to call isNull() separately. if (isNull()) return 0; try { bool exceptionOccurred = false; TupleHandle tupleHandle(inTargetTupleDesc); if (boost::indeterminate(inTargetIsComposite)) { inTargetIsComposite = isRowTypeInCache(inTargetTypeID); backendGetIsCompositeTypeAndTupleHandle(inTargetTypeID, inTargetIsComposite, tupleHandle); } if (inTargetIsComposite && !isComposite()) throw std::runtime_error("Invalid type conversion requested. " "Simple type supplied but PostgreSQL expects composite type."); if (!inTargetIsComposite && isComposite()) throw std::runtime_error("Invalid type conversion requested. " "Composite type supplied but PostgreSQL expects simple type."); madlib_assert(inTargetIsComposite == (tupleHandle.desc != NULL), MADLIB_DEFAULT_EXCEPTION); if (inTargetIsComposite) { if (static_cast<size_t>(tupleHandle.desc->natts) < mChildren.size()) throw std::runtime_error("Invalid type conversion requested. " "Internal composite type has more elements than PostgreSQL " "composite type."); std::vector<Datum> values; std::vector<char> nulls; for (uint16_t pos = 0; pos < mChildren.size(); ++pos) { Oid targetTypeID = tupleHandle.desc->attrs[pos]->atttypid; values.push_back(mChildren[pos].getAsDatum(targetTypeID)); nulls.push_back(mChildren[pos].isNull()); } // All elements that have not been initialized will be set to Null for (uint16_t pos = mChildren.size(); pos < static_cast<size_t>(tupleHandle.desc->natts); ++pos) { values.push_back(Datum(0)); nulls.push_back(true); } Datum returnValue; PG_TRY(); { HeapTuple heapTuple = heap_form_tuple(tupleHandle.desc, &values[0], reinterpret_cast<bool*>(&nulls[0])); returnValue = HeapTupleGetDatum(heapTuple); } PG_CATCH(); { exceptionOccurred = true; } PG_END_TRY(); if (exceptionOccurred) throw PGException(); return returnValue; } } catch (PGException &e) { throw std::invalid_argument("An exception occurred while " "gathering inormation about the PostgreSQL return type."); } if (inTargetTypeID != mTypeID) throw std::invalid_argument("Invalid type conversion requested. " "C++ type and PostgreSQL return type do not match."); return mDatum; }