text:
#include "postgres.h"

#include <float.h>

#include "access/gist_private.h"
#include "access/hash.h"
#include "access/htup_details.h"
#include "access/nbtree.h"
#include "access/reloptions.h"
#include "access/spgist.h"
#include "access/tuptoaster.h"
#include "catalog/pg_type.h"
#include "cdb/cdbappendonlyam.h"
#include "cdb/cdbvars.h"
#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "commands/view.h"
#include "nodes/makefuncs.h"
#include "postmaster/postmaster.h"
#include "utils/array.h"
#include "utils/attoptcache.h"
#include "utils/builtins.h"
#include "utils/formatting.h"
#include "utils/guc.h"
#include "utils/guc_tables.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "miscadmin.h"

/*
 * Contents of pg_class.reloptions
 *
 * To add an option:
 *
 * (i) decide on a type (integer, real, bool, string), name, default value,
 * upper and lower bounds (if applicable); for strings, consider a validation
 * routine.
 * (ii) add a record below (or use add_<type>_reloption).
 * (iii) add it to the appropriate options struct (perhaps StdRdOptions)
 * (iv) add it to the appropriate handling routine (perhaps
 * default_reloptions)
 * (v) make sure the lock level is set correctly for that operation
 * (vi) don't forget to document the option
 *
 * To add an GPDB option, please touch reloptions_gp.c rather than this file.
 *
 * The default choice for any new option should be AccessExclusiveLock.
 * In some cases the lock level can be reduced from there, but the lock
 * level chosen should always conflict with itself to ensure that multiple
 * changes aren't lost when we attempt concurrent changes.
 * The choice of lock level depends completely upon how that parameter
 * is used within the server, not upon how and when you'd like to change it.
 * Safety first. Existing choices are documented here, and elsewhere in
 * backend code where the parameters are used.
 *
 * In general, anything that affects the results obtained from a SELECT must be
 * protected by AccessExclusiveLock.
 *
 * Autovacuum related parameters can be set at ShareUpdateExclusiveLock
 * since they are only used by the AV procs and don't change anything
 * currently executing.
 *
 * Fillfactor can be set because it applies only to subsequent changes made to
 * data blocks, as documented in heapio.c
 *
 * n_distinct options can be set at ShareUpdateExclusiveLock because they
 * are only used during ANALYZE, which uses a ShareUpdateExclusiveLock,
 * so the ANALYZE will not be affected by in-flight changes. Changing those
 * values has no effect until the next ANALYZE, so no need for stronger lock.
 *
 * Planner-related parameters can be set with ShareUpdateExclusiveLock because
 * they only affect planning and not the correctness of the execution. Plans
 * cannot be changed in mid-flight, so changes here could not easily result in
 * new improved plans in any case. So we allow existing queries to continue
 * and existing plans to survive, a small price to pay for allowing better
 * plans to be introduced concurrently without interfering with users.
 *
 * Setting parallel_workers is safe, since it acts the same as
 * max_parallel_workers_per_gather which is a USERSET parameter that doesn't
 * affect existing plans or queries.
 *
 * vacuum_truncate can be set at ShareUpdateExclusiveLock because it
 * is only used during VACUUM, which uses a ShareUpdateExclusiveLock,
 * so the VACUUM will not be affected by in-flight changes. Changing its
 * value has no effect until the next VACUUM, so no need for stronger lock.
 */

