📄 sqlparser.java
字号:
break; } } return retval; } /** * Get a DELETE node given the pieces. * * * @exception StandardException */ private QueryTreeNode getDeleteNode(FromTable fromTable, TableName tableName, ValueNode whereClause) throws StandardException { FromList fromList = (FromList) nodeFactory.getNode( C_NodeTypes.FROM_LIST, getContextManager()); QueryTreeNode retval; SelectNode resultSet; fromList.addFromTable(fromTable); resultSet = (SelectNode) nodeFactory.getNode( C_NodeTypes.SELECT_NODE, null, null, /* AGGREGATE list */ fromList, /* FROM list */ whereClause, /* WHERE clause */ null, /* GROUP BY list */ getContextManager()); retval = (QueryTreeNode) nodeFactory.getNode( C_NodeTypes.DELETE_NODE, tableName, resultSet, getContextManager()); setUpAndLinkParameters(); return retval; } /** * Get an UPDATE node given the pieces. * * * @exception StandardException */ private QueryTreeNode getUpdateNode(FromTable fromTable, TableName tableName, ResultColumnList setClause, ValueNode whereClause) throws StandardException { FromList fromList = (FromList) nodeFactory.getNode( C_NodeTypes.FROM_LIST, getContextManager()); QueryTreeNode retval; SelectNode resultSet; fromList.addFromTable(fromTable); resultSet = (SelectNode) nodeFactory.getNode( C_NodeTypes.SELECT_NODE, setClause, null, /* AGGREGATE list */ fromList, /* FROM list */ whereClause, /* WHERE clause */ null, /* GROUP BY list */ getContextManager()); retval = (QueryTreeNode) nodeFactory.getNode( C_NodeTypes.UPDATE_NODE, tableName, resultSet, getContextManager()); setUpAndLinkParameters(); return retval; } /** * Determine whether the next sequence of tokens can be the beginning * of a remainingPredicate() rule. * * @return TRUE iff the next set of tokens is the beginning of a * remainingPredicate() */ private boolean remainingPredicateFollows() { boolean retval = false; switch (getToken(1).kind) { case EQUALS_OPERATOR: case NOT_EQUALS_OPERATOR: case NOT_EQUALS_OPERATOR2: // != case LESS_THAN_OPERATOR: case GREATER_THAN_OPERATOR: case LESS_THAN_OR_EQUALS_OPERATOR: case GREATER_THAN_OR_EQUALS_OPERATOR: case IN: case LIKE: case BETWEEN: retval = true; break; case NOT: switch (getToken(2).kind) { case IN: case LIKE: case BETWEEN: retval = true; } break; } return retval; } /** * Determine whether the next token is a DROP * * @return TRUE iff the next token is DROP */ private boolean dropFollows() { if (getToken(1).kind == DROP) { return true; } else { return false; } } /** * Determine whether the next sequence of tokens can be the beginning * of a escapedValueFunction(). * * We check only for the punctuation here, because identifiers are * very hard to check for in semantic lookahead. * * @return TRUE iff the next set of tokens is the beginning of a * escapedValueFunction() */ private boolean escapedValueFunctionFollows() { if (getToken(1).kind != LEFT_BRACE) { return false; } return getToken(2).kind == FN; } /** * Determine whether the next sequence of tokens can be the beginning * of a columnInvocation() rule. columnInvocations start with * [ [ id . ] id . ] id . id ( * * We check only for the punctuation here, because identifiers are * very hard to check for in semantic lookahead. * * @return TRUE iff the next set of tokens is the beginning of a * columnInvocation() */ private boolean columnMethodInvocationFollows() { int tokKind; // First token must not be a built-in function name that can be // followed immediately by a PERIOD. There are only a few of // these - most built-in functions have a LEFT_PAREN following // the function name. // if we run out of token, it's probably a syntax error, // in fact tokKind = getToken(1).kind; if ( tokKind == EOF ) { return false; } // disambiguate from named parameter reference if ( getToken(1).image.charAt(0) == '?' ) { return false; } if (tokKind == CURRENT_DATE || tokKind == CURRENT_TIME || tokKind == CURRENT_TIMESTAMP || tokKind == CURRENT && (isDATETIME(getToken(2).kind)) ) { return false; } // Second token must be a PERIOD if (getToken(2).kind != PERIOD) { return false; } // We have established that we start with " id . " tokKind = getToken(4).kind; if (tokKind == LEFT_PAREN) { // id.id( return true; } // Not id.id(, so 4th token must be PERIOD if (tokKind != PERIOD) { return false; } tokKind = getToken(6).kind; if (tokKind == LEFT_PAREN) { // id.id.id( return true; } // Not id.id.id(, so 6th token must be PERIOD if (tokKind != PERIOD) { return false; } tokKind = getToken(8).kind; if (tokKind == LEFT_PAREN) { // id.id.id.id( return true; } return false; } /** * Determine whether the next sequence of tokens can be the beginning * of an aggregateNode()() rule. aggregateNodes() start with one * of the built-in aggregate names, or with an identifier followed * by "( DISTINCT". A non-distinct user-defined aggregate invocation * is treated as a staticMethodInvocationAlias() by the parser, * and the binding phase figures out what it really is by looking * at the data dictionary. * * We check only for the punctuation here, because identifiers are * very hard to check for in semantic lookahead. * * @return TRUE iff the next set of tokens is the beginning of a * aggregateNode() */ private boolean aggregateFollows() { boolean retval = false; switch (getToken(1).kind) { case MAX: case AVG: case MIN: case SUM: // This is a built-in aggregate retval = true; break; case COUNT: // COUNT is not a reserved word // This may eclipse use of COUNT as a function or a procedure that is probably what we want if (getToken(2).kind == LEFT_PAREN) retval = true; default: // Not a built-in aggregate - assume the first token is an // identifier, and see whether it is followed by " ( DISTINCT " if (getToken(2).kind == LEFT_PAREN && getToken(3).kind == DISTINCT) retval = true; break; } return retval; } /** * Determine whether the next sequence of tokens can be the beginning * of a miscBuiltins(). * * We check only for the punctuation here, because identifiers are * very hard to check for in semantic lookahead. * * @return TRUE iff the next set of tokens is the beginning of a * aggregateNode() */ private boolean miscBuiltinFollows() { boolean retval = false; int tokKind = getToken(1).kind; if (getToken(0).kind == CALL) retval = true; switch (tokKind) { case GET_CURRENT_CONNECTION: case CURRENT_DATE: case CURRENT_TIME: case CURRENT_TIMESTAMP: retval = true; break; case CURRENT: if (isDATETIME(getToken(2).kind)) retval = true; break; case CAST: case LEFT_PAREN: retval = false; break; default: if (getToken(2).kind == LEFT_PAREN) retval = true; break; } return retval; } /** * Determine whether the next sequence of tokens can be the beginning * of a subquery. A subquery can begin with an arbitrary number of * left parentheses, followed by either SELECT or VALUES. * * @return TRUE iff the next set of tokens is the beginning of a * subquery. */ private boolean subqueryFollows() { int tokKind; boolean retval = false; for (int i = 1; true; i++) { tokKind = getToken(i).kind; if (tokKind == LEFT_PAREN) { // A subquery can start with an arbitrary number of left // parentheses. continue; } else if (tokKind == SELECT || tokKind == VALUES)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -