use of org.apache.calcite.sql.SqlCall in project drill by axbaretto.
the class UnsupportedOperatorsVisitor method detectMultiplePartitions.
/**
* Disable multiple partitions in a SELECT-CLAUSE
* If multiple partitions are defined in the query,
* SqlUnsupportedException would be thrown to inform
* @param sqlSelect SELECT-CLAUSE in the query
*/
private void detectMultiplePartitions(SqlSelect sqlSelect) {
for (SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
// enter the first operand of AS operator
if (nodeInSelectList.getKind() == SqlKind.AS && (((SqlCall) nodeInSelectList).getOperandList().get(0).getKind() == SqlKind.OVER)) {
nodeInSelectList = ((SqlCall) nodeInSelectList).getOperandList().get(0);
}
if (nodeInSelectList.getKind() != SqlKind.OVER) {
continue;
}
// This is used to keep track of the window function which has been defined
SqlNode definedWindow = null;
SqlNode window = ((SqlCall) nodeInSelectList).operand(1);
// which is defined in the window list
if (window instanceof SqlIdentifier) {
// Expand the SqlIdentifier as the expression defined in the window list
for (SqlNode sqlNode : sqlSelect.getWindowList()) {
if (((SqlWindow) sqlNode).getDeclName().equalsDeep(window, false)) {
window = sqlNode;
break;
}
}
assert !(window instanceof SqlIdentifier) : "Identifier should have been expanded as a window defined in the window list";
}
// In a SELECT-SCOPE, only a partition can be defined
if (definedWindow == null) {
definedWindow = window;
} else {
if (!definedWindow.equalsDeep(window, false)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Multiple window definitions in a single SELECT list is not currently supported \n" + "See Apache Drill JIRA: DRILL-3196");
throw new UnsupportedOperationException();
}
}
}
}
use of org.apache.calcite.sql.SqlCall in project calcite by apache.
the class SqlPrettyWriterTest method assertExprPrintsTo.
protected void assertExprPrintsTo(boolean newlines, final String sql, String expected) {
final SqlCall valuesCall = (SqlCall) parseQuery("VALUES (" + sql + ")");
final SqlCall rowCall = valuesCall.operand(0);
final SqlNode node = rowCall.operand(0);
final SqlPrettyWriter prettyWriter = new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
prettyWriter.setAlwaysUseParentheses(false);
if (newlines) {
prettyWriter.setCaseClausesOnNewLines(true);
}
String actual = prettyWriter.format(node);
getDiffRepos().assertEquals("formatted", expected, actual);
// Now parse the result, and make sure it is structurally equivalent
// to the original.
final String actual2 = actual.replaceAll("`", "\"");
final SqlNode valuesCall2 = parseQuery("VALUES (" + actual2 + ")");
assertTrue(valuesCall.equalsDeep(valuesCall2, Litmus.THROW));
}
use of org.apache.calcite.sql.SqlCall in project calcite by apache.
the class SqlTesterImpl method buildQuery2.
/**
* Builds a query that extracts all literals as columns in an underlying
* select.
*
* <p>For example,</p>
*
* <blockquote>{@code 1 < 5}</blockquote>
*
* <p>becomes</p>
*
* <blockquote>{@code SELECT p0 < p1
* FROM (VALUES (1, 5)) AS t(p0, p1)}</blockquote>
*
* <p>Null literals don't have enough type information to be extracted.
* We push down {@code CAST(NULL AS type)} but raw nulls such as
* {@code CASE 1 WHEN 2 THEN 'a' ELSE NULL END} are left as is.</p>
*
* @param expression Scalar expression
* @return Query that evaluates a scalar expression
*/
private String buildQuery2(String expression) {
// "values (1 < 5)"
// becomes
// "select p0 < p1 from (values (1, 5)) as t(p0, p1)"
SqlNode x;
final String sql = "values (" + expression + ")";
try {
x = parseQuery(sql);
} catch (SqlParseException e) {
throw new RuntimeException(e);
}
final Collection<SqlNode> literalSet = new LinkedHashSet<>();
x.accept(new SqlShuttle() {
private final List<SqlOperator> ops = ImmutableList.of(SqlStdOperatorTable.LITERAL_CHAIN, SqlStdOperatorTable.LOCALTIME, SqlStdOperatorTable.LOCALTIMESTAMP, SqlStdOperatorTable.CURRENT_TIME, SqlStdOperatorTable.CURRENT_TIMESTAMP);
@Override
public SqlNode visit(SqlLiteral literal) {
if (!isNull(literal) && literal.getTypeName() != SqlTypeName.SYMBOL) {
literalSet.add(literal);
}
return literal;
}
@Override
public SqlNode visit(SqlCall call) {
final SqlOperator operator = call.getOperator();
if (operator == SqlStdOperatorTable.CAST && isNull(call.operand(0))) {
literalSet.add(call);
return call;
} else if (ops.contains(operator)) {
// literal"
return call;
} else {
return super.visit(call);
}
}
private boolean isNull(SqlNode sqlNode) {
return sqlNode instanceof SqlLiteral && ((SqlLiteral) sqlNode).getTypeName() == SqlTypeName.NULL;
}
});
final List<SqlNode> nodes = new ArrayList<>(literalSet);
Collections.sort(nodes, new Comparator<SqlNode>() {
public int compare(SqlNode o1, SqlNode o2) {
final SqlParserPos pos0 = o1.getParserPosition();
final SqlParserPos pos1 = o2.getParserPosition();
int c = -Utilities.compare(pos0.getLineNum(), pos1.getLineNum());
if (c != 0) {
return c;
}
return -Utilities.compare(pos0.getColumnNum(), pos1.getColumnNum());
}
});
String sql2 = sql;
final List<Pair<String, String>> values = new ArrayList<>();
int p = 0;
for (SqlNode literal : nodes) {
final SqlParserPos pos = literal.getParserPosition();
final int start = SqlParserUtil.lineColToIndex(sql, pos.getLineNum(), pos.getColumnNum());
final int end = SqlParserUtil.lineColToIndex(sql, pos.getEndLineNum(), pos.getEndColumnNum()) + 1;
String param = "p" + (p++);
values.add(Pair.of(sql2.substring(start, end), param));
sql2 = sql2.substring(0, start) + param + sql2.substring(end);
}
if (values.isEmpty()) {
values.add(Pair.of("1", "p0"));
}
return "select " + sql2.substring("values (".length(), sql2.length() - 1) + " from (values (" + Util.commaList(Pair.left(values)) + ")) as t(" + Util.commaList(Pair.right(values)) + ")";
}
use of org.apache.calcite.sql.SqlCall in project calcite by apache.
the class AggChecker method visit.
public Void visit(SqlCall call) {
final SqlValidatorScope scope = scopes.peek();
if (call.getOperator().isAggregator()) {
if (distinct) {
if (scope instanceof AggregatingSelectScope) {
SqlNodeList selectList = ((SqlSelect) scope.getNode()).getSelectList();
// Check if this aggregation function is just an element in the select
for (SqlNode sqlNode : selectList) {
if (sqlNode.getKind() == SqlKind.AS) {
sqlNode = ((SqlCall) sqlNode).operand(0);
}
if (validator.expand(sqlNode, scope).equalsDeep(call, Litmus.IGNORE)) {
return null;
}
}
}
// Cannot use agg fun in ORDER BY clause if have SELECT DISTINCT.
SqlNode originalExpr = validator.getOriginal(call);
final String exprString = originalExpr.toString();
throw validator.newValidationError(call, RESOURCE.notSelectDistinctExpr(exprString));
}
// BY deptno'
return null;
}
if (call.getKind() == SqlKind.FILTER) {
call.operand(0).accept(this);
return null;
}
// Visit the operand in window function
if (call.getKind() == SqlKind.OVER) {
for (SqlNode operand : call.<SqlCall>operand(0).getOperandList()) {
operand.accept(this);
}
// Check the OVER clause
final SqlNode over = call.operand(1);
if (over instanceof SqlCall) {
over.accept(this);
} else if (over instanceof SqlIdentifier) {
// Check the corresponding SqlWindow in WINDOW clause
final SqlWindow window = scope.lookupWindow(((SqlIdentifier) over).getSimple());
window.getPartitionList().accept(this);
window.getOrderList().accept(this);
}
}
if (isGroupExpr(call)) {
// This call matches an expression in the GROUP BY clause.
return null;
}
final SqlCall groupCall = SqlStdOperatorTable.convertAuxiliaryToGroupCall(call);
if (groupCall != null) {
if (isGroupExpr(groupCall)) {
// TUMBLE(rowtime, INTERVAL '1' HOUR')
return null;
}
throw validator.newValidationError(groupCall, RESOURCE.auxiliaryWithoutMatchingGroupCall(call.getOperator().getName(), groupCall.getOperator().getName()));
}
if (call.isA(SqlKind.QUERY)) {
// references to forbidden columns.
return null;
}
// Switch to new scope.
SqlValidatorScope newScope = scope.getOperandScope(call);
scopes.push(newScope);
// Visit the operands (only expressions).
call.getOperator().acceptCall(this, call, true, ArgHandlerImpl.<Void>instance());
// Restore scope.
scopes.pop();
return null;
}
use of org.apache.calcite.sql.SqlCall in project calcite by apache.
the class PsTableFunction method eval.
public static ScannableTable eval(boolean b) {
return new ScannableTable() {
public Enumerable<Object[]> scan(DataContext root) {
final RelDataType rowType = getRowType(root.getTypeFactory());
final List<String> fieldNames = ImmutableList.copyOf(rowType.getFieldNames());
final String[] args;
final String osName = System.getProperty("os.name");
final String osVersion = System.getProperty("os.version");
Util.discard(osVersion);
switch(osName) {
case // tested on version 10.12.5
"Mac OS X":
args = new String[] { "ps", "ax", "-o", "ppid=,pid=,pgid=,tpgid=,stat=," + "user=,pcpu=,pmem=,vsz=,rss=,tty=,start=,time=,uid=,ruid=," + "sess=,comm=" };
break;
default:
args = new String[] { "ps", "--no-headers", "axo", "ppid,pid,pgrp," + "tpgid,stat,user,pcpu,pmem,vsz,rss,tty,start_time,time,euid," + "ruid,sess,comm" };
}
return Processes.processLines(args).select(new Function1<String, Object[]>() {
public Object[] apply(String line) {
final String[] fields = line.trim().split(" +");
final Object[] values = new Object[fieldNames.size()];
for (int i = 0; i < values.length; i++) {
try {
values[i] = field(fieldNames.get(i), fields[i]);
} catch (RuntimeException e) {
throw new RuntimeException("while parsing value [" + fields[i] + "] of field [" + fieldNames.get(i) + "] in line [" + line + "]");
}
}
return values;
}
private Object field(String field, String value) {
switch(field) {
case "pid":
case "ppid":
// linux only; macOS equivalent is "pgid"
case "pgrp":
// see "pgrp"
case "pgid":
case "tpgid":
return Integer.valueOf(value);
case "pcpu":
case "pmem":
return (int) (Float.valueOf(value) * 10f);
case "time":
final Matcher m1 = MINUTE_SECOND_MILLIS_PATTERN.matcher(value);
if (m1.matches()) {
final long h = Long.parseLong(m1.group(1));
final long m = Long.parseLong(m1.group(2));
final long s = Long.parseLong(m1.group(3));
return h * 3600000L + m * 60000L + s * 1000L;
}
final Matcher m2 = HOUR_MINUTE_SECOND_PATTERN.matcher(value);
if (m2.matches()) {
final long m = Long.parseLong(m2.group(1));
final long s = Long.parseLong(m2.group(2));
String g3 = m2.group(3);
while (g3.length() < 3) {
g3 = g3 + "0";
}
final long millis = Long.parseLong(g3);
return m * 60000L + s * 1000L + millis;
}
return 0L;
// linux only; macOS version is "lstart"
case "start_time":
// see "start_time"
case "lstart":
// linux only; macOS equivalent is "uid"
case "euid":
// see "euid"
case "uid":
default:
return value;
}
}
});
}
public RelDataType getRowType(RelDataTypeFactory typeFactory) {
return typeFactory.builder().add("pid", SqlTypeName.INTEGER).add("ppid", SqlTypeName.INTEGER).add("pgrp", SqlTypeName.INTEGER).add("tpgid", SqlTypeName.INTEGER).add("stat", SqlTypeName.VARCHAR).add("user", SqlTypeName.VARCHAR).add("pcpu", SqlTypeName.DECIMAL, 3, 1).add("pmem", SqlTypeName.DECIMAL, 3, 1).add("vsz", SqlTypeName.INTEGER).add("rss", SqlTypeName.INTEGER).add("tty", SqlTypeName.VARCHAR).add("start_time", SqlTypeName.VARCHAR).add("time", TimeUnit.HOUR, -1, TimeUnit.SECOND, 0).add("euid", SqlTypeName.VARCHAR).add("ruid", SqlTypeName.VARCHAR).add("sess", SqlTypeName.VARCHAR).add("command", SqlTypeName.VARCHAR).build();
}
public Statistic getStatistic() {
return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1)));
}
public Schema.TableType getJdbcTableType() {
return Schema.TableType.TABLE;
}
public boolean isRolledUp(String column) {
return false;
}
public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, SqlNode parent, CalciteConnectionConfig config) {
return true;
}
};
}
Aggregations