static relopt_bool boolRelOpts[] =
{
	{
		{
			"autosummarize",
			"Enables automatic summarization on this BRIN index",
			RELOPT_KIND_BRIN,
			AccessExclusiveLock
		},
		false
	},
	{
		{
			"autovacuum_enabled",
			"Enables autovacuum in this relation",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		true
	},
	{
		{
			"user_catalog_table",
			"Declare a table as an additional catalog table, e.g. for the purpose of logical replication",
			RELOPT_KIND_HEAP,
			AccessExclusiveLock
		},
		false
	},
	{
		{
			"fastupdate",
			"Enables \"fast update\" feature for this GIN index",
			RELOPT_KIND_GIN,
			AccessExclusiveLock
		},
		true
	},
	{
		{
			"security_barrier",
			"View acts as a row security barrier",
			RELOPT_KIND_VIEW,
			AccessExclusiveLock
		},
		false
	},
	{
		{
			"vacuum_index_cleanup",
			"Enables index vacuuming and index cleanup",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		true
	},
	{
		{
			"vacuum_truncate",
			"Enables vacuum to truncate empty pages at the end of this table",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		true
	},
	/* list terminator */
	{{NULL}}
};

static relopt_int intRelOpts[] =
{
	{
		{
			"fillfactor",
			"Packs table pages only to this percentage",
			RELOPT_KIND_HEAP,
			ShareUpdateExclusiveLock	/* since it applies only to later
										 * inserts */
		},
		HEAP_DEFAULT_FILLFACTOR, HEAP_MIN_FILLFACTOR, 100
	},
	{
		{
			"fillfactor",
			"Packs btree index pages only to this percentage",
			RELOPT_KIND_BTREE,
			ShareUpdateExclusiveLock	/* since it applies only to later
										 * inserts */
		},
		BTREE_DEFAULT_FILLFACTOR, BTREE_MIN_FILLFACTOR, 100
	},
	{
		{
			"fillfactor",
			"Packs hash index pages only to this percentage",
			RELOPT_KIND_HASH,
			ShareUpdateExclusiveLock	/* since it applies only to later
										 * inserts */
		},
		HASH_DEFAULT_FILLFACTOR, HASH_MIN_FILLFACTOR, 100
	},
	{
		{
			"fillfactor",
			"Packs gist index pages only to this percentage",
			RELOPT_KIND_GIST,
			ShareUpdateExclusiveLock	/* since it applies only to later
										 * inserts */
		},
		GIST_DEFAULT_FILLFACTOR, GIST_MIN_FILLFACTOR, 100
	},
	{
		{
			"fillfactor",
			"Packs spgist index pages only to this percentage",
			RELOPT_KIND_SPGIST,
			ShareUpdateExclusiveLock	/* since it applies only to later
										 * inserts */
		},
		SPGIST_DEFAULT_FILLFACTOR, SPGIST_MIN_FILLFACTOR, 100
	},
	{
		{
			"autovacuum_vacuum_threshold",
			"Minimum number of tuple updates or deletes prior to vacuum",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 0, INT_MAX
	},
	{
		{
			"autovacuum_analyze_threshold",
			"Minimum number of tuple inserts, updates or deletes prior to analyze",
			RELOPT_KIND_HEAP,
			ShareUpdateExclusiveLock
		},
		-1, 0, INT_MAX
	},
	{
		{
			"autovacuum_vacuum_cost_limit",
			"Vacuum cost amount available before napping, for autovacuum",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 1, 10000
	},
	{
		{
			"autovacuum_freeze_min_age",
			"Minimum age at which VACUUM should freeze a table row, for autovacuum",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 0, 1000000000
	},
	{
		{
			"autovacuum_multixact_freeze_min_age",
			"Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 0, 1000000000
	},
	{
		{
			"autovacuum_freeze_max_age",
			"Age at which to autovacuum a table to prevent transaction ID wraparound",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 100000, 2000000000
	},
	{
		{
			"autovacuum_multixact_freeze_max_age",
			"Multixact age at which to autovacuum a table to prevent multixact wraparound",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 10000, 2000000000
	},
	{
		{
			"autovacuum_freeze_table_age",
			"Age at which VACUUM should perform a full table sweep to freeze row versions",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		}, -1, 0, 2000000000
	},
	{
		{
			"autovacuum_multixact_freeze_table_age",
			"Age of multixact at which VACUUM should perform a full table sweep to freeze row versions",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		}, -1, 0, 2000000000
	},
	{
		{
			"log_autovacuum_min_duration",
			"Sets the minimum execution time above which autovacuum actions will be logged",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, -1, INT_MAX
	},
	{
		{
			"toast_tuple_target",
			"Sets the target tuple length at which external columns will be toasted",
			RELOPT_KIND_HEAP,
			ShareUpdateExclusiveLock
		},
		TOAST_TUPLE_TARGET, 128, TOAST_TUPLE_TARGET_MAIN
	},
	{
		{
			"pages_per_range",
			"Number of pages that each page range covers in a BRIN index",
			RELOPT_KIND_BRIN,
			AccessExclusiveLock
		}, 128, 1, 131072
	},
	{
		{
			"gin_pending_list_limit",
			"Maximum size of the pending list for this GIN index, in kilobytes.",
			RELOPT_KIND_GIN,
			AccessExclusiveLock
		},
		-1, 64, MAX_KILOBYTES
	},
	{
		{
			"effective_io_concurrency",
			"Number of simultaneous requests that can be handled efficiently by the disk subsystem.",
			RELOPT_KIND_TABLESPACE,
			ShareUpdateExclusiveLock
		},
#ifdef USE_PREFETCH
		-1, 0, MAX_IO_CONCURRENCY
#else
		0, 0, 0
#endif
	},
	{
		{
			"parallel_workers",
			"Number of parallel processes that can be used per executor node for this relation.",
			RELOPT_KIND_HEAP,
			ShareUpdateExclusiveLock
		},
		-1, 0, 1024
	},

	/* list terminator */
	{{NULL}}
};

static relopt_real realRelOpts[] =
{
	{
		{
			"autovacuum_vacuum_cost_delay",
			"Vacuum cost delay in milliseconds, for autovacuum",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 0.0, 100.0
	},
	{
		{
			"autovacuum_vacuum_scale_factor",
			"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
			ShareUpdateExclusiveLock
		},
		-1, 0.0, 100.0
	},
	{
		{
			"autovacuum_analyze_scale_factor",
			"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
			RELOPT_KIND_HEAP,
			ShareUpdateExclusiveLock
		},
		-1, 0.0, 100.0
	},
	{
		{
			"seq_page_cost",
			"Sets the planner's estimate of the cost of a sequentially fetched disk page.",
			RELOPT_KIND_TABLESPACE,
			ShareUpdateExclusiveLock
		},
		-1, 0.0, DBL_MAX
	},
	{
		{
			"random_page_cost",
			"Sets the planner's estimate of the cost of a nonsequentially fetched disk page.",
			RELOPT_KIND_TABLESPACE,
			ShareUpdateExclusiveLock
		},
		-1, 0.0, DBL_MAX
	},
	{
		{
			"n_distinct",
			"Sets the planner's estimate of the number of distinct values appearing in a column (excluding child relations).",
			RELOPT_KIND_ATTRIBUTE,
			ShareUpdateExclusiveLock
		},
		0, -1.0, DBL_MAX
	},
	{
		{
			"n_distinct_inherited",
			"Sets the planner's estimate of the number of distinct values appearing in a column (including child relations).",
			RELOPT_KIND_ATTRIBUTE,
			ShareUpdateExclusiveLock
		},
		0, -1.0, DBL_MAX
	},
	{
		{
			"vacuum_cleanup_index_scale_factor",
			"Number of tuple inserts prior to index cleanup as a fraction of reltuples.",
			RELOPT_KIND_BTREE,
			ShareUpdateExclusiveLock
		},
		-1, 0.0, 1e10
	},
	/* list terminator */
	{{NULL}}
};

static relopt_string stringRelOpts[] =
{
	{
		{
			"buffering",
			"Enables buffering build for this GiST index",
			RELOPT_KIND_GIST,
			AccessExclusiveLock
		},
		4,
		false,
		gistValidateBufferingOption,
		"auto"
	},
	{
		{
			"check_option",
			"View has WITH CHECK OPTION defined (local or cascaded).",
			RELOPT_KIND_VIEW,
			AccessExclusiveLock
		},
		0,
		true,
		validateWithCheckOption,
		NULL
	},
	/* list terminator */
	{{NULL}}
};

static relopt_gen **relOpts = NULL;
static bits32 last_assigned_kind = RELOPT_KIND_LAST_DEFAULT;

static int	num_custom_options = 0;
static relopt_gen **custom_options = NULL;
static bool need_initialization = true;

static void initialize_reloptions(void);
static void parse_one_reloption(relopt_value *option, char *text_str,
								int text_len, bool validate);

/*
 * initialize_reloptions
 *		initialization routine, must be called before parsing
 *
 * Initialize the relOpts array and fill each variable's type and name length.
 */
static void
initialize_reloptions(void)
{
	int			i;
	int			j;

	initialize_reloptions_gp();

	j = 0;
	for (i = 0; boolRelOpts[i].gen.name; i++)
	{
		Assert(DoLockModesConflict(boolRelOpts[i].gen.lockmode,
								   boolRelOpts[i].gen.lockmode));
		j++;
	}
	for (i = 0; intRelOpts[i].gen.name; i++)
	{
		Assert(DoLockModesConflict(intRelOpts[i].gen.lockmode,
								   intRelOpts[i].gen.lockmode));
		j++;
	}
	for (i = 0; realRelOpts[i].gen.name; i++)
	{
		Assert(DoLockModesConflict(realRelOpts[i].gen.lockmode,
								   realRelOpts[i].gen.lockmode));
		j++;
	}
	for (i = 0; stringRelOpts[i].gen.name; i++)
	{
		Assert(DoLockModesConflict(stringRelOpts[i].gen.lockmode,
								   stringRelOpts[i].gen.lockmode));
		j++;
	}
	j += num_custom_options;

	if (relOpts)
		pfree(relOpts);
	relOpts = MemoryContextAlloc(TopMemoryContext,
								 (j + 1) * sizeof(relopt_gen *));

	j = 0;
	for (i = 0; boolRelOpts[i].gen.name; i++)
	{
		relOpts[j] = &boolRelOpts[i].gen;
		relOpts[j]->type = RELOPT_TYPE_BOOL;
		relOpts[j]->namelen = strlen(relOpts[j]->name);
		j++;
	}

	for (i = 0; intRelOpts[i].gen.name; i++)
	{
		relOpts[j] = &intRelOpts[i].gen;
		relOpts[j]->type = RELOPT_TYPE_INT;
		relOpts[j]->namelen = strlen(relOpts[j]->name);
		j++;
	}

	for (i = 0; realRelOpts[i].gen.name; i++)
	{
		relOpts[j] = &realRelOpts[i].gen;
		relOpts[j]->type = RELOPT_TYPE_REAL;
		relOpts[j]->namelen = strlen(relOpts[j]->name);
		j++;
	}

	for (i = 0; stringRelOpts[i].gen.name; i++)
	{
		relOpts[j] = &stringRelOpts[i].gen;
		relOpts[j]->type = RELOPT_TYPE_STRING;
		relOpts[j]->namelen = strlen(relOpts[j]->name);
		j++;
	}

	for (i = 0; i < num_custom_options; i++)
	{
		relOpts[j] = custom_options[i];
		j++;
	}

	/* add a list terminator */
	relOpts[j] = NULL;

	/* flag the work is complete */
	need_initialization = false;
}

/*
 * add_reloption_kind
 *		Create a new relopt_kind value, to be used in custom reloptions by
 *		user-defined AMs.
 */
relopt_kind
add_reloption_kind(void)
{
	/* don't hand out the last bit so that the enum's behavior is portable */
	if (last_assigned_kind >= RELOPT_KIND_MAX)
		ereport(ERROR,
				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
				 errmsg("user-defined relation parameter types limit exceeded")));
	last_assigned_kind <<= 1;
	return (relopt_kind) last_assigned_kind;
}

/*
 * add_reloption
 *		Add an already-created custom reloption to the list, and recompute the
 *		main parser table.
 */
static void
add_reloption(relopt_gen *newoption)
{
	static int	max_custom_options = 0;

	if (num_custom_options >= max_custom_options)
	{
		MemoryContext oldcxt;

		oldcxt = MemoryContextSwitchTo(TopMemoryContext);

		if (max_custom_options == 0)
		{
			max_custom_options = 8;
			custom_options = palloc(max_custom_options * sizeof(relopt_gen *));
		}
		else
		{
			max_custom_options *= 2;
			custom_options = repalloc(custom_options,
									  max_custom_options * sizeof(relopt_gen *));
		}
		MemoryContextSwitchTo(oldcxt);
	}
	custom_options[num_custom_options++] = newoption;

	need_initialization = true;
}

/*
 * allocate_reloption
 *		Allocate a new reloption and initialize the type-agnostic fields
 *		(for types other than string)
 */
static relopt_gen *
allocate_reloption(bits32 kinds, int type, const char *name, const char *desc)
{
	MemoryContext oldcxt;
	size_t		size;
	relopt_gen *newoption;

	oldcxt = MemoryContextSwitchTo(TopMemoryContext);

	switch (type)
	{
		case RELOPT_TYPE_BOOL:
			size = sizeof(relopt_bool);
			break;
		case RELOPT_TYPE_INT:
			size = sizeof(relopt_int);
			break;
		case RELOPT_TYPE_REAL:
			size = sizeof(relopt_real);
			break;
		case RELOPT_TYPE_STRING:
			size = sizeof(relopt_string);
			break;
		default:
			elog(ERROR, "unsupported reloption type %d", type);
			return NULL;		/* keep compiler quiet */
	}

	newoption = palloc(size);

	newoption->name = pstrdup(name);
	if (desc)
		newoption->desc = pstrdup(desc);
	else
		newoption->desc = NULL;
	newoption->kinds = kinds;
	newoption->namelen = strlen(name);
	newoption->type = type;

	MemoryContextSwitchTo(oldcxt);

	return newoption;
}

/*
 * GPDB: the add_*_reloption() functions don't take 'lockmode' argument,but
 * we need to set it correctly for the GPDB-specific options. So use this
 * to set it after calling add_*_reloption() function.
 */
void
set_reloption_lockmode(const char *name, LOCKMODE lockmode)
{
	for (int i = num_custom_options - 1; i >= 0; i--)
	{
		if (strcmp(custom_options[i]->name, name) == 0)
		{
			custom_options[i]->lockmode = lockmode;
			return;
		}
	}
	elog(ERROR, "could not find reloption \"%s\"", name);
}

/*
 * add_bool_reloption
 *		Add a new boolean reloption
 */
void
add_bool_reloption(bits32 kinds, const char *name, const char *desc, bool default_val)
{
	relopt_bool *newoption;

	newoption = (relopt_bool *) allocate_reloption(kinds, RELOPT_TYPE_BOOL,
												   name, desc);
	newoption->default_val = default_val;

	add_reloption((relopt_gen *) newoption);
}

/*
 * add_int_reloption
 *		Add a new integer reloption
 */
void
add_int_reloption(bits32 kinds, const char *name, const char *desc, int default_val,
				  int min_val, int max_val)
{
	relopt_int *newoption;

	newoption = (relopt_int *) allocate_reloption(kinds, RELOPT_TYPE_INT,
												  name, desc);
	newoption->default_val = default_val;
	newoption->min = min_val;
	newoption->max = max_val;

	add_reloption((relopt_gen *) newoption);
}

/*
 * add_real_reloption
 *		Add a new float reloption
 */
void
add_real_reloption(bits32 kinds, const char *name, const char *desc, double default_val,
				   double min_val, double max_val)
{
	relopt_real *newoption;

	newoption = (relopt_real *) allocate_reloption(kinds, RELOPT_TYPE_REAL,
												   name, desc);
	newoption->default_val = default_val;
	newoption->min = min_val;
	newoption->max = max_val;

	add_reloption((relopt_gen *) newoption);
}

/*
 * add_string_reloption
 *		Add a new string reloption
 *
 * "validator" is an optional function pointer that can be used to test the
 * validity of the values.  It must elog(ERROR) when the argument string is
 * not acceptable for the variable.  Note that the default value must pass
 * the validation.
 */
void
add_string_reloption(bits32 kinds, const char *name, const char *desc, const char *default_val,
					 validate_string_relopt validator)
{
	relopt_string *newoption;

	/* make sure the validator/default combination is sane */
	if (validator)
		(validator) (default_val);

	newoption = (relopt_string *) allocate_reloption(kinds, RELOPT_TYPE_STRING,
													 name, desc);
	newoption->validate_cb = validator;
	if (default_val)
	{
		newoption->default_val = MemoryContextStrdup(TopMemoryContext,
													 default_val);
		newoption->default_len = strlen(default_val);
		newoption->default_isnull = false;
	}
	else
	{
		newoption->default_val = "";
		newoption->default_len = 0;
		newoption->default_isnull = true;
	}

	add_reloption((relopt_gen *) newoption);
}

/*
 * Transform a relation options list (list of DefElem) 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
 * reloptions value (possibly NULL), and we replace or remove entries
 * as needed.
 *
 * If acceptOidsOff is true, then we allow oids = false, but throw error when
 * on. This is solely needed for backwards compatibility.
 *
 * 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 need not be
 * explicitly 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, const char *namspace,
					char *validnsps[], bool acceptOidsOff, bool isReset)
{
	Datum		result;
	ArrayBuildState *astate;
	ListCell   *cell;

	/* no change if empty list */
	if (defList == NIL)
		return oldOptions;

	/* We build new array using accumArrayResult */
	astate = NULL;

	/* Copy any oldOptions that aren't to be replaced */
	if (PointerIsValid(DatumGetPointer(oldOptions)))
	{
		ArrayType  *array = DatumGetArrayTypeP(oldOptions);
		Datum	   *oldoptions;
		int			noldoptions;
		int			i;

		deconstruct_array(array, TEXTOID, -1, false, 'i',
						  &oldoptions, NULL, &noldoptions);

		for (i = 0; i < noldoptions; i++)
		{
			char	   *text_str = VARDATA(oldoptions[i]);
			int			text_len = VARSIZE(oldoptions[i]) - VARHDRSZ;

			/* Search for a match in defList */
			foreach(cell, defList)
			{
				DefElem    *def = (DefElem *) lfirst(cell);
				int			kw_len;

				/* ignore if not in the same namespace */
				if (namspace == NULL)
				{
					if (def->defnamespace != NULL)
						continue;
				}
				else if (def->defnamespace == NULL)
					continue;
				else if (strcmp(def->defnamespace, namspace) != 0)
					continue;

				kw_len = strlen(def->defname);
				if (text_len > kw_len && text_str[kw_len] == '=' &&
					strncmp(text_str, def->defname, kw_len) == 0)
					break;
			}
			if (!cell)
			{
				/* No match, so keep old option */
				astate = accumArrayResult(astate, oldoptions[i],
										  false, TEXTOID,
										  CurrentMemoryContext);
			}
		}
	}

	/*
	 * If CREATE/SET, add new options to array; if RESET, just check that the
	 * user didn't say RESET (option=val).  (Must do this because the grammar
	 * doesn't enforce it.)
	 */
	foreach(cell, defList)
	{
		DefElem    *def = (DefElem *) lfirst(cell);

		if (isReset)
		{
			if (def->arg != NULL)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("RESET must not include values for parameters")));
		}
		else
		{
			text	   *t;
			const char *value;
			Size		len;

			/*
			 * Error out if the namespace is not valid.  A NULL namespace is
			 * always valid.
			 */
			if (def->defnamespace != NULL)
			{
				bool		valid = false;
				int			i;

				if (validnsps)
				{
					for (i = 0; validnsps[i]; i++)
					{
						if (strcmp(def->defnamespace, validnsps[i]) == 0)
						{
							valid = true;
							break;
						}
					}
				}

				if (!valid)
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
							 errmsg("unrecognized parameter namespace \"%s\"",
									def->defnamespace)));
			}

			/* ignore if not in the same namespace */
			if (namspace == NULL)
			{
				if (def->defnamespace != NULL)
					continue;
			}
			else if (def->defnamespace == NULL)
				continue;
			else if (strcmp(def->defnamespace, namspace) != 0)
				continue;

			/*
			 * Flatten the DefElem 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 = defGetString(def);
			else
				value = "true";

			/*
			 * This is not a great place for this test, but there's no other
			 * convenient place to filter the option out. As WITH (oids =
			 * false) will be removed someday, this seems like an acceptable
			 * amount of ugly.
			 */
			if (acceptOidsOff && def->defnamespace == NULL &&
				strcmp(def->defname, "oids") == 0)
			{
				if (defGetBoolean(def))
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("tables declared WITH OIDS are not supported")));
				/* skip over option, reloptions machinery doesn't know it */
				continue;
			}

			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,
									  CurrentMemoryContext);
		}
	}

	if (astate)
		result = makeArrayResult(astate, CurrentMemoryContext);
	else
		result = (Datum) 0;

	return result;
}

/*
 * Convert the text-array format of reloptions into a List of DefElem.
 * This is the inverse of transformRelOptions().
 */
List *
untransformRelOptions(Datum options)
{
	List	   *result = NIL;
	ArrayType  *array;
	Datum	   *optiondatums;
	int			noptions;
	int			i;

	/* Nothing to do if no options */
	if (!PointerIsValid(DatumGetPointer(options)))
		return result;

	array = DatumGetArrayTypeP(options);

	deconstruct_array(array, TEXTOID, -1, false, 'i',
					  &optiondatums, NULL, &noptions);

	for (i = 0; i < noptions; i++)
	{
		char	   *s;
		char	   *p;
		Node	   *val = NULL;

		s = TextDatumGetCString(optiondatums[i]);
		p = strchr(s, '=');
		if (p)
		{
			*p++ = '\0';
			val = (Node *) makeString(pstrdup(p));
		}
		result = lappend(result, makeDefElem(pstrdup(s), val, -1));
	}

	return result;
}

/*
 * Extract and parse reloptions from a pg_class tuple.
 *
 * This is a low-level routine, expected to be used by relcache code and
 * callers that do not have a table's relcache entry (e.g. autovacuum).  For
 * other uses, consider grabbing the rd_options pointer from the relcache entry
 * instead.
 *
 * tupdesc is pg_class' tuple descriptor.  amoptions is a pointer to the index
 * AM's options parser function in the case of a tuple corresponding to an
 * index, or NULL otherwise.
 */
bytea *
extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
				  amoptions_function amoptions)
{
	bytea	   *options;
	bool		isnull;
	Datum		datum;
	Form_pg_class classForm;

	datum = fastgetattr(tuple,
						Anum_pg_class_reloptions,
						tupdesc,
						&isnull);
	if (isnull)
		return NULL;

	classForm = (Form_pg_class) GETSTRUCT(tuple);

	/* Parse into appropriate format; don't error out here */
	switch (classForm->relkind)
	{
		case RELKIND_RELATION:
		case RELKIND_TOASTVALUE:
		case RELKIND_MATVIEW:
		case RELKIND_PARTITIONED_TABLE:
			options = heap_reloptions(classForm->relkind, datum, false);
			break;
		case RELKIND_VIEW:
			options = view_reloptions(datum, false);
			break;
		case RELKIND_INDEX:
		case RELKIND_PARTITIONED_INDEX:
			options = index_reloptions(amoptions, datum, false);
			break;
		case RELKIND_FOREIGN_TABLE:
			options = NULL;
			break;
		default:
			Assert(false);		/* can't get here */
			options = NULL;		/* keep compiler quiet */
			break;
	}

	return options;
}

/*
 * Interpret reloptions that are given in text-array format.
 *
 * options is a reloption text array as constructed by transformRelOptions.
 * kind specifies the family of options to be processed.
 *
 * The return value is a relopt_value * array on which the options actually
 * set in the options array are marked with isset=true.  The length of this
 * array is returned in *numrelopts.  Options not set are also present in the
 * array; this is so that the caller can easily locate the default values.
 *
 * If there are no options of the given kind, numrelopts is set to 0 and NULL
 * is returned (unless options are illegally supplied despite none being
 * defined, in which case an error occurs).
 *
 * Note: values of type int, bool and real are allocated as part of the
 * returned array.  Values of type string are allocated separately and must
 * be freed by the caller.
 */
relopt_value *
parseRelOptions(Datum options, bool validate, relopt_kind kind,
				int *numrelopts)
{
	relopt_value *reloptions = NULL;
	int			numoptions = 0;
	int			i;
	int			j;

	if (need_initialization)
		initialize_reloptions();

	/* Build a list of expected options, based on kind */

	for (i = 0; relOpts[i]; i++)
		if (relOpts[i]->kinds & kind)
			numoptions++;

	if (numoptions > 0)
	{
		reloptions = palloc(numoptions * sizeof(relopt_value));

		for (i = 0, j = 0; relOpts[i]; i++)
		{
			if (relOpts[i]->kinds & kind)
			{
				reloptions[j].gen = relOpts[i];
				reloptions[j].isset = false;
				j++;
			}
		}
	}

	/* Done if no options */
	if (PointerIsValid(DatumGetPointer(options)))
	{
		ArrayType  *array = DatumGetArrayTypeP(options);
		Datum	   *optiondatums;
		int			noptions;

		deconstruct_array(array, TEXTOID, -1, false, 'i',
						  &optiondatums, NULL, &noptions);

		for (i = 0; i < noptions; i++)
		{
			char	   *text_str = VARDATA(optiondatums[i]);
			int			text_len = VARSIZE(optiondatums[i]) - VARHDRSZ;
			int			j;

			/* Search for a match in reloptions */
			for (j = 0; j < numoptions; j++)
			{
				int			kw_len = reloptions[j].gen->namelen;

				if (text_len > kw_len && text_str[kw_len] == '=' &&
					strncmp(text_str, reloptions[j].gen->name, kw_len) == 0)
				{
					parse_one_reloption(&reloptions[j], text_str, text_len,
										validate);
					break;
				}
			}

			if (j >= numoptions && validate)
			{
				char	   *s;
				char	   *p;

				s = TextDatumGetCString(optiondatums[i]);
				p = strchr(s, '=');
				if (p)
					*p = '\0';
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						 errmsg("unrecognized parameter \"%s\"", s)));
			}
		}

		/* It's worth avoiding memory leaks in this function */
		pfree(optiondatums);
		if (((void *) array) != DatumGetPointer(options))
			pfree(array);
	}

	*numrelopts = numoptions;
	return reloptions;
}

