*** pgsql/src/backend/access/common/reloptions.c 2009/01/26 19:41:06 1.19 --- pgsql/src/backend/access/common/reloptions.c 2009/02/02 19:31:38 1.20 *************** *** 8,14 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.18 2009/01/12 21:02:14 alvherre Exp $ * *------------------------------------------------------------------------- */ --- 8,14 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.19 2009/01/26 19:41:06 alvherre Exp $ * *------------------------------------------------------------------------- */ *************** add_string_reloption(int kind, char *nam *** 390,397 **** } /* ! * Transform a relation options list (list of DefElem) into the text array ! * format that is kept in pg_class.reloptions. * * This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and * ALTER TABLE RESET. In the ALTER cases, oldOptions is the existing --- 390,399 ---- } /* ! * Transform a relation options list (list of ReloptElem) into the text array ! * format that is kept in pg_class.reloptions, including only those options ! * that are in the passed namespace. The output values do not include the ! * namespace. * * This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and * ALTER TABLE RESET. In the ALTER cases, oldOptions is the existing *************** add_string_reloption(int kind, char *nam *** 402,415 **** * in the list (it will be or has been handled by interpretOidsOption()). * * Note that this is not responsible for determining whether the options ! * are valid. * * Both oldOptions and the result are text arrays (or NULL for "default"), * but we declare them as Datums to avoid including array.h in reloptions.h. */ Datum ! transformRelOptions(Datum oldOptions, List *defList, ! bool ignoreOids, bool isReset) { Datum result; ArrayBuildState *astate; --- 404,420 ---- * in the list (it will be or has been handled by interpretOidsOption()). * * Note that this is not responsible for determining whether the options ! * are valid, but it does check that namespaces for all the options given are ! * listed in validnsps. The NULL namespace is always valid and needs not be ! * explicitely listed. Passing a NULL pointer means that only the NULL ! * namespace is valid. * * Both oldOptions and the result are text arrays (or NULL for "default"), * but we declare them as Datums to avoid including array.h in reloptions.h. */ Datum ! transformRelOptions(Datum oldOptions, List *defList, char *namspace, ! char *validnsps[], bool ignoreOids, bool isReset) { Datum result; ArrayBuildState *astate; *************** transformRelOptions(Datum oldOptions, Li *** 444,454 **** /* Search for a match in defList */ foreach(cell, defList) { ! DefElem *def = lfirst(cell); ! int kw_len = strlen(def->defname); if (text_len > kw_len && text_str[kw_len] == '=' && ! pg_strncasecmp(text_str, def->defname, kw_len) == 0) break; } if (!cell) --- 449,471 ---- /* Search for a match in defList */ foreach(cell, defList) { ! ReloptElem *def = lfirst(cell); ! int kw_len; + /* ignore if not in the same namespace */ + if (namspace == NULL) + { + if (def->nmspc != NULL) + continue; + } + else if (def->nmspc == NULL) + continue; + else if (pg_strcasecmp(def->nmspc, namspace) != 0) + continue; + + kw_len = strlen(def->optname); if (text_len > kw_len && text_str[kw_len] == '=' && ! pg_strncasecmp(text_str, def->optname, kw_len) == 0) break; } if (!cell) *************** transformRelOptions(Datum oldOptions, Li *** 468,474 **** */ foreach(cell, defList) { ! DefElem *def = lfirst(cell); if (isReset) { --- 485,492 ---- */ foreach(cell, defList) { ! ReloptElem *def = lfirst(cell); ! if (isReset) { *************** transformRelOptions(Datum oldOptions, Li *** 483,504 **** const char *value; Size len; ! if (ignoreOids && pg_strcasecmp(def->defname, "oids") == 0) continue; /* ! * Flatten the DefElem into a text string like "name=arg". If we ! * have just "name", assume "name=true" is meant. */ if (def->arg != NULL) ! value = defGetString(def); else value = "true"; ! len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value); /* +1 leaves room for sprintf's trailing null */ t = (text *) palloc(len + 1); SET_VARSIZE(t, len); ! sprintf(VARDATA(t), "%s=%s", def->defname, value); astate = accumArrayResult(astate, PointerGetDatum(t), false, TEXTOID, --- 501,562 ---- const char *value; Size len; ! /* ! * Error out if the namespace is not valid. A NULL namespace ! * is always valid. ! */ ! if (def->nmspc != NULL) ! { ! bool valid = false; ! int i; ! ! if (validnsps) ! { ! for (i = 0; validnsps[i]; i++) ! { ! if (pg_strcasecmp(def->nmspc, validnsps[i]) == 0) ! { ! valid = true; ! break; ! } ! } ! } ! ! if (!valid) ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ! errmsg("unrecognized parameter namespace \"%s\"", ! def->nmspc))); ! } ! ! if (ignoreOids && pg_strcasecmp(def->optname, "oids") == 0) ! continue; ! ! /* ignore if not in the same namespace */ ! if (namspace == NULL) ! { ! if (def->nmspc != NULL) ! continue; ! } ! else if (def->nmspc == NULL) ! continue; ! else if (pg_strcasecmp(def->nmspc, namspace) != 0) continue; /* ! * Flatten the ReloptElem into a text string like "name=arg". If we ! * have just "name", assume "name=true" is meant. Note: the ! * namespace is not output. */ if (def->arg != NULL) ! value = reloptGetString(def); else value = "true"; ! len = VARHDRSZ + strlen(def->optname) + 1 + strlen(value); /* +1 leaves room for sprintf's trailing null */ t = (text *) palloc(len + 1); SET_VARSIZE(t, len); ! sprintf(VARDATA(t), "%s=%s", def->optname, value); astate = accumArrayResult(astate, PointerGetDatum(t), false, TEXTOID, *************** default_reloptions(Datum reloptions, boo *** 944,950 **** } /* ! * Parse options for heaps (and perhaps someday toast tables). */ bytea * heap_reloptions(char relkind, Datum reloptions, bool validate) --- 1002,1008 ---- } /* ! * Parse options for heaps and toast tables. */ bytea * heap_reloptions(char relkind, Datum reloptions, bool validate)