/* errorf() callback for PGtypeArgs, see PQputf() and PQgetf(). * Always returns -1. */ int pqt_argserrorf(PGtypeArgs *args, const char *format, ...) { va_list ap; char fqtn[200]; if (!args || !format || !*format) return -1; pqt_fqtn(fqtn, sizeof(fqtn), args->typhandler->typschema, args->typhandler->typname); /* put the header */ PQseterror("%s[pos:%d] - ", fqtn, args->typpos); /* append message from type handler */ va_start(ap, format); vseterror(format, ap, TRUE); return -1; }
static int registerSubClass(PGtypeData *connData, const char *type_name, PGtypeProc typput, PGtypeProc typget) { char *s; PGtypeHandler *h_sub; PGtypeHandler *h_base; char sub_typschema[PQT_MAXIDLEN + 1]; char sub_typname[PQT_MAXIDLEN + 1]; char base_typschema[PQT_MAXIDLEN + 1]; char base_typname[PQT_MAXIDLEN + 1]; char sub_fqtn[200]; char base_fqtn[200]; if (!(s = parseType(type_name, sub_typschema, sub_typname, 1))) return FALSE; if (*s != '=') { PQseterror("Missing inheritence operator '=': %s", type_name); return FALSE; } if (!parseType(s + 1, base_typschema, base_typname, 1)) return FALSE; /* lookup the base handler */ h_base = pqt_gethandler(connData->typhandlers, connData->typhcnt, base_typschema, base_typname); if (!h_base) { PQseterror("typname '%s' does not exist, '%s' cannot sub-class it", pqt_fqtn(base_fqtn, sizeof(base_fqtn), base_typschema, base_typname), pqt_fqtn(sub_fqtn, sizeof(sub_fqtn), sub_typschema, sub_typname)); return FALSE; } /* cannot sub-class a record type */ if (h_base->typoid == RECORDOID) { PQseterror("Cannot sub-class pg_catalog.record '%s'", pqt_fqtn(sub_fqtn, sizeof(sub_fqtn), sub_typschema, sub_typname)); return FALSE; } if (!expandHandlers(connData)) return FALSE; h_sub = &connData->typhandlers[connData->typhcnt]; memset(h_sub, 0, sizeof(PGtypeHandler)); h_sub->id = connData->typhcnt + countof(pg_handlers); h_sub->typlen = h_base->typlen; h_sub->typoid = h_base->typoid; h_sub->typoid_array = h_base->typoid_array; h_sub->typput = typput; h_sub->typget = typget; h_sub->base_id = h_base->id; pqt_strcpy(h_sub->typschema, sizeof(h_sub->typschema), sub_typschema); pqt_strcpy(h_sub->typname, sizeof(h_sub->typname), sub_typname); connData->typhcnt++; return TRUE; }
char *pqt_parse(const char *format, PGtypeHandler *h, int hcnt, char *stmtBuf, size_t stmtBufLen, PGtypeHandler **out, size_t *stmtPos, int *typpos, int *flags) { int specMark; char *s = skipQuotes((char *) format); char typname[PQT_MAXIDLEN + 1]; char schema[PQT_MAXIDLEN + 1]; char tmp[200]; *out = NULL; if (!s) return NULL; /* found quotes to skip */ if (s != format) { if (stmtBuf) { size_t n = s - format; CHKSTMTBUF(n); memcpy(stmtBuf + *stmtPos, format, n); (*stmtPos) += n; } return s; } specMark = *format; if (specMark != '%' && specMark != '#') { if (stmtBuf) { CHKSTMTBUF(1); stmtBuf[*stmtPos] = *format; (*stmtPos)++; } format++; return (char *) format; } /* spec skips % or # */ if (!(s = pqt_parsetype(format + 1, schema, typname, flags, *typpos + 1))) return NULL; if (*flags & TYPFLAG_INVALID) { if (stmtBuf) { CHKSTMTBUF(1); stmtBuf[*stmtPos] = *format++; (*stmtPos)++; PQseterror(NULL); /* set by pqt_parsetype */ return (char *) format; } return NULL; } (*typpos)++; if (!(*out = pqt_gethandler(h, hcnt, schema, typname))) { PQseterror("Uknown type '%s' (position %d)", pqt_fqtn(tmp, sizeof(tmp), schema, typname), *typpos); return NULL; } if (stmtBuf) { int n = pqt_snprintf(tmp, sizeof(tmp), "$%d", *typpos); CHKSTMTBUF(n); memcpy(stmtBuf + *stmtPos, tmp, n); (*stmtPos) += n; } if (!(*out)->typput) { PGtypeHandler *o = pqt_gethandlerbyid(h, hcnt, h->base_id); if (!o || !o->typput) { PQseterror( "Type '%s' doesn't support put operations (position %d)", pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, (*out)->typname), *typpos); *out = NULL; return NULL; } *out = o; } if ((*flags & TYPFLAG_POINTER) && !pqt_allowsptr(*out)) { PQseterror( "Type '%s' doesn't support putting pointers (position %d)", pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, (*out)->typname), *typpos); *out = NULL; return NULL; } if (specMark == '#') (*flags) |= TYPFLAG_BYNAME; return s; }