/*
 * Subroutine for parseRelOptions, to parse and validate a single option's
 * value
 */
static void
parse_one_reloption(relopt_value *option, char *text_str, int text_len,
					bool validate)
{
	char	   *value;
	int			value_len;
	bool		parsed;
	bool		nofree = false;

	if (option->isset && validate)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("parameter \"%s\" specified more than once",
						option->gen->name)));

	value_len = text_len - option->gen->namelen - 1;
	value = (char *) palloc(value_len + 1);
	memcpy(value, text_str + option->gen->namelen + 1, value_len);
	value[value_len] = '\0';

	switch (option->gen->type)
	{
		case RELOPT_TYPE_BOOL:
			{
				parsed = parse_bool(value, &option->values.bool_val);
				if (validate && !parsed)
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
							 errmsg("invalid value for boolean option \"%s\": %s",
									option->gen->name, value)));
			}
			break;
		case RELOPT_TYPE_INT:
			{
				relopt_int *optint = (relopt_int *) option->gen;

				parsed = parse_int(value, &option->values.int_val, 0, NULL);
				if (validate && !parsed)
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
							 errmsg("invalid value for integer option \"%s\": %s",
									option->gen->name, value)));
				if (validate && (option->values.int_val < optint->min ||
								 option->values.int_val > optint->max))
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
							 errmsg("value %s out of bounds for option \"%s\"",
									value, option->gen->name),
							 errdetail("Valid values are between \"%d\" and \"%d\".",
									   optint->min, optint->max)));
			}
			break;
		case RELOPT_TYPE_REAL:
			{
				relopt_real *optreal = (relopt_real *) option->gen;

				parsed = parse_real(value, &option->values.real_val, 0, NULL);
				if (validate && !parsed)
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
							 errmsg("invalid value for floating point option \"%s\": %s",
									option->gen->name, value)));
				if (validate && (option->values.real_val < optreal->min ||
								 option->values.real_val > optreal->max))
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
							 errmsg("value %s out of bounds for option \"%s\"",
									value, option->gen->name),
							 errdetail("Valid values are between \"%f\" and \"%f\".",
									   optreal->min, optreal->max)));
			}
			break;
		case RELOPT_TYPE_STRING:
			{
				relopt_string *optstring = (relopt_string *) option->gen;

				option->values.string_val = value;
				nofree = true;
				if (validate && optstring->validate_cb)
					(optstring->validate_cb) (value);
				parsed = true;
			}
			break;
		default:
			elog(ERROR, "unsupported reloption type %d", option->gen->type);
			parsed = true;		/* quiet compiler */
			break;
	}

	if (parsed)
		option->isset = true;
	if (!nofree)
		pfree(value);
}

/*
 * Given the result from parseRelOptions, allocate a struct that's of the
 * specified base size plus any extra space that's needed for string variables.
 *
 * "base" should be sizeof(struct) of the reloptions struct (StdRdOptions or
 * equivalent).
 */
void *
allocateReloptStruct(Size base, relopt_value *options, int numoptions)
{
	Size		size = base;
	int			i;

	for (i = 0; i < numoptions; i++)
		if (options[i].gen->type == RELOPT_TYPE_STRING)
			size += GET_STRING_RELOPTION_LEN(options[i]) + 1;

	return palloc0(size);
}

/*
 * Given the result of parseRelOptions and a parsing table, fill in the
 * struct (previously allocated with allocateReloptStruct) with the parsed
 * values.
 *
 * rdopts is the pointer to the allocated struct to be filled.
 * basesize is the sizeof(struct) that was passed to allocateReloptStruct.
 * options, of length numoptions, is parseRelOptions' output.
 * elems, of length numelems, is the table describing the allowed options.
 * When validate is true, it is expected that all options appear in elems.
 */
void
fillRelOptions(void *rdopts, Size basesize,
			   relopt_value *options, int numoptions,
			   bool validate,
			   const relopt_parse_elt *elems, int numelems)
{
	int			i;
	int			offset = basesize;

	for (i = 0; i < numoptions; i++)
	{
		int			j;
		bool		found = false;

		for (j = 0; j < numelems; j++)
		{
			if (strcmp(options[i].gen->name, elems[j].optname) == 0)
			{
				relopt_string *optstring;
				char	   *itempos = ((char *) rdopts) + elems[j].offset;
				char	   *string_val;

				switch (options[i].gen->type)
				{
					case RELOPT_TYPE_BOOL:
						*(bool *) itempos = options[i].isset ?
							options[i].values.bool_val :
							((relopt_bool *) options[i].gen)->default_val;
						break;
					case RELOPT_TYPE_INT:
						*(int *) itempos = options[i].isset ?
							options[i].values.int_val :
							((relopt_int *) options[i].gen)->default_val;
						break;
					case RELOPT_TYPE_REAL:
						*(double *) itempos = options[i].isset ?
							options[i].values.real_val :
							((relopt_real *) options[i].gen)->default_val;
						break;
					case RELOPT_TYPE_STRING:
						optstring = (relopt_string *) options[i].gen;
						if (options[i].isset)
							string_val = options[i].values.string_val;
						else if (!optstring->default_isnull)
							string_val = optstring->default_val;
						else
							string_val = NULL;

						if (string_val == NULL)
							*(int *) itempos = 0;
						else
						{
							strcpy((char *) rdopts + offset, string_val);
							*(int *) itempos = offset;
							offset += strlen(string_val) + 1;
						}
						break;
					default:
						elog(ERROR, "unsupported reloption type %d",
							 options[i].gen->type);
						break;
				}
				found = true;
				break;
			}
		}
		if (validate && !found)
			elog(ERROR, "reloption \"%s\" not found in parse table",
				 options[i].gen->name);
	}
	SET_VARSIZE(rdopts, offset);
}

/*
 * Option parser for anything that uses StdRdOptions.
 */
