static foreign_t uri_authority_components(term_t Authority, term_t components) { pl_wchar_t *s; size_t len; if ( PL_get_wchars(Authority, &len, &s, CVT_ATOM|CVT_STRING|CVT_LIST) ) { return unify_uri_authority_components(components, len, s); } else if ( PL_is_functor(components, FUNCTOR_uri_authority4) ) { charbuf b; int rc; init_charbuf(&b); if ( (rc=get_text_arg(components, 1, &len, &s, TXT_EX_TEXT)) == TRUE ) { add_nchars_charbuf(&b, len, s); if ( (rc=get_text_arg(components, 2, &len, &s, TXT_EX_TEXT)) == TRUE ) { add_charbuf(&b, ':'); add_nchars_charbuf(&b, len, s); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } add_charbuf(&b, '@'); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } if ( (rc=get_text_arg(components, 3, &len, &s, TXT_EX_TEXT)) == TRUE ) { add_nchars_charbuf(&b, len, s); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } if ( (rc=get_text_arg(components, 4, &len, &s, TXT_EX_TEXT|CVT_INTEGER)) == TRUE ) { add_charbuf(&b, ':'); add_nchars_charbuf(&b, len, s); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } rc = PL_unify_wchars(Authority, PL_ATOM, b.here-b.base, b.base); free_charbuf(&b); return rc; } else { return PL_get_wchars(Authority, &len, &s, CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION); } }
/* * get_args * Retrieve arguments from FunctionCallInfo and validate them. We assume * that order of arguments is: * 1) schema name * 2) relation oid * 3) attribute name * 4) absolute path of source file, or 'stdin' (case insensitive) */ static void get_args(FunctionCallInfo fcinfo, char **nspname, char **relname, char **attname, char **filename) { Oid nspid; Oid relid; AttrNumber attnum; HeapTuple tp; Form_pg_class reltup; char relkind; *nspname = *relname = *attname = *filename = NULL; /* * First of all, check whether combination of arguments is consistent. * * 1) relid and attname can't be used with schemaname. * 2) relid is required when attname is given. */ if (!PG_ARGISNULL(0) && (!PG_ARGISNULL(1) || !PG_ARGISNULL(2))) elog(ERROR, "relid and attnum can not be used with schemaname"); else if (PG_ARGISNULL(1) && !PG_ARGISNULL(2)) elog(ERROR, "relation is required"); /* filepath validation */ if (!PG_ARGISNULL(3)) { *filename = get_text_arg(fcinfo, 3, false); /* * If given filepath is "stdin", clear filename to tell caller to * import from standard input. Note that we accept only absolute path * for security reason. */ if (pg_strcasecmp(*filename, "stdin") == 0) *filename = NULL; else if (!is_absolute_path(*filename)) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("relative path not allowed for dbms_stats_export" " to file"))); } /* schemaname validation */ if (!PG_ARGISNULL(0)) { *nspname = get_text_arg(fcinfo, 0, true); /* check that a schema with given name exists */ get_namespace_oid(*nspname, false); /* check that given schema is not one of system schemas */ if (dbms_stats_is_system_schema_internal(*nspname)) elog(ERROR, "\"%s\" is a system catalog", *nspname); } /* table oid validation */ if (!PG_ARGISNULL(1)) { relid = PG_GETARG_OID(1); tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tp)) elog(ERROR, "relid %d does not exist", relid); /* check that the target is an ordinary table or an index */ reltup = (Form_pg_class) GETSTRUCT(tp); *relname = pstrdup(reltup->relname.data); relkind = reltup->relkind; nspid = reltup->relnamespace; ReleaseSysCache(tp); if (relkind != RELKIND_RELATION && relkind != RELKIND_INDEX #if PG_VERSION_NUM >= 90200 && relkind != RELKIND_FOREIGN_TABLE #endif #if PG_VERSION_NUM >= 90300 && relkind != RELKIND_MATVIEW #endif ) elog(ERROR, "relkind of \"%s\" is \"%c\", can not import", get_rel_name(relid), relkind); /* check that the relation is not in one of system schemas */ *nspname = get_namespace_name(nspid); if (dbms_stats_is_system_schema_internal(*nspname)) elog(ERROR, "\"%s\" is a system catalog", *nspname); /* attribute name validation */ if (!PG_ARGISNULL(2)) { *attname = get_text_arg(fcinfo, 2, true); attnum = get_attnum(relid, *attname); if (!AttributeNumberIsValid(attnum)) elog(ERROR, "column \"%s\" of \"%s.%s\" does not exist", *attname, *nspname, *relname); } } }
static foreign_t uri_components(term_t URI, term_t components) { pl_wchar_t *s; size_t len; if ( PL_get_wchars(URI, &len, &s, CVT_ATOM|CVT_STRING|CVT_LIST) ) { uri_component_ranges ranges; term_t rt = PL_new_term_refs(6); term_t av = rt+1; parse_uri(&ranges, len, s); unify_range(av+0, &ranges.scheme); unify_range(av+1, &ranges.authority); unify_range(av+2, &ranges.path); unify_range(av+3, &ranges.query); unify_range(av+4, &ranges.fragment); return (PL_cons_functor_v(rt, FUNCTOR_uri_components5, av) && PL_unify(components, rt)); } else if ( PL_is_functor(components, FUNCTOR_uri_components5) ) { charbuf b; int rc; init_charbuf(&b); /* schema */ if ( (rc=get_text_arg(components, 1, &len, &s, TXT_EX_TEXT)) == TRUE ) { add_nchars_charbuf(&b, len, s); add_charbuf(&b, ':'); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } /* authority */ if ( (rc=get_text_arg(components, 2, &len, &s, TXT_EX_TEXT)) == TRUE ) { add_charbuf(&b, '/'); add_charbuf(&b, '/'); add_nchars_charbuf(&b, len, s); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } /* path */ if ( (rc=get_text_arg(components, 3, &len, &s, TXT_EX_TEXT)) == TRUE ) { add_nchars_charbuf(&b, len, s); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } /* query */ if ( (rc=get_text_arg(components, 4, &len, &s, TXT_EX_TEXT)) == TRUE ) { if ( len > 0 ) { add_charbuf(&b, '?'); add_nchars_charbuf(&b, len, s); } } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } /* fragment */ if ( (rc=get_text_arg(components, 5, &len, &s, TXT_EX_TEXT)) == TRUE ) { add_charbuf(&b, '#'); add_nchars_charbuf(&b, len, s); } else if ( rc == -1 ) { free_charbuf(&b); return FALSE; } rc = PL_unify_wchars(URI, PL_ATOM, b.here-b.base, b.base); free_charbuf(&b); return rc; } else /* generate an error */ { return PL_get_wchars(URI, &len, &s, CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION); } }