const ModelType *ModelData::findType(OovStringRef const name) const { const ModelType *type = nullptr; #if(BINARYSPEED) // This comparison must produce the same sort order as addType. std::string baseTypeName = getBaseType(name); auto iter = std::lower_bound(mTypes.begin(), mTypes.end(), baseTypeName, [](std::unique_ptr<ModelType> const &mod1, OovStringRef const mod2Name) -> bool { return(compareStrs(mod1->getName(), mod2Name)); } ); if(iter != mTypes.end()) { if(baseTypeName.compare((*iter)->getName()) == 0) type = (*iter).get(); } #else std::string baseTypeName = getBaseType(name); for(auto &iterType : mTypes) { if(iterType->getName().compare(baseTypeName) == 0) { type = iterType; break; } } #endif return type; }
MInstrEffects::MInstrEffects(const Opcode rawOp, const Type origBase) { // Note: MInstrEffects wants to manipulate pointer types in some situations // for historical reasons. We'll eventually change that. bool const is_ptr = origBase <= TPtrToGen; auto const basePtr = is_ptr ? origBase.ptrKind() : Ptr::Unk; baseType = origBase.derefIfPtr(); baseTypeChanged = baseValChanged = false; // Process the inner and outer types separately and then recombine them, // since the minstr operations all operate on the inner cell of boxed bases. // We treat the new inner type as a prediction because it will be verified // the next time we load from the box. auto inner = (baseType & TBoxedCell).inner(); auto outer = baseType & TCell; getBaseType(rawOp, false, outer, baseValChanged); getBaseType(rawOp, true, inner, baseValChanged); baseType = inner.box() | outer; baseType = is_ptr ? baseType.ptr(basePtr) : baseType; baseTypeChanged = baseType != origBase; /* Boxed bases may have their inner value changed but the value of the box * will never change. */ baseValChanged = !(origBase <= TBoxedCell) && (baseValChanged || baseTypeChanged); }
MInstrEffects::MInstrEffects(const Opcode rawOp, const Type origBase) { baseType = origBase; // Note: MInstrEffects wants to manipulate pointer types in some situations // for historical reasons. We'll eventually change that. always_assert(baseType.isPtr() ^ baseType.notPtr()); auto const basePtr = baseType.isPtr(); auto const basePtrKind = basePtr ? baseType.ptrKind() : Ptr::Unk; baseType = baseType.derefIfPtr(); // Only certain types of bases are supported now but this list may expand in // the future. assert_not_implemented(basePtr || baseType.subtypeOfAny(Type::Obj, Type::Arr)); baseTypeChanged = baseValChanged = false; // Process the inner and outer types separately and then recombine them, // since the minstr operations all operate on the inner cell of boxed // bases. We treat the new inner type as a prediction because it will be // verified the next time we load from the box. auto inner = (baseType & Type::BoxedCell).innerType(); auto outer = baseType & Type::Cell; getBaseType(rawOp, false, outer, baseValChanged); getBaseType(rawOp, true, inner, baseValChanged); baseType = inner.box() | outer; baseType = basePtr ? baseType.ptr(basePtrKind) : baseType; baseTypeChanged = baseType != origBase; /* Boxed bases may have their inner value changed but the value of the box * will never change. */ baseValChanged = !origBase.isBoxed() && (baseValChanged || baseTypeChanged); }
std::string VolumeOctreeBase::getFormat() const { tgtAssert(getNumChannels() > 0, "invalid number of channels"); if (numChannels_ == 1) return getBaseType(); else return "Vector" + itos(getNumChannels()) + "(" + getBaseType() + ")"; }
bool isGreenplumDbHashable(Oid typid) { /* we can hash all arrays */ if (typeIsArrayType(typid)) return true; /* * if this type is a domain type, get its base type. */ if (get_typtype(typid) == 'd') typid = getBaseType(typid); switch(typid) { case INT2OID: case INT4OID: case INT8OID: case FLOAT4OID: case FLOAT8OID: case NUMERICOID: case CHAROID: case BPCHAROID: case TEXTOID: case VARCHAROID: case BYTEAOID: case NAMEOID: case OIDOID: case TIDOID: case REGPROCOID: case REGPROCEDUREOID: case REGOPEROID: case REGOPERATOROID: case REGCLASSOID: case REGTYPEOID: case TIMESTAMPOID: case TIMESTAMPTZOID: case DATEOID: case TIMEOID: case TIMETZOID: case INTERVALOID: case ABSTIMEOID: case RELTIMEOID: case TINTERVALOID: case INETOID: case CIDROID: case MACADDROID: case BITOID: case VARBITOID: case BOOLOID: case ACLITEMOID: case ANYARRAYOID: case INT2VECTOROID: case OIDVECTOROID: case CASHOID: return true; default: return false; } }
static void PLy_output_datum_func2(PLyObToDatum *arg, HeapTuple typeTup) { Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup); Oid element_type; perm_fmgr_info(typeStruct->typinput, &arg->typfunc); arg->typoid = HeapTupleGetOid(typeTup); arg->typmod = -1; arg->typioparam = getTypeIOParam(typeTup); arg->typbyval = typeStruct->typbyval; element_type = get_base_element_type(arg->typoid); /* * Select a conversion function to convert Python objects to PostgreSQL * datums. Most data types can go through the generic function. */ switch (getBaseType(element_type ? element_type : arg->typoid)) { case BOOLOID: arg->func = PLyObject_ToBool; break; case BYTEAOID: arg->func = PLyObject_ToBytea; break; default: arg->func = PLyObject_ToDatum; break; } /* Composite types need their own input routine, though */ if (typeStruct->typtype == TYPTYPE_COMPOSITE) { arg->func = PLyObject_ToComposite; } if (element_type) { char dummy_delim; Oid funcid; if (type_is_rowtype(element_type)) arg->func = PLyObject_ToComposite; arg->elm = PLy_malloc0(sizeof(*arg->elm)); arg->elm->func = arg->func; arg->func = PLySequence_ToArray; arg->elm->typoid = element_type; arg->elm->typmod = -1; get_type_io_data(element_type, IOFunc_input, &arg->elm->typlen, &arg->elm->typbyval, &arg->elm->typalign, &dummy_delim, &arg->elm->typioparam, &funcid); perm_fmgr_info(funcid, &arg->elm->typfunc); } }
TYPE_DESC getBaseType(TYPE_DESC tp) { if (TYPE_REF(tp) != NULL) { return getBaseType(TYPE_REF(tp)); } else { return tp; } }
ModelType *ModelData::createOrGetTypeRef(OovStringRef const typeName, eModelDataTypes dtype) { std::string baseTypeName = getBaseType(typeName); ModelType *type = findType(baseTypeName); if(!type) { type = static_cast<ModelType*>(createDataType(dtype, baseTypeName)); } return type; }
/* * Check if datatype is the specified type or equivalent to it. * * Note: we could just do getBaseType() unconditionally, but since that's * a relatively expensive catalog lookup that most users won't need, we * try the straight comparison first. */ static bool is_expected_type(Oid typid, Oid expected_type) { if (typid == expected_type) return true; typid = getBaseType(typid); if (typid == expected_type) return true; return false; }
void DeclarationASTNode::declareSymbols() { getBaseType(); for (DeclaratorList::iterator it = declarators->begin(); it != declarators->end(); ++it) { DeclaratorASTNode *decl = *it; decl->makeSymbol(*baseType); } }
/* Check if datatype is TEXT or binary-equivalent to it */ static bool is_text_type(Oid typid) { /* varchar(n) and char(n) are binary-compatible with text */ if (typid == TEXTOID || typid == VARCHAROID || typid == BPCHAROID) return true; /* Allow domains over these types, too */ typid = getBaseType(typid); if (typid == TEXTOID || typid == VARCHAROID || typid == BPCHAROID) return true; return false; }
void ModelData::addType(std::unique_ptr<ModelType> &&type) { #if(BINARYSPEED) std::string baseTypeName = getBaseType(type->getName()); type->setName(baseTypeName); auto it = std::upper_bound(mTypes.begin(), mTypes.end(), baseTypeName, [](OovStringRef const mod1Name, std::unique_ptr<ModelType> &mod2) -> bool { return(compareStrs(mod1Name, mod2->getName())); } ); mTypes.insert(it, std::move(type)); #else mTypes.push_back(type); #endif }
void CLinearMapping::writeParamsToStream(ostream& out) const { writeToStream(out, "baseType", getBaseType()); writeToStream(out, "type", getType()); writeToStream(out, "numData", getNumData()); writeToStream(out, "outputDim", getOutputDim()); writeToStream(out, "inputDim", getInputDim()); writeToStream(out, "numParams", getOptNumParams()); CMatrix par(1, getOptNumParams()); getOptParams(par); par.toStream(out); }
void CLinearMapping::readParamsFromStream(istream& in) { string tbaseType = getBaseTypeStream(in); if(tbaseType != getBaseType()) throw ndlexceptions::StreamFormatError("baseType", "Error mismatch between saved base type, " + tbaseType + ", and Class base type, " + getType() + "."); string ttype = getTypeStream(in); if(ttype != getType()) throw ndlexceptions::StreamFormatError("type", "Error mismatch between saved type, " + ttype + ", and Class type, " + getType() + "."); setNumData(readIntFromStream(in, "numData")); setOutputDim(readIntFromStream(in, "outputDim")); setInputDim(readIntFromStream(in, "inputDim")); initStoreage(); unsigned int nPar = readIntFromStream(in, "numParams"); if(nPar!=getOptNumParams()) throw ndlexceptions::StreamFormatError("numParams", "Number of parameters does not match."); CMatrix par(1, getOptNumParams()); par.fromStream(in); setOptParams(par); }
/* * Write type info to the output stream. * * This function will always write base type info. */ void logicalrep_write_typ(StringInfo out, Oid typoid) { Oid basetypoid = getBaseType(typoid); HeapTuple tup; Form_pg_type typtup; pq_sendbyte(out, 'Y'); /* sending TYPE */ tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(basetypoid)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", basetypoid); typtup = (Form_pg_type) GETSTRUCT(tup); /* use Oid as relation identifier */ pq_sendint(out, typoid, 4); /* send qualified type name */ logicalrep_write_namespace(out, typtup->typnamespace); pq_sendstring(out, NameStr(typtup->typname)); ReleaseSysCache(tup); }
/* binary_oper_exact() * Check for an "exact" match to the specified operand types. * * If one operand is an unknown literal, assume it should be taken to be * the same type as the other operand for this purpose. Also, consider * the possibility that the other operand is a domain type that needs to * be reduced to its base type to find an "exact" match. */ static Oid binary_oper_exact(List *opname, Oid arg1, Oid arg2) { Oid result; bool was_unknown = false; /* Unspecified type for one of the arguments? then use the other */ if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid)) { arg1 = arg2; was_unknown = true; } else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid)) { arg2 = arg1; was_unknown = true; } result = OpernameGetOprid(opname, arg1, arg2); if (OidIsValid(result)) return result; if (was_unknown) { /* arg1 and arg2 are the same here, need only look at arg1 */ Oid basetype = getBaseType(arg1); if (basetype != arg1) { result = OpernameGetOprid(opname, basetype, basetype); if (OidIsValid(result)) return result; } } return InvalidOid; }
/* * get_type_func_class * Given the type OID, obtain its TYPEFUNC classification. * Also, if it's a domain, return the base type OID. * * This is intended to centralize a bunch of formerly ad-hoc code for * classifying types. The categories used here are useful for deciding * how to handle functions returning the datatype. */ static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid) { *base_typeid = typid; switch (get_typtype(typid)) { case TYPTYPE_COMPOSITE: return TYPEFUNC_COMPOSITE; case TYPTYPE_BASE: case TYPTYPE_ENUM: case TYPTYPE_RANGE: return TYPEFUNC_SCALAR; case TYPTYPE_DOMAIN: *base_typeid = typid = getBaseType(typid); if (get_typtype(typid) == TYPTYPE_COMPOSITE) return TYPEFUNC_COMPOSITE_DOMAIN; else /* domain base type can't be a pseudotype */ return TYPEFUNC_SCALAR; case TYPTYPE_PSEUDO: if (typid == RECORDOID) return TYPEFUNC_RECORD; /* * We treat VOID and CSTRING as legitimate scalar datatypes, * mostly for the convenience of the JDBC driver (which wants to * be able to do "SELECT * FROM foo()" for all legitimately * user-callable functions). */ if (typid == VOIDOID || typid == CSTRINGOID) return TYPEFUNC_SCALAR; return TYPEFUNC_OTHER; } /* shouldn't get here, probably */ return TYPEFUNC_OTHER; }
bool TLKFile::typeIsCorrect(void) { errcode = 0; if(getBaseType(type) == NWN_BASE_TLK) return true; return false; }
/* * lookup_default_opclass * * Given the OIDs of a datatype and an access method, find the default * operator class, if any. Returns InvalidOid if there is none. */ static Oid lookup_default_opclass(Oid type_id, Oid am_id) { int nexact = 0; int ncompatible = 0; Oid exactOid = InvalidOid; Oid compatibleOid = InvalidOid; Relation rel; ScanKeyData skey[1]; SysScanDesc scan; HeapTuple tup; /* If it's a domain, look at the base type instead */ type_id = getBaseType(type_id); /* * We scan through all the opclasses available for the access method, * looking for one that is marked default and matches the target type * (either exactly or binary-compatibly, but prefer an exact match). * * We could find more than one binary-compatible match, in which case we * require the user to specify which one he wants. If we find more * than one exact match, then someone put bogus entries in pg_opclass. * * This is the same logic as GetDefaultOpClass() in indexcmds.c, except * that we consider all opclasses, regardless of the current search path. */ rel = heap_openr(OperatorClassRelationName, AccessShareLock); ScanKeyEntryInitialize(&skey[0], 0x0, Anum_pg_opclass_opcamid, F_OIDEQ, ObjectIdGetDatum(am_id)); scan = systable_beginscan(rel, OpclassAmNameNspIndex, true, SnapshotNow, 1, skey); while (HeapTupleIsValid(tup = systable_getnext(scan))) { Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tup); if (opclass->opcdefault) { if (opclass->opcintype == type_id) { nexact++; exactOid = HeapTupleGetOid(tup); } else if (IsBinaryCoercible(type_id, opclass->opcintype)) { ncompatible++; compatibleOid = HeapTupleGetOid(tup); } } } systable_endscan(scan); heap_close(rel, AccessShareLock); if (nexact == 1) return exactOid; if (nexact != 0) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("there are multiple default operator classes for data type %s", format_type_be(type_id)))); if (ncompatible == 1) return compatibleOid; return InvalidOid; }
/* * Recursively initialize the PLyObToDatum structure(s) needed to construct * a SQL value of the specified typeOid/typmod from a Python value. * (But note that at this point we may have RECORDOID/-1, ie, an indeterminate * record type.) * proc is used to look up transform functions. */ void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc) { TypeCacheEntry *typentry; char typtype; Oid trfuncid; Oid typinput; /* Since this is recursive, it could theoretically be driven to overflow */ check_stack_depth(); arg->typoid = typeOid; arg->typmod = typmod; arg->mcxt = arg_mcxt; /* * Fetch typcache entry for the target type, asking for whatever info * we'll need later. RECORD is a special case: just treat it as composite * without bothering with the typcache entry. */ if (typeOid != RECORDOID) { typentry = lookup_type_cache(typeOid, TYPECACHE_DOMAIN_BASE_INFO); typtype = typentry->typtype; arg->typbyval = typentry->typbyval; arg->typlen = typentry->typlen; arg->typalign = typentry->typalign; } else { typentry = NULL; typtype = TYPTYPE_COMPOSITE; /* hard-wired knowledge about type RECORD: */ arg->typbyval = false; arg->typlen = -1; arg->typalign = 'd'; } /* * Choose conversion method. Note that transform functions are checked * for composite and scalar types, but not for arrays or domains. This is * somewhat historical, but we'd have a problem allowing them on domains, * since we drill down through all levels of a domain nest without looking * at the intermediate levels at all. */ if (typtype == TYPTYPE_DOMAIN) { /* Domain */ arg->func = PLyObject_ToDomain; arg->u.domain.domain_info = NULL; /* Recursively set up conversion info for the element type */ arg->u.domain.base = (PLyObToDatum *) MemoryContextAllocZero(arg_mcxt, sizeof(PLyObToDatum)); PLy_output_setup_func(arg->u.domain.base, arg_mcxt, typentry->domainBaseType, typentry->domainBaseTypmod, proc); } else if (typentry && OidIsValid(typentry->typelem) && typentry->typlen == -1) { /* Standard varlena array (cf. get_element_type) */ arg->func = PLySequence_ToArray; /* Get base type OID to insert into constructed array */ /* (note this might not be the same as the immediate child type) */ arg->u.array.elmbasetype = getBaseType(typentry->typelem); /* Recursively set up conversion info for the element type */ arg->u.array.elm = (PLyObToDatum *) MemoryContextAllocZero(arg_mcxt, sizeof(PLyObToDatum)); PLy_output_setup_func(arg->u.array.elm, arg_mcxt, typentry->typelem, typmod, proc); } else if ((trfuncid = get_transform_tosql(typeOid, proc->langid, proc->trftypes))) { arg->func = PLyObject_ToTransform; fmgr_info_cxt(trfuncid, &arg->u.transform.typtransform, arg_mcxt); } else if (typtype == TYPTYPE_COMPOSITE) { /* Named composite type, or RECORD */ arg->func = PLyObject_ToComposite; /* We'll set up the per-field data later */ arg->u.tuple.recdesc = NULL; arg->u.tuple.typentry = typentry; arg->u.tuple.tupdescseq = typentry ? typentry->tupDescSeqNo - 1 : 0; arg->u.tuple.atts = NULL; arg->u.tuple.natts = 0; /* Mark this invalid till needed, too */ arg->u.tuple.recinfunc.fn_oid = InvalidOid; } else { /* Scalar type, but we have a couple of special cases */ switch (typeOid) { case BOOLOID: arg->func = PLyObject_ToBool; break; case BYTEAOID: arg->func = PLyObject_ToBytea; break; default: arg->func = PLyObject_ToScalar; getTypeInputInfo(typeOid, &typinput, &arg->u.scalar.typioparam); fmgr_info_cxt(typinput, &arg->u.scalar.typfunc, arg_mcxt); break; } } }
int SimDynamicDataPlugin::getType(const char *lpszType) { int iTmp = 0, iType = 0; char *lpszTmp; char szDup[BUFSIZ]; strcpy(szDup, lpszType); char *lpszDup = strupr(szDup); while (lpszDup && *lpszDup != '\0') { // Find the next separating token for (lpszTmp = lpszDup; lpszTmp && *lpszTmp != '\0'; lpszTmp ++) { if (*lpszTmp == ' ' || *lpszTmp == '[') { *(lpszTmp ++) = '\0'; break; } } if (*lpszDup != '\0') { // See if we can find the base type if (BASETYPE(iType) == 0 && (iTmp = getBaseType(lpszDup))) { iType |= iTmp; } // Otherwise, see if it's a qualifier else if (strcmp(lpszDup, "UNSIGNED") == 0) { iType |= DATAQUALIFIER_UNSIGNED; } // Otherwise, see if it's a ptr else if (strchr(lpszDup, '*')) { iType |= DATAQUALIFIER_PTR; } // See if it's an array else if (strchr(lpszDup, ']')) { if (iType & DATAQUALIFIER_ARRAY) { iType ^= DATAQUALIFIER_ARRAY; iType |= DATAQUALIFIER_2DARRAY; } else { iType |= DATAQUALIFIER_ARRAY; } } } lpszDup = lpszTmp; } #if defined(_MSC_VER) || (defined(__BORLANDC__) && (__BORLANDC__ < 0x0530)) // MS and Borland (before CBuilder 3) see arrays as pointers, so we have // to do some fixups to make sure what we see is what we get // Take care of any pointers (except char *) by converting // them to arrays if ((iType & DATAQUALIFIER_PTR) && (BASETYPE(iType) != DATATYPE_CHAR)) { // If already an array, make it a 2D array if (iType & DATAQUALIFIER_ARRAY) { iType ^= DATAQUALIFIER_ARRAY; iType |= DATAQUALIFIER_2DARRAY; } else { iType |= DATAQUALIFIER_ARRAY; } iType ^= DATAQUALIFIER_PTR; } // Take care of pointer pointers by converting char * * to // array-of-char *, and others to 2D arrays if (iType & DATAQUALIFIER_PTRPTR) { iType ^= DATAQUALIFIER_PTRPTR; iType |= BASETYPE(iType) == DATATYPE_CHAR ? DATAQUALIFIER_PTR | DATAQUALIFIER_ARRAY : DATAQUALIFIER_2DARRAY; } #endif // We may have done some wacky stuff, so a sanity check is good: // - pointers other than char * are not allowed // - pointers to pointers are not allowed // - can't have a type that is both an array and a 2D array if (((iType & DATAQUALIFIER_PTR) && (BASETYPE(iType) != DATATYPE_CHAR)) || (iType & DATAQUALIFIER_PTRPTR) || ((iType & DATAQUALIFIER_ARRAY) && (iType & DATAQUALIFIER_2DARRAY))) { iType = DATATYPE_COUNT; } return (iType); }
static void PLy_output_datum_func2(PLyObToDatum *arg, HeapTuple typeTup, Oid langid, List *trftypes) { Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup); Oid element_type; Oid base_type; Oid funcid; perm_fmgr_info(typeStruct->typinput, &arg->typfunc); arg->typoid = HeapTupleGetOid(typeTup); arg->typmod = -1; arg->typioparam = getTypeIOParam(typeTup); arg->typbyval = typeStruct->typbyval; element_type = get_base_element_type(arg->typoid); base_type = getBaseType(element_type ? element_type : arg->typoid); /* * Select a conversion function to convert Python objects to PostgreSQL * datums. */ if ((funcid = get_transform_tosql(base_type, langid, trftypes))) { arg->func = PLyObject_ToTransform; perm_fmgr_info(funcid, &arg->typtransform); } else if (typeStruct->typtype == TYPTYPE_COMPOSITE) { arg->func = PLyObject_ToComposite; } else switch (base_type) { case BOOLOID: arg->func = PLyObject_ToBool; break; case BYTEAOID: arg->func = PLyObject_ToBytea; break; default: arg->func = PLyObject_ToDatum; break; } if (element_type) { char dummy_delim; Oid funcid; if (type_is_rowtype(element_type)) arg->func = PLyObject_ToComposite; arg->elm = PLy_malloc0(sizeof(*arg->elm)); arg->elm->func = arg->func; arg->elm->typtransform = arg->typtransform; arg->func = PLySequence_ToArray; arg->elm->typoid = element_type; arg->elm->typmod = -1; get_type_io_data(element_type, IOFunc_input, &arg->elm->typlen, &arg->elm->typbyval, &arg->elm->typalign, &dummy_delim, &arg->elm->typioparam, &funcid); perm_fmgr_info(funcid, &arg->elm->typfunc); } }
bool ASTUserType::isOpaque() { return !getDeclaration()->length() && !getBaseType(); // XXX should be if type does not have body }
bool isGreenplumDbHashable(Oid typid) { /* we can hash all arrays */ if (typeIsArrayType(typid)) return true; /* if this type is a domain type, get its base type */ if (get_typtype(typid) == 'd') typid = getBaseType(typid); /* we can hash all enums */ if (typeIsEnumType(typid)) return true; /* * NB: Every GPDB-hashable datatype must also be mergejoinable, i.e. * must have a B-tree operator family. There is a sanity check for * that in the opr_sanity_gp regression test. If you modify the list * below, please also update the list in opr_sanity_gp! */ switch(typid) { case INT2OID: case INT4OID: case INT8OID: case FLOAT4OID: case FLOAT8OID: case NUMERICOID: case CHAROID: case BPCHAROID: case TEXTOID: case VARCHAROID: case BYTEAOID: case NAMEOID: case OIDOID: case TIDOID: case REGPROCOID: case REGPROCEDUREOID: case REGOPEROID: case REGOPERATOROID: case REGCLASSOID: case REGTYPEOID: case TIMESTAMPOID: case TIMESTAMPTZOID: case DATEOID: case TIMEOID: case TIMETZOID: case INTERVALOID: case ABSTIMEOID: case RELTIMEOID: case TINTERVALOID: case INETOID: case CIDROID: case MACADDROID: case BITOID: case VARBITOID: case BOOLOID: case ANYARRAYOID: case OIDVECTOROID: case CASHOID: case UUIDOID: case COMPLEXOID: return true; default: return false; } }
// // Factory::expPromo_Assign // SR::Exp::CRef Factory::expPromo_Assign(SR::Type const *typeL, SR::Exp const *e, Core::Origin pos) { auto exp = expPromo_LValue(e, pos); auto typeR = exp->getType(); // If assigning to same type, no conversion is needed. if(typeL->getTypeQual() == typeR->getTypeQual()) return exp; // bool = pointer // bool = arithmetic if(typeL->isTypeBoolean() && (typeR->isTypePointer() || typeR->isCTypeArith())) { return expConvert_Bool(typeL, exp, pos); } // integer = line-special if(typeL->isCTypeInteg() && typeR->isTypePointer() && typeR->getBaseType()->isTypeFunction() && typeR->getBaseType()->getCallType() == IR::CallType::Special) { return expConvert_ArithPtr(typeL, exp, pos); } // arithmetic = arithmetic if(typeL->isCTypeArith()) { if(!typeR->isCTypeArith()) Core::Error(pos, "cannot implicitly convert to " "arithmetic type from non-arithmetic type"); return expConvert_Arith(typeL, exp, pos); } // struct = struct if(typeL->isCTypeStruct() || typeL->isCTypeUnion()) { if(typeL->getTypeQual() != typeR->getTypeQual()) Core::Error(pos, "cannot implicitly convert to " "incompatible structure or union type"); return exp; } // pointer = pointer if(typeL->isTypePointer()) { // Check for exp being a null pointer constant. if(typeR->isCTypeInteg() && exp->isZero()) return expConvert_PtrArith(typeL, exp, pos); if(!typeR->isTypePointer()) Core::Error(pos, "cannot implicitly convert to " "pointer type from non-pointer type"); auto baseL = typeL->getBaseType(); auto baseR = typeR->getBaseType(); // Treat __str_ent* as char const __str_ars* for these checks. if(baseR->isTypeStrEnt()) { SR::TypeQual qual = {{IR::AddrBase::StrArs, Core::STR_}}; qual.aCons = true; baseR = TypeChar->getTypeQual(qual); } // Check underlying type compatibility. if(!baseL->isTypeVoid() && !baseR->isTypeVoid() && baseL->getTypeArrayQual() != baseR->getTypeArrayQual()) Core::Error(pos, "cannot implicitly convert to " "incompatible pointer type"); auto qualL = baseL->getQual(); auto qualR = baseR->getQual(); // Check address space compatibility. if(!Target::IsAddrEnclosed(qualL.space, qualR.space)) Core::Error(pos, "cannot implicitly convert to " "pointer to disjoint address space"); // Check for discarded qualifiers. if((!qualL.aAtom && qualR.aAtom) || (!qualL.aCons && qualR.aCons) || (!qualL.aRest && qualR.aRest) || (!qualL.aVola && qualR.aVola)) Core::Error(pos, "cannot implicitly discard qualifiers"); return expConvert_Pointer(typeL, exp, pos); } Core::Error(pos, "cannot implicitly convert"); }
static void PLy_input_datum_func2(PLyDatumToOb *arg, Oid typeOid, HeapTuple typeTup) { Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup); Oid element_type = get_element_type(typeOid); /* Get the type's conversion information */ perm_fmgr_info(typeStruct->typoutput, &arg->typfunc); arg->typoid = HeapTupleGetOid(typeTup); arg->typmod = -1; arg->typioparam = getTypeIOParam(typeTup); arg->typbyval = typeStruct->typbyval; arg->typlen = typeStruct->typlen; arg->typalign = typeStruct->typalign; /* Determine which kind of Python object we will convert to */ switch (getBaseType(element_type ? element_type : typeOid)) { case BOOLOID: arg->func = PLyBool_FromBool; break; case FLOAT4OID: arg->func = PLyFloat_FromFloat4; break; case FLOAT8OID: arg->func = PLyFloat_FromFloat8; break; case NUMERICOID: arg->func = PLyFloat_FromNumeric; break; case INT2OID: arg->func = PLyInt_FromInt16; break; case INT4OID: arg->func = PLyInt_FromInt32; break; case INT8OID: arg->func = PLyLong_FromInt64; break; case BYTEAOID: arg->func = PLyBytes_FromBytea; break; default: arg->func = PLyString_FromDatum; break; } if (element_type) { char dummy_delim; Oid funcid; arg->elm = PLy_malloc0(sizeof(*arg->elm)); arg->elm->func = arg->func; arg->func = PLyList_FromArray; arg->elm->typoid = element_type; arg->elm->typmod = -1; get_type_io_data(element_type, IOFunc_output, &arg->elm->typlen, &arg->elm->typbyval, &arg->elm->typalign, &dummy_delim, &arg->elm->typioparam, &funcid); perm_fmgr_info(funcid, &arg->elm->typfunc); } }
ModelType *ModelData::createTypeRef(OovStringRef const typeName, eModelDataTypes dtype) { std::string baseTypeName = getBaseType(typeName); return static_cast<ModelType*>(createDataType(dtype, baseTypeName)); }
/* * Determine how we want to render values of a given type in datum_to_jsonb. * * Given the datatype OID, return its JsonbTypeCategory, as well as the type's * output function OID. If the returned category is JSONBTYPE_JSONCAST, * we return the OID of the relevant cast function instead. */ static void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid) { bool typisvarlena; /* Look through any domain */ typoid = getBaseType(typoid); *outfuncoid = InvalidOid; /* * We need to get the output function for everything except date and * timestamp types, booleans, array and composite types, json and jsonb, * and non-builtin types where there's a cast to json. In this last case * we return the oid of the cast function instead. */ switch (typoid) { case BOOLOID: *tcategory = JSONBTYPE_BOOL; break; case INT2OID: case INT4OID: case INT8OID: case FLOAT4OID: case FLOAT8OID: case NUMERICOID: getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); *tcategory = JSONBTYPE_NUMERIC; break; case DATEOID: *tcategory = JSONBTYPE_DATE; break; case TIMESTAMPOID: *tcategory = JSONBTYPE_TIMESTAMP; break; case TIMESTAMPTZOID: *tcategory = JSONBTYPE_TIMESTAMPTZ; break; case JSONBOID: *tcategory = JSONBTYPE_JSONB; break; case JSONOID: *tcategory = JSONBTYPE_JSON; break; default: /* Check for arrays and composites */ if (OidIsValid(get_element_type(typoid))) *tcategory = JSONBTYPE_ARRAY; else if (type_is_rowtype(typoid)) *tcategory = JSONBTYPE_COMPOSITE; else { /* It's probably the general case ... */ *tcategory = JSONBTYPE_OTHER; /* * but first let's look for a cast to json (note: not to * jsonb) if it's not built-in. */ if (typoid >= FirstNormalObjectId) { Oid castfunc; CoercionPathType ctype; ctype = find_coercion_pathway(JSONOID, typoid, COERCION_EXPLICIT, &castfunc); if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc)) { *tcategory = JSONBTYPE_JSONCAST; *outfuncoid = castfunc; } else { /* not a cast type, so just get the usual output func */ getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); } } else { /* any other builtin type */ getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); } break; } } }
/* * Verify lvalue It doesn't repeat a checks that are done. Checks a subscript * expressions, verify a validity of record's fields. */ void plpgsql_check_target(PLpgSQL_checkstate *cstate, int varno, Oid *expected_typoid, int *expected_typmod) { PLpgSQL_datum *target = cstate->estate->datums[varno]; plpgsql_check_record_variable_usage(cstate, varno, true); switch (target->dtype) { case PLPGSQL_DTYPE_VAR: { PLpgSQL_var *var = (PLpgSQL_var *) target; PLpgSQL_type *tp = var->datatype; if (expected_typoid != NULL) *expected_typoid = tp->typoid; if (expected_typmod != NULL) *expected_typmod = tp->atttypmod; } break; case PLPGSQL_DTYPE_REC: { PLpgSQL_rec *rec = (PLpgSQL_rec *) target; #if PG_VERSION_NUM >= 110000 if (rec->rectypeid != RECORDOID) { if (expected_typoid != NULL) *expected_typoid = rec->rectypeid; if (expected_typmod != NULL) *expected_typmod = -1; } else #endif if (recvar_tupdesc(rec) != NULL) { if (expected_typoid != NULL) *expected_typoid = recvar_tupdesc(rec)->tdtypeid; if (expected_typmod != NULL) *expected_typmod = recvar_tupdesc(rec)->tdtypmod; } else { if (expected_typoid != NULL) *expected_typoid = RECORDOID; if (expected_typmod != NULL) *expected_typmod = -1; } } break; case PLPGSQL_DTYPE_ROW: { PLpgSQL_row *row = (PLpgSQL_row *) target; if (row->rowtupdesc != NULL) { if (expected_typoid != NULL) *expected_typoid = row->rowtupdesc->tdtypeid; if (expected_typmod != NULL) *expected_typmod = row->rowtupdesc->tdtypmod; } else { if (expected_typoid != NULL) *expected_typoid = RECORDOID; if (expected_typmod != NULL) *expected_typmod = -1; } plpgsql_check_row_or_rec(cstate, row, NULL); } break; case PLPGSQL_DTYPE_RECFIELD: { PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) target; PLpgSQL_rec *rec; int fno; rec = (PLpgSQL_rec *) (cstate->estate->datums[recfield->recparentno]); /* * Check that there is already a tuple in the record. We need * that because records don't have any predefined field * structure. */ if (!HeapTupleIsValid(recvar_tuple(rec))) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("record \"%s\" is not assigned to tuple structure", rec->refname))); /* * Get the number of the records field to change and the * number of attributes in the tuple. Note: disallow system * column names because the code below won't cope. */ fno = SPI_fnumber(recvar_tupdesc(rec), recfield->fieldname); if (fno <= 0) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("record \"%s\" has no field \"%s\"", rec->refname, recfield->fieldname))); if (expected_typoid) *expected_typoid = SPI_gettypeid(recvar_tupdesc(rec), fno); if (expected_typmod) *expected_typmod = TupleDescAttr(recvar_tupdesc(rec), fno - 1)->atttypmod; } break; case PLPGSQL_DTYPE_ARRAYELEM: { /* * Target is an element of an array */ int nsubscripts; Oid arrayelemtypeid; Oid arraytypeid; /* * To handle constructs like x[1][2] := something, we have to * be prepared to deal with a chain of arrayelem datums. Chase * back to find the base array datum, and save the subscript * expressions as we go. (We are scanning right to left here, * but want to evaluate the subscripts left-to-right to * minimize surprises.) */ nsubscripts = 0; do { PLpgSQL_arrayelem *arrayelem = (PLpgSQL_arrayelem *) target; if (nsubscripts++ >= MAXDIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", nsubscripts + 1, MAXDIM))); plpgsql_check_expr(cstate, arrayelem->subscript); target = cstate->estate->datums[arrayelem->arrayparentno]; } while (target->dtype == PLPGSQL_DTYPE_ARRAYELEM); /* * If target is domain over array, reduce to base type */ #if PG_VERSION_NUM >= 90600 arraytypeid = plpgsql_exec_get_datum_type(cstate->estate, target); #else arraytypeid = exec_get_datum_type(cstate->estate, target); #endif arraytypeid = getBaseType(arraytypeid); arrayelemtypeid = get_element_type(arraytypeid); if (!OidIsValid(arrayelemtypeid)) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("subscripted object is not an array"))); if (expected_typoid) *expected_typoid = arrayelemtypeid; if (expected_typmod) *expected_typmod = ((PLpgSQL_var *) target)->datatype->atttypmod; plpgsql_check_record_variable_usage(cstate, target->dno, true); } break; default: ; /* nope */ } }
const ModelType *ModelData::getTypeRef(OovStringRef const typeName) const { OovString baseTypeName = getBaseType(typeName); return findType(baseTypeName); }