bytea *
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
{
	relopt_value *options;
	StdRdOptions *rdopts;
	int			numoptions;
	static const relopt_parse_elt tab[] = {
		{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)},

		/* AO table options */
		{SOPT_BLOCKSIZE, RELOPT_TYPE_INT, offsetof(StdRdOptions, blocksize)},
		{SOPT_COMPLEVEL, RELOPT_TYPE_INT, offsetof(StdRdOptions, compresslevel)},
		{SOPT_COMPTYPE, RELOPT_TYPE_STRING, offsetof(StdRdOptions, compresstype)},
		{SOPT_CHECKSUM, RELOPT_TYPE_BOOL, offsetof(StdRdOptions, checksum)},

		{"autovacuum_enabled", RELOPT_TYPE_BOOL,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, enabled)},
		{"autovacuum_vacuum_threshold", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold)},
		{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold)},
		{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit)},
		{"autovacuum_freeze_min_age", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_min_age)},
		{"autovacuum_freeze_max_age", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_max_age)},
		{"autovacuum_freeze_table_age", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_table_age)},
		{"autovacuum_multixact_freeze_min_age", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_min_age)},
		{"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_max_age)},
		{"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_table_age)},
		{"log_autovacuum_min_duration", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)},
		{"toast_tuple_target", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, toast_tuple_target)},
		{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_REAL,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)},
		{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)},
		{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_scale_factor)},
		{"user_catalog_table", RELOPT_TYPE_BOOL,
		offsetof(StdRdOptions, user_catalog_table)},
		{"parallel_workers", RELOPT_TYPE_INT,
		offsetof(StdRdOptions, parallel_workers)},
		{"vacuum_cleanup_index_scale_factor", RELOPT_TYPE_REAL,
		offsetof(StdRdOptions, vacuum_cleanup_index_scale_factor)},
		{"vacuum_index_cleanup", RELOPT_TYPE_BOOL,
		offsetof(StdRdOptions, vacuum_index_cleanup)},
		{"vacuum_truncate", RELOPT_TYPE_BOOL,
		offsetof(StdRdOptions, vacuum_truncate)}
	};

	options = parseRelOptions(reloptions, validate, kind, &numoptions);

	/* if none set, we're done */
	if (numoptions == 0)
		return NULL;

	rdopts = allocateReloptStruct(sizeof(StdRdOptions), options, numoptions);

	fillRelOptions((void *) rdopts, sizeof(StdRdOptions), options, numoptions,
				   validate, tab, lengthof(tab));

	validate_and_refill_options(rdopts, options, numoptions, kind, validate);

	pfree(options);

	return (bytea *) rdopts;
}

/*
 * Option parser for views
 */
bytea *
view_reloptions(Datum reloptions, bool validate)
{
	relopt_value *options;
	ViewOptions *vopts;
	int			numoptions;
	static const relopt_parse_elt tab[] = {
		{"security_barrier", RELOPT_TYPE_BOOL,
		offsetof(ViewOptions, security_barrier)},
		{"check_option", RELOPT_TYPE_STRING,
		offsetof(ViewOptions, check_option_offset)}
	};

	options = parseRelOptions(reloptions, validate, RELOPT_KIND_VIEW, &numoptions);

	/* if none set, we're done */
	if (numoptions == 0)
		return NULL;

	vopts = allocateReloptStruct(sizeof(ViewOptions), options, numoptions);

	fillRelOptions((void *) vopts, sizeof(ViewOptions), options, numoptions,
				   validate, tab, lengthof(tab));

	pfree(options);

	return (bytea *) vopts;
}

/*
 * Parse options for heaps, views and toast tables.
 */
bytea *
heap_reloptions(char relkind, Datum reloptions, bool validate)
{
	StdRdOptions *rdopts;

	switch (relkind)
	{
		case RELKIND_TOASTVALUE:
			rdopts = (StdRdOptions *)
				default_reloptions(reloptions, validate, RELOPT_KIND_TOAST);
			if (rdopts != NULL)
			{
				/* adjust default-only parameters for TOAST relations */
				rdopts->fillfactor = 100;
				rdopts->autovacuum.analyze_threshold = -1;
				rdopts->autovacuum.analyze_scale_factor = -1;
			}
			return (bytea *) rdopts;
		case RELKIND_RELATION:
		case RELKIND_MATVIEW:
				return default_reloptions(reloptions, validate,
										  RELOPT_KIND_HEAP);
		case RELKIND_PARTITIONED_TABLE:
			/*
			 * GPDB_12_AFTER_MERGE_FIXME: should we accept AO-related options for
			 * partitioned tables? A partitioned table has no data, but the options
			 * might be inherited by partitions.
			 */
			return default_reloptions(reloptions, validate,
									  RELOPT_KIND_PARTITIONED);
		default:
			/* other relkinds are not supported */
			return NULL;
	}
}

/*
 * Parse options for indexes.
 *
 *	amoptions	index AM's option parser function
 *	reloptions	options as text[] datum
 *	validate	error flag
 */
bytea *
index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate)
{
	Assert(amoptions != NULL);

	/* Assume function is strict */
	if (!PointerIsValid(DatumGetPointer(reloptions)))
		return NULL;

	return amoptions(reloptions, validate);
}

/*
 * Option parser for attribute reloptions
 */
bytea *
attribute_reloptions(Datum reloptions, bool validate)
{
	relopt_value *options;
	AttributeOpts *aopts;
	int			numoptions;
	static const relopt_parse_elt tab[] = {
		{"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)},
		{"n_distinct_inherited", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct_inherited)}
	};

	options = parseRelOptions(reloptions, validate, RELOPT_KIND_ATTRIBUTE,
							  &numoptions);

	/* if none set, we're done */
	if (numoptions == 0)
		return NULL;

	aopts = allocateReloptStruct(sizeof(AttributeOpts), options, numoptions);

	fillRelOptions((void *) aopts, sizeof(AttributeOpts), options, numoptions,
				   validate, tab, lengthof(tab));

	pfree(options);

	return (bytea *) aopts;
}

/*
 * Option parser for tablespace reloptions
 */
