@Override public OptionValue getDefault() { return inner.getDefault(); }
public QueryLevelOptionValidation(OptionValidator inner) { super(inner.getOptionName()); this.inner = inner; }
@Override public int getTtl() { return inner.getTtl(); }
switch(validator.getDefault().getKind()){ case BOOLEAN: this.setOption(OptionValue.createBoolean(OptionType.SYSTEM, validator.getOptionName(), Boolean.parseBoolean(value))); break; case DOUBLE: this.setOption(OptionValue.createDouble(OptionType.SYSTEM, validator.getOptionName(), Double.parseDouble(value))); break; case LONG: this.setOption(OptionValue.createLong(OptionType.SYSTEM, validator.getOptionName(), Long.parseLong(value))); break; case STRING: this.setOption(OptionValue.createString(OptionType.SYSTEM, validator.getOptionName(), value)); break; default:
@Override public void setOption(final OptionValue value) { checkArgument(value.getType() == OptionType.SYSTEM, "OptionType must be SYSTEM."); final String name = value.getName().toLowerCase(); final OptionValidator validator = getValidator(name); validator.validate(value); // validate the option if (options.get(name) == null && value.equals(validator.getDefault())) { return; // if the option is not overridden, ignore setting option to default } options.put(name, value); }
@Override public void setOption(OptionValue value) { final OptionValidator validator = fallback.getValidator(value.getName()); validator.validate(value); // validate the option // fallback if unable to set locally if (!setLocalOption(value)) { fallback.setOption(value); } }
@Override boolean setLocalOption(final OptionValue value) { final boolean set = super.setLocalOption(value); if (!set) { return false; } final String name = value.getName(); final OptionValidator validator = getValidator(name); // if set, validator must exist. final boolean shortLived = validator.isShortLived(); if (shortLived) { final int start = session.getQueryCount() + 1; // start from the next query final int ttl = validator.getTtl(); final int end = start + ttl; shortLivedOptions.put(name, new ImmutablePair<>(start, end)); } return true; }
@Override public boolean isShortLived() { return inner.isShortLived(); }
@Test @Ignore // TODO file JIRA to fix this public void testFix2967() throws Exception { setSessionOption(PlannerSettings.BROADCAST.getOptionName(), "false"); setSessionOption(PlannerSettings.HASHJOIN.getOptionName(), "false"); setSessionOption(ExecConstants.SLICE_TARGET, "1"); setSessionOption(ExecConstants.MAX_WIDTH_PER_NODE_KEY, "23"); final String TEST_RES_PATH = TestTools.getWorkingPath() + "/src/test/resources"; try { test("select * from dfs.\"%s/join/j1\" j1 left outer join dfs.\"%s/join/j2\" j2 on (j1.c_varchar = j2.c_varchar)", TEST_RES_PATH, TEST_RES_PATH); } finally { setSessionOption(PlannerSettings.BROADCAST.getOptionName(), String.valueOf(PlannerSettings.BROADCAST.getDefault ().getBoolVal())); setSessionOption(PlannerSettings.HASHJOIN.getOptionName(), String.valueOf(PlannerSettings.HASHJOIN.getDefault() .getBoolVal())); setSessionOption(ExecConstants.SLICE_TARGET, String.valueOf(ExecConstants.SLICE_TARGET_DEFAULT)); setSessionOption(ExecConstants.MAX_WIDTH_PER_NODE_KEY, String.valueOf(ExecConstants.MAX_WIDTH_PER_NODE .getDefault().getNumVal())); } }
@Override public void validate(OptionValue v) { if (v.getType() != OptionType.QUERY) { throw UserException.validationError() .message("Query level options can only be set at QUERY level scope. Given scope '%s'.", v.getType()) .build(logger); } inner.validate(v); } }
/** * If an option is short-lived, this method returns the number of queries for which the option is valid. * Please read the note at {@link #isShortLived} * * @return number of queries for which the option should be valid */ public int getTtl() { if (!isShortLived()) { throw new UnsupportedOperationException("This option is not short-lived."); } return 0; }
@Override public String getOptionName() { return inner.getOptionName(); }
@Override public Iterator<OptionValue> iterator() { final Map<String, OptionValue> buildList = CaseInsensitiveMap.newHashMap(); // populate the default options for (final Map.Entry<String, OptionValidator> entry : validators.entrySet()) { buildList.put(entry.getKey(), entry.getValue().getDefault()); } // override if changed for (final Map.Entry<String, OptionValue> entry : Lists.newArrayList(options.getAll())) { buildList.put(entry.getKey(), entry.getValue()); } return buildList.values().iterator(); }
@Test public void ok() { OptionValidator validator = newValidator("foo"); // check no fail... validator.validate(OptionValue.createString(OptionValue.OptionType.QUERY, "test-option", "bar")); }
/** * Gets the current option value given a validator. * * @param validator the validator * @return option value * @throws IllegalArgumentException - if the validator is not found */ private OptionValue getOptionSafe(OptionValidator validator) { return getOption(validator.getOptionName()); }
@Override public OptionValue getOption(final String name) { // check local space (persistent store) final OptionValue value = options.get(name); if (value != null) { return value; } // otherwise, return default. final OptionValidator validator = getValidator(name); return validator.getDefault(); }
@Test(expected = UserException.class) public void invalidOption() { OptionValidator validator = newValidator("foo"); validator.validate(newStringValue("bar")); } }
private static CaseInsensitiveMap<OptionValidator> getValidators(ScanResult scanResult) { ImmutableMap.Builder<String, OptionValidator> builder = ImmutableMap.builder(); for(Class<?> clazz: scanResult.getAnnotatedClasses(Options.class)) { for(Field field: clazz.getDeclaredFields()) { if (!(OptionValidator.class.isAssignableFrom(field.getType()))) { continue; } final OptionValidator optionValidator; try { optionValidator = (OptionValidator) field.get(null); } catch (IllegalAccessException e) { logger.info("Ignoring not-accessible option {}.{}", clazz.getName(), field.getName(), e); continue; } builder.put(optionValidator.getOptionName(), optionValidator); } } return CaseInsensitiveMap.newImmutableMap(builder.build()); }
@Override OptionValue getLocalOption(final String name) { final OptionValue value = super.getLocalOption(name); if (shortLivedOptions.containsKey(name)) { if (withinRange(name)) { return value; } final int queryNumber = session.getQueryCount(); final int start = shortLivedOptions.get(name).getLeft(); // option is not in effect if queryNumber < start if (queryNumber < start) { return getValidator(name).getDefault(); // reset if queryNumber <= end } else { options.remove(name); shortLivedOptions.remove(name); return null; // fallback takes effect } } return value; }
public static void setControls(final UserSession session, final String controls) { validateControlsString(controls); final OptionValue opValue = OptionValue.createString(OptionValue.OptionType.SESSION, NODE_CONTROL_INJECTIONS, controls); final OptionManager options = session.getOptions(); try { NODE_CONTROLS_VALIDATOR.validate(opValue); options.setOption(opValue); } catch (final Exception e) { fail("Could not set controls options: " + e.getMessage()); } session.incrementQueryCount(); }