use of org.json_voltpatches.JSONException in project voltdb by VoltDB.
the class PlanNodeList method toJSONString.
@Override
public String toJSONString() {
try {
JSONStringer stringer = new JSONStringer();
stringer.object();
m_tree.toJSONString(stringer);
if (m_executeLists.size() == 1) {
stringer.key(EXECUTE_LIST_MEMBER_NAME).array();
List<AbstractPlanNode> list = m_executeLists.get(0);
for (AbstractPlanNode node : list) {
stringer.value(node.getPlanNodeId().intValue());
}
//end execution list
stringer.endArray();
} else {
stringer.key(EXECUTE_LISTS_MEMBER_NAME).array();
for (List<AbstractPlanNode> list : m_executeLists) {
stringer.object().key(EXECUTE_LIST_MEMBER_NAME).array();
for (AbstractPlanNode node : list) {
stringer.value(node.getPlanNodeId().intValue());
}
//end execution list
stringer.endArray().endObject();
}
//end execution list
stringer.endArray();
}
//end PlanNodeList
stringer.endObject();
return stringer.toString();
} catch (JSONException e) {
// Consider this the coward's way out.
return "This JSON error message is a lie";
}
}
use of org.json_voltpatches.JSONException in project voltdb by VoltDB.
the class PlanNodeTree method toJSONString.
@Override
public String toJSONString() {
JSONStringer stringer = new JSONStringer();
try {
stringer.object();
toJSONString(stringer);
stringer.endObject();
} catch (JSONException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return stringer.toString();
}
use of org.json_voltpatches.JSONException in project voltdb by VoltDB.
the class PlanNodeTree method loadPlanNodesFromJSONArrays.
/**
* Load plan nodes from the "PLAN_NODE" array. All the nodes are from
* a substatement with the id = stmtId
* @param stmtId
* @param jArray - PLAN_NODES
* @param db
* @throws JSONException
*/
private void loadPlanNodesFromJSONArrays(int stmtId, JSONArray jArray, Database db) {
List<AbstractPlanNode> planNodes = new ArrayList<AbstractPlanNode>();
int size = jArray.length();
try {
for (int i = 0; i < size; i++) {
JSONObject jobj = jArray.getJSONObject(i);
String nodeTypeStr = jobj.getString("PLAN_NODE_TYPE");
PlanNodeType nodeType = PlanNodeType.get(nodeTypeStr);
AbstractPlanNode apn = nodeType.getPlanNodeClass().newInstance();
apn.loadFromJSONObject(jobj, db);
planNodes.add(apn);
}
//link children and parents
for (int i = 0; i < size; i++) {
JSONObject jobj = jArray.getJSONObject(i);
if (jobj.has("CHILDREN_IDS")) {
AbstractPlanNode parent = planNodes.get(i);
JSONArray children = jobj.getJSONArray("CHILDREN_IDS");
for (int j = 0; j < children.length(); j++) {
AbstractPlanNode child = getNodeofId(children.getInt(j), planNodes);
parent.addAndLinkChild(child);
}
}
}
m_planNodesListMap.put(stmtId, planNodes);
} catch (JSONException | InstantiationException | IllegalAccessException e) {
System.err.println(e);
e.printStackTrace();
}
}
use of org.json_voltpatches.JSONException in project voltdb by VoltDB.
the class IndexCountPlanNode method explainPlanForNode.
@Override
protected String explainPlanForNode(String indent) {
assert (m_catalogIndex != null);
int indexSize = CatalogUtil.getCatalogIndexSize(m_catalogIndex);
int searchkeySize = m_searchkeyExpressions.size();
int endkeySize = m_endkeyExpressions.size();
int keySize = Math.max(searchkeySize, endkeySize);
String scanType = "tree-counter";
String cover = "covering";
if (indexSize > keySize)
cover = String.format("%d/%d cols", keySize, indexSize);
String usageInfo = String.format("(%s %s)", scanType, cover);
String[] asIndexed = new String[indexSize];
// they beat an NPE.
for (int ii = 0; ii < keySize; ++ii) {
asIndexed[ii] = "(index key " + ii + ")";
}
String jsonExpr = m_catalogIndex.getExpressionsjson();
// if this is a pure-column index...
if (jsonExpr.isEmpty()) {
// grab the short names of the indexed columns in use.
for (ColumnRef cref : m_catalogIndex.getColumns()) {
Column col = cref.getColumn();
asIndexed[cref.getIndex()] = col.getName();
}
} else {
try {
List<AbstractExpression> indexExpressions = AbstractExpression.fromJSONArrayString(jsonExpr, m_tableScan);
int ii = 0;
for (AbstractExpression ae : indexExpressions) {
asIndexed[ii++] = ae.explain(m_targetTableName);
}
} catch (JSONException e) {
// If something unexpected went wrong,
// just fall back on the positional key labels.
}
}
// "(event_type = 1 AND event_start > x.start_time)"
if (searchkeySize > 0) {
String start = explainKeys(asIndexed, m_searchkeyExpressions, m_targetTableName, m_lookupType, m_compareNotDistinct);
usageInfo += "\n" + indent + " count matches from " + start;
}
if (endkeySize > 0) {
String end = explainKeys(asIndexed, m_endkeyExpressions, m_targetTableName, m_endType, m_compareNotDistinct);
usageInfo += "\n" + indent + " count matches to " + end;
}
if (m_skip_null_predicate != null) {
String predicate = m_skip_null_predicate.explain(m_targetTableName);
usageInfo += "\n" + indent + " discounting rows where " + predicate;
}
// Describe the table name and either a user-provided name of the index or
// its user-specified role ("primary key").
String retval = "INDEX COUNT of \"" + m_targetTableName + "\"";
String indexDescription = " using \"" + m_targetIndexName + "\"";
// Replace ugly system-generated index name with a description of its user-specified role.
if (m_targetIndexName.startsWith(HSQLInterface.AUTO_GEN_PRIMARY_KEY_PREFIX) || m_targetIndexName.startsWith(HSQLInterface.AUTO_GEN_NAMED_CONSTRAINT_IDX) || m_targetIndexName.equals(HSQLInterface.AUTO_GEN_MATVIEW_IDX)) {
indexDescription = " using its primary key index";
}
// Bring all the pieces together describing the index, how it is scanned,
// and whatever extra filter processing is done to the result.
retval += indexDescription;
retval += usageInfo;
return retval;
}
use of org.json_voltpatches.JSONException in project voltdb by VoltDB.
the class IndexScanPlanNode method explainPlanForNode.
@Override
protected String explainPlanForNode(String indent) {
assert (m_catalogIndex != null);
int keySize = m_searchkeyExpressions.size();
// When there is no start key, count a range scan key for each ANDed end condition.
if (keySize == 0 && m_endExpression != null) {
keySize = ExpressionUtil.uncombineAny(m_endExpression).size();
}
String usageInfo;
String predicatePrefix;
if (keySize == 0) {
// -- either for determinism or for an explicit ORDER BY requirement.
if (m_purpose == FOR_DETERMINISM) {
usageInfo = " (for deterministic order only)";
} else if (m_purpose == FOR_GROUPING) {
usageInfo = " (for optimized grouping only)";
} else {
usageInfo = " (for sort order only)";
}
// Introduce on its own indented line, any unrelated post-filter applied to the result.
// e.g. " filter by OTHER_COL = 1"
predicatePrefix = "\n" + indent + " filter by ";
} else {
int indexSize = CatalogUtil.getCatalogIndexSize(m_catalogIndex);
String[] asIndexed = new String[indexSize];
// they beat an NPE.
for (int ii = 0; ii < keySize; ++ii) {
asIndexed[ii] = "(index key " + ii + ")";
}
String jsonExpr = m_catalogIndex.getExpressionsjson();
// if this is a pure-column index...
if (jsonExpr.isEmpty()) {
// grab the short names of the indexed columns in use.
for (ColumnRef cref : m_catalogIndex.getColumns()) {
Column col = cref.getColumn();
asIndexed[cref.getIndex()] = col.getName();
}
} else {
try {
List<AbstractExpression> indexExpressions = AbstractExpression.fromJSONArrayString(jsonExpr, m_tableScan);
int ii = 0;
for (AbstractExpression ae : indexExpressions) {
asIndexed[ii++] = ae.explain(getTableNameForExplain());
}
} catch (JSONException e) {
// If something unexpected went wrong,
// just fall back on the positional key labels.
}
}
// Explain the search criteria that describe the start of the index scan, like
// "(event_type = 1 AND event_start > x.start_time)"
String start = explainSearchKeys(asIndexed, keySize);
if (m_lookupType == IndexLookupType.EQ) {
// " scan matches for (event_type = 1) AND (event_location = x.region)"
if (m_catalogIndex.getUnique()) {
usageInfo = "\n" + indent + " uniquely match " + start;
} else {
usageInfo = "\n" + indent + " scan matches for " + start;
}
} else if (m_lookupType == IndexLookupType.GEO_CONTAINS) {
usageInfo = "\n" + indent + " scan for " + start;
} else {
usageInfo = "\n" + indent;
if (isReverseScan()) {
usageInfo += "reverse ";
}
// " " range-scan on 1 of 2 cols from event_type = 1"
if (indexSize == keySize) {
usageInfo += "range-scan covering from " + start;
} else {
usageInfo += String.format("range-scan on %d of %d cols from %s", keySize, indexSize, start);
}
// Explain the criteria for continuinuing the scan such as
// "while (event_type = 1 AND event_start < x.start_time+30)"
// or label it as a scan "to the end"
usageInfo += explainEndKeys();
}
// Introduce any additional filters not related to the index
// that could cause rows to be skipped.
// e.g. "... scan ... from ... while ..., filter by OTHER_COL = 1"
predicatePrefix = ", filter by ";
}
// Describe any additional filters not related to the index
// e.g. "...filter by OTHER_COL = 1".
String predicate = explainPredicate(predicatePrefix);
// Describe the table name and either a user-provided name of the index or
// its user-specified role ("primary key").
String tableName = m_targetTableName;
if (m_targetTableAlias != null && !m_targetTableAlias.equals(m_targetTableName)) {
tableName += " (" + m_targetTableAlias + ")";
}
String retval = "INDEX SCAN of \"" + tableName + "\"";
String indexDescription = " using \"" + m_targetIndexName + "\"";
// Replace ugly system-generated index name with a description of its user-specified role.
if (m_targetIndexName.startsWith(HSQLInterface.AUTO_GEN_PRIMARY_KEY_PREFIX) || m_targetIndexName.startsWith(HSQLInterface.AUTO_GEN_NAMED_CONSTRAINT_IDX) || m_targetIndexName.equals(HSQLInterface.AUTO_GEN_MATVIEW_IDX)) {
indexDescription = " using its primary key index";
}
// Bring all the pieces together describing the index, how it is scanned,
// and whatever extra filter processing is done to the result.
retval += indexDescription;
retval += usageInfo + predicate;
return retval;
}
Aggregations