bytea *
tablespace_reloptions(Datum reloptions, bool validate)
{
	relopt_value *options;
	TableSpaceOpts *tsopts;
	int			numoptions;
	static const relopt_parse_elt tab[] = {
		{"random_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, random_page_cost)},
		{"seq_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, seq_page_cost)},
		{"effective_io_concurrency", RELOPT_TYPE_INT, offsetof(TableSpaceOpts, effective_io_concurrency)}
	};

	options = parseRelOptions(reloptions, validate, RELOPT_KIND_TABLESPACE,
							  &numoptions);

	/* if none set, we're done */
	if (numoptions == 0)
		return NULL;

	tsopts = allocateReloptStruct(sizeof(TableSpaceOpts), options, numoptions);

	fillRelOptions((void *) tsopts, sizeof(TableSpaceOpts), options, numoptions,
				   validate, tab, lengthof(tab));

	pfree(options);

	return (bytea *) tsopts;
}

/*
 * Determine the required LOCKMODE from an option list.
 *
 * Called from AlterTableGetLockLevel(), see that function
 * for a longer explanation of how this works.
 */
LOCKMODE
AlterTableGetRelOptionsLockLevel(List *defList)
{
	LOCKMODE	lockmode = NoLock;
	ListCell   *cell;

	if (defList == NIL)
		return AccessExclusiveLock;

	if (need_initialization)
		initialize_reloptions();

	foreach(cell, defList)
	{
		DefElem    *def = (DefElem *) lfirst(cell);
		int			i;

		for (i = 0; relOpts[i]; i++)
		{
			if (strncmp(relOpts[i]->name,
						def->defname,
						relOpts[i]->namelen + 1) == 0)
			{
				if (lockmode < relOpts[i]->lockmode)
					lockmode = relOpts[i]->lockmode;
			}
		}
	}

	return lockmode;
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Mycosphaerella mulgedii-alpini Petr.

### Remarks
null

redpajama_set_name: RedPajamaGithub


text:
var common = require('./common.js');

var async = require('async');
var breach = require('breach_module');

// ### devtools
//
// ```
// @spec { http_port }
// ```
var devtools = function(spec, my) {
  var _super = {};
  my = my || {};
  spec = spec || {};

  my.http_port = spec.http_port;
  my.devtools_url = null;

  my.sockets = [];

  //
  // ### _public_
  //
  var handshake;                 /* handshake(socket) */
  var init;                      /* init(cb_); */
  var kill;                      /* kill(cb_); */

  //
  // ### _private_
  //
  var socket_push;               /* socket_push(); */

  var stack_devtools_handler;    /* stack_devtools_handler(evt); */

  //
  // ### _exposed_
  //

  var that = {};

  /****************************************************************************/
  /* PRIVATE HELPERS */
  /****************************************************************************/
  // ### socket_push
  //
  // Pushes the current state on the UI socket
  socket_push = function() {
    var update = {
      devtools_url: my.devtools_url ||
        'http://localhost:' + my.http_port + '/devtools/blank.html',
    };
    my.sockets.forEach(function(s) {
      s.emit('state', update);
    });
  };

  /****************************************************************************/
  /* CORE EVENT HANDLERS */
  /****************************************************************************/

  /****************************************************************************/
  /* SOCKET EVENT HANDLERS */
  /****************************************************************************/

  /****************************************************************************/
  /* STACK EVENT HANDLERS */
  /****************************************************************************/
  // ### stack_devtools_handler
  //
  // Handler called when the mod_stack requests to display the dev tools on
  // a given URL.
  // ```
  // @evt {object} the event data
  // ```
  stack_devtools_handler = function(evt) {
    if(my.devtools_url !== evt.devtools_url) {
      my.devtools_url = evt.devtools_url;
      if(my.devtools_url) {
        breach.module('core').call('controls_dimension', {
          type: 'BOTTOM',
          dimension: 400,
          focus: true
        });
      }
      else {
        breach.module('core').call('controls_dimension', {
          type: 'BOTTOM',
          dimension: 0
        });
      }
      socket_push();
    }
  };

  /****************************************************************************/
  /* PUBLIC METHODS */
  /****************************************************************************/
  // ### handshake
  //
  // Called when the UI client connected to the Socket
  // ```
  // @socket {socket.io} the socket.io to connect with
  // ```
  handshake = function(socket) {
    common.log.out('[devtools] HANDSHAKE');
    my.sockets.unshift(socket);
    socket_push();

    socket.on('disconnect', function() {
      common.log.out('[devtools] disconnect');
      common.remove(my.sockets, socket, true);
    });
  };

  // ### init
  //
  // Called at initialisation of the module
  // ```
  // @cb_  {function(err)} the async callback
  // ```
  init = function(cb_) {
    breach.module(null).on('devtools', stack_devtools_handler);

    breach.module('core').call('controls_set', {
      type: 'BOTTOM',
      url: 'http://localhost:' + my.http_port + '/devtools',
      dimension: 0
    });

    return cb_();
  };

  // ### kill
  //
  // Called at destruction of the module
  // ```
  // @cb_  {function(err)} the async callback
  // ```
  kill = function(cb_) {
    breach.module('core').call('controls_unset', {
      type: 'BOTTOM',
    }, cb_);
  };

  common.method(that, 'init', init, _super);
  common.method(that, 'kill', kill, _super);

  common.method(that, 'handshake', handshake, _super);

  return that;
};

exports.devtools = devtools;


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>WindowConstants (Java Platform SE 7 )</title>
<meta name="date" content="2014-12-18">
<meta name="keywords" content="javax.swing.WindowConstants interface">
<meta name="keywords" content="DO_NOTHING_ON_CLOSE">
<meta name="keywords" content="HIDE_ON_CLOSE">
<meta name="keywords" content="DISPOSE_ON_CLOSE">
<meta name="keywords" content="EXIT_ON_CLOSE">
<link rel="stylesheet" type="text/css" href="../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Java™ Platform
Standard Ed. 7

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

javax.swing

Interface WindowConstants

All Known Implementing Classes:

JDialog, JFrame, JInternalFrame

public interface WindowConstants

Constants used to control the window-closing operation.
 The setDefaultCloseOperation and
 getDefaultCloseOperation methods
 provided by JFrame,
 JInternalFrame, and
 JDialog
 use these constants.
 For examples of setting the default window-closing operation, see
 Responding to Window-Closing Events,
 a section in The Java Tutorial.

See Also:

JFrame.setDefaultCloseOperation(int),
JDialog.setDefaultCloseOperation(int),
JInternalFrame.setDefaultCloseOperation(int)

Field Summary

Fields

Modifier and Type
Field and Description

static int
DISPOSE_ON_CLOSE

The dispose-window default window close operation.

static int
DO_NOTHING_ON_CLOSE

The do-nothing default window close operation.

static int
EXIT_ON_CLOSE

The exit application default window close operation.

static int
HIDE_ON_CLOSE

The hide-window default window close operation

Field Detail

DO_NOTHING_ON_CLOSE

static final int DO_NOTHING_ON_CLOSE

The do-nothing default window close operation.

See Also:

Constant Field Values

HIDE_ON_CLOSE

static final int HIDE_ON_CLOSE

The hide-window default window close operation

See Also:

Constant Field Values

DISPOSE_ON_CLOSE

static final int DISPOSE_ON_CLOSE

The dispose-window default window close operation.

 Note: When the last displayable window
 within the Java virtual machine (VM) is disposed of, the VM may
 terminate.  See
 AWT Threading Issues for more information.

See Also:

Window.dispose(),
JInternalFrame.dispose(),
Constant Field Values

EXIT_ON_CLOSE

static final int EXIT_ON_CLOSE

The exit application default window close operation. Attempting
 to set this on Windows that support this, such as
 JFrame, may throw a SecurityException based
 on the SecurityManager.
 It is recommended you only use this in an application.

Since:

1.4

See Also:

JFrame.setDefaultCloseOperation(int),
Constant Field Values

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Java™ Platform
Standard Ed. 7

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

 Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
 Copyright © 1993, 2015, Oracle and/or its affiliates.  All rights reserved.


text:
<?php

namespace Delight\Auth;

use Delight\Db\PdoDatabase;
use Delight\Db\PdoDsn;
use Delight\Db\Throwable\Error;

/** Component that can be used for administrative tasks by privileged and authorized users */
final class Administration extends UserManager {

	/**
	 * @param PdoDatabase|PdoDsn|\PDO $databaseConnection the database connection to operate on
	 * @param string|null $dbTablePrefix (optional) the prefix for the names of all database tables used by this component
	 * @param string|null $dbSchema (optional) the schema name for all database tables used by this component
	 */
	public function __construct($databaseConnection, $dbTablePrefix = null, $dbSchema = null) {
		parent::__construct($databaseConnection, $dbTablePrefix, $dbSchema);
	}

	/**
	 * Creates a new user
	 *
	 * @param string $email the email address to register
	 * @param string $password the password for the new account
	 * @param string|null $username (optional) the username that will be displayed
	 * @return int the ID of the user that has been created (if any)
	 * @throws InvalidEmailException if the email address was invalid
	 * @throws InvalidPasswordException if the password was invalid
	 * @throws UserAlreadyExistsException if a user with the specified email address already exists
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function createUser($email, $password, $username = null) {
		return $this->createUserInternal(false, $email, $password, $username, null);
	}

	/**
	 * Creates a new user while ensuring that the username is unique
	 *
	 * @param string $email the email address to register
	 * @param string $password the password for the new account
	 * @param string|null $username (optional) the username that will be displayed
	 * @return int the ID of the user that has been created (if any)
	 * @throws InvalidEmailException if the email address was invalid
	 * @throws InvalidPasswordException if the password was invalid
	 * @throws UserAlreadyExistsException if a user with the specified email address already exists
	 * @throws DuplicateUsernameException if the specified username wasn't unique
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function createUserWithUniqueUsername($email, $password, $username = null) {
		return $this->createUserInternal(true, $email, $password, $username, null);
	}

	/**
	 * Deletes the user with the specified ID
	 *
	 * This action cannot be undone
	 *
	 * @param int $id the ID of the user to delete
	 * @throws UnknownIdException if no user with the specified ID has been found
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function deleteUserById($id) {
		$numberOfDeletedUsers = $this->deleteUsersByColumnValue('id', (int) $id);

		if ($numberOfDeletedUsers === 0) {
			throw new UnknownIdException();
		}
	}

	/**
	 * Deletes the user with the specified email address
	 *
	 * This action cannot be undone
	 *
	 * @param string $email the email address of the user to delete
	 * @throws InvalidEmailException if no user with the specified email address has been found
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function deleteUserByEmail($email) {
		$email = self::validateEmailAddress($email);

		$numberOfDeletedUsers = $this->deleteUsersByColumnValue('email', $email);

		if ($numberOfDeletedUsers === 0) {
			throw new InvalidEmailException();
		}
	}

	/**
	 * Deletes the user with the specified username
	 *
	 * This action cannot be undone
	 *
	 * @param string $username the username of the user to delete
	 * @throws UnknownUsernameException if no user with the specified username has been found
	 * @throws AmbiguousUsernameException if multiple users with the specified username have been found
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function deleteUserByUsername($username) {
		$userData = $this->getUserDataByUsername(
			\trim($username),
			[ 'id' ]
		);

		$this->deleteUsersByColumnValue('id', (int) $userData['id']);
	}

	/**
	 * Assigns the specified role to the user with the given ID
	 *
	 * A user may have any number of roles (i.e. no role at all, a single role, or any combination of roles)
	 *
	 * @param int $userId the ID of the user to assign the role to
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @throws UnknownIdException if no user with the specified ID has been found
	 *
	 * @see Role
	 */
	public function addRoleForUserById($userId, $role) {
		$userFound = $this->addRoleForUserByColumnValue(
			'id',
			(int) $userId,
			$role
		);

		if ($userFound === false) {
			throw new UnknownIdException();
		}
	}

	/**
	 * Assigns the specified role to the user with the given email address
	 *
	 * A user may have any number of roles (i.e. no role at all, a single role, or any combination of roles)
	 *
	 * @param string $userEmail the email address of the user to assign the role to
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @throws InvalidEmailException if no user with the specified email address has been found
	 *
	 * @see Role
	 */
	public function addRoleForUserByEmail($userEmail, $role) {
		$userEmail = self::validateEmailAddress($userEmail);

		$userFound = $this->addRoleForUserByColumnValue(
			'email',
			$userEmail,
			$role
		);

		if ($userFound === false) {
			throw new InvalidEmailException();
		}
	}

	/**
	 * Assigns the specified role to the user with the given username
	 *
	 * A user may have any number of roles (i.e. no role at all, a single role, or any combination of roles)
	 *
	 * @param string $username the username of the user to assign the role to
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @throws UnknownUsernameException if no user with the specified username has been found
	 * @throws AmbiguousUsernameException if multiple users with the specified username have been found
	 *
	 * @see Role
	 */
	public function addRoleForUserByUsername($username, $role) {
		$userData = $this->getUserDataByUsername(
			\trim($username),
			[ 'id' ]
		);

		$this->addRoleForUserByColumnValue(
			'id',
			(int) $userData['id'],
			$role
		);
	}

	/**
	 * Takes away the specified role from the user with the given ID
	 *
	 * A user may have any number of roles (i.e. no role at all, a single role, or any combination of roles)
	 *
	 * @param int $userId the ID of the user to take the role away from
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @throws UnknownIdException if no user with the specified ID has been found
	 *
	 * @see Role
	 */
	public function removeRoleForUserById($userId, $role) {
		$userFound = $this->removeRoleForUserByColumnValue(
			'id',
			(int) $userId,
			$role
		);

		if ($userFound === false) {
			throw new UnknownIdException();
		}
	}

	/**
	 * Takes away the specified role from the user with the given email address
	 *
	 * A user may have any number of roles (i.e. no role at all, a single role, or any combination of roles)
	 *
	 * @param string $userEmail the email address of the user to take the role away from
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @throws InvalidEmailException if no user with the specified email address has been found
	 *
	 * @see Role
	 */
	public function removeRoleForUserByEmail($userEmail, $role) {
		$userEmail = self::validateEmailAddress($userEmail);

		$userFound = $this->removeRoleForUserByColumnValue(
			'email',
			$userEmail,
			$role
		);

		if ($userFound === false) {
			throw new InvalidEmailException();
		}
	}

	/**
	 * Takes away the specified role from the user with the given username
	 *
	 * A user may have any number of roles (i.e. no role at all, a single role, or any combination of roles)
	 *
	 * @param string $username the username of the user to take the role away from
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @throws UnknownUsernameException if no user with the specified username has been found
	 * @throws AmbiguousUsernameException if multiple users with the specified username have been found
	 *
	 * @see Role
	 */
	public function removeRoleForUserByUsername($username, $role) {
		$userData = $this->getUserDataByUsername(
			\trim($username),
			[ 'id' ]
		);

		$this->removeRoleForUserByColumnValue(
			'id',
			(int) $userData['id'],
			$role
		);
	}

	/**
	 * Returns whether the user with the given ID has the specified role
	 *
	 * @param int $userId the ID of the user to check the roles for
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @return bool
	 * @throws UnknownIdException if no user with the specified ID has been found
	 *
	 * @see Role
	 */
	public function doesUserHaveRole($userId, $role) {
		if (empty($role) || !\is_numeric($role)) {
			return false;
		}

		$userId = (int) $userId;

		$rolesBitmask = $this->db->selectValue(
			'SELECT roles_mask FROM ' . $this->makeTableName('users') . ' WHERE id = ?',
			[ $userId ]
		);

		if ($rolesBitmask === null) {
			throw new UnknownIdException();
		}

		$role = (int) $role;

		return ($rolesBitmask & $role) === $role;
	}

	/**
	 * Returns the roles of the user with the given ID, mapping the numerical values to their descriptive names
	 *
	 * @param int $userId the ID of the user to return the roles for
	 * @return array
	 * @throws UnknownIdException if no user with the specified ID has been found
	 *
	 * @see Role
	 */
	public function getRolesForUserById($userId) {
		$userId = (int) $userId;

		$rolesBitmask = $this->db->selectValue(
			'SELECT roles_mask FROM ' . $this->makeTableName('users') . ' WHERE id = ?',
			[ $userId ]
		);

		if ($rolesBitmask === null) {
			throw new UnknownIdException();
		}

		return \array_filter(
			Role::getMap(),
			function ($each) use ($rolesBitmask) {
				return ($rolesBitmask & $each) === $each;
			},
			\ARRAY_FILTER_USE_KEY
		);
	}

	/**
	 * Signs in as the user with the specified ID
	 *
	 * @param int $id the ID of the user to sign in as
	 * @throws UnknownIdException if no user with the specified ID has been found
	 * @throws EmailNotVerifiedException if the user has not verified their email address via a confirmation method yet
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function logInAsUserById($id) {
		$numberOfMatchedUsers = $this->logInAsUserByColumnValue('id', (int) $id);

		if ($numberOfMatchedUsers === 0) {
			throw new UnknownIdException();
		}
	}

	/**
	 * Signs in as the user with the specified email address
	 *
	 * @param string $email the email address of the user to sign in as
	 * @throws InvalidEmailException if no user with the specified email address has been found
	 * @throws EmailNotVerifiedException if the user has not verified their email address via a confirmation method yet
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function logInAsUserByEmail($email) {
		$email = self::validateEmailAddress($email);

		$numberOfMatchedUsers = $this->logInAsUserByColumnValue('email', $email);

		if ($numberOfMatchedUsers === 0) {
			throw new InvalidEmailException();
		}
	}

	/**
	 * Signs in as the user with the specified display name
	 *
	 * @param string $username the display name of the user to sign in as
	 * @throws UnknownUsernameException if no user with the specified username has been found
	 * @throws AmbiguousUsernameException if multiple users with the specified username have been found
	 * @throws EmailNotVerifiedException if the user has not verified their email address via a confirmation method yet
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function logInAsUserByUsername($username) {
		$numberOfMatchedUsers = $this->logInAsUserByColumnValue('username', \trim($username));

		if ($numberOfMatchedUsers === 0) {
			throw new UnknownUsernameException();
		}
		elseif ($numberOfMatchedUsers > 1) {
			throw new AmbiguousUsernameException();
		}
	}

	/**
	 * Changes the password for the user with the given ID
	 *
	 * @param int $userId the ID of the user whose password to change
	 * @param string $newPassword the new password to set
	 * @throws UnknownIdException if no user with the specified ID has been found
	 * @throws InvalidPasswordException if the desired new password has been invalid
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function changePasswordForUserById($userId, $newPassword) {
		$userId = (int) $userId;
		$newPassword = self::validatePassword($newPassword);

		$this->updatePasswordInternal(
			$userId,
			$newPassword
		);

		$this->forceLogoutForUserById($userId);
	}

	/**
	 * Changes the password for the user with the given username
	 *
	 * @param string $username the username of the user whose password to change
	 * @param string $newPassword the new password to set
	 * @throws UnknownUsernameException if no user with the specified username has been found
	 * @throws AmbiguousUsernameException if multiple users with the specified username have been found
	 * @throws InvalidPasswordException if the desired new password has been invalid
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	public function changePasswordForUserByUsername($username, $newPassword) {
		$userData = $this->getUserDataByUsername(
			\trim($username),
			[ 'id' ]
		);

		$this->changePasswordForUserById(
			(int) $userData['id'],
			$newPassword
		);
	}

	/**
	 * Deletes all existing users where the column with the specified name has the given value
	 *
	 * You must never pass untrusted input to the parameter that takes the column name
	 *
	 * @param string $columnName the name of the column to filter by
	 * @param mixed $columnValue the value to look for in the selected column
	 * @return int the number of deleted users
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	private function deleteUsersByColumnValue($columnName, $columnValue) {
		try {
			return $this->db->delete(
				$this->makeTableNameComponents('users'),
				[
					$columnName => $columnValue
				]
			);
		}
		catch (Error $e) {
			throw new DatabaseError($e->getMessage());
		}
	}

	/**
	 * Modifies the roles for the user where the column with the specified name has the given value
	 *
	 * You must never pass untrusted input to the parameter that takes the column name
	 *
	 * @param string $columnName the name of the column to filter by
	 * @param mixed $columnValue the value to look for in the selected column
	 * @param callable $modification the modification to apply to the existing bitmask of roles
	 * @return bool whether any user with the given column constraints has been found
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 *
	 * @see Role
	 */
	private function modifyRolesForUserByColumnValue($columnName, $columnValue, callable $modification) {
		try {
			$userData = $this->db->selectRow(
				'SELECT id, roles_mask FROM ' . $this->makeTableName('users') . ' WHERE ' . $columnName . ' = ?',
				[ $columnValue ]
			);
		}
		catch (Error $e) {
			throw new DatabaseError($e->getMessage());
		}

		if ($userData === null) {
			return false;
		}

		$newRolesBitmask = $modification($userData['roles_mask']);

		try {
			$this->db->exec(
				'UPDATE ' . $this->makeTableName('users') . ' SET roles_mask = ? WHERE id = ?',
				[
					$newRolesBitmask,
					(int) $userData['id']
				]
			);

			return true;
		}
		catch (Error $e) {
			throw new DatabaseError($e->getMessage());
		}
	}

	/**
	 * Assigns the specified role to the user where the column with the specified name has the given value
	 *
	 * You must never pass untrusted input to the parameter that takes the column name
	 *
	 * @param string $columnName the name of the column to filter by
	 * @param mixed $columnValue the value to look for in the selected column
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @return bool whether any user with the given column constraints has been found
	 *
	 * @see Role
	 */
	private function addRoleForUserByColumnValue($columnName, $columnValue, $role) {
		$role = (int) $role;

		return $this->modifyRolesForUserByColumnValue(
			$columnName,
			$columnValue,
			function ($oldRolesBitmask) use ($role) {
				return $oldRolesBitmask | $role;
			}
		);
	}

	/**
	 * Takes away the specified role from the user where the column with the specified name has the given value
	 *
	 * You must never pass untrusted input to the parameter that takes the column name
	 *
	 * @param string $columnName the name of the column to filter by
	 * @param mixed $columnValue the value to look for in the selected column
	 * @param int $role the role as one of the constants from the {@see Role} class
	 * @return bool whether any user with the given column constraints has been found
	 *
	 * @see Role
	 */
	private function removeRoleForUserByColumnValue($columnName, $columnValue, $role) {
		$role = (int) $role;

		return $this->modifyRolesForUserByColumnValue(
			$columnName,
			$columnValue,
			function ($oldRolesBitmask) use ($role) {
				return $oldRolesBitmask & ~$role;
			}
		);
	}

	/**
	 * Signs in as the user for which the column with the specified name has the given value
	 *
	 * You must never pass untrusted input to the parameter that takes the column name
	 *
	 * @param string $columnName the name of the column to filter by
	 * @param mixed $columnValue the value to look for in the selected column
	 * @return int the number of matched users (where only a value of one means that the login may have been successful)
	 * @throws EmailNotVerifiedException if the user has not verified their email address via a confirmation method yet
	 * @throws AuthError if an internal problem occurred (do *not* catch)
	 */
	private function logInAsUserByColumnValue($columnName, $columnValue) {
		try {
			$users = $this->db->select(
				'SELECT verified, id, email, username, status, roles_mask FROM ' . $this->makeTableName('users') . ' WHERE ' . $columnName . ' = ? LIMIT 2 OFFSET 0',
				[ $columnValue ]
			);
		}
		catch (Error $e) {
			throw new DatabaseError($e->getMessage());
		}

		$numberOfMatchingUsers = ($users !== null) ? \count($users) : 0;

		if ($numberOfMatchingUsers === 1) {
			$user = $users[0];

			if ((int) $user['verified'] === 1) {
				$this->onLoginSuccessful($user['id'], $user['email'], $user['username'], $user['status'], $user['roles_mask'], \PHP_INT_MAX, false);
			}
			else {
				throw new EmailNotVerifiedException();
			}
		}

		return $numberOfMatchingUsers;
	}

}


text:
using Xunit;

namespace Shouldly.Tests.Strings
{
    public class ShouldBeNullOrEmpty
    {
        [Fact]
        public void SingleLetterShouldFail()
        {
            Verify.ShouldFail(() =>
"a".ShouldBeNullOrEmpty("Some additional context"),
errorWithSource: @"""a""
    should be null or empty

Additional Info:
    Some additional context",
errorWithoutSource: @"""a""
    should be null or empty

Additional Info:
    Some additional context");
        }

        [Fact]
        public void SingleLetterAsVariableShouldFail()
        {
            var singleLetter = "a";

            Verify.ShouldFail(() =>
singleLetter.ShouldBeNullOrEmpty("Some additional context"),
errorWithSource: @"singleLetter (""a"")
    should be null or empty

Additional Info:
    Some additional context",
errorWithoutSource: @"""a""
    should be null or empty

Additional Info:
    Some additional context");
        }

        [Fact]
        public void ShouldPass()
        {
            ((string)null).ShouldBeNullOrEmpty();
            string.Empty.ShouldBeNullOrEmpty();
        }
    }
}


text:
USE [ANTERO]
GO

/****** Object:  StoredProcedure [dw].[p_lataa_d_horizon_ohjelma]    Script Date: 23.9.2022 14:23:21 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dw].[p_lataa_d_horizon_ohjelma]
AS
IF NOT EXISTS (SELECT * FROM dw.d_horizon_ohjelma WHERE id=-1)

	BEGIN

	  SET IDENTITY_INSERT dw.d_horizon_ohjelma ON;

	  INSERT INTO dw.d_horizon_ohjelma (
		id, ohjelma_koodi, Ohjelma, [Ohjelman lyhenne], rcn, loadtime, username, source
	  )
	SELECT
		-1,
		'ÖÖ','Missing data', 'Missing data', -1,
		loadtime = getdate(),
		username = suser_name(),
		'ETL: p_lataa_d_horizon_ohjelma'
	  ;

	  SET IDENTITY_INSERT dw.d_horizon_ohjelma OFF;

	END

ELSE

	BEGIN
		UPDATE d
		SET
			ohjelma_koodi = s.programme_id,
			Ohjelma=coalesce(s.title, s.shortTitle),
			[Ohjelman lyhenne]=coalesce(s.shortTitle, s.title),
			rcn = s.rcn,
			loadtime = getdate(),
			username = suser_name(),
			source = 'ETL: p_lataa_d_horizon_ohjelma'
		FROM dw.d_horizon_ohjelma d
		JOIN sa.sa_horizon_ohjelmat s ON d.ohjelma_koodi = s.programme_id

		;
	END

MERGE dw.d_horizon_ohjelma AS target
USING (
	SELECT DISTINCT
	   [programme_id] as ohjelma_koodi
      ,coalesce(coalesce([title], [shortTitle]), 'Missing information') as Ohjelma
      ,coalesce(coalesce([shortTitle], [title]), 'Missing information') as [Ohjelman lyhenne]
      ,[rcn]
	  ,source = 'ETL: p_lataa_d_horizon_ohjelma'
	FROM ANTERO.sa.sa_horizon_ohjelmat
	WHERE programme_id is not null
	) AS src
	ON target.ohjelma_koodi = src.ohjelma_koodi
WHEN MATCHED
	THEN
		UPDATE
		SET
			ohjelma_koodi = src.ohjelma_koodi
			,Ohjelma = src.Ohjelma
			,[Ohjelman lyhenne] = src.[Ohjelman lyhenne]
			,rcn = src.rcn
			,target.source = src.source

WHEN NOT MATCHED
	THEN
		INSERT (
				ohjelma_koodi, Ohjelma, [Ohjelman lyhenne], rcn, source
				)
		VALUES (
				src.ohjelma_koodi, src.Ohjelma, src.[Ohjelman lyhenne], src.rcn, src.source
				)

WHEN NOT MATCHED BY source and id != '-1' and (select count(*) from sa.sa_horizon_ohjelmat) > 0 THEN DELETE
;

GO

USE [ANTERO]


text:
require "commotion/test/names"
require "thread"

class Thread
  def to_s
    name
  end
  include Commotion::Test::Names
  def name
    Thread.current[:name] ||= (( Thread.current == Thread.main ) ? "main" : get_name )
  end
end

class ConditionVariable
  alias_method :original_signal, :signal
  def signal
    original_signal
    #Commotion.logger.debug "Signaled #{self}"
  end
  alias_method :original_wait, :wait
  def wait( mutex )
    #Commotion.logger.debug "Waiting for #{self}"
    original_wait(mutex)
    #Commotion.logger.debug "Reached #{self}"
  end
  def to_s
    name
  end
  include Commotion::Test::Names
  def name
    @name ||= "CV:#{get_name}"
  end
  def name=(n)
    @name = n
  end
end

module Kernel
  alias_method :original_puts, :puts
  def puts(m)
    STDERR.printf "%10.8f [%-10s] %s\n", Time.now.to_f, Thread.current.to_s, m.to_s
  end
end


text:
/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file  usb_descriptors.h ***************************************************
 *
 * \brief
 *      This file contains the usb parameters that uniquely identify the
 *      application through descriptor tables.
 *
 * \addtogroup usbstick
 *
 * \author
 *      Atmel Corporation: http://www.atmel.com
 * \author
 *      Colin O'Flynn <coflynn@newae.com>
 *
 ******************************************************************************/
/* Copyright (c) 2008  ATMEL Corporation
   Copyright (c) 2008 Colin O'Flynn
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
   * Neither the name of the copyright holders nor the names of
     contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.
*/

/**
  \addtogroup usbconf
  @{
  */

#ifndef USB_USERCONFIG_H_
#define USB_USERCONFIG_H_

//_____ I N C L U D E S ____________________________________________________

#include "config.h"
#include "usb_standard_request.h"
#include "conf_usb.h"
#include <avr/pgmspace.h>

//_____ M A C R O S ________________________________________________________

//_____ U S B    D E F I N E _______________________________________________

                  // USB Device descriptor
#define USB_SPECIFICATION     0x0200
#if USB_CONF_MACINTOSH
#define COMPOSITE_DEVICE_CLASS       0x02      // Misc
#define COMPOSITE_DEVICE_SUB_CLASS   0x00      // Common
#define COMPOSITE_DEVICE_PROTOCOL    0x00      // IAD
#else //Windows wants these for composite device
//Above seems to work for Vista and Win7 but XP and Ubuntu 904 might need the old values
#define COMPOSITE_DEVICE_CLASS       0xEF      // Misc
#define COMPOSITE_DEVICE_SUB_CLASS   0x02      // Common
#define COMPOSITE_DEVICE_PROTOCOL    0x01      // IAD
#endif

#define NETWORK_DEVICE_CLASS          0x02      // CDC ACM
#define NETWORK_DEVICE_SUB_CLASS      0x02      //
#define NETWORK_DEVICE_PROTOCOL       0xFF      // Vendor-specific

#define MASS_DEVICE_CLASS            0x00      //
#define MASS_DEVICE_SUB_CLASS        0x00      //
#define MASS_DEVICE_PROTOCOL         0x00      //

#define EEM_DEVICE_CLASS              0x02      // CDC
#define EEM_DEVICE_SUB_CLASS          0x0C      // EEM
#define EEM_DEVICE_PROTOCOL           0x07      // EEM

#define EP_CONTROL_LENGTH     64
#define VENDOR_ID             0x03EB // Atmel vendor ID = 03EBh

#if USB_CONF_MACINTOSH
//A different product ID avoids instant windows corruption when it tries to use the cached drivers
//TODO:Get some valid ID's from Atmel
#define COMPOSITE_PRODUCT_ID  0x9921 //Product ID for composite device
#define NETWORK_PRODUCT_ID    0x9919 //Product ID for just CDC-ECM device
#else
#define COMPOSITE_PRODUCT_ID  0x2021 //Product ID for composite device
#define NETWORK_PRODUCT_ID    0x2019 //Product ID for just RNDIS device
#endif

#define MASS_PRODUCT_ID       0x202F //Product ID for mass storage
#define RELEASE_NUMBER        0x1000

enum {
	USB_STRING_NONE = 0,
	USB_STRING_MAN = 1,
	USB_STRING_PRODUCT,
	USB_STRING_SERIAL,
	USB_STRING_MAC_ADDRESS,
	USB_STRING_CONFIG_COMPOSITE,
	USB_STRING_CONFIG_RNDIS,
	USB_STRING_CONFIG_EEM,
	USB_STRING_CONFIG_ECM,
	USB_STRING_CONFIG_ECM_DEBUG,
	USB_STRING_CONFIG_MS,
	USB_STRING_INTERFACE_RNDIS,
	USB_STRING_INTERFACE_EEM,
	USB_STRING_INTERFACE_ECM,
	USB_STRING_INTERFACE_ECM_ATTACHED,
	USB_STRING_INTERFACE_ECM_DETACHED,
	USB_STRING_INTERFACE_SERIAL,
	USB_STRING_INTERFACE_MS,

};

enum {
	USB_CONFIG_UNCONFIGURED = 0,

	USB_CONFIG_RNDIS		= 1,
	USB_CONFIG_RNDIS_DEBUG	= 1+(1<<7),

	USB_CONFIG_ECM			= 2,
	USB_CONFIG_ECM_DEBUG	= 2+(1<<7),

	USB_CONFIG_EEM			= 3,

#if USB_CONF_STORAGE
	USB_CONFIG_MS			= 4,
#endif
};

#define USB_CONFIG_HAS_DEBUG_PORT(x)	((x==USB_CONFIG_ECM_DEBUG)||(x==USB_CONFIG_RNDIS_DEBUG))

//#define USB_CONFIG_COUNT (USB_CONFIG_COUNT_PLUS_ONE-1)
//#define NB_CONFIGURATION      USB_CONFIG_COUNT

#define NETWORK_NB_INTERFACE         2
#define COMPOSITE_NB_INTERFACE       4
#define MASS_NB_INTERFACE            1
#define EEM_NB_INTERFACE          1
#define CONF_NB            1
#define CONF_INDEX         0
#define CONF_ATTRIBUTES    USB_CONFIG_BUSPOWERED
#define MAX_POWER          50          // 100 mA

/*** CDC RNDIS CONFIGURATION CONFIGURATION ***/

// Interface 0 descriptor
#define INTERFACE0_NB        0
#define ALTERNATE0           0
#define NB_ENDPOINT0         1
#define INTERFACE0_CLASS     0x02    // CDC ACM Com
#define INTERFACE0_SUB_CLASS 0x02
#define INTERFACE0_PROTOCOL  0xFF	 // Vendor specific
#define INTERFACE0_INDEX     0

// Interface 1 descriptor
#define INTERFACE1_NB        1
#define ALTERNATE1           0
#define NB_ENDPOINT1         2
#define INTERFACE1_CLASS     0x0A    // CDC ACM Data
#define INTERFACE1_SUB_CLASS 0
#define INTERFACE1_PROTOCOL  0
#define INTERFACE1_INDEX     0

             // USB Endpoint 1 descriptor
				 // Interrupt IN
#define ENDPOINT_NB_1       0x80 | INT_EP
#define EP_ATTRIBUTES_1     0x03          // BULK = 0x02, INTERUPT = 0x03
#define EP_SIZE_1           0x08
#define EP_INTERVAL_1       0x01 //ms interrupt pooling from host

             // USB Endpoint 1 descriptor
				 // Bulk IN
#define ENDPOINT_NB_2       0x80 | TX_EP
#define EP_ATTRIBUTES_2     0x02          // BULK = 0x02, INTERUPT = 0x03
#define EP_SIZE_2           0x40  //64 byte max size
#define EP_INTERVAL_2       0x01

             // USB Endpoint 2 descriptor
				 //Bulk OUT  RX endpoint
#define ENDPOINT_NB_3       RX_EP
#define EP_ATTRIBUTES_3     0x02          // BULK = 0x02, INTERUPT = 0x03
#define EP_SIZE_3           0x40  //64 byte max size
#define EP_INTERVAL_3       0x01

/*** CDC Virtual Serial Port ***/

             // Interface 2 descriptor
#define INTERFACE2_NB        2
#define ALTERNATE2           0
#define NB_ENDPOINT2         1
#define INTERFACE2_CLASS     0x02    // CDC ACM Com
#define INTERFACE2_SUB_CLASS 0x02
#define INTERFACE2_PROTOCOL  0x01
#define INTERFACE2_INDEX     0

             // Interface 3 descriptor
#define INTERFACE3_NB        3
#define ALTERNATE3           0
#define NB_ENDPOINT3         2
#define INTERFACE3_CLASS     0x0A    // CDC ACM Data
#define INTERFACE3_SUB_CLASS 0
#define INTERFACE3_PROTOCOL  0
#define INTERFACE3_INDEX     0

             // USB Endpoint 4 descriptor
				 // Interrupt IN
#define TX_EP_SIZE          0x20
#define ENDPOINT_NB_4       0x80 | VCP_INT_EP
#define EP_ATTRIBUTES_4     0x03          // BULK = 0x02, INTERUPT = 0x03
#define EP_SIZE_4           TX_EP_SIZE
#define EP_INTERVAL_4       0xFF //ms interrupt pooling from host

             // USB Endpoint 5 descriptor
				 // Bulk IN
#define ENDPOINT_NB_5       0x80 | VCP_TX_EP
#define EP_ATTRIBUTES_5     0x02          // BULK = 0x02, INTERUPT = 0x03
#define EP_SIZE_5           0x20
#define EP_INTERVAL_5       0x01

             // USB Endpoint 6 descriptor
				 // Bulk OUT
#define ENDPOINT_NB_6       VCP_RX_EP
#define EP_ATTRIBUTES_6     0x02          // BULK = 0x02, INTERUPT = 0x03
#define EP_SIZE_6           0x20
#define EP_INTERVAL_6       0x01

/*** Mass Storage ***/

#define MS_INTERFACE_NB        0
#define MS_ALTERNATE           0
#define MS_NB_ENDPOINT         2
#define MS_INTERFACE_CLASS     0x08   		// Mass Storage Class
#define MS_INTERFACE_SUB_CLASS 0x06			// SCSI transparent Command Set
#define MS_INTERFACE_PROTOCOL  0x50			// Bulk-Only Transport
#define MS_INTERFACE_INDEX     0

// USB Endpoint 1 descriptor FS
#define MS_ENDPOINT_NB_1       (MS_IN_EP | 0x80)
#define MS_EP_ATTRIBUTES_1     0x02          // BULK = 0x02, INTERUPT = 0x03
#define MS_EP_IN_LENGTH        64
#define MS_EP_SIZE_1           MS_EP_IN_LENGTH
#define MS_EP_INTERVAL_1       0x00

// USB Endpoint 2 descriptor FS
#define MS_ENDPOINT_NB_2       MS_OUT_EP
#define MS_EP_ATTRIBUTES_2     0x02          // BULK = 0x02, INTERUPT = 0x03
#define MS_EP_IN_LENGTH        64
#define MS_EP_SIZE_2           MS_EP_IN_LENGTH
#define MS_EP_INTERVAL_2       0x00

/******* EEM Configuration *******/

// Interface 0 descriptor
#define EEM_INTERFACE0_NB        0
#define EEM_ALTERNATE0           0
#define EEM_NB_ENDPOINT0         2
#define EEM_INTERFACE0_CLASS     0x02    // CDC ACM Com
#define EEM_INTERFACE0_SUB_CLASS 0x0C    // EEM
#define EEM_INTERFACE0_PROTOCOL  0x07    // EEM
#define EEM_INTERFACE0_INDEX     0

            // USB Endpoint 1 descriptor
            // Bulk IN
#define EEM_ENDPOINT_NB_1       0x80 | TX_EP
#define EEM_EP_ATTRIBUTES_1     0x02          // BULK = 0x02, INTERUPT = 0x03
#define EEM_EP_SIZE_1           0x40 //64 byte max size
#define EEM_EP_INTERVAL_1       0x01

             // USB Endpoint 2 descriptor
             // Bulk OUT
#define EEM_ENDPOINT_NB_2       RX_EP
#define EEM_EP_ATTRIBUTES_2     0x02          // BULK = 0x02, INTERUPT = 0x03
#define EEM_EP_SIZE_2           0x40  //64 byte max size
#define EEM_EP_INTERVAL_2       0x01

/******* ECM Configuration *******/

// Interface 0 descriptor
#define ECM_INTERFACE0_NB        0
#define ECM_ALTERNATE0           0
#define ECM_NB_ENDPOINT0         2
#define ECM_INTERFACE0_CLASS     0x02    // CDC ACM Com
#define ECM_INTERFACE0_SUB_CLASS 0x06    // ECM
#define ECM_INTERFACE0_PROTOCOL  0x00    // Empty
#define ECM_INTERFACE0_INDEX     0

#define DEVICE_STATUS         0x00 // TBD
#define INTERFACE_STATUS      0x00 // TBD

#define LANG_ID               0x00

#define LANGUAGE_ID           0x0409

                  //! Usb Request
typedef struct
{
   U8      bmRequestType;        //!< Characteristics of the request
   U8      bRequest;             //!< Specific request
   U16     wValue;               //!< field that varies according to request
   U16     wIndex;               //!< field that varies according to request
   U16     wLength;              //!< Number of bytes to transfer if Data
}  S_UsbRequest;

                //! Usb Device Descriptor
typedef struct {
   U8      bLength;              //!< Size of this descriptor in bytes
   U8      bDescriptorType;      //!< DEVICE descriptor type
   U16     bscUSB;               //!< Binay Coded Decimal Spec. release
   U8      bDeviceClass;         //!< Class code assigned by the USB
   U8      bDeviceSubClass;      //!< Sub-class code assigned by the USB
   U8      bDeviceProtocol;      //!< Protocol code assigned by the USB
   U8      bMaxPacketSize0;      //!< Max packet size for EP0
   U16     idVendor;             //!< Vendor ID. ATMEL = 0x03EB
   U16     idProduct;            //!< Product ID assigned by the manufacturer
   U16     bcdDevice;            //!< Device release number
   U8      iManufacturer;        //!< Index of manu. string descriptor
   U8      iProduct;             //!< Index of prod. string descriptor
   U8      iSerialNumber;        //!< Index of S.N.  string descriptor
   U8      bNumConfigurations;   //!< Number of possible configurations
}  S_usb_device_descriptor;

          //! Usb Configuration Descriptor
typedef struct {
   U8      bLength;              //!< size of this descriptor in bytes
   U8      bDescriptorType;      //!< CONFIGURATION descriptor type
   U16     wTotalLength;         //!< total length of data returned
   U8      bNumInterfaces;       //!< number of interfaces for this conf.
   U8      bConfigurationValue;  //!< value for SetConfiguration resquest
   U8      iConfiguration;       //!< index of string descriptor
   U8      bmAttibutes;          //!< Configuration characteristics
   U8      MaxPower;             //!< maximum power consumption
}  S_usb_configuration_descriptor;

              //! Usb Interface Descriptor
typedef struct {
   U8      bLength;               //!< size of this descriptor in bytes
   U8      bDescriptorType;       //!< INTERFACE descriptor type
   U8      bInterfaceNumber;      //!< Number of interface
   U8      bAlternateSetting;     //!< value to select alternate setting
   U8      bNumEndpoints;         //!< Number of EP except EP 0
   U8      bInterfaceClass;       //!< Class code assigned by the USB
   U8      bInterfaceSubClass;    //!< Sub-class code assigned by the USB
   U8      bInterfaceProtocol;    //!< Protocol code assigned by the USB
   U8      iInterface;            //!< Index of string descriptor
}  S_usb_interface_descriptor;

               //! Usb Endpoint Descriptor
typedef struct {
   U8      bLength;               //!< Size of this descriptor in bytes
   U8      bDescriptorType;       //!< ENDPOINT descriptor type
   U8      bEndpointAddress;      //!< Address of the endpoint
   U8      bmAttributes;          //!< Endpoint's attributes
   U16     wMaxPacketSize;        //!< Maximum packet size for this EP
   U8      bInterval;             //!< Interval for polling EP in ms
} S_usb_endpoint_descriptor;

               //! Usb Device Qualifier Descriptor
typedef struct {
   U8      bLength;               //!< Size of this descriptor in bytes
   U8      bDescriptorType;       //!< Device Qualifier descriptor type
   U16     bscUSB;                //!< Binay Coded Decimal Spec. release
   U8      bDeviceClass;          //!< Class code assigned by the USB
   U8      bDeviceSubClass;       //!< Sub-class code assigned by the USB
   U8      bDeviceProtocol;       //!< Protocol code assigned by the USB
   U8      bMaxPacketSize0;       //!< Max packet size for EP0
   U8      bNumConfigurations;    //!< Number of possible configurations
   U8      bReserved;             //!< Reserved for future use, must be zero
} S_usb_device_qualifier_descriptor;

               //! Usb Language Descriptor
typedef struct {
   U8      bLength;               //!< size of this descriptor in bytes
   U8      bDescriptorType;       //!< STRING descriptor type
   U16     wlangid;               //!< language id
} S_usb_language_id;

/*_____ U S B   I A D _______________________________________________________*/

#define DSC_TYPE_IAD  11

typedef struct
{
	U8 bLength;
	U8 bDescriptorType;
	U8 bFirstInterface;
	U8 bInterfaceCount;
	U8 bFunctionClass;
	U8 bFunctionSubClass;
	U8 bFunctionProtocol;
	U8 iInterface;
} S_usb_interface_association_descriptor;

/*_____ U S B   D E S C R I P T O R __________________________________*/

/* RNDIS + Serial Port */
typedef struct
{
   S_usb_configuration_descriptor cfg;

  S_usb_interface_association_descriptor   iad0;
   S_usb_interface_descriptor     ifc0;
	U8 CS1_INTERFACE[19];
 S_usb_endpoint_descriptor      ep1;
   S_usb_interface_descriptor     ifc1;
   S_usb_endpoint_descriptor      ep2;
   S_usb_endpoint_descriptor      ep3;

  S_usb_interface_association_descriptor   iad1;
   S_usb_interface_descriptor     ifc2;
	U8 CS2_INTERFACE[19];
   S_usb_endpoint_descriptor      ep4;
   S_usb_interface_descriptor     ifc3;
   S_usb_endpoint_descriptor      ep5;
   S_usb_endpoint_descriptor      ep6;

} S_usb_user_configuration_descriptor_composite;

/* Just RNDIS */
typedef struct
{
   S_usb_configuration_descriptor cfg;
   S_usb_interface_descriptor     ifc0;
	U8 CS1_INTERFACE[19];
   S_usb_endpoint_descriptor      ep1;
   S_usb_interface_descriptor     ifc1;
   S_usb_endpoint_descriptor      ep2;
   S_usb_endpoint_descriptor      ep3;

} S_usb_user_configuration_descriptor_network;

/* EEM */
typedef struct
{
   S_usb_configuration_descriptor cfg;
   S_usb_interface_descriptor     ifc0;
   S_usb_endpoint_descriptor      ep1;
   S_usb_endpoint_descriptor      ep2;
} S_usb_user_configuration_descriptor_eem;

typedef struct
{
	U8 bLength;
	U8 bDescriptorType;
	U8 bDescriptorSubtype;
	U8 iMACAddress;
	U32 bmEthernetStatistics;
	U16 wMaxSegmentSize;
	U16 wNumberMCFilters;
	U8 bNumberPowerFilters;
} S_usb_ethernet_networking_functional_descriptor;

/* ECM */
typedef struct
{
   S_usb_configuration_descriptor cfg;
   S_usb_interface_descriptor     ifc0;
   U8 CS1_INTERFACE[5+5];
   S_usb_ethernet_networking_functional_descriptor fd0;
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
   S_usb_endpoint_descriptor      ep1;
#endif
#if 0
   S_usb_interface_descriptor     ifc1_0;
#endif
   S_usb_interface_descriptor     ifc1_1;
   S_usb_endpoint_descriptor      ep2;
   S_usb_endpoint_descriptor      ep3;
} S_usb_user_configuration_descriptor_ecm;

/* ECM + Serial Port */
typedef struct
{
   S_usb_configuration_descriptor cfg;
  S_usb_interface_association_descriptor   iad0;
   S_usb_interface_descriptor     ifc0;
   U8 CS1_INTERFACE[5+5];
   S_usb_ethernet_networking_functional_descriptor fd0;
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
   S_usb_endpoint_descriptor      ep1;
#endif
#if 0
   S_usb_interface_descriptor     ifc1_0;
#endif
   S_usb_interface_descriptor     ifc1_1;
   S_usb_endpoint_descriptor      ep2;
   S_usb_endpoint_descriptor      ep3;

  S_usb_interface_association_descriptor   iad1;
   S_usb_interface_descriptor     ifc2;
	U8 CS2_INTERFACE[19];
   S_usb_endpoint_descriptor      ep4;
   S_usb_interface_descriptor     ifc3;
   S_usb_endpoint_descriptor      ep5;
   S_usb_endpoint_descriptor      ep6;

} S_usb_user_configuration_descriptor_ecm_debug;

/* Mass Storage */

typedef struct
{
   S_usb_configuration_descriptor cfg;
   S_usb_interface_descriptor     ifc0;
   S_usb_endpoint_descriptor      ep1;
   S_usb_endpoint_descriptor      ep2;

} S_usb_user_configuration_descriptor_mass;

PGM_VOID_P Usb_get_dev_desc_pointer(void);
U8 Usb_get_dev_desc_length(void);
PGM_VOID_P  Usb_get_conf_desc_pointer(U8 index) ;
U8  Usb_get_conf_desc_length(U8 index);

#endif //USB_USERCONFIG_H_

/** @} */


text:
class CreateUuidifyUuids < ActiveRecord::Migration
  def up
    uuid_type = connection.adapter_name == "PostgreSQL" ? :string : :binary

    create_table :uuidify_uuids do |t|
      t.string :model_name
      t.integer :model_id

      if uuid_type == :string
        t.string :model_uuid, :limit => 36
      end

    end

    if uuid_type == :binary
      execute "ALTER TABLE uuidify_uuids ADD COLUMN model_uuid BINARY(16)"
    end

    add_index :uuidify_uuids, [:model_name, :model_id], :unique => true
    add_index :uuidify_uuids, :model_uuid, :unique => true
    add_index :uuidify_uuids, [:model_uuid, :model_id], :unique => true
  end

  def down
    drop_table :uuidify_uuids
  end
end


text:
Composer.service('AppStorageService', [
  '$rootScope',
  function($rootScope) {
    var svc = {};

    // namepsace for UI state storage
    var slScope = '';

    var getSlScope = function() {
      if ($rootScope.projectName) {
        slScope = $rootScope.projectName;
        return JSON.parse(window.localStorage.getItem($rootScope.projectName)) || {};
      }
      return null;
    };

    svc.setItem = function(itemName, item) {
      var localScope = getSlScope();
      var mappingFn = function(key, val) {
        if (val && (typeof val === 'object') && angular.isFunction(val.then)) {
          return;
        }

        return val;
      };

      if (localScope) {
        localScope[itemName] = item;
        window.localStorage.setItem(
          slScope, JSON.stringify(localScope, mappingFn)
        );
      }

    };
    svc.getItem = function(itemName) {
      var localScope = getSlScope();
      if (localScope) {
        return localScope[itemName];
      }
      return null;

    };
    svc.removeItem = function(itemName) {
      var localScope = getSlScope();
      if (localScope) {
        delete localScope[itemName];
        window.localStorage.setItem(slScope, JSON.stringify(localScope));
        return localScope;
      }
      return null;

    };
    svc.clearActiveInstance = function() {
      svc.removeItem('activeInstance');
    };
    svc.clearStorage = function() {
      var localScope = getSlScope();
      if (localScope) {
        window.localStorage.removeItem(slScope);
      }

    };
    return svc;
  }
]);


text:
qpkg-bolt
=========

Bolt CMS - QPKG package for Qnap

```
- To build:
1) git clone https://github.com/zeon/qpkg-sdk.git
2) cd qpkg-sdk/apps
3) git clone https://github.com/jupe/qpkg-bolt.git bolt
4) cd bolt
5) ../build.sh all
```


text:
<?php

declare(strict_types=1);

namespace Adsmurai\Currency\Tests\Currency;

use Adsmurai\Currency\Money;
use Litipk\BigNumbers\Decimal;
use PHPUnit\Framework\TestCase;

class BasicGetterTests extends TestCase
{
    /**
     * @covers \Adsmurai\Currency\Money::getAmountAsDecimal
     * @covers \Adsmurai\Currency\Money::getCurrency
     */
    public function test_basic_getters()
    {
        // @todo: Improve the test to decouple from Decimal. It requires refactoring Decimal.

        $amount = Decimal::fromString('34.56');
        $currencyType = CurrencyTypeMocks::getTwoDecimalDigitsCurrencyType();

        $currency = Money::fromDecimal($amount, $currencyType);

        $this->assertSame($amount, $currency->getAmountAsDecimal());
        $this->assertSame($currencyType, $currency->getCurrency());
    }
}


text:
package cf.rachlinski.cryspscript.runtime.exec.keyword;

public class UnmatchedNestException extends Error
{
	public UnmatchedNestException(String start, String finding)
	{
		super("Could not find the matching " + finding + " for " + start);
	}
}


text:
package co.lqnt.lockbox.util;

import java.nio.charset.Charset;
import org.testng.Assert;
import org.testng.annotations.Test;

public class SecureRandomTest
{
    public SecureRandomTest()
    {
        this.jceSecureRandom = new java.security.SecureRandom("foobar".getBytes(Charset.forName("US-ASCII")));
        this.random = new SecureRandom(jceSecureRandom);
    }

    @Test
    public void testConstructor()
    {
        Assert.assertSame(this.random.jceSecureRandom(), this.jceSecureRandom);
        Assert.assertSame(this.random.jceSecureRandom(), this.jceSecureRandom);
    }

    @Test
    public void testConstructorDefaults()
    {
        this.random = new SecureRandom();
        java.security.SecureRandom actualJceSecureRandom = this.random.jceSecureRandom();

        Assert.assertNotNull(actualJceSecureRandom);
        Assert.assertSame(this.random.jceSecureRandom(), actualJceSecureRandom);
    }

    @Test
    public void testGenerate() throws Throwable
    {
        byte[] data = this.random.generate(16);

        Assert.assertEquals(data.length, 16);
    }

    private java.security.SecureRandom jceSecureRandom;
    private SecureRandom random;
}


text:
namespace Ui {
class dtkPluginGeneratorPage;
}

class dtkPluginGeneratorPage : public QWizardPage
{
    Q_OBJECT

public:
    explicit dtkPluginGeneratorPage(QWidget *parent = 0);
    ~dtkPluginGeneratorPage();
protected:
    void initializePage();

public slots:
    void refresh();

private:
    Ui::dtkPluginGeneratorPage *ui;
};

#endif // DTKPLUGINGENERATORPAGE_H


text:
from django.conf.urls.defaults import patterns, url, include

from consent.views import ConsentListView, ConsentEditView

from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
    url(r'^$', ConsentListView.as_view(), name="privileges"),
    url(r'^edit/$', ConsentEditView.as_view(), name="edit_privileges"),

)