def getDatatype(plpy, datatypeid, objectid, objecttype=None):
  try:
    if objecttype is None:
      # finding objecttype if not given
      objecttype_query = plpy.prepare("SELECT * FROM object WHERE objectid = $1", ["int"])
      objecttypes = plpy.execute(objecttype_query, [objectid])
      objecttype = objecttypes[0]["objecttypeid"]

    # taking valuetype
    subquery = "position($2 IN array_to_string(objecttypeid, ' ')) > 0"
    datatype_query = plpy.prepare("SELECT * FROM datatype NATURAL JOIN valuetype WHERE datatypeid = $1 AND (("+subquery+") OR objecttypeid = array[]::text[])", ["text", "text"])
    datatypes = plpy.execute(datatype_query, [datatypeid, objecttype])
    if datatypes.nrows() > 0:
      datatype = datatypes[0]
    else:
      return 0

    # testing the subtype if necessary
    if datatype["objecttypeid"]:
      subtype = datatype["objecttypeid"][0].partition(".")[2]
      if subtype:
        subtype_query = plpy.prepare("SELECT dataid FROM data WHERE objectid = $1 AND position( $2 IN value) > 0 AND visible = TRUE", ["int", "text"])
        subtypes = plpy.execute(subtype_query, [objectid, subtype])
        if not (subtypes.nrows() > 0):
          plpy.notice("no subtype correctly set")
          plpy.notice("query:SELECT dataid FROM data WHERE objectid = "+str(objectid)+" AND position( "+subtype+" IN value) > 0 AND visible = TRUE")
          return 0

    # adding the given objecttype into return array
    datatype["objecttype"] = objecttype

  except (IndexError, NameError) as e:
    plpy.notice("SELECT * FROM datatype NATURAL JOIN valuetype WHERE datatypeid = '"+datatypeid+"' AND (("+subquery+") OR objecttypeid = array[]::text[])")
    plpy.notice(e)
    return 0

  return datatype
