use of org.teiid.api.exception.query.FunctionExecutionException in project teiid by teiid.
the class FunctionMethods method mvstatus.
@TeiidFunction(category = FunctionCategoryConstants.SYSTEM, determinism = Determinism.COMMAND_DETERMINISTIC, pushdown = PushDown.CANNOT_PUSHDOWN)
public static int mvstatus(CommandContext context, String schemaName, String viewName) throws FunctionExecutionException, SQLException, QueryMetadataException, TeiidComponentException {
Object id = context.getMetadata().getGroupID(schemaName + AbstractMetadataRecord.NAME_DELIM_CHAR + viewName);
String statusTable = context.getMetadata().getExtensionProperty(id, MaterializationMetadataRepository.MATVIEW_STATUS_TABLE, false);
if (statusTable == null) {
throw new FunctionExecutionException(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31177, schemaName, viewName));
}
// add quoting if needed, although this needs to be resolved to be fully correct
statusTable = SQLStringVisitor.getSQLString(new GroupSymbol(statusTable)).toString();
String ownerVDB = context.getMetadata().getExtensionProperty(id, MaterializationMetadataRepository.MATVIEW_OWNER_VDB_NAME, false);
if (ownerVDB == null) {
ownerVDB = context.getVdbName();
}
String ownerVersion = context.getMetadata().getExtensionProperty(id, MaterializationMetadataRepository.MATVIEW_OWNER_VDB_VERSION, false);
if (ownerVersion == null) {
ownerVersion = context.getVdbVersion();
}
String scope = context.getMetadata().getExtensionProperty(id, MaterializationMetadataRepository.MATVIEW_SHARE_SCOPE, false);
if (scope != null && Scope.valueOf(scope) == Scope.FULL) {
// $NON-NLS-1$
ownerVersion = "0";
}
String action = context.getMetadata().getExtensionProperty(id, MaterializationMetadataRepository.MATVIEW_ONERROR_ACTION, false);
Boolean validity = null;
String status = null;
PreparedStatement ps = null;
try {
Connection c = context.getConnection();
// $NON-NLS-1$ //$NON-NLS-2$
ps = c.prepareStatement("SELECT Valid, LoadState FROM " + statusTable + " WHERE VDBName = ? AND VDBVersion = ? AND SchemaName = ? AND Name = ?");
ps.setString(1, ownerVDB);
ps.setString(2, ownerVersion);
ps.setString(3, schemaName);
ps.setString(4, viewName);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
validity = rs.getBoolean(1);
if (validity) {
return 1;
}
status = rs.getString(1);
}
} finally {
if (ps != null) {
ps.close();
}
}
// $NON-NLS-1$
boolean loading = status != null && DQPWorkContext.getWorkContext().isAdmin() && status.equals("LOADING");
// $NON-NLS-1$ //$NON-NLS-2$
String key = "mat_management_waits_" + schemaName + "." + viewName;
if (!MaterializationMetadataRepository.ErrorAction.IGNORE.name().equalsIgnoreCase(action) || loading) {
if (!loading && MaterializationMetadataRepository.ErrorAction.THROW_EXCEPTION.name().equalsIgnoreCase(action)) {
throw new FunctionExecutionException(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31147, schemaName, viewName));
}
int spins = 0;
Object value = context.getSessionVariable(key);
if (value instanceof Integer) {
spins = (Integer) value;
}
context.getWorkItem().scheduleWork(100 * (1 << Math.min(spins, 7)));
context.setSessionVariable(key, ++spins);
throw BlockedException.INSTANCE;
}
context.setSessionVariable(key, null);
return 1;
}
use of org.teiid.api.exception.query.FunctionExecutionException in project teiid by teiid.
the class FunctionMethods method regexpReplace.
/**
* Perform find-replace operation on a string using regular expressions.
*
* See {@link java.util.regex.Pattern} for more information.
*
* Flags can be used to modify the matching behavior of the regular expression.
* <ul>
* <li>g - Replaces all matches instead of just the first.</li>
* <li>i - Performs case insensitive pattern match.</li>
* <li>m - Changes behavior of "^" and "$" to match the beginning and end
* of the line instead of the entire string.</li>
* </ul>
*
* @param context
* @param source Value to perform replacement on.
* @param regex Regular expression pattern.
* @param replacement Replacement string.
* @param flags Flags to modify behavior of the pattern.
* @return Modified source if the pattern was matched, otherwise source.
* @throws FunctionExecutionException If an invalid flag was supplied or if the
* regex pattern was invalid.
*/
public static String regexpReplace(CommandContext context, CharSequence source, String regex, String replacement, String flags) throws FunctionExecutionException {
// Parse regex flags into a bitmask for Pattern API.
// Exception is the 'g' flag which makes us call replaceAll instead of
// replaceFirst.
boolean global = false;
int bitFlags = 0;
for (int i = 0; i < flags.length(); ++i) {
char c = flags.charAt(i);
if (c == 'g') {
// Global match.
global = true;
} else if (c == 'i') {
// Case insensitive match.
bitFlags |= Pattern.CASE_INSENSITIVE;
} else if (c == 'm') {
// Change ^$ to match line endings instad of entire source.
bitFlags |= Pattern.MULTILINE;
} else {
throw new FunctionExecutionException(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31168, c));
}
}
// Compile regex into pattern and do replacement.
Pattern pattern;
try {
pattern = CommandContext.getPattern(context, regex, bitFlags);
} catch (PatternSyntaxException e) {
throw new FunctionExecutionException(e);
}
Matcher matcher = pattern.matcher(source);
String result;
if (global) {
result = matcher.replaceAll(replacement);
} else {
result = matcher.replaceFirst(replacement);
}
return result;
}
use of org.teiid.api.exception.query.FunctionExecutionException in project teiid by teiid.
the class FunctionMethods method timestampDiff.
public static Long timestampDiff(String intervalType, Timestamp ts1Obj, Timestamp ts2Obj, boolean calendarBased) throws FunctionExecutionException {
long ts1 = ts1Obj.getTime() / 1000;
long ts2 = ts2Obj.getTime() / 1000;
long tsDiff = ts2 - ts1;
long count = 0;
if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_FRAC_SECOND)) {
if (Math.abs(tsDiff) > Integer.MAX_VALUE) {
throw new FunctionExecutionException(QueryPlugin.Event.TEIID31144, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31144));
}
count = tsDiff * 1000000000 + ts2Obj.getNanos() - ts1Obj.getNanos();
} else {
if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_SECOND)) {
count = tsDiff;
} else if (calendarBased) {
// which looks at elapsed date parts, not total time between
if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_MINUTE)) {
count = ts2 / 60 - ts1 / 60;
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_HOUR)) {
TimeZone tz = TimestampWithTimezone.getCalendar().getTimeZone();
if (tz.getDSTSavings() > 0 || tz.getRawOffset() % 3600000 != 0) {
ts1 += tz.getOffset(ts1Obj.getTime()) / 1000;
ts2 += tz.getOffset(ts2Obj.getTime()) / 1000;
}
count = ts2 / (60 * 60) - ts1 / (60 * 60);
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_DAY) || intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_WEEK)) {
TimeZone tz = TimestampWithTimezone.getCalendar().getTimeZone();
if (tz.getDSTSavings() > 0 || tz.getRawOffset() % 3600000 != 0) {
ts1 += tz.getOffset(ts1Obj.getTime()) / 1000;
ts2 += tz.getOffset(ts2Obj.getTime()) / 1000;
}
// since we are now effectively using GMT we can simply divide since the unix epoch starts at midnight.
count = ts2 / (60 * 60 * 24) - ts1 / (60 * 60 * 24);
if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_WEEK)) {
// TODO: this behavior matches SQL Server - but not Derby which expects only whole week
long days = count;
// whole weeks between the two dates
count = count / 7;
// check for calendar difference assuming sunday as the first week day
if (days % 7 != 0) {
int day1 = dayOfWeek(ts1Obj);
int day2 = dayOfWeek(ts2Obj);
int diff = Integer.signum(day2 - day1);
if (diff > 0) {
if (tsDiff < 0) {
count--;
}
} else if (diff < 0) {
if (tsDiff > 0) {
count++;
}
}
}
}
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_MONTH)) {
Calendar cal = TimestampWithTimezone.getCalendar();
cal.setTimeInMillis(ts1Obj.getTime());
int months1 = cal.get(Calendar.YEAR) * 12 + cal.get(Calendar.MONTH);
cal.setTimeInMillis(ts2Obj.getTime());
int months2 = cal.get(Calendar.YEAR) * 12 + cal.get(Calendar.MONTH);
count = months2 - months1;
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_QUARTER)) {
Calendar cal = TimestampWithTimezone.getCalendar();
cal.setTimeInMillis(ts1Obj.getTime());
int quarters1 = cal.get(Calendar.YEAR) * 4 + cal.get(Calendar.MONTH) / 3;
cal.setTimeInMillis(ts2Obj.getTime());
int quarters2 = cal.get(Calendar.YEAR) * 4 + cal.get(Calendar.MONTH) / 3;
count = quarters2 - quarters1;
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_YEAR)) {
Calendar cal = TimestampWithTimezone.getCalendar();
cal.setTimeInMillis(ts1Obj.getTime());
int years1 = cal.get(Calendar.YEAR);
cal.setTimeInMillis(ts2Obj.getTime());
int years2 = cal.get(Calendar.YEAR);
count = years2 - years1;
}
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_MINUTE)) {
count = tsDiff / 60;
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_HOUR)) {
count = tsDiff / (60 * 60);
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_DAY)) {
count = tsDiff / (60 * 60 * 24);
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_WEEK)) {
count = tsDiff / (60 * 60 * 24 * 7);
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_MONTH)) {
count = tsDiff / (60 * 60 * 24 * 30);
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_QUARTER)) {
count = tsDiff / (60 * 60 * 24 * 91);
} else if (intervalType.equalsIgnoreCase(NonReserved.SQL_TSI_YEAR)) {
count = tsDiff / (60 * 60 * 24 * 365);
}
}
/*if (calendarBased && ((count > 0 && count > Integer.MAX_VALUE) || (count < 0 && count < Integer.MIN_VALUE))) {
throw new FunctionExecutionException(QueryPlugin.Event.TEIID31136, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31136));
}*/
return Long.valueOf(count);
}
use of org.teiid.api.exception.query.FunctionExecutionException in project teiid by teiid.
the class FunctionTree method createFunctionDescriptor.
private FunctionDescriptor createFunctionDescriptor(FunctionMetadataSource source, FunctionMethod method, Class<?>[] types, boolean system) {
// Get return type
FunctionParameter outputParam = method.getOutputParameter();
Class<?> outputType = null;
if (outputParam != null) {
outputType = DataTypeManager.getDataTypeClass(outputParam.getRuntimeType());
}
List<Class<?>> inputTypes = new ArrayList<Class<?>>(Arrays.asList(types));
boolean hasWrappedArg = false;
if (!system) {
for (int i = 0; i < types.length; i++) {
if (types[i] == DataTypeManager.DefaultDataClasses.VARBINARY) {
hasWrappedArg = true;
inputTypes.set(i, byte[].class);
}
}
}
if (method.isVarArgs()) {
inputTypes.set(inputTypes.size() - 1, DataTypeManager.getArrayType(inputTypes.get(inputTypes.size() - 1)));
}
Method invocationMethod = method.getMethod();
boolean requiresContext = false;
// Defect 20007 - Ignore the invocation method if pushdown is not required.
if (validateClass && (method.getPushdown() == PushDown.CAN_PUSHDOWN || method.getPushdown() == PushDown.CANNOT_PUSHDOWN)) {
if (invocationMethod == null) {
if (method.getInvocationClass() == null || method.getInvocationMethod() == null) {
throw new MetadataException(QueryPlugin.Event.TEIID31123, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31123, method.getName()));
}
try {
Class<?> methodClass = source.getInvocationClass(method.getInvocationClass());
ReflectionHelper helper = new ReflectionHelper(methodClass);
try {
invocationMethod = helper.findBestMethodWithSignature(method.getInvocationMethod(), inputTypes);
} catch (NoSuchMethodException e) {
inputTypes.add(0, CommandContext.class);
invocationMethod = helper.findBestMethodWithSignature(method.getInvocationMethod(), inputTypes);
requiresContext = true;
}
} catch (ClassNotFoundException e) {
throw new MetadataException(QueryPlugin.Event.TEIID30387, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30387, method.getName(), method.getInvocationClass()));
} catch (NoSuchMethodException e) {
throw new MetadataException(QueryPlugin.Event.TEIID30388, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30388, method, method.getInvocationClass(), method.getInvocationMethod()));
} catch (Exception e) {
throw new MetadataException(QueryPlugin.Event.TEIID30389, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30389, method, method.getInvocationClass(), method.getInvocationMethod()));
}
} else {
requiresContext = (invocationMethod.getParameterTypes().length > 0 && org.teiid.CommandContext.class.isAssignableFrom(invocationMethod.getParameterTypes()[0]));
}
if (invocationMethod != null) {
// Check return type is non void
Class<?> methodReturn = invocationMethod.getReturnType();
if (method.getAggregateAttributes() == null && methodReturn.equals(Void.TYPE)) {
throw new MetadataException(QueryPlugin.Event.TEIID30390, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30390, method.getName(), invocationMethod));
}
// Check that method is public
int modifiers = invocationMethod.getModifiers();
if (!Modifier.isPublic(modifiers)) {
throw new MetadataException(QueryPlugin.Event.TEIID30391, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30391, method.getName(), invocationMethod));
}
// Check that method is static
if (!Modifier.isStatic(modifiers)) {
if (method.getAggregateAttributes() == null) {
throw new MetadataException(QueryPlugin.Event.TEIID30392, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30392, method.getName(), invocationMethod));
}
} else if (method.getAggregateAttributes() != null) {
throw new MetadataException(QueryPlugin.Event.TEIID30600, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30600, method.getName(), invocationMethod));
}
if (method.getAggregateAttributes() != null && !(UserDefinedAggregate.class.isAssignableFrom(invocationMethod.getDeclaringClass()))) {
throw new MetadataException(QueryPlugin.Event.TEIID30601, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30601, method.getName(), method.getInvocationClass(), UserDefinedAggregate.class.getName()));
}
try {
// turn off access checks for a small performance boost
invocationMethod.setAccessible(true);
} catch (SecurityException e) {
// just ignore
}
method.setMethod(invocationMethod);
}
}
FunctionDescriptor result = new FunctionDescriptor(method, types, outputType, invocationMethod, requiresContext, source.getClassLoader());
if (validateClass && method.getAggregateAttributes() != null && (method.getPushdown() == PushDown.CAN_PUSHDOWN || method.getPushdown() == PushDown.CANNOT_PUSHDOWN)) {
try {
result.newInstance();
} catch (FunctionExecutionException e) {
// should only happen if the method is null / not found
throw new MetadataException(QueryPlugin.Event.TEIID30387, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30387, method.getName(), method.getInvocationClass()));
}
}
result.setHasWrappedArgs(hasWrappedArg);
return result;
}
use of org.teiid.api.exception.query.FunctionExecutionException in project teiid by teiid.
the class GeometryUtils method snapToGrid.
public static GeometryType snapToGrid(GeometryType geom, double size) throws FunctionExecutionException {
if (size == 0) {
return geom;
}
Geometry g1 = getGeometry(geom);
PrecisionModel precisionModel = new PrecisionModel(1 / size);
GeometryPrecisionReducer reducer = new GeometryPrecisionReducer(precisionModel);
reducer.setPointwise(true);
reducer.setChangePrecisionModel(true);
Geometry result = reducer.reduce(g1);
// since the wkb writer doesn't consider precision, we have to first write/read through wkt
WKTWriter writer = new WKTWriter();
String val = writer.write(result);
WKTReader reader = new WKTReader(GEOMETRY_FACTORY);
try {
result = reader.read(new StringReader(val));
} catch (ParseException e) {
throw new FunctionExecutionException(e);
}
result.setSRID(geom.getSrid());
return getGeometryType(result);
}
Aggregations