1 package org.apache.calcite.prepare;
3 import org.apache.calcite.sql.SqlBasicCall;
4 import org.apache.calcite.sql.SqlDataTypeSpec;
5 import org.apache.calcite.sql.SqlDelete;
6 import org.apache.calcite.sql.SqlIdentifier;
7 import org.apache.calcite.sql.SqlInsert;
8 import org.apache.calcite.sql.SqlJoin;
9 import org.apache.calcite.sql.SqlKind;
10 import org.apache.calcite.sql.SqlLiteral;
11 import org.apache.calcite.sql.SqlNode;
12 import org.apache.calcite.sql.SqlNodeList;
13 import org.apache.calcite.sql.SqlOrderBy;
14 import org.apache.calcite.sql.SqlSelect;
15 import org.apache.calcite.sql.SqlUpdate;
16 import org.apache.calcite.sql.SqlWith;
17 import org.apache.calcite.sql.SqlWithItem;
18 import org.apache.calcite.sql.parser.SqlParser;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22 import java.util.Collection;
23 import java.util.HashSet;
24 import java.util.IdentityHashMap;
27 import java.util.Stack;
28 import java.util.concurrent.ConcurrentHashMap;
36 new ConcurrentHashMap<>();
38 private IdentityHashMap<SqlNode, SqlNode>
visitedNodes =
new IdentityHashMap<>();
42 public final Set<String>
selects =
new HashSet<>();
43 public final Set<String>
inserts =
new HashSet<>();
44 public final Set<String>
updates =
new HashSet<>();
45 public final Set<String>
deletes =
new HashSet<>();
47 private final Set<String>
ignore =
new HashSet<>();
49 { currentList.push(
ignore); }
51 public void scan(SqlNode root) {
56 if (root instanceof SqlLiteral || root instanceof SqlDataTypeSpec) {
64 if (root instanceof SqlNodeList) {
65 SqlNodeList snl = (SqlNodeList) root;
66 for (SqlNode node : snl) {
72 if (root instanceof SqlIdentifier) {
74 currentList.peek().add(((SqlIdentifier) root).names.reverse().
get(0));
78 if (root instanceof SqlBasicCall) {
79 SqlBasicCall call = (SqlBasicCall) root;
80 if (call.getOperator().getKind() == SqlKind.AS) {
82 scan(call.getOperands()[0]);
87 if (root instanceof SqlOrderBy) {
88 scan(((SqlOrderBy) root).fetch);
89 scan(((SqlOrderBy) root).offset);
90 scan(((SqlOrderBy) root).query);
94 boolean needsPop =
false;
95 if (root instanceof SqlSelect) {
97 scan(((SqlSelect) root).getFrom());
101 }
else if (root instanceof SqlInsert) {
103 scan(((SqlInsert) root).getTargetTable());
107 }
else if (root instanceof SqlUpdate) {
109 scan(((SqlUpdate) root).getTargetTable());
113 }
else if (root instanceof SqlDelete) {
115 scan(((SqlDelete) root).getTargetTable());
119 }
else if (root instanceof SqlJoin) {
121 scan(((SqlJoin) root).getCondition());
126 for (Method m : methods) {
129 value = m.invoke(root);
130 }
catch (Exception e) {
133 if (value instanceof SqlNode[]) {
134 SqlNode[] nodes = (SqlNode[]) value;
135 for (SqlNode node : nodes) {
138 }
else if (value instanceof SqlNode) {
139 scan((SqlNode) value);
140 }
else if (value instanceof Collection) {
141 for (Object vobj : ((Collection<?>) value)) {
142 if (vobj instanceof SqlNode) {
143 scan((SqlNode) vobj);
149 if (root instanceof SqlWith) {
150 SqlWith with = (SqlWith) root;
152 for (SqlNode node : with.withList) {
153 SqlWithItem item = (SqlWithItem) node;
154 selects.remove(item.name.getSimple());
164 Class<?> root = obj.getClass();
166 Set<Method> methods = GETTERS_CACHE.get(root);
167 if (null != methods) {
170 methods =
new HashSet<>();
173 while (root != null) {
174 if (root == SqlNode.class)
break;
176 for (Method m : root.getDeclaredMethods()) {
177 if (m.getParameterTypes().length > 0)
continue;
179 if (!Modifier.isPublic(m.getModifiers()))
continue;
181 Class<?> returnType = m.getReturnType();
182 if (!SqlNode.class.isAssignableFrom(returnType) && SqlNode[].class != returnType
183 && !Collection.class.isAssignableFrom(returnType)) {
190 root = root.getSuperclass();
193 GETTERS_CACHE.put(obj.getClass(), methods);
200 out +=
" Selects: " +
selects +
"\n";
201 out +=
" Inserts: " +
inserts +
"\n";
202 out +=
" Updates: " +
updates +
"\n";
203 out +=
" Deletes: " +
deletes +
"\n";
204 out +=
" Ignore : " +
ignore +
"\n";
210 String sql =
"UPDATE sales set f=(SELECT max(r.num) from report as r)";
211 sql =
"INSER INTO sales (a, b, c ) VALUES(10, (SELECT max(foo) from bob), 0)";
212 sql =
"SELECT * FROM sales a left outer join (select (select max(id) from rupert) from report2) r on a.id=(select max(r.di) from test)";
214 SqlParser
parser = SqlParser.create(sql);
217 capturer.scan(parser.parseQuery());
219 System.out.println(capturer.selects);
220 System.out.println(capturer.inserts);
221 System.out.println(capturer.updates);
222 System.out.println(capturer.deletes);
223 System.out.println(capturer.ignore);
static void main(String[] args)
final Set< String > deletes
final Set< String > inserts
static final Map< Class<?>, Set< Method > > GETTERS_CACHE
final Set< String > updates
IdentityHashMap< SqlNode, SqlNode > visitedNodes
Stack< Set< String > > currentList
final Set< String > ignore
Set< Method > getRelevantGetters(Object obj)
final Set< String > selects
const int8_t const int64_t const uint64_t const int32_t const int64_t int64_